From f0b0c9d98798bd2190a07de863a1d9f3f6c27fc2 Mon Sep 17 00:00:00 2001 From: Viktar Makouski Date: Mon, 25 Sep 2023 19:14:27 +0300 Subject: [PATCH 001/121] Running all tests even if one was failed --- tools/run-tests-zkasm.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/run-tests-zkasm.js b/tools/run-tests-zkasm.js index 904c1f10..5304e07b 100644 --- a/tools/run-tests-zkasm.js +++ b/tools/run-tests-zkasm.js @@ -40,7 +40,7 @@ async function runTest(pathTest, cmPols) { allowOverwriteLabels: true, }; - const rom = await zkasm.compile(pathTest, null, configZkasm); + const config = { debug: true, stepsN: 8388608, @@ -49,6 +49,7 @@ async function runTest(pathTest, cmPols) { // execute zkasm tests try { + const rom = await zkasm.compile(pathTest, null, configZkasm); const result = await smMain.execute(cmPols.Main, emptyInput, rom, config); console.log(chalk.green(' --> pass'), pathTest); if (argv.verbose) { @@ -62,7 +63,7 @@ async function runTest(pathTest, cmPols) { } } catch (e) { console.log(chalk.red(' --> fail'), pathTest); - throw new Error(e); + console.log(e); } } From 927ecd0438c9fd43436bee61e1db5a7fa7b61eff Mon Sep 17 00:00:00 2001 From: Viktar Makouski Date: Mon, 25 Sep 2023 19:26:25 +0300 Subject: [PATCH 002/121] Exit code handling --- tools/run-tests-zkasm.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/run-tests-zkasm.js b/tools/run-tests-zkasm.js index 5304e07b..a31b1541 100644 --- a/tools/run-tests-zkasm.js +++ b/tools/run-tests-zkasm.js @@ -21,14 +21,20 @@ async function main() { // Get all zkasm files const pathZkasm = path.join(process.cwd(), process.argv[2]); const files = await getTestFiles(pathZkasm); - + + let exit_code = 0; // Run all zkasm files // eslint-disable-next-line no-restricted-syntax console.log(chalk.yellow('--> Start running zkasm files')); for (const file of files) { if (file.includes('ignore')) continue; - await runTest(file, cmPols); + if (await runTest(file, cmPols) == 1) { + exit_code = 1; + } + } + if (exit_code == 1) { + process.exit(1); } } @@ -46,7 +52,7 @@ async function runTest(pathTest, cmPols) { stepsN: 8388608, assertOutputs: false, }; - + let exit_code = 0; // execute zkasm tests try { const rom = await zkasm.compile(pathTest, null, configZkasm); @@ -64,7 +70,9 @@ async function runTest(pathTest, cmPols) { } catch (e) { console.log(chalk.red(' --> fail'), pathTest); console.log(e); + exit_code = 1; } + return exit_code; } main(); From 0cc962b65c8b70adcf0aae3a4b153629a9627d12 Mon Sep 17 00:00:00 2001 From: Viktar Makouski Date: Tue, 26 Sep 2023 15:59:04 +0300 Subject: [PATCH 003/121] switch to bool flag instead exit code --- tools/run-tests-zkasm.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/run-tests-zkasm.js b/tools/run-tests-zkasm.js index a31b1541..0dd374de 100644 --- a/tools/run-tests-zkasm.js +++ b/tools/run-tests-zkasm.js @@ -22,7 +22,7 @@ async function main() { const pathZkasm = path.join(process.cwd(), process.argv[2]); const files = await getTestFiles(pathZkasm); - let exit_code = 0; + let wasFailed = false; // Run all zkasm files // eslint-disable-next-line no-restricted-syntax console.log(chalk.yellow('--> Start running zkasm files')); @@ -30,14 +30,15 @@ async function main() { if (file.includes('ignore')) continue; if (await runTest(file, cmPols) == 1) { - exit_code = 1; + wasFailed = true; } } - if (exit_code == 1) { + if (wasFailed) { process.exit(1); } } +// returns true if test succeed and false if test failed async function runTest(pathTest, cmPols) { // Compile rom const configZkasm = { @@ -52,7 +53,7 @@ async function runTest(pathTest, cmPols) { stepsN: 8388608, assertOutputs: false, }; - let exit_code = 0; + let failed = false; // execute zkasm tests try { const rom = await zkasm.compile(pathTest, null, configZkasm); @@ -70,9 +71,9 @@ async function runTest(pathTest, cmPols) { } catch (e) { console.log(chalk.red(' --> fail'), pathTest); console.log(e); - exit_code = 1; + failed = true; } - return exit_code; + return failed; } main(); From 52c68ea1c89523a338d552e09cea062387b83b9a Mon Sep 17 00:00:00 2001 From: Ignasi Date: Mon, 21 Aug 2023 10:50:05 +0200 Subject: [PATCH 004/121] Fork etrog implementation Set l2 tx hash computing at rlp parsing Fix counters + counter tests Fix log index add pairings add modexp fixes & updates forkid6 update tests zkasm & helpers Cleaning the repo Fixing tests Minor refactor and removing unnecessary zkasm files Cleaning the repo Removing some comments and moving unused files Big refactor of pairings Test passing now with a minor refactor Test refactor and module tree fixed Finished cleaning the pairing repo. Unused helpers removed Finished cleaning the modexp repo Setting the new number of chunks limit based on the gas limit Reorganization and optimizations fix modexp add tool labels last fixes & comments fix mulArith fix imports update package update package update GHA fix modexp gas fix outofgas modexp & delete helpers update package Optimizations and code clarifications Splitting the main operations in modexp and starting to perform tests... Bug in long divison fixed Fixing soundness errors in Fp arithemtic Modexp-op1 test generator update GHA fork-etrog fix selector add first counters modexp Uncovered paths fixed Some minor optimizations Almost all counters added. Some major optimizations. Ended the expected optimizations update pre-modexp counters Modexp counters done Fixing minor typos and uncommenting the counters --- .github/workflows/main.yaml | 2 +- counters/counters-executor.js | 39 +- counters/countersConstants.zkasm | 4 +- counters/endIncludes.zkasm | 3 +- counters/tests/opBLOCKHASH.zkasm | 2 +- main/block-info.zkasm | 178 ++ main/constants.zkasm | 41 +- main/load-change-l2-block.zkasm | 28 + main/load-tx-rlp-utils.zkasm | 16 + main/load-tx-rlp.zkasm | 60 +- main/main.zkasm | 101 +- main/modexp/README.md | 6 + main/modexp/array_lib/array_add_AGTB.zkasm | 132 ++ main/modexp/array_lib/array_add_short.zkasm | 88 + main/modexp/array_lib/array_div_mod.zkasm | 235 ++ .../modexp/array_lib/array_div_mod_long.zkasm | 260 ++ .../array_lib/array_div_mod_short.zkasm | 228 ++ main/modexp/array_lib/array_mul.zkasm | 103 + main/modexp/array_lib/array_mul_long.zkasm | 158 ++ main/modexp/array_lib/array_mul_short.zkasm | 123 + main/modexp/array_lib/array_square.zkasm | 275 +++ main/modexp/array_lib/unused/array_add.zkasm | 100 + .../array_lib/unused/array_is_odd.zkasm | 23 + .../array_lib/unused/array_is_one.zkasm | 33 + .../array_lib/unused/array_is_zero.zkasm | 34 + .../array_lib/unused/array_sub_AGTB.zkasm | 111 + .../array_lib/unused/array_unshift.zkasm | 37 + .../array_lib/utils/array_compare.zkasm | 88 + main/modexp/array_lib/utils/array_trim.zkasm | 47 + main/modexp/modexp.zkasm | 382 +++ main/modexp/modexp_utils.zkasm | 213 ++ main/opcodes/block.zkasm | 12 +- main/opcodes/create-terminate-context.zkasm | 12 +- main/opcodes/logs.zkasm | 72 +- main/pairings/BN254/addPointBN254.zkasm | 245 ++ main/pairings/BN254/ecAdd.zkasm | 311 +++ main/pairings/BN254/ecMul.zkasm | 158 ++ main/pairings/BN254/escalarMulBN254.zkasm | 155 ++ main/pairings/BN254/lineDiffPointsBN254.zkasm | 80 + main/pairings/BN254/lineSamePointsBN254.zkasm | 93 + .../CYCLOFP12BN254/compressFp12BN254.zkasm | 47 + .../CYCLOFP12BN254/decompressFp12BN254.zkasm | 231 ++ .../expByXCompCycloFp12BN254.zkasm | 443 ++++ .../squareCompCycloFp12BN254.zkasm | 210 ++ .../CYCLOFP12BN254/squareCycloFp12BN254.zkasm | 226 ++ .../CYCLOFP12BN254/xBinDecompBN254.zkasm | 64 + main/pairings/FP12BN254/frob2Fp12BN254.zkasm | 79 + main/pairings/FP12BN254/frob3Fp12BN254.zkasm | 95 + main/pairings/FP12BN254/frobFp12BN254.zkasm | 95 + .../pairings/FP12BN254/inverseFp12BN254.zkasm | 288 +++ main/pairings/FP12BN254/mulFp12BN254.zkasm | 407 ++++ .../FP12BN254/sparseMulAFp12BN254.zkasm | 295 +++ .../FP12BN254/sparseMulBFp12BN254.zkasm | 290 +++ main/pairings/FP12BN254/squareFp12BN254.zkasm | 375 +++ main/pairings/FP2BN254/addFp2BN254.zkasm | 18 + .../FP2BN254/escalarMulFp2BN254.zkasm | 19 + main/pairings/FP2BN254/invFp2BN254.zkasm | 17 + main/pairings/FP2BN254/mulFp2BN254.zkasm | 18 + main/pairings/FP2BN254/squareFp2BN254.zkasm | 20 + main/pairings/FP2BN254/subFp2BN254.zkasm | 18 + main/pairings/FP4BN254/squareFp4BN254.zkasm | 75 + main/pairings/FP6BN254/addFp6BN254.zkasm | 58 + .../FP6BN254/escalarMulFp6BN254.zkasm | 50 + main/pairings/FP6BN254/inverseFp6BN254.zkasm | 207 ++ main/pairings/FP6BN254/mulFp6BN254.zkasm | 200 ++ .../FP6BN254/sparseMulAFp6BN254.zkasm | 64 + .../FP6BN254/sparseMulBFp6BN254.zkasm | 133 ++ .../FP6BN254/sparseMulCFp6BN254.zkasm | 127 + main/pairings/FP6BN254/squareFp6BN254.zkasm | 146 ++ main/pairings/FP6BN254/subFp6BN254.zkasm | 58 + main/pairings/FPBN254/addFpBN254.zkasm | 27 + main/pairings/FPBN254/invFpBN254.zkasm | 49 + main/pairings/FPBN254/mulFpBN254.zkasm | 27 + main/pairings/FPBN254/reduceFpBN254.zkasm | 24 + main/pairings/FPBN254/squareFpBN254.zkasm | 29 + main/pairings/FPBN254/subFpBN254.zkasm | 28 + main/pairings/FRBN254/reduceFrBN254.zkasm | 24 + main/pairings/constants.zkasm | 62 + main/pairings/ecPairing.zkasm | 240 ++ main/pairings/finalExpBN254.zkasm | 2094 +++++++++++++++++ main/pairings/halfPairingBN254.zkasm | 428 ++++ main/pairings/loopLengthBN254.zkasm | 75 + main/pairings/millerLoopBN254.zkasm | 740 ++++++ main/pairings/pairingBN254.zkasm | 481 ++++ main/pairings/unused/addFp12BN254.zkasm | 130 + .../unused/expByXCycloFp12BN254.zkasm | 411 ++++ main/pairings/unused/expFp12BN254.zkasm | 333 +++ main/pairings/unused/subFp12BN254.zkasm | 130 + .../unused/xPseudoBinDecompBN254.zkasm | 68 + .../utilsTests/expCycloFp12BN254.zkasm | 333 +++ main/precompiled/end.zkasm | 19 +- main/precompiled/identity.zkasm | 11 +- main/precompiled/pre-ecAdd.zkasm | 92 + main/precompiled/pre-ecMul.zkasm | 89 + main/precompiled/pre-ecPairing.zkasm | 85 + main/precompiled/pre-ecrecover.zkasm | 10 + main/precompiled/pre-modexp.zkasm | 289 +++ main/precompiled/revert-precompiled.zkasm | 2 +- main/precompiled/selector.zkasm | 65 +- main/process-change-l2-block.zkasm | 111 + main/process-tx.zkasm | 25 +- main/utils.zkasm | 93 +- main/vars.zkasm | 26 +- package.json | 16 +- test/modexp-utils/README.md | 5 + test/modexp-utils/modexp-test-gen.js | 168 ++ test/modexp-utils/modexp-test-int.sage | 37 + test/testArrayArith.zkasm | 987 ++++++++ test/testArrayUtils.zkasm | 481 ++++ test/testCycloFp12ArithBN254.zkasm | 499 ++++ test/testEcAdd.zkasm | 255 ++ test/testEcMul.zkasm | 236 ++ test/testEcPairing.zkasm | 484 ++++ test/testFinalExpBn254.zkasm | 136 ++ test/testFp12ArithBN254.zkasm | 618 +++++ test/testFp2ArithBN254.zkasm | 138 ++ test/testFp4ArithBN254.zkasm | 128 + test/testFp6ArithBN254.zkasm | 238 ++ test/testFpArithBN254.zkasm | 145 ++ test/testFrArithBN254.zkasm | 113 + test/testHalfPairingBN254.zkasm | 132 ++ test/testModExp.zkasm | 452 ++++ test/testPairingBN254.zkasm | 442 ++++ test/testPointArithBN254.zkasm | 266 +++ tools/gen-parallel-tests.js | 9 +- tools/get-not-used-labels.js | 31 + tools/parallel-tests-sample/sample.test.js | 32 +- tools/run-tests-zkasm.js | 9 +- 128 files changed, 21146 insertions(+), 222 deletions(-) create mode 100644 main/block-info.zkasm create mode 100644 main/load-change-l2-block.zkasm create mode 100644 main/modexp/README.md create mode 100644 main/modexp/array_lib/array_add_AGTB.zkasm create mode 100644 main/modexp/array_lib/array_add_short.zkasm create mode 100644 main/modexp/array_lib/array_div_mod.zkasm create mode 100644 main/modexp/array_lib/array_div_mod_long.zkasm create mode 100644 main/modexp/array_lib/array_div_mod_short.zkasm create mode 100644 main/modexp/array_lib/array_mul.zkasm create mode 100644 main/modexp/array_lib/array_mul_long.zkasm create mode 100644 main/modexp/array_lib/array_mul_short.zkasm create mode 100644 main/modexp/array_lib/array_square.zkasm create mode 100644 main/modexp/array_lib/unused/array_add.zkasm create mode 100644 main/modexp/array_lib/unused/array_is_odd.zkasm create mode 100644 main/modexp/array_lib/unused/array_is_one.zkasm create mode 100644 main/modexp/array_lib/unused/array_is_zero.zkasm create mode 100644 main/modexp/array_lib/unused/array_sub_AGTB.zkasm create mode 100644 main/modexp/array_lib/unused/array_unshift.zkasm create mode 100644 main/modexp/array_lib/utils/array_compare.zkasm create mode 100644 main/modexp/array_lib/utils/array_trim.zkasm create mode 100644 main/modexp/modexp.zkasm create mode 100644 main/modexp/modexp_utils.zkasm create mode 100644 main/pairings/BN254/addPointBN254.zkasm create mode 100644 main/pairings/BN254/ecAdd.zkasm create mode 100644 main/pairings/BN254/ecMul.zkasm create mode 100644 main/pairings/BN254/escalarMulBN254.zkasm create mode 100644 main/pairings/BN254/lineDiffPointsBN254.zkasm create mode 100644 main/pairings/BN254/lineSamePointsBN254.zkasm create mode 100644 main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm create mode 100644 main/pairings/FP12BN254/frob2Fp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/frob3Fp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/frobFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/inverseFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/mulFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm create mode 100644 main/pairings/FP12BN254/squareFp12BN254.zkasm create mode 100644 main/pairings/FP2BN254/addFp2BN254.zkasm create mode 100644 main/pairings/FP2BN254/escalarMulFp2BN254.zkasm create mode 100644 main/pairings/FP2BN254/invFp2BN254.zkasm create mode 100644 main/pairings/FP2BN254/mulFp2BN254.zkasm create mode 100644 main/pairings/FP2BN254/squareFp2BN254.zkasm create mode 100644 main/pairings/FP2BN254/subFp2BN254.zkasm create mode 100644 main/pairings/FP4BN254/squareFp4BN254.zkasm create mode 100644 main/pairings/FP6BN254/addFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/escalarMulFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/inverseFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/mulFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/squareFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/subFp6BN254.zkasm create mode 100644 main/pairings/FPBN254/addFpBN254.zkasm create mode 100644 main/pairings/FPBN254/invFpBN254.zkasm create mode 100644 main/pairings/FPBN254/mulFpBN254.zkasm create mode 100644 main/pairings/FPBN254/reduceFpBN254.zkasm create mode 100644 main/pairings/FPBN254/squareFpBN254.zkasm create mode 100644 main/pairings/FPBN254/subFpBN254.zkasm create mode 100644 main/pairings/FRBN254/reduceFrBN254.zkasm create mode 100644 main/pairings/constants.zkasm create mode 100644 main/pairings/ecPairing.zkasm create mode 100644 main/pairings/finalExpBN254.zkasm create mode 100644 main/pairings/halfPairingBN254.zkasm create mode 100644 main/pairings/loopLengthBN254.zkasm create mode 100644 main/pairings/millerLoopBN254.zkasm create mode 100644 main/pairings/pairingBN254.zkasm create mode 100644 main/pairings/unused/addFp12BN254.zkasm create mode 100644 main/pairings/unused/expByXCycloFp12BN254.zkasm create mode 100644 main/pairings/unused/expFp12BN254.zkasm create mode 100644 main/pairings/unused/subFp12BN254.zkasm create mode 100644 main/pairings/unused/xPseudoBinDecompBN254.zkasm create mode 100644 main/pairings/utilsTests/expCycloFp12BN254.zkasm create mode 100644 main/precompiled/pre-ecAdd.zkasm create mode 100644 main/precompiled/pre-ecMul.zkasm create mode 100644 main/precompiled/pre-ecPairing.zkasm create mode 100644 main/precompiled/pre-modexp.zkasm create mode 100644 main/process-change-l2-block.zkasm create mode 100644 test/modexp-utils/README.md create mode 100644 test/modexp-utils/modexp-test-gen.js create mode 100644 test/modexp-utils/modexp-test-int.sage create mode 100644 test/testArrayArith.zkasm create mode 100644 test/testArrayUtils.zkasm create mode 100644 test/testCycloFp12ArithBN254.zkasm create mode 100644 test/testEcAdd.zkasm create mode 100644 test/testEcMul.zkasm create mode 100644 test/testEcPairing.zkasm create mode 100644 test/testFinalExpBn254.zkasm create mode 100644 test/testFp12ArithBN254.zkasm create mode 100644 test/testFp2ArithBN254.zkasm create mode 100644 test/testFp4ArithBN254.zkasm create mode 100644 test/testFp6ArithBN254.zkasm create mode 100644 test/testFpArithBN254.zkasm create mode 100644 test/testFrArithBN254.zkasm create mode 100644 test/testHalfPairingBN254.zkasm create mode 100644 test/testModExp.zkasm create mode 100644 test/testPairingBN254.zkasm create mode 100644 test/testPointArithBN254.zkasm create mode 100644 tools/get-not-used-labels.js diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index a02bb7d7..874a589b 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -6,7 +6,7 @@ name: Test executor inputs on: workflow_dispatch: pull_request: - branches: [main, develop] + branches: [main, develop, develop-etrog, feature/fork-etrog] jobs: build: diff --git a/counters/counters-executor.js b/counters/counters-executor.js index a72d65eb..a1213669 100644 --- a/counters/counters-executor.js +++ b/counters/counters-executor.js @@ -1,18 +1,23 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable no-use-before-define */ +/* eslint-disable no-restricted-syntax */ const path = require('path'); const fs = require('fs'); const smMain = require('@0xpolygonhermez/zkevm-proverjs/src/sm/sm_main/sm_main'); + const fileCachePil = path.join(__dirname, '../node_modules/@0xpolygonhermez/zkevm-proverjs/cache-main-pil.json'); -const empty_input = require('@0xpolygonhermez/zkevm-proverjs/test/inputs/empty_input.json') +const emptyInput = require('@0xpolygonhermez/zkevm-proverjs/test/inputs/empty_input.json'); const buildPoseidon = require('@0xpolygonhermez/zkevm-commonjs').getPoseidon; + const pathMainPil = path.join(__dirname, '../node_modules/@0xpolygonhermez/zkevm-proverjs/pil/main.pil'); const { newCommitPolsArray } = require('pilcom'); const { compile } = require('pilcom'); -const zkasm = require("@0xpolygonhermez/zkasmcom"); +const zkasm = require('@0xpolygonhermez/zkasmcom'); + const testFilesDir = path.join(__dirname, './tests'); const { argv } = require('yargs'); async function main() { - // Compile pil const cmPols = await compilePil(); @@ -20,8 +25,8 @@ async function main() { const files = getTestFiles(); // Run all zkasm files - for (let file of files) { - await runTest(file, cmPols) + for (const file of files) { + await runTest(file, cmPols); } } @@ -30,27 +35,28 @@ async function runTest(testName, cmPols) { // Compile rom const configZkasm = { defines: [], - allowUndefinedLabels: true + allowUndefinedLabels: true, }; const rom = await zkasm.compile(zkasmFile, null, configZkasm); const config = { debug: true, stepsN: 8388608, - } - console.log(`Running ${testName}`) + }; + console.log(`Running ${testName}`); // Execute test - const res = await smMain.execute(cmPols.Main, empty_input, rom, config); - console.log(res.counters) + const res = await smMain.execute(cmPols.Main, emptyInput, rom, config); + console.log(res.counters); } // Get all zkasm counter test files function getTestFiles() { - if(argv.test){ - return [`${argv.test}.zkasm`] + if (argv.test) { + return [`${argv.test}.zkasm`]; } - const files = fs.readdirSync(testFilesDir).filter(name => name.endsWith('.zkasm')) - return files + const files = fs.readdirSync(testFilesDir).filter((name) => name.endsWith('.zkasm')); + + return files; } async function compilePil() { @@ -60,14 +66,15 @@ async function compilePil() { const pilConfig = { defines: { N: 4096 }, namespaces: ['Main', 'Global'], - disableUnusedError: true + disableUnusedError: true, }; const p = await compile(F, pathMainPil, null, pilConfig); fs.writeFileSync(fileCachePil, `${JSON.stringify(p, null, 1)}\n`, 'utf8'); } const pil = JSON.parse(fs.readFileSync(fileCachePil)); + return newCommitPolsArray(pil); } -main() \ No newline at end of file +main(); diff --git a/counters/countersConstants.zkasm b/counters/countersConstants.zkasm index 5712a24c..b35d6a4a 100644 --- a/counters/countersConstants.zkasm +++ b/counters/countersConstants.zkasm @@ -248,8 +248,8 @@ CONST %OPCREATE_CNT_MEM_ALIGN = 0 CONST %OPCREATE_CNT_PADDING_PG = 0 CONST %OPCREATE_CNT_POSEIDON_G = 23 ; opCREATE2 - COMPLEX - hardcoded values at test -CONST %OPCREATE2_STEP = 500 -CONST %OPCREATE2_CNT_BINARY = 22 +CONST %OPCREATE2_STEP = 400 +CONST %OPCREATE2_CNT_BINARY = 21 CONST %OPCREATE2_CNT_ARITH = 2 CONST %OPCREATE2_CNT_KECCAK_F = 0 CONST %OPCREATE2_CNT_MEM_ALIGN = 0 diff --git a/counters/endIncludes.zkasm b/counters/endIncludes.zkasm index aea4e436..5027bb08 100644 --- a/counters/endIncludes.zkasm +++ b/counters/endIncludes.zkasm @@ -14,4 +14,5 @@ INCLUDE "../main/opcodes/logs.zkasm" INCLUDE "../main/opcodes/stack-operations.zkasm" INCLUDE "../main/opcodes/storage-memory.zkasm" INCLUDE "../main/touched.zkasm" -INCLUDE "../main/end.zkasm" \ No newline at end of file +INCLUDE "../main/end.zkasm" +INCLUDE "../main/block-info.zkasm" \ No newline at end of file diff --git a/counters/tests/opBLOCKHASH.zkasm b/counters/tests/opBLOCKHASH.zkasm index f534d4e0..0679c951 100644 --- a/counters/tests/opBLOCKHASH.zkasm +++ b/counters/tests/opBLOCKHASH.zkasm @@ -5,7 +5,7 @@ start: operation: 2 :HASHK1(0) - 10 :MSTORE(txCount) + 10 :MSTORE(blockNum) 1 :MSTORE(SP++) :JMP(opBLOCKHASH) checkCounters: diff --git a/main/block-info.zkasm b/main/block-info.zkasm new file mode 100644 index 00000000..618e9489 --- /dev/null +++ b/main/block-info.zkasm @@ -0,0 +1,178 @@ +VAR GLOBAL tmpBlockInfoSR +VAR GLOBAL currentLogIndex + +initBlockInfoTree: + 0 :MSTORE(blockInfoSR), RETURN + +; @info Save blockInfo root when a new context is created +checkpointBlockInfoTree: + $ => B :MLOAD(currentLogIndex) + B :MSTORE(initLogIndex) + $ => B :MLOAD(blockInfoSR) + B :MSTORE(initBlockInfoSR), RETURN + +; @info Back to initial blockInfo root +revertBlockInfoTree: + $ => A :MLOAD(initLogIndex) + A :MSTORE(currentLogIndex) + $ => A :MLOAD(initBlockInfoSR) + A :MSTORE(blockInfoSR), RETURN + +; @info Fill Block Info tree with initial block values +setupNewBlockInfoTree: + ; checks zk-counters + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*6 :JMPN(outOfCountersPoseidon) + ; save current state root & load block info root + SR :MSTORE(tmpBlockInfoSR) + $ => SR :MLOAD(blockInfoSR) + + ; Insert previous block hash + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: previousBlockHash + %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + $ => D :MLOAD(previousBlockHash) + $ => SR :SSTORE + + ; Insert coinbase address + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: sequencerAddr + %INDEX_BLOCK_HEADER_PARAM_COINBASE => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + $ => D :MLOAD(sequencerAddr) + $ => SR :SSTORE + + ; Insert block number + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: blockNum + %INDEX_BLOCK_HEADER_PARAM_NUMBER => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + $ => D :MLOAD(blockNum) + $ => SR :SSTORE + + ; Insert block gas limit + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: blockNum + %INDEX_BLOCK_HEADER_PARAM_GAS_LIMIT => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + %BLOCK_GAS_LIMIT => D + $ => SR :SSTORE + + ; Insert block timestamp + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: timestamp + %INDEX_BLOCK_HEADER_PARAM_TIMESTAMP => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + $ => D :MLOAD(timestamp) + $ => SR :SSTORE + + ; Insert block timestamp + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: GER + %INDEX_BLOCK_HEADER_PARAM_GER => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + $ => D :MLOAD(newGER) + $ => SR :SSTORE + + ; Restore current SR + SR :MSTORE(blockInfoSR) + $ => SR :MLOAD(tmpBlockInfoSR), RETURN + +; @info Fill Block Info tree with tx receipt values +fillBlockInfoTreeWithTxReceipt: + ; checks zk-counters + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon) + ; save current state root & load block info root + SR :MSTORE(tmpBlockInfoSR) + $ => SR :MLOAD(blockInfoSR) + ; Insert transaction hash + ; key: H([txIndex[0:4], txIndex[4:8], txIndex[8:12], txIndex[12:16], txIndex[16:20], 0, SMT_KEY_BLOCK_HEADER_TRANSACTION_HASH, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: txHash + $ => A :MLOAD(txIndex) + %SMT_KEY_BLOCK_HEADER_TRANSACTION_HASH => B + 0 => C + $ => D :MLOAD(l2TxHash) + $ => SR :SSTORE + + ; Insert transaction status + ; key: H([txIndex[0:4], txIndex[4:8], txIndex[8:12], txIndex[12:16], txIndex[16:20], 0, SMT_KEY_BLOCK_HEADER_STATUS, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: txStatus + %SMT_KEY_BLOCK_HEADER_STATUS => B + 0 => C + $ => D :MLOAD(txStatus) + $ => SR :SSTORE + + ; Insert transaction cumulativeGasUsed + ; key: H([txIndex[0:4], txIndex[4:8], txIndex[8:12], txIndex[12:16], txIndex[16:20], 0, SMT_KEY_BLOCK_HEADER_CUMULATIVE_GAS_USED, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: txStatus + %SMT_KEY_BLOCK_HEADER_CUMULATIVE_GAS_USED => B + 0 => C + $ => D :MLOAD(cumulativeGasUsed) + $ => SR :SSTORE + + ; Restore current SR + SR :MSTORE(blockInfoSR) + $ => SR :MLOAD(tmpBlockInfoSR), RETURN + +; @info Fill Block Info tree with block gas used at the end of block processing and Store block Info Root in storage +consolidateBlock: + ; checks zk-counters + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) + ; save current state root & load block info root + SR :MSTORE(tmpBlockInfoSR) + $ => SR :MLOAD(blockInfoSR) + + ; Insert transaction cumulativeGasUsed + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: txStatus + %INDEX_BLOCK_HEADER_PARAM_GAS_USED => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + $ => D :MLOAD(cumulativeGasUsed) + $ => SR :SSTORE + + ; Restore current SR + SR :MSTORE(blockInfoSR) + $ => SR :MLOAD(tmpBlockInfoSR) + + ; Store block Info Root in storage + %ADDRESS_SYSTEM => A + %SMT_KEY_SC_STORAGE => B + %BLOCK_INFO_ROOT_STORAGE_POS => C + $ => D :MLOAD(blockInfoSR) + $ => SR :SSTORE, RETURN + +; @info add new log hash to block info tree +; @in D => Value to store (linearPoseidon(log_data + log_topics)) +fillBlockInfoTreeWithLog: + ; checks zk-counters + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE :JMPN(outOfCountersPoseidon) + ; save current state root & load block info root + SR :MSTORE(tmpBlockInfoSR) + $ => SR :MLOAD(blockInfoSR) + + ; Retrieve and update curentLogIndex + $ => C :MLOAD(currentLogIndex) + C + 1 :MSTORE(currentLogIndex) + + ; Insert new log to block info tree + ; key: H([logIndexKey[0:4], logIndexKey[4:8], logIndexKey[8:12], logIndexKey[12:16], logIndexKey[16:20], 0, SMT_KEY_BLOCK_HEADER_LOGS, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; hk0: H([logIndex[0:4], logIndex[4:8], logIndex[8:12], logIndex[12:16], logIndex[16:20], logIndex[20:24], logIndex[24:28], logIndex[28:32], [0, 0, 0, 0]) + ; value: linearPoseidon(log_data + log_topics) + $ => A :MLOAD(txIndex) + %SMT_KEY_BLOCK_HEADER_LOGS => B + $ => SR :SSTORE + + ; Restore current SR + SR :MSTORE(blockInfoSR) + $ => SR :MLOAD(tmpBlockInfoSR), RETURN \ No newline at end of file diff --git a/main/constants.zkasm b/main/constants.zkasm index 4b2e41ec..ddd831f6 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -4,14 +4,22 @@ CONSTL %ADDRESS_SYSTEM = 0x000000000000000000000000000000005ca1ab1en CONST %MAX_STACK_SIZE = 1024 CONST %BATCH_DIFFICULTY = 0 CONST %TX_GAS_LIMIT = 30000000 -CONST %GLOBAL_EXIT_ROOT_STORAGE_POS = 0 -CONST %LOCAL_EXIT_ROOT_STORAGE_POS = 1 -CONST %LAST_TX_STORAGE_POS = 0 -CONST %STATE_ROOT_STORAGE_POS = 1 +CONST %BLOCK_GAS_LIMIT = 2**32-1 CONST %MAX_MEM_EXPANSION_BYTES = 0x3fffe0 CONST %FORK_ID = 6 +CONST %GER_TREE_LEVELS = 32 CONST %CALLDATA_RESERVED_CTX = 1 +; GER manager storage positions constants +CONST %GLOBAL_EXIT_ROOT_STORAGE_POS = 0 +CONST %LOCAL_EXIT_ROOT_STORAGE_POS = 1 + +; System address storage positions constants +CONST %LAST_BLOCK_STORAGE_POS = 0 +CONST %STATE_ROOT_STORAGE_POS = 1 +CONST %TIMESTAMP_STORAGE_POS = 2 +CONST %BLOCK_INFO_ROOT_STORAGE_POS = 3 + ; RLP CONST %MIN_VALUE_SHORT = 128 CONST %MIN_BYTES_LONG = 56 @@ -27,6 +35,22 @@ CONST %SMT_KEY_SC_LENGTH = 4 CONST %SMT_KEY_TOUCHED_ADDR = 5 CONST %SMT_KEY_TOUCHED_SLOTS = 6 +; SMT block header constants +CONST %SMT_KEY_BLOCK_HEADER_PARAM = 7 +CONST %SMT_KEY_BLOCK_HEADER_TRANSACTION_HASH = 8 +CONST %SMT_KEY_BLOCK_HEADER_STATUS = 9 +CONST %SMT_KEY_BLOCK_HEADER_CUMULATIVE_GAS_USED = 10 +CONST %SMT_KEY_BLOCK_HEADER_LOGS = 11 + +; SMT block header data leaf keys +CONST %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH = 0; +CONST %INDEX_BLOCK_HEADER_PARAM_COINBASE = 1; +CONST %INDEX_BLOCK_HEADER_PARAM_NUMBER = 2; +CONST %INDEX_BLOCK_HEADER_PARAM_GAS_LIMIT = 3; +CONST %INDEX_BLOCK_HEADER_PARAM_TIMESTAMP = 4; +CONST %INDEX_BLOCK_HEADER_PARAM_GER = 5; +CONST %INDEX_BLOCK_HEADER_PARAM_GAS_USED = 6; + ; GAS CONST %BASE_TX_GAS = 21000 CONST %BASE_TX_DEPLOY_GAS = 53000 @@ -43,6 +67,9 @@ CONST %CALL_STIPEND = 2300 CONST %ECRECOVER_GAS = 3000 ; Elliptic curve sender recovery gas price CONST %IDENTITY_GAS = 15 ; Base price for a data copy operation CONST %IDENTITY_WORD_GAS = 3 ; Per-work price for a data copy operation +CONST %ECADD_GAS = 150; ecAdd gas price +CONST %ECMUL_GAS = 6000; ecMul gas price +CONST %ECPAIRING_GAS = 45000; ecPairing gas price CONST %KECCAK_GAS = 30 ; Once per KECCAK256 operation. CONST %KECCAK_WORD_GAS = 6 ; Once per word of the KECCAK256 operation's data. CONST %LOG_GAS = 375 ; Per LOG* operation. @@ -98,4 +125,8 @@ CONST %MIN_CNT_KECCAK_BATCH = 1 ; minimum necessary keccaks to compute global ha CONSTL %MAX_NONCE = 0xffffffffffffffffn CONSTL %MAX_UINT_256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn CONST %CODE_SIZE_LIMIT = 0x6000 -CONST %BYTECODE_STARTS_EF = 0xEF \ No newline at end of file +CONST %BYTECODE_STARTS_EF = 0xEF +CONST %MAX_SIZE_MODEXP = 2147483647 +CONSTL %MAX_SAFE_INTEGER_MODEXP = 0x1fffffffffffffn +CONST %MAX_GAS_WORD_MODEXP = 9487 +CONSTL %MAX_GAS_IT_MODEXP = 90000000; %TX_GAS_LIMIT*3 \ No newline at end of file diff --git a/main/load-change-l2-block.zkasm b/main/load-change-l2-block.zkasm new file mode 100644 index 00000000..16e25b33 --- /dev/null +++ b/main/load-change-l2-block.zkasm @@ -0,0 +1,28 @@ +decodeChangeL2BlockTx: + ; No changeL2BlockTx to allowed at forced batches + $ :MLOAD(isForced), JMPNZ(invalidTxRLP) + + ; decode "txType" / 1 byte + 1 => D :CALL(getTxData) + C + D => C :CALL(addBatchHashData) + ; Decode deltaTimestamp / 8 bytes + 8 => D :CALL(getTxData) + C + D => C :CALL(addBatchHashData) + A :MSTORE(deltaTimestamp) + ; Decode indexHistGERTree / 4 bytes + 4 => D :CALL(getTxData) + C + D => C :CALL(addBatchHashData) + A :MSTORE(indexHistGERTree) + 1 :MSTORE(isChangeL2BlockTx), JMP(finishLoadChangeL2BlockTx) + +getTxData: + ${getTxs(p,D)} => A + $${p = p + D} + :RETURN +finishLoadChangeL2BlockTx: +;; update bytes parsed + $ => A :MLOAD(batchL2DataParsed) + A + C :MSTORE(batchL2DataParsed) +;; increase number of transaction to process + $ => A :MLOAD(pendingTxs) + A + 1 :MSTORE(pendingTxs), JMP(txLoopRLP) \ No newline at end of file diff --git a/main/load-tx-rlp-utils.zkasm b/main/load-tx-rlp-utils.zkasm index 93639d06..f5046940 100644 --- a/main/load-tx-rlp-utils.zkasm +++ b/main/load-tx-rlp-utils.zkasm @@ -17,6 +17,21 @@ getTxBytes: $${p = p + D} :RETURN +VAR CTX l2HASHP +VAR GLOBAL addL2HashTxAux +;Add bytes to generate L2 transaction hash. transactionHash = linearPoseidon(nonce, gasprice, gaslimit, to, value, data, from) +; @in A => bytes to add to hash +; @in D => length of the bytes to add to hash +addL2HashTx: + E => B + $ => E :MLOAD(l2TxHashPointer) + HASHPOS :MSTORE(addL2HashTxAux) + $ => HASHPOS :MLOAD(l2HASHP) + A :HASHP(E) + HASHPOS :MSTORE(l2HASHP) + $ => HASHPOS :MLOAD(addL2HashTxAux) + B => E :RETURN + ;; Add bytes to generate ethereum transaction hash. transactionHash = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)) addHashTx: $ => A :MLOAD(txRLPLength) @@ -30,6 +45,7 @@ addHashTxBegin: A :HASHK(E) C + D => C :RETURN + ;; Check short value is over 127. Error RLP: single byte < 0x80 are not prefixed checkShortRLP: D - 1 :JMPNZ(skipCheckShort) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index ca6f7c91..75f3e77e 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -1,4 +1,6 @@ INCLUDE "load-tx-rlp-utils.zkasm" +INCLUDE "load-change-l2-block.zkasm" + ; Blocks RLP parsing ; A - Initialization ; B - Read and check RLP fields. Fill 'batchHashData' and Ethereum signed transaction bytes @@ -22,12 +24,24 @@ loadTx_rlp: ; A new hash with position 0 is started 0 => HASHPOS - ; We get a new hashId - $ => E :MLOAD(lastHashKIdUsed) - E+1 => E :MSTORE(lastHashKIdUsed) ; Pointer to next RLP bytes to read 0 => C + ; Check its a change L2 block transaction + 1 => D + ${getTxs(p,D)} => A + A - 0x0b :JMPZ(decodeChangeL2BlockTx) + ; First transaction must be a change L2 block transaction if is NOT a forced batch + $ => A :MLOAD(pendingTxs), JMPNZ(loadTx_rlp_continue) + ; If is not forced and is not a change L2 block transaction, we discard the entire batch + $ :MLOAD(isForced), JMPZ(invalidTxRLP) +loadTx_rlp_continue: + ; We get a new hashId + $ => E :MLOAD(nextHashPId) + E :MSTORE(l2TxHashPointer) + E + 1 :MSTORE(nextHashPId) + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) ;;;;;;;;;;;;;;;;;; ;; B - Read and check RLP fields. Fill 'batchHashData' and Ethereum signed transaction bytes ;;;;;;;;;;;;;;;;;; @@ -54,7 +68,9 @@ shortList: endList: A + C => B :MSTORE(txRLPLength) - ; Check enough zk counters to digest tx hash + ; Check enough keccak zk counters to digest tx hash + ; We don't check poseidon counters spent for l2 tx hash computing because the number of poseidon counters available is x100 the number of keccack available + ; so while rlp parsing, keccaks will always be the bottleneck B + 1 :MSTORE(arithA) 136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => B :MLOAD(arithRes1) @@ -71,17 +87,18 @@ nonceREAD: A - 0x89 :JMPN(shortNonce, invalidTxRLP) nonce0: - 0 => A :MSTORE(lengthNonce), JMP(endNonce) + 0 => A :MSTORE(lengthNonce) + :JMP(endNonce) shortNonce: A - 0x80 => D - D :MSTORE(lengthNonce), CALL(addHashTx) + D :MSTORE(lengthNonce),CALL(addHashTx) :CALL(addBatchHashData) :CALL(checkShortRLP) :CALL(checkNonLeadingZeros) endNonce: - A :MSTORE(txNonce) + A :MSTORE(txNonce), CALL(addL2HashTx) ;; Read RLP 'gas price' ; 256 bits max @@ -102,7 +119,7 @@ shortGasPrice: :CALL(checkNonLeadingZeros) endGasPrice: - A :MSTORE(txGasPriceRLP) + A :MSTORE(txGasPriceRLP), CALL(addL2HashTx) ;; Read RLP 'gas limit' @@ -124,7 +141,7 @@ shortGasLimit: :CALL(checkNonLeadingZeros) endGasLimit: - A :MSTORE(txGasLimit) + A :MSTORE(txGasLimit), CALL(addL2HashTx) ;; Read RLP 'to' ; 160 bits or empty @@ -137,10 +154,12 @@ toREAD: A - 0x95 :JMPN(shortTo, invalidTxRLP) noTo: + 0 => A 1 :MSTORE(isCreateContract), JMP(endTo) shortTo: A - 0x80 => D :CALL(addHashTx) + :CALL(addL2HashTx) :CALL(addBatchHashData) A :MSTORE(txDestAddr) A :MSTORE(storageAddr) @@ -166,7 +185,7 @@ shortValue: :CALL(checkNonLeadingZeros) endValue: - A :MSTORE(txValue) + A :MSTORE(txValue), CALL(addL2HashTx) ;; Read RLP 'data' ; should not be a list @@ -188,7 +207,7 @@ dataREAD: A - 0xbb :JMPN(longData, invalidTxRLP) veryShortData: - 1 :MSTORE(txCalldataLen) + 1 :MSTORE(txCalldataLen), CALL(addL2HashTx) 31 => D :CALL(SHLarith) ; in: [A: value, D: #bytes to left shift] out: [A: shifted result] ; Store current CTX CTX => B @@ -219,7 +238,7 @@ readData: 32 => D B - D :JMPN(readDataFinal) B - D :MSTORE(txDataRead), CALL(addHashTx) - $ => E :MLOAD(globalCalldataMemoryOffset) + $ => E :MLOAD(globalCalldataMemoryOffset), CALL(addL2HashTx) ; Store current CTX CTX => B ; Store calldata to calldata CTX's memory @@ -233,6 +252,7 @@ readData: readDataFinal: B - 1 :JMPN(endData) B => D :CALL(addHashTx) + :CALL(addL2HashTx) 32 - D => D :CALL(SHLarith); in: [A: value, D: #bytes to left shift] out: [A: shifted result] $ => E :MLOAD(globalCalldataMemoryOffset) ; Store current CTX @@ -321,6 +341,7 @@ effectivePercentageTx: ;;;;;;;;; ;; D - Finish RLP parsing ;;;;;;;;; +finishLoadRLP: ;; update bytes parsed $ => A :MLOAD(batchL2DataParsed) A + C :MSTORE(batchL2DataParsed) @@ -329,7 +350,20 @@ effectivePercentageTx: A + 1 :MSTORE(pendingTxs) ;; compute signature $ => A :HASHKDIGEST(E) - A :MSTORE(txHash), JMP(txLoopRLP) + A :MSTORE(txHash) +;; Compute L2txHash +;; Get source address from tx signature + $ => B :MLOAD(txR) + $ => C :MLOAD(txS) + $ => D :MLOAD(txV), CALL(ecrecover_tx) + A :MSTORE(txSrcAddr) + 20 => D + $ => E :MLOAD(l2TxHashPointer) + $ => HASHPOS :MLOAD(l2HASHP) + A :HASHP(E) + HASHPOS :HASHPLEN(E) + $ => B :HASHPDIGEST(E) + B :MSTORE(l2TxHash),JMP(txLoopRLP) ;;;;;;;;; ;; E - Handler error RLP fields diff --git a/main/main.zkasm b/main/main.zkasm index fecd9f08..aa7e0acf 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -3,9 +3,9 @@ INCLUDE "vars.zkasm" ; Blocks zkROM ; A - Load initial registers into memory: oldStateRoot (B), oldAccInputHash (C), oldNumBatch (SP) & chainID (GAS) -; B - Set batch global variables +; B - Compute keccaks needed to finish the batch ; C - Loop parsing RLP transactions -; D - Loop processing transactions +; D - Load blockNum variable & Loop processing transactions ; E - Batch computations: get newLocalExitRoot, assert transactions size, compute batchHashData & compute newAccInputHash ; F - Finalize execution @@ -24,60 +24,22 @@ start: ; main zkROM entry point SP :MSTORE(oldNumBatch) GAS :MSTORE(chainID) ; assumed to be less than 32 bits - ${getGlobalExitRoot()} :MSTORE(globalExitRoot) + ${getHistoricGERRoot()} :MSTORE(historicGER) ${getSequencerAddr()} :MSTORE(sequencerAddr) - ${getTimestamp()} :MSTORE(timestamp) + ${getTimestampLimit()} :MSTORE(timestampLimit) ${getTxsLen()} :MSTORE(batchL2DataLength) ; less than 300.000 bytes. Enforced by the smart contract + ${getIsForced()} :MSTORE(isForced) B => SR ;set initial state root - + SR :MSTORE(batchSR) ; Increase batch number SP + 1 :MSTORE(newNumBatch) ;;;;;;;;;;;;;;;;;; -;; B - Set batch global variables -;; - set globalExitRoot in Bridge contract -;; - load transaction count from system smart contract -;; - compute keccaks needed to finish the batch +;; B - Compute keccaks needed to finish the batch ;;;;;;;;;;;;;;;;;; $${eventLog(onStartBatch, C)} - $ => A :MLOAD(globalExitRoot) - 0 => B - $ :EQ, JMPC(skipSetGlobalExitRoot) - -;; Set global exit root -setGlobalExitRoot: - 0 => HASHPOS - $ => E :MLOAD(lastHashKIdUsed) - E+1 => E :MSTORE(lastHashKIdUsed) - - 32 => D - A :HASHK(E) - %GLOBAL_EXIT_ROOT_STORAGE_POS :HASHK(E) ; Storage position of the global exit root map - HASHPOS :HASHKLEN(E) - $ => C :HASHKDIGEST(E) - - %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A - %SMT_KEY_SC_STORAGE => B - - ; read timestamp given the globalExitRoot - ; skip overwrite timestamp if it is different than 0 - ; Since timestamp is enforced by the smart contract it is safe to compare only 32 bits in 'op0' with JMPNZ - $ => D :SLOAD, JMPNZ(skipSetGlobalExitRoot) - - $ => D :MLOAD(timestamp) - $ => SR :SSTORE ; Store 'timestamp' in storage position 'keccak256(globalExitRoot, 0)' - -skipSetGlobalExitRoot: - SR :MSTORE(batchSR) - ; Load current tx count - %LAST_TX_STORAGE_POS => C - %ADDRESS_SYSTEM => A - %SMT_KEY_SC_STORAGE => B - $ => D :SLOAD - D :MSTORE(txCount) - ; Compute necessary keccak counters to finish batch $ => A :MLOAD(batchL2DataLength) ; Divide the total data length + 1 by 136 to obtain the keccak counter increment. @@ -95,7 +57,7 @@ skipSetGlobalExitRoot: ;; - If an error is found in any transaction, the batch will not process any transaction ;;;;;;;;;;;;;;;;;; - E+1 => E :MSTORE(lastHashKIdUsed) + 1 => E :MSTORE(lastHashKIdUsed) 0 :MSTORE(batchHashPos) E :MSTORE(batchHashDataId) $ => A :MLOAD(lastCtxUsed) @@ -116,26 +78,51 @@ txLoopRLP: endCheckRLP: ; set flag isLoadingRLP to 0 0 :MSTORE(isLoadingRLP) - :JMP(txLoop) ;;;;;;;;;;;;;;;;;; -;; D - Loop processing transactions -;; - Load transaction data and interpret it +;; D - Load blockNum variable +;; - Loop processing transactions +;; - Load transaction data and interpret it ;;;;;;;;;;;;;;;;;; +setBlockNum: + %LAST_BLOCK_STORAGE_POS => C + %ADDRESS_SYSTEM => A + %SMT_KEY_SC_STORAGE => B + $ :SLOAD,MSTORE(blockNum) + ; If forced batch, process a forced changeL2BlockTx + $ :MLOAD(isForced), JMPZ(txLoop, handleForcedBatch) +handleForcedBatch: + 1 :MSTORE(currentTx), JMP(processChangeL2Block) txLoop: $ => A :MLOAD(pendingTxs) A - 1 :MSTORE(pendingTxs), JMPN(processTxsEnd) - + $ => A :MLOAD(currentTx) + A + 1 :MSTORE(currentTx) $ => A :MLOAD(ctxTxToUse) ; Load first context used by transaction - A + 1 => CTX :MSTORE(ctxTxToUse),JMP(processTx) + A + 1 => CTX :MSTORE(ctxTxToUse) + ; Detect if transaction is a change L2 block tx + ; Store initial state at the beginning of the transaction + SR :MSTORE(originSR) + $ => A :MLOAD(isChangeL2BlockTx) + A - 1 :JMPZ(processChangeL2Block, processTx) -processTxEnd: - :CALL(updateSystemData) processTxFinished: + ; Increase cumulativeGasUsed + $ => A :MLOAD(txGasLimit) + A - GAS => A + $ => B :MLOAD(cumulativeGasUsed) + ; Fill block info tree with tx receipt + A + B :MSTORE(cumulativeGasUsed), CALL(fillBlockInfoTreeWithTxReceipt) + ; Increase txIndex + $ => A :MLOAD(txIndex) + A + 1 :MSTORE(txIndex) +processIntrinsicTxFinished: $${eventLog(onFinishTx)} :JMP(txLoop) processTxsEnd: + ; Write values at storage at the end of block processing + :CALL(consolidateBlock) ;;;;;;;;;;;;;;;;;; ;; E - Batch asserts & computations: @@ -178,17 +165,19 @@ processTxsEnd: $ => A :MLOAD(batchHashData) A :HASHK(0) - $ => A :MLOAD(globalExitRoot) + $ => A :MLOAD(historicGER) A :HASHK(0) 8 => D - $ => A :MLOAD(timestamp) + $ => A :MLOAD(timestampLimit) A :HASHK(0) 20 => D $ => A :MLOAD(sequencerAddr) A :HASHK(0) + $ => A :MLOAD(isForced) + A :HASHK1(0) HASHPOS :HASHKLEN(0) $ => C :HASHKDIGEST(0) @@ -215,5 +204,7 @@ processTxsEnd: INCLUDE "end.zkasm" INCLUDE "load-tx-rlp.zkasm" INCLUDE "process-tx.zkasm" +INCLUDE "process-change-l2-block.zkasm" INCLUDE "utils.zkasm" +INCLUDE "block-info.zkasm" diff --git a/main/modexp/README.md b/main/modexp/README.md new file mode 100644 index 00000000..2941e553 --- /dev/null +++ b/main/modexp/README.md @@ -0,0 +1,6 @@ +## Notes + +- We work with unbounded and unsigned integers represented in (little-endian) chunks of $256$ bits. +- The maximum input array lengths for the ModExp are justified [here](https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43), in particular: +$$\text{BLen} \leq 75.894, \quad \text{MLen} \leq 75.894, \quad \text{ELen} \leq 720M + 32.$$ + - This is important because it allows us to use the `JMPZ` instruction against the registers holding these values, instead of a binary `EQ` instruction, which is more costly. Here, remember that `JMPZ` only takes into account the first $32$ bits of the registers it is used for (i.e., you can safely use it as long as the register is between $0$ and $2^{32}$). \ No newline at end of file diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm new file mode 100644 index 00000000..2eda6c1f --- /dev/null +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -0,0 +1,132 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: len(inA) >= len(inB) +;; +;; +;; array_add_AGTB: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · out = inA + inB, with len(out) <= C + 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_add_AGTB(a: bigint[], b: bigint[], B: bigint): bigint[] { +; const alen = a.length; +; const blen = b.length; +; let result = new Array(alen); +; let sum = 0n; +; let carry = 0n; +; for (let i = 0; i < blen; i++) { +; sum = a[i] + b[i] + carry; +; carry = sum >= B ? 1n : 0n; +; result[i] = sum - carry * B; +; } +; for (let i = blen; i < alen; i++) { +; sum = a[i] + carry; +; carry = sum == B ? 1n : 0n; // the past carry is at most 1n +; result[i] = sum - carry * B; +; } + +; if (carry === 1n) { +; result.push(carry); +; } +; return result; +; } + +; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead if possible. + +VAR GLOBAL array_add_AGTB_inA[839] +VAR GLOBAL array_add_AGTB_inB[839] +VAR GLOBAL array_add_AGTB_out[840] +VAR GLOBAL array_add_AGTB_len_inA +VAR GLOBAL array_add_AGTB_len_inB +VAR GLOBAL array_add_AGTB_len_out + +VAR GLOBAL array_add_AGTB_carry + +VAR GLOBAL array_add_AGTB_RR + +array_add_AGTB: + %MAX_CNT_BINARY - CNT_BINARY - 3*D - 1 - C+ D - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 6 - 17*D - 4 - 11*C+11*D - 8 :JMPN(outOfCountersStep) + + RR :MSTORE(array_add_AGTB_RR) + + C :MSTORE(array_add_AGTB_len_inA) + D :MSTORE(array_add_AGTB_len_inB) + + 0 => E ; index in loops + 0 :MSTORE(array_add_AGTB_carry) + :JMP(array_add_AGTB_loopZero2inB) + +; Begin of branching +array_add_AGTB_add_carry1: + D + 1 => D :JMP(return_array_add_AGTB_add_carry1) + +array_add_AGTB_add_carry2: + D + 1 => D :JMP(return_array_add_AGTB_add_carry2) + +array_add_AGTB_add_carry3: + D + 1 => D :JMP(return_array_add_AGTB_add_carry3) +; End of branching + +array_add_AGTB_loopZero2inB: + 0 => D ; for the carry + + ; a[i] + b[i] + $ => A :MLOAD(array_add_AGTB_inA + E) + $ => B :MLOAD(array_add_AGTB_inB + E) + $ => C :ADD, JMPC(array_add_AGTB_add_carry1) + return_array_add_AGTB_add_carry1: + + ; sum = (a[i] + b[i]) + carry + $ => A :MLOAD(array_add_AGTB_carry) + C => B + $ => C :ADD, JMPC(array_add_AGTB_add_carry2) + return_array_add_AGTB_add_carry2: + + C :MSTORE(array_add_AGTB_out + E) + D :MSTORE(array_add_AGTB_carry) + + E + 1 => E + E => A + $ => B :MLOAD(array_add_AGTB_len_inB) + $ :EQ, JMPC(array_add_AGTB_loop_index_check1, array_add_AGTB_loopZero2inB) + +array_add_AGTB_loop_index_check1: + E => A + $ => B :MLOAD(array_add_AGTB_len_inA) + $ :EQ, JMPC(array_add_AGTB_check_carry) + 0 => D +array_add_AGTB_loopInB2InA: + ; sum = a[i] + carry + $ => A :MLOAD(array_add_AGTB_inA + E) + $ => B :MLOAD(array_add_AGTB_carry) + $ => C :ADD, JMPC(array_add_AGTB_add_carry3) + return_array_add_AGTB_add_carry3: + + C :MSTORE(array_add_AGTB_out + E) + D :MSTORE(array_add_AGTB_carry) + + E + 1 => E + E => A + $ => B :MLOAD(array_add_AGTB_len_inA) + $ :EQ, JMPC(array_add_AGTB_check_carry, array_add_AGTB_loopInB2InA) + +array_add_AGTB_check_carry: + $ => A :MLOAD(array_add_AGTB_carry) + 1 => B + $ :EQ, JMPNC(array_add_AGTB_len_out) + 1 :MSTORE(array_add_AGTB_out + E) + E + 1 :MSTORE(array_add_AGTB_len_out) + :JMP(array_add_AGTB_end) + +array_add_AGTB_len_out: + E :MSTORE(array_add_AGTB_len_out) + +array_add_AGTB_end: + $ => RR :MLOAD(array_add_AGTB_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm new file mode 100644 index 00000000..f2466d70 --- /dev/null +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -0,0 +1,88 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; array_add_short: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1], the second input +;; +;; output: +;; · out = inA + inB, with len(out) <= C + 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_add_short(a: bigint[], b: bigint, B: bigint): bigint[] { +; const alen = a.length; +; let result = new Array(alen); +; let sum = 0n; +; let carry = b; +; for (let i = 0; i < alen; i++) { +; sum = a[i] + carry; +; carry = sum >= B ? 1n : 0n; +; result[i] = sum - carry * B; +; } + +; if (carry === 1n) { +; result.push(carry); +; } +; return result; +; } + +VAR GLOBAL array_add_short_inA[839] +VAR GLOBAL array_add_short_len_inA +VAR GLOBAL array_add_short_inB +VAR GLOBAL array_add_short_out[840] +VAR GLOBAL array_add_short_len_out + +VAR GLOBAL array_add_short_carry + +VAR GLOBAL array_add_short_RR + +array_add_short: + %MAX_CNT_BINARY - CNT_BINARY - 2*C - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 6 - 12*C - 8 :JMPN(outOfCountersStep) + + RR :MSTORE(array_add_short_RR) + + C :MSTORE(array_add_short_len_inA) + + 0 => E ; index in loops + $ => A :MLOAD(array_add_short_inB) + A :MSTORE(array_add_short_carry) + :JMP(array_add_short_loopZero2inA) + +; Begin of branching +array_add_short_add_carry: + D + 1 => D :JMP(return_array_add_short_add_carry) +; End of branching + +array_add_short_loopZero2inA: + 0 => D ; for the carry + + ; a[i] + carry. If i = 0, then carry = inB. + $ => A :MLOAD(array_add_short_inA + E) + $ => B :MLOAD(array_add_short_carry) + $ => C :ADD, JMPC(array_add_short_add_carry) + return_array_add_short_add_carry: + + C :MSTORE(array_add_short_out + E) + D :MSTORE(array_add_short_carry) + + E + 1 => E + E => A + $ => B :MLOAD(array_add_short_len_inA) + $ :EQ, JMPC(array_add_short_check_carry, array_add_short_loopZero2inA) + +array_add_short_check_carry: + D => A + 1 => B + $ :EQ, JMPNC(array_add_short_len_out) + 1 :MSTORE(array_add_short_out + E) + E + 1 :MSTORE(array_add_short_len_out) + :JMP(array_add_short_end) + +array_add_short_len_out: + E :MSTORE(array_add_short_len_out) + +array_add_short_end: + $ => RR :MLOAD(array_add_short_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_div_mod.zkasm b/main/modexp/array_lib/array_div_mod.zkasm new file mode 100644 index 00000000..cc7a7775 --- /dev/null +++ b/main/modexp/array_lib/array_div_mod.zkasm @@ -0,0 +1,235 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed; +;; POST: If div_mod_long, then the remainer is trimmed; if div_mod_short, then the quotient (and naturally the remainder) is trimmed +;; +;; array_div_mod: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_div_mod(a: bigint[], b: bigint[], B: bigint): bigint[] { +; if (a === [0n]) { +; if (b === [0n]) { +; throw new Error("Division by zero"); +; } +; return [0n, 0n]; +; } else if (b === [0n]) { +; throw new Error("Division by zero"); +; } +; +; if (a === b) { +; return [1n, 0n]; +; } else if (a < b) { +; return [0n, a]; +; } +; +; if (b.length === 1) { +; return array_div_mod_short(a, b, B); +; } +; return array_div_mod_long(a, b, B); +; } + +VAR GLOBAL array_div_mod_inA[839] +VAR GLOBAL array_div_mod_inB[839] +VAR GLOBAL array_div_mod_quo[839] +VAR GLOBAL array_div_mod_rem[839] + +VAR GLOBAL array_div_mod_len_inA +VAR GLOBAL array_div_mod_len_inB +VAR GLOBAL array_div_mod_len_quo +VAR GLOBAL array_div_mod_len_rem + +VAR GLOBAL array_div_mod_RR + +; ERROR CODES (B) +; 0 - no error +; 1 - inB is zero + +array_div_mod: + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + + RR :MSTORE(array_div_mod_RR) + C :MSTORE(array_div_mod_len_inA) + D :MSTORE(array_div_mod_len_inB) + + ; Let's cover the edge cases + ; 1] Is C == 1 and inA == 0? + C => A + 1 => B + $ :EQ, JMPNC(array_div_mod_inA_continue) + 0 => B + $ => A :MLOAD(array_div_mod_inA) + $ :EQ, JMPC(array_div_mod_inA_is_zero) + array_div_mod_inA_continue: + + ; 2] Is D == 1 and inB == 0? + D => A + 1 => B + $ :EQ, JMPNC(array_div_mod_inB_continue1) + 0 => B + $ => A :MLOAD(array_div_mod_inB) + $ :EQ, JMPC(array_div_mod_inB_is_zero) + array_div_mod_inB_continue1: + + ; 3] Check if inA = inB or inA < inB + C => RR + D => E +array_div_mod_compare_inA: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_inA + RR) + A :MSTORE(array_compare_inA + RR) + RR :JMPZ(array_div_mod_compare_inB, array_div_mod_compare_inA) + +array_div_mod_compare_inB: + E - 1 => E + $ => A :MLOAD(array_div_mod_inB + E) + A :MSTORE(array_compare_inB + E) + E :JMPZ(array_div_mod_compare, array_div_mod_compare_inB) + +array_div_mod_compare: + :CALL(array_compare) + + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + + $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_prep_inALTinB) + 1 => B + $ :EQ, JMPC(array_div_mod_same_input) + ; From here, inA > inB + + C => RR + D => A,E + 1 => B + $ :EQ, JMPC(array_div_mod_inA_to_div_mod_short, array_div_mod_inA_to_div_mod_long); worst case is mod long + +; Begin of edge cases +array_div_mod_inA_is_zero: + ;Is D == 1 and inB == 0? 0/0 is undefined + D => A + 1 => B + $ :EQ, JMPNC(array_div_mod_inB_continue2) + 0 => B + $ => A :MLOAD(array_div_mod_inB) + $ :EQ, JMPC(array_div_mod_inB_is_zero) + array_div_mod_inB_continue2: + ; From here, inB != 0 + + ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 + 0 :MSTORE(array_div_mod_quo) + 0 :MSTORE(array_div_mod_rem) + 1 :MSTORE(array_div_mod_len_quo) + 1 :MSTORE(array_div_mod_len_rem) + 0 => B :JMP(array_div_mod_end) + +array_div_mod_inB_is_zero: + ; Error, you cannot divide by 0 + 1 => B :JMP(array_div_mod_end) + +array_div_mod_same_input: + 1 :MSTORE(array_div_mod_quo) + 0 :MSTORE(array_div_mod_rem) + 1 :MSTORE(array_div_mod_len_quo) + 1 :MSTORE(array_div_mod_len_rem) + 0 => B :JMP(array_div_mod_end) + +array_div_mod_prep_inALTinB: + C :MSTORE(array_div_mod_len_rem) + 1 :MSTORE(array_div_mod_len_quo) + + %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) + + 0 => RR + +array_div_mod_inALTinB: + $ => A :MLOAD(array_div_mod_inA + RR) + A :MSTORE(array_div_mod_rem + RR) + RR + 1 => RR + C - 1 => C :JMPNZ(array_div_mod_inALTinB) + +array_div_mod_inALTinB_before_end: + 0 :MSTORE(array_div_mod_quo) + 0 => B :JMP(array_div_mod_end) +; End of edge cases + +; Long +array_div_mod_inA_to_div_mod_long: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_inA + RR) + A :MSTORE(array_div_mod_long_inA + RR) + RR :JMPZ(array_div_mod_inB_to_div_mod_long, array_div_mod_inA_to_div_mod_long) + +array_div_mod_inB_to_div_mod_long: + E - 1 => E + $ => A :MLOAD(array_div_mod_inB + E) + A :MSTORE(array_div_mod_long_inB + E) + E :JMPZ(array_div_mod_compute_long, array_div_mod_inB_to_div_mod_long) + +array_div_mod_compute_long: + :CALL(array_div_mod_long) + + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_mod_long_len_quo) + $ => D :MLOAD(array_div_mod_long_len_rem) + C :MSTORE(array_div_mod_len_quo) + D :MSTORE(array_div_mod_len_rem) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 2 :JMPN(outOfCountersStep) + +array_div_mod_assign_long_quo: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_long_quo + RR) + A :MSTORE(array_div_mod_quo + RR) + RR :JMPZ(array_div_mod_assign_long_rem, array_div_mod_assign_long_quo) + +array_div_mod_assign_long_rem: + E - 1 => E + $ => A :MLOAD(array_div_mod_long_rem + E) + A :MSTORE(array_div_mod_rem + E) + E :JMPZ(array_div_mod_end, array_div_mod_assign_long_rem) + +; Short +array_div_mod_inA_to_div_mod_short: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_inA + RR) + A :MSTORE(array_div_mod_short_inA + RR) + RR :JMPZ(array_div_mod_inB_to_div_mod_short, array_div_mod_inA_to_div_mod_short) + +array_div_mod_inB_to_div_mod_short: + $ => A :MLOAD(array_div_mod_inB) + A :MSTORE(array_div_mod_short_inB) + +array_div_mod_compute_short: + :CALL(array_div_mod_short) + + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_mod_short_len_quo) + C :MSTORE(array_div_mod_len_quo) + 1 :MSTORE(array_div_mod_len_rem) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 4 :JMPN(outOfCountersStep) + +array_div_mod_assign_short_quo: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_short_quo + RR) + A :MSTORE(array_div_mod_quo + RR) + RR :JMPZ(array_div_mod_assign_short_rem, array_div_mod_assign_short_quo) + +array_div_mod_assign_short_rem: + $ => A :MLOAD(array_div_mod_short_rem) + A :MSTORE(array_div_mod_rem) + +array_div_mod_end: + $ => RR :MLOAD(array_div_mod_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm new file mode 100644 index 00000000..f3e897ab --- /dev/null +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -0,0 +1,260 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed. +;; POST: The remainder is trimmed. +;; +;; array_div_mod_long: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_div_mod_long(a: bigint[], b: bigint[], B: bigint): bigint[] { +; if (a === [0n]) { +; if (b === [0n]) { +; throw new Error("Division by zero"); +; } +; return [0n, 0n]; +; } else if (b === [0n]) { +; throw new Error("Division by zero"); +; } +; +; if (a === b) { +; return [1n, 0n]; +; } else if (a < b) { +; return [0n, a]; +; } +; } + +; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); +; checks the correctness of the result and returns the result to the caller + +VAR GLOBAL array_div_mod_long_inA[839] +VAR GLOBAL array_div_mod_long_inB[839] +VAR GLOBAL array_div_mod_long_quo[838] +VAR GLOBAL array_div_mod_long_rem[839] + +VAR GLOBAL array_div_mod_long_len_inA +VAR GLOBAL array_div_mod_long_len_inB +VAR GLOBAL array_div_mod_long_len_quo +VAR GLOBAL array_div_mod_long_len_rem + +VAR GLOBAL array_div_mod_long_RR + +; ERROR CODES (B) +; 0 - no error +; 1 - inB is zero + +array_div_mod_long: + %MAX_CNT_BINARY - CNT_BINARY - 4 - C - D :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + + RR :MSTORE(array_div_mod_long_RR) + C :MSTORE(array_div_mod_long_len_inA) + D :MSTORE(array_div_mod_long_len_inB) + + ; Let's cover the edge cases + ; 1] Is C == 1 and inA == 0? + C => A + 1 => B + $ :EQ, JMPNC(array_div_mod_long_inA_continue) + 0 => B + $ => A :MLOAD(array_div_mod_long_inA) + $ :EQ, JMPC(array_div_mod_long_inA_is_zero) + array_div_mod_long_inA_continue: + + ; 2] Is D == 1 and inB == 0? + D => A + 1 => B + $ :EQ, JMPNC(array_div_mod_long_inB_continue1) + 0 => B + $ => A :MLOAD(array_div_mod_long_inB) + $ :EQ, JMPC(array_div_mod_long_inB_is_zero) + array_div_mod_long_inB_continue1: + + ; 3] Check if inA = inB or inA < inB + C => RR + D => E +array_div_mod_long_compare_inA1: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_long_inA + RR) + A :MSTORE(array_compare_inA + RR) + RR :JMPZ(array_div_mod_long_compare_inB1, array_div_mod_long_compare_inA1) + +array_div_mod_long_compare_inB1: + E - 1 => E + $ => A :MLOAD(array_div_mod_long_inB + E) + A :MSTORE(array_compare_inB + E) + E :JMPZ(array_div_mod_long_compare1, array_div_mod_long_compare_inB1) + +array_div_mod_long_compare1: + :CALL(array_compare) + + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + + $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_long_prep_inALTinB) + 1 => B + $ :EQ, JMPC(array_div_mod_long_same_input) + ; From here, inA > inB + + $${MPdiv(addr.array_div_mod_long_inA,mem.array_div_mod_long_len_inA,addr.array_div_mod_long_inB,mem.array_div_mod_long_len_inB)} + + :JMP(array_div_mod_long_prepare_trim_rem) + +; Begin of edge cases +array_div_mod_long_inA_is_zero: + ; Is D == 1 and inB == 0? 0/0 is undefined + D => A + 1 => B + $ :EQ, JMPNC(array_div_mod_long_inB_continue2) + 0 => B + $ => A :MLOAD(array_div_mod_long_inB) + $ :EQ, JMPC(array_div_mod_long_inB_is_zero) + array_div_mod_long_inB_continue2: + ; From here, inB != 0 + + ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 + 0 :MSTORE(array_div_mod_long_quo) + 0 :MSTORE(array_div_mod_long_rem) + 1 :MSTORE(array_div_mod_long_len_quo) + 1 :MSTORE(array_div_mod_long_len_rem) + 0 => B :JMP(array_div_mod_long_end) + +array_div_mod_long_inB_is_zero: + ; Error, you cannot divide by 0 + 1 => B :JMP(array_div_mod_long_end) + +array_div_mod_long_same_input: + 1 :MSTORE(array_div_mod_long_quo) + 0 :MSTORE(array_div_mod_long_rem) + 1 :MSTORE(array_div_mod_long_len_quo) + 1 :MSTORE(array_div_mod_long_len_rem) + 0 => B :JMP(array_div_mod_long_end) + +array_div_mod_long_prep_inALTinB: + C :MSTORE(array_div_mod_long_len_rem) + 1 :MSTORE(array_div_mod_long_len_quo) + + %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) + + 0 => RR + +array_div_mod_long_inALTinB: + $ => A :MLOAD(array_div_mod_long_inA + RR) + A :MSTORE(array_div_mod_long_rem + RR) + RR + 1 => RR + C - 1 => C :JMPNZ(array_div_mod_long_inALTinB) + +array_div_mod_long_inALTinB_before_end: + 0 :MSTORE(array_div_mod_long_quo) + 0 => B :JMP(array_div_mod_long_end) +; End of edge cases + +array_div_mod_long_prepare_trim_rem: + ${receiveLenRemainder()} => C + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +array_div_mod_long_trim_rem_in: + RR - 1 => RR + ${receiveRemainderChunk(RR)} => A + A :MSTORE(array_trim_in + RR) + RR :JMPZ(array_div_mod_long_trim_rem, array_div_mod_long_trim_rem_in) + +array_div_mod_long_trim_rem: + :CALL(array_trim) + + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + + C :MSTORE(array_div_mod_long_len_rem) + +array_div_mod_long_prepare_mul_quo_inB: + ${receiveLenQuotient()} => C + C :MSTORE(array_div_mod_long_len_quo) + $ => D :MLOAD(array_div_mod_long_len_inB) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 5*C - 4*D - 1 :JMPN(outOfCountersStep) + +array_div_mod_long_quo_to_mul: + RR - 1 => RR + ${receiveQuotientChunk(RR)} => A + A :MSTORE(array_div_mod_long_quo + RR) + A :MSTORE(array_mul_inA + RR) + RR :JMPZ(array_div_mod_long_inB_to_mul, array_div_mod_long_quo_to_mul) + +array_div_mod_long_inB_to_mul: + E - 1 => E + $ => A :MLOAD(array_div_mod_long_inB + E) + A :MSTORE(array_mul_inB + E) + E :JMPZ(array_div_mod_long_mul_quo_inB, array_div_mod_long_inB_to_mul) + +array_div_mod_long_mul_quo_inB: + :CALL(array_mul) + + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) + + ; prepare next + $ => C :MLOAD(array_mul_len_out) + $ => D :MLOAD(array_div_mod_long_len_rem) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 5*D - 1 :JMPN(outOfCountersStep) + +array_div_mod_long_res_to_add: + RR - 1 => RR + $ => A :MLOAD(array_mul_out + RR) + A :MSTORE(array_add_AGTB_inA + RR) + RR :JMPZ(array_div_mod_long_rem_to_add, array_div_mod_long_res_to_add) + +array_div_mod_long_rem_to_add: + E - 1 => E + ${receiveRemainderChunk(E)} => A + A :MSTORE(array_div_mod_long_rem + E) + A :MSTORE(array_add_AGTB_inB + E) + E :JMPZ(array_div_mod_long_add_res_rem, array_div_mod_long_rem_to_add) + +array_div_mod_long_add_res_rem: + :CALL(array_add_AGTB) + + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + ; prepare next + $ => C :MLOAD(array_add_AGTB_len_out) + $ => D :MLOAD(array_div_mod_long_len_inA) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + +array_div_mod_long_compare_inA2: + RR - 1 => RR + $ => A :MLOAD(array_add_AGTB_out + RR) + A :MSTORE(array_compare_inA + RR) + RR :JMPZ(array_div_mod_long_compare_inB2, array_div_mod_long_compare_inA2) + +array_div_mod_long_compare_inB2: + E - 1 => E + $ => A :MLOAD(array_div_mod_long_inA + E) + A :MSTORE(array_compare_inB + E) + E :JMPZ(array_div_mod_long_compare2, array_div_mod_long_compare_inB2) + +array_div_mod_long_compare2: + :CALL(array_compare) + + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + 1 :MLOAD(array_compare_result) + 0 => B ; everything worked fine + +array_div_mod_long_end: + $ => RR :MLOAD(array_div_mod_long_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm new file mode 100644 index 00000000..9b4be528 --- /dev/null +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -0,0 +1,228 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed. +;; POST: The quotient is trimmed. +;; +;; array_div_mod_short: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1], the second input +;; +;; output: +;; · [quo,rem] = [inA / inB[0], inA % inB[0]], with len(quo) <= C - 1, len(rem) = 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_div_mod_short(a: bigint[], b: bigint, B: bigint): bigint[] { +; if (a === [0n]) { +; if (b === 0n) { +; throw new Error("Division by zero"); +; } +; return [0n, 0n]; +; } else if (b === 0n) { +; throw new Error("Division by zero"); +; } +; +; if (a === b) { +; return [1n, 0n]; +; } else if (a < b) { +; return [0n, a]; +; } +; } + +; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); +; checks the correctness of the result and returns the result to the caller + +VAR GLOBAL array_div_mod_short_inA[839] +VAR GLOBAL array_div_mod_short_inB +VAR GLOBAL array_div_mod_short_quo[838] +VAR GLOBAL array_div_mod_short_rem + +VAR GLOBAL array_div_mod_short_len_inA +VAR GLOBAL array_div_mod_short_len_quo + +VAR GLOBAL array_div_mod_short_RR + +; ERROR CODES (B) +; 0 - no error +; 1 - inB is zero + +array_div_mod_short: + + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 15 - 4*C - 3 :JMPN(outOfCountersStep) + + RR :MSTORE(array_div_mod_short_RR) + C :MSTORE(array_div_mod_short_len_inA) + C :MSTORE(array_div_mod_short_len_quo) + + ; Let's cover the edge cases + ; 1] Is inA == 0? + C => A + 1 => B + $ :EQ, JMPNC(array_div_mod_short_inA_continue) + 0 => B + $ => A :MLOAD(array_div_mod_short_inA) + $ :EQ, JMPC(array_div_mod_short_inA_is_zero) + array_div_mod_short_inA_continue: + + ; 2] Is inB == 0? + 0 => B + $ => A :MLOAD(array_div_mod_short_inB) + $ :EQ, JMPC(array_div_mod_short_inB_is_zero) + + ; Check whether inA = inB or inA < inB + C => RR + 1 => D +array_div_mod_short_inA_to_compare1: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_short_inA + RR) + A :MSTORE(array_compare_inA + RR) + RR :JMPZ(array_div_mod_short_inB_to_compare, array_div_mod_short_inA_to_compare1) + +array_div_mod_short_inB_to_compare: + $ => A :MLOAD(array_div_mod_short_inB) + A :MSTORE(array_compare_inB) + +array_div_mod_short_compare_inA_inB: + :CALL(array_compare) + + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + + $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_short_inALTinB) + 1 => B + $ :EQ, JMPC(array_div_mod_short_same_input) + + ; From here, it is known that inA > inB + + ; Strategy: Divide outside and check the result inside + $${MPdiv_short(addr.array_div_mod_short_inA,mem.array_div_mod_short_len_inA,mem.array_div_mod_short_inB)} + + :JMP(array_div_mod_short_prepare_trim_quo) + +; Begin of edge cases +array_div_mod_short_inA_is_zero: + ; Is inB == 0? 0/0 is undefined + $ => A :MLOAD(array_div_mod_short_inB) + $ :EQ, JMPC(array_div_mod_short_inB_is_zero) + ; From here, inB != 0 + + ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 + 0 :MSTORE(array_div_mod_short_quo) + 0 :MSTORE(array_div_mod_short_rem) + 1 :MSTORE(array_div_mod_short_len_quo) + 0 => B :JMP(array_div_mod_short_end) + +array_div_mod_short_inB_is_zero: + ; Error, you cannot divide by 0 + 1 => B :JMP(array_div_mod_short_end) + +array_div_mod_short_same_input: + ; If inA = inB, then the result is [1,0] since inA = 1·inB + 0 + 1 :MSTORE(array_div_mod_short_quo) + 1 :MSTORE(array_div_mod_short_len_quo) + 0 :MSTORE(array_div_mod_short_rem) + 0 => B :JMP(array_div_mod_short_end) + +array_div_mod_short_inALTinB: + ; If inA < inB, then the result is [0, inA] since inA = 0·inB + inA + 0 :MSTORE(array_div_mod_short_quo) + 1 :MSTORE(array_div_mod_short_len_quo) + $ => A :MLOAD(array_div_mod_short_inA) + A :MSTORE(array_div_mod_short_rem) + 0 => B :JMP(array_div_mod_short_end) +; End of edge cases + +array_div_mod_short_prepare_trim_quo: + ${receiveLenQuotient_short()} => C + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +array_div_mod_short_trim_quo_in: + RR - 1 => RR + ${receiveQuotientChunk_short(RR)} => A + A :MSTORE(array_trim_in + RR) + RR :JMPZ(array_div_mod_short_trim_quo, array_div_mod_short_trim_quo_in) + +array_div_mod_short_trim_quo: + :CALL(array_trim) + + %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) + + C :MSTORE(array_div_mod_short_len_quo) + +array_div_mod_short_prepare_mul_quo_inB: + C => RR + + %MAX_CNT_STEPS - STEP - 5*C - 3 :JMPN(outOfCountersStep) + +array_div_mod_short_quo_to_mul: + RR - 1 => RR + ${receiveQuotientChunk_short(RR)} => A + A :MSTORE(array_div_mod_short_quo + RR) + A :MSTORE(array_mul_short_inA + RR) + RR :JMPZ(array_div_mod_short_inB_to_mul, array_div_mod_short_quo_to_mul) + +array_div_mod_short_inB_to_mul: + $ => A :MLOAD(array_div_mod_short_inB) + A :MSTORE(array_mul_short_inB) + +array_div_mod_short_mul_quo_inB: + :CALL(array_mul_short) + + %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) + + ; prepare next + $ => C :MLOAD(array_mul_short_len_out) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 4 :JMPN(outOfCountersStep) + +array_div_mod_short_result_to_add: + RR - 1 => RR + $ => A :MLOAD(array_mul_short_out + RR) + A :MSTORE(array_add_short_inA + RR) + RR :JMPZ(array_div_mod_short_rem_to_add, array_div_mod_short_result_to_add) + +array_div_mod_short_rem_to_add: + ${receiveRemainderChunk_short()} => A + A :MSTORE(array_div_mod_short_rem) + A :MSTORE(array_add_short_inB) + +array_div_mod_short_add_result_rem: + :CALL(array_add_short) + + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + ; prepare next + $ => C :MLOAD(array_add_short_len_out) + $ => D :MLOAD(array_div_mod_short_len_inA) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + +array_div_mod_short_result_to_compare: + RR - 1 => RR + $ => A :MLOAD(array_add_short_out + RR) + A :MSTORE(array_compare_inA + RR) + RR :JMPZ(array_div_mod_short_inA_to_compare2, array_div_mod_short_result_to_compare) + +array_div_mod_short_inA_to_compare2: + E - 1 => E + $ => A :MLOAD(array_div_mod_short_inA + E) + A :MSTORE(array_compare_inB + E) + E :JMPZ(array_div_mod_short_compare_result_inA, array_div_mod_short_inA_to_compare2) + +array_div_mod_short_compare_result_inA: + :CALL(array_compare) + + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + 1 :MLOAD(array_compare_result) + 0 => B + +array_div_mod_short_end: + $ => RR :MLOAD(array_div_mod_short_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm new file mode 100644 index 00000000..1831bc4a --- /dev/null +++ b/main/modexp/array_lib/array_mul.zkasm @@ -0,0 +1,103 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: out is trimmed +;; +;; array_mul: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · out = inA·inB, with len(out) <= C + D +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_mul(a: bigint[], b: bigint[], B: bigint): bigint[] { +; if (b.length === 1) { +; return array_mul_short(a, b, B); +; } +; return array_mul_long(a, b, B); +; } + +VAR GLOBAL array_mul_inA[839] +VAR GLOBAL array_mul_inB[839] +VAR GLOBAL array_mul_out[1678] +VAR GLOBAL array_mul_len_inA +VAR GLOBAL array_mul_len_inB +VAR GLOBAL array_mul_len_out + +VAR GLOBAL array_mul_RR + +array_mul: + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + + RR :MSTORE(array_mul_RR) + C :MSTORE(array_mul_len_inA) + D :MSTORE(array_mul_len_inB) + + C => RR + D => A,E + 1 => B + $ :EQ, JMPC(array_mul_inA_to_mul_short) ; worst case is mul long +; Long +array_mul_inA_to_mul_long: + RR - 1 => RR + $ => A :MLOAD(array_mul_inA + RR) + A :MSTORE(array_mul_long_inA + RR) + RR :JMPZ(array_mul_inB_to_mul_long, array_mul_inA_to_mul_long) + +array_mul_inB_to_mul_long: + E - 1 => E + $ => A :MLOAD(array_mul_inB + E) + A :MSTORE(array_mul_long_inB + E) + E :JMPZ(array_mul_compute_long, array_mul_inB_to_mul_long) + +array_mul_compute_long: + :CALL(array_mul_long) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_mul_long_len_out) + C :MSTORE(array_mul_len_out) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) + +array_mul_assign_long: + RR - 1 => RR + $ => A :MLOAD(array_mul_long_out + RR) + A :MSTORE(array_mul_out + RR) + RR :JMPZ(array_mul_end, array_mul_assign_long) + +; Short +array_mul_inA_to_mul_short: + RR - 1 => RR + $ => A :MLOAD(array_mul_inA + RR) + A :MSTORE(array_mul_short_inA + RR) + RR :JMPZ(array_mul_inB_to_mul_short, array_mul_inA_to_mul_short) + +array_mul_inB_to_mul_short: + $ => A :MLOAD(array_mul_inB) + A :MSTORE(array_mul_short_inB) + +array_mul_compute_short: + :CALL(array_mul_short) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_mul_short_len_out) + C :MSTORE(array_mul_len_out) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) + +array_mul_assign_short: + RR - 1 => RR + $ => A :MLOAD(array_mul_short_out + RR) + A :MSTORE(array_mul_out + RR) + RR :JMPZ(array_mul_end, array_mul_assign_short) + +array_mul_end: + $ => RR :MLOAD(array_mul_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm new file mode 100644 index 00000000..8842a02f --- /dev/null +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -0,0 +1,158 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: len(inB) >= 2 +;; POST: out is trimmed +;; +;; array_mul_long: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · out = inA·inB, with len(out) <= C + D +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_mul_long(a: bigint[], b: bigint[], B: bigint): bigint[] { +; const alen = a.length; +; const blen = b.length; +; const len = alen + blen; +; const result = new Array(len).fill(0n); +; let product: bigint; +; let carry: bigint; +; let ai: bigint; +; let bj: bigint; +; for (let i = 0; i < alen; i++) { +; ai = a[i]; +; for (let j = 0; j < blen; j++) { +; bj = b[j]; +; product = ai * bj + result[i + j]; +; carry = product / B; +; result[i + j] = product - carry * B; +; result[i + j + 1] += carry; +; } +; } +; trim(result); +; return result; +; } + +VAR GLOBAL array_mul_long_inA[839] +VAR GLOBAL array_mul_long_inB[839] +VAR GLOBAL array_mul_long_out[1678] +VAR GLOBAL array_mul_long_len_inA +VAR GLOBAL array_mul_long_len_inB +VAR GLOBAL array_mul_long_len_out + +VAR GLOBAL array_mul_long_result_carry + +VAR GLOBAL array_mul_long_RR + +array_mul_long: + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + + C => A + D => B + 0 => C,D + ${A*B} => E :ARITH + A => C + B => D + ; E holds C*D + + %MAX_CNT_BINARY - CNT_BINARY - 5*E :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - E :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 7 - 3*C - 3*D - 35*E - 2 - 4*C - 1 :JMPN(outOfCountersStep) + + RR :MSTORE(array_mul_long_RR) + C :MSTORE(array_mul_long_len_inA) + D :MSTORE(array_mul_long_len_inB) + C + D :MSTORE(array_mul_long_len_out) + + C + D => E ; auxiliar index + 0 => RCX ; first index in loops + 0 => RR ; second index in loops + +array_mul_long_clean_out: + E - 1 => E + 0 :MSTORE(array_mul_long_out + E) + E :JMPZ(array_mul_long_loopZero2inB, array_mul_long_clean_out) + +; Begin of branching +array_mul_long_add_carry: + D + 1 => D :JMP(return_array_mul_long_add_carry) + +array_mul_long_add_result_carry: + 1 :MSTORE(array_mul_long_result_carry) + :JMP(return_array_mul_long_add_result_carry) + +array_mul_long_loop_index_check: + RCX + 1 => RCX + RCX => A + $ => B :MLOAD(array_mul_long_len_inA) + $ :EQ, JMPC(array_mul_long_prep_trim_in) + + 0 => RR + :JMP(return_array_mul_long_loop_index_check) +; End of branching + +array_mul_long_loopZero2inB: + RCX => E + ; product = a_i * b_j + out[i + j] + $ => A :MLOAD(array_mul_long_inA + E) + $ => B :MLOAD(array_mul_long_inB + RR) + 0 => C + $${var _arrayLongMul_AB = A*B} + ${_arrayLongMul_AB >> 256} => D + ${_arrayLongMul_AB} => E :ARITH + + ; sum lower part + E => A + RCX + RR => E + $ => B :MLOAD(array_mul_long_out + E) + $ => C :ADD, JMPC(array_mul_long_add_carry) + return_array_mul_long_add_carry: + + ; sum higher part + D => A + $ => B :MLOAD(array_mul_long_result_carry) + $ => D :ADD + + ; out[i + j] = product - carry·B + C :MSTORE(array_mul_long_out + E) + + ; out[i + j + 1] += carry + E + 1 => E + $ => A :MLOAD(array_mul_long_out + E) + D => B + $ => C :ADD, JMPC(array_mul_long_add_result_carry) + 0 :MSTORE(array_mul_long_result_carry) + return_array_mul_long_add_result_carry: + C :MSTORE(array_mul_long_out + E) + + RR + 1 => RR + RR => A + $ => B :MLOAD(array_mul_long_len_inB) + $ :EQ, JMPC(array_mul_long_loop_index_check) + return_array_mul_long_loop_index_check: + :JMP(array_mul_long_loopZero2inB) + +array_mul_long_prep_trim_in: + $ => C :MLOAD(array_mul_long_len_out) + C => E + +array_mul_long_trim_in: + E - 1 => E + $ => A :MLOAD(array_mul_long_out + E) + A :MSTORE(array_trim_in + E) + E :JMPZ(array_mul_long_trim, array_mul_long_trim_in) + +array_mul_long_trim: + :CALL(array_trim) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + C :MSTORE(array_mul_long_len_out) + +array_mul_long_end: + $ => RR :MLOAD(array_mul_long_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm new file mode 100644 index 00000000..debafbb3 --- /dev/null +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -0,0 +1,123 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: out is trimmed +;; +;; array_mul_short: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1], the second input +;; +;; output: +;; · out = inA·inB, with len(out) <= C + 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_mul_short(a: bigint[], b: bigint, B: bigint): bigint[] { +; const alen = a.length; +; const len = alen; +; const result = new Array(len).fill(0n); +; let product: bigint; +; let carry = 0n; +; let i; +; for (i = 0; i < alen; i++) { +; product = a[i] * b + carry; +; carry = product / B; +; result[i] = product - carry * B; +; } + +; if (carry > 0n) { +; result.push(carry); +; } + +; trim(result); +; return result; +; } + +VAR GLOBAL array_mul_short_inA[839] +VAR GLOBAL array_mul_short_inB +VAR GLOBAL array_mul_short_out[840] +VAR GLOBAL array_mul_short_len_inA +VAR GLOBAL array_mul_short_len_out + +VAR GLOBAL array_mul_short_carry + +VAR GLOBAL array_mul_short_RR + +array_mul_short: + %MAX_CNT_BINARY - CNT_BINARY - 2*C - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - C :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 6 - 3*C-3 - 18*C - 7 :JMPN(outOfCountersStep) + + RR :MSTORE(array_mul_short_RR) + C :MSTORE(array_mul_short_len_inA) + C + 1 :MSTORE(array_mul_short_len_out) + + C + 1 => E ; auxiliar index + 0 => RCX ; index in loops + 0 :MSTORE(array_mul_short_carry) + +array_mul_short_clean_out: + E - 1 => E + 0 :MSTORE(array_mul_short_out + E) + E :JMPZ(array_mul_short_loopZero2inA, array_mul_short_clean_out) + +; Begin of branching +array_mul_short_add_carry: + D + 1 => D :JMP(return_array_mul_short_add_carry) +; End of branching + +array_mul_short_loopZero2inA: + RCX => E + ; product = a_i * b + carry + $ => A :MLOAD(array_mul_short_inA + E) + $ => B :MLOAD(array_mul_short_inB) + 0 => C + $${var _arrayShortMul_AB = A*B} + ${_arrayShortMul_AB >> 256} => D + ${_arrayShortMul_AB} => E :ARITH + + E => A + $ => B :MLOAD(array_mul_short_carry) + $ => C :ADD, JMPC(array_mul_short_add_carry) + return_array_mul_short_add_carry: + D :MSTORE(array_mul_short_carry) + + ; out[i] = product - carry·2²⁵⁶ + RCX => E + C :MSTORE(array_mul_short_out + E) + + RCX + 1 => RCX + RCX => A + $ => B :MLOAD(array_mul_short_len_inA) + $ :EQ, JMPC(array_mul_short_carry_check, array_mul_short_loopZero2inA) + +; If carry > 0, we need to add it to the output +array_mul_short_carry_check: + $ => A :MLOAD(array_mul_short_carry) + 0 => B + $ :EQ, JMPC(array_mul_short_prep_trim_in) + + RCX => E + A :MSTORE(array_mul_short_out + E) + +array_mul_short_prep_trim_in: + $ => C :MLOAD(array_mul_short_len_out) + C => E + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +array_mul_short_trim_in: + E - 1 => E + $ => A :MLOAD(array_mul_short_out + E) + A :MSTORE(array_trim_in + E) + E :JMPZ(array_mul_short_trim, array_mul_short_trim_in) + +array_mul_short_trim: + :CALL(array_trim) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + C :MSTORE(array_mul_short_len_out) + +array_mul_short_end: + $ => RR :MLOAD(array_mul_short_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm new file mode 100644 index 00000000..f52aba25 --- /dev/null +++ b/main/modexp/array_lib/array_square.zkasm @@ -0,0 +1,275 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: out is trimmed +;; +;; array_square: +;; in: +;; · C ∈ [1, 839], the len of in +;; · in ∈ [0, 2²⁵ ⁶- 1]^C, the input array +;; +;; output: +;; · out = in², with len(out) <= 2·C +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_square(a: bigint[], B: bigint): bigint[] { +; let len = a.length; +; let result = new Array(len).fill(0n); +; let product: bigint; +; let carry: bigint; +; let a_i: bigint; +; let a_j: bigint; +; for (let i = 0; i < len; i++) { +; a_i = a[i]; +; carry = 0n - a_i * a_i; +; for (var j = i; j < len; j++) { +; a_j = a[j]; +; product = 2n * (a_i * a_j) + result[i + j] + carry; +; carry = product / B; + +; result[i + j] = product - carry * B; +; } +; result[i + len] = carry; +; } +; trim(result); +; return result; +; } + +VAR GLOBAL array_square_in[839] +VAR GLOBAL array_square_out[1678] +VAR GLOBAL array_square_len_in +VAR GLOBAL array_square_len_out + +VAR GLOBAL array_square_carry_high +VAR GLOBAL array_square_carry_low +VAR GLOBAL array_square_carry_sign; 0 if negative, 1 if positive +VAR GLOBAL array_square_aiaj_high +VAR GLOBAL array_square_highest_carry +VAR GLOBAL array_square_out_carry + +VAR GLOBAL array_square_RR + +array_square: + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + C => A,B + 0 => C,D + ${A*A} => E :ARITH + A => C + ; E holds C*C + + %MAX_CNT_BINARY - CNT_BINARY - 10*E :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1 - 2*E :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 14 - 3*C - 83*E - 2 :JMPN(outOfCountersStep) + + RR :MSTORE(array_square_RR) + C :MSTORE(array_square_len_in) + C + C :MSTORE(array_square_len_out) + + 0 => RCX ; first index in loops + C + C => RR ; second index in loops + + ; 1] carry = 0 - a_0²: The (unsigned) number cannot be GT (base - 2)·base + 1, two chunks + $ => A :MLOAD(array_square_in) + A => B + 0 => C + $${var _arraySquare_a02 = A*B} + ${_arraySquare_a02 >> 256} => D + ${_arraySquare_a02} => E :ARITH + D :MSTORE(array_square_carry_high) + E :MSTORE(array_square_carry_low) + 0 :MSTORE(array_square_carry_sign) + 0 :MSTORE(array_square_highest_carry) + +array_square_clean_out: + RR - 1 => RR + 0 :MSTORE(array_square_out + RR) + RR :JMPZ(array_square_loopZero2inA, array_square_clean_out) + +; Begin of branching +array_square_add_carry_1: + D + 1 => D :JMP(return_array_square_add_carry_1) + +array_square_add_carry_2: + D => A + 1 => B + $ => D :ADD, JMPC(array_square_add_carry_carry_2, return_array_square_add_carry_2) + +array_square_add_carry_3: + D => A + 1 => B + $ => D :ADD, JMPC(array_square_add_carry_carry_4, return_array_square_add_carry_3) + +array_square_add_carry_carry_1: + $ => A :MLOAD(array_square_highest_carry) + A + 1 :MSTORE(array_square_highest_carry) + :JMP(return_array_square_add_carry_carry_1) + +array_square_add_carry_carry_2: + $ => A :MLOAD(array_square_highest_carry) + A + 1 :MSTORE(array_square_highest_carry) + :JMP(return_array_square_add_carry_2) + +array_square_add_carry_carry_3: + $ => A :MLOAD(array_square_highest_carry) + A + 1 :MSTORE(array_square_highest_carry) + :JMP(return_array_square_add_carry_carry_3) + +array_square_add_carry_carry_4: + $ => A :MLOAD(array_square_highest_carry) + A + 1 :MSTORE(array_square_highest_carry) + :JMP(return_array_square_add_carry_3) + +array_square_add_carry_carry_5: + $ => A :MLOAD(array_square_highest_carry) + A + 1 :MSTORE(array_square_highest_carry) + :JMP(return_array_square_add_carry_carry_5) + +array_square_is_negative_1: + $ => C :SUB, JMPC(array_square_sub_carry_2, return_array_square_is_negative_1) + +array_square_is_negative_2: + $ => D :SUB, JMPC(array_square_sub_carry_carry_2, return_array_square_is_negative_2) + +array_square_sub_carry_2: + D => A + 1 => B + $ => D :SUB, JMPC(array_square_sub_carry_carry_1, return_array_square_is_negative_1) + +array_square_sub_carry_carry_1: + $ => A :MLOAD(array_square_highest_carry) + A - 1 :MSTORE(array_square_highest_carry) + :JMP(return_array_square_is_negative_1) + +array_square_sub_carry_carry_2: + $ => A :MLOAD(array_square_highest_carry) + A - 1 :MSTORE(array_square_highest_carry) + :JMP(return_array_square_is_negative_2) + +array_square_loop_index_check: + ; out[i + len] = carry; + $ => A :MLOAD(array_square_carry_low) + $ => B :MLOAD(array_square_len_in) + RCX + B => E + A :MSTORE(array_square_out + E) + + $ => A :MLOAD(array_square_carry_high) + A :MSTORE(array_square_out_carry) + + ; update indices + RCX + 1 => RCX + RCX => RR + + RCX => A + $ :EQ, JMPC(array_square_prep_trim_in) + + ; carry = 0 - a_i·a_i + ; a_i·a_i: This number cannot be GT (base - 2)·base + 1, two chunks + $ => A :MLOAD(array_square_in + RR) + A => B + 0 => C + $${var _arraySquare_aiai = A*B} + ${_arraySquare_aiai >> 256} => D + ${_arraySquare_aiai} => E :ARITH + D :MSTORE(array_square_carry_high) + E :MSTORE(array_square_carry_low) + 0 :MSTORE(array_square_carry_sign) + 0 :MSTORE(array_square_highest_carry) + + :JMP(return_array_square_loop_index_check) +; End of branching + +array_square_loopZero2inA: + RCX => E + ; product = 2·(a_i·a_j) + out[i + j] + carry + + ; 1] a_i·a_j: This number cannot be GT (base - 2)·base + 1, two chunks + $ => A :MLOAD(array_square_in + E) + $ => B :MLOAD(array_square_in + RR) + 0 => C + $${var _arraySquare_aiaj = A*B} + ${_arraySquare_aiaj >> 256} => D + ${_arraySquare_aiaj} => E :ARITH + D :MSTORE(array_square_aiaj_high) + + ; 2] 2·a_i·a_j: This number cannot be GT base² + (base - 4)·base + 2, three chunks + E => A,B + $ => C :ADD, JMPC(array_square_add_carry_1) + return_array_square_add_carry_1: + $ => A :MLOAD(array_square_aiaj_high) + D => B + $ => D :ADD, JMPC(array_square_add_carry_carry_1) + return_array_square_add_carry_carry_1: + + ; The result is stored as array_square_highest_carry·base² + D·base + C + + + ; 3] 2·a_i·a_j + out[i + j]: + ; a) j != len: This number cannot be GT base² + (base - 3)·base + 1, as out[i + j] < B + ; b) j == len: This number cannot be GT base² + (base - 3)·base + base - 1, as out[i + j] <= B + (B - 3) + ; In both cases, three chunks + RR + RCX => E + $ => A :MLOAD(array_square_out + E) + C => B + $ => C :ADD, JMPC(array_square_add_carry_2) + return_array_square_add_carry_2: + + $ => A :MLOAD(array_square_out_carry) + D => B + $ => D :ADD, JMPC(array_square_add_carry_carry_3) + return_array_square_add_carry_carry_3: + + ; 4] 2·a_i·a_j + out[i + j] + carry: This number cannot be GT (base - 2)·base + 1, two chunks + C => A + $ => B :MLOAD(array_square_carry_low) + $ :MLOAD(array_square_carry_sign), JMPZ(array_square_is_negative_1) + $ => C :ADD, JMPC(array_square_add_carry_3) + return_array_square_add_carry_3: + return_array_square_is_negative_1: + + D => A + $ => B :MLOAD(array_square_carry_high) + $ :MLOAD(array_square_carry_sign), JMPZ(array_square_is_negative_2) + $ => D :ADD, JMPC(array_square_add_carry_carry_5) + return_array_square_add_carry_carry_5: + return_array_square_is_negative_2: + + ; carry = product / B; This number cannot be greater than base + (base - 3) + D :MSTORE(array_square_carry_low) + $ => A :MLOAD(array_square_highest_carry) + A :MSTORE(array_square_carry_high) + 1 :MSTORE(array_square_carry_sign) + + ; out[i + j] = product - carry·B; + RCX + RR => E + C :MSTORE(array_square_out + E) + + RR + 1 => RR + 0 :MSTORE(array_square_highest_carry) + RR => A + $ => B :MLOAD(array_square_len_in) + $ :EQ, JMPC(array_square_loop_index_check) ; [Steps: 61] + return_array_square_loop_index_check: + :JMP(array_square_loopZero2inA) + +array_square_prep_trim_in: + $ => C :MLOAD(array_square_len_out) + C => E + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +array_square_trim_in: + E - 1 => E + $ => A :MLOAD(array_square_out + E) + A :MSTORE(array_trim_in + E) + E :JMPZ(array_square_trim, array_square_trim_in) + +array_square_trim: + :CALL(array_trim) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + C :MSTORE(array_square_len_out) + +array_square_end: + $ => RR :MLOAD(array_square_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/unused/array_add.zkasm b/main/modexp/array_lib/unused/array_add.zkasm new file mode 100644 index 00000000..3a50bbba --- /dev/null +++ b/main/modexp/array_lib/unused/array_add.zkasm @@ -0,0 +1,100 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; array_add: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · out = inA + inB, with len(out) <= C + 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL array_add_inA[839] +VAR GLOBAL array_add_inB[839] +VAR GLOBAL array_add_out[840] +VAR GLOBAL array_add_len_inA +VAR GLOBAL array_add_len_inB +VAR GLOBAL array_add_len_out + +VAR GLOBAL array_add_RR + +array_add: + RR :MSTORE(array_add_RR) + C :MSTORE(array_add_len_inA) + D :MSTORE(array_add_len_inB) + 0 => RR,E + + D => A + C => B + $ :LT, JMPC(array_add_inA_to_add_AGTB) + +; BGTA +array_add_prep_BGTA: + C => A + D => C + A => D + +array_add_inA_to_add_BGTA: + $ => A :MLOAD(array_add_inB + RR) + A :MSTORE(array_add_AGTB_inA + RR) + RR + 1 => RR + RR => A + D => B + $ :EQ, JMPC(array_add_inB_to_add_BGTA, array_add_inA_to_add_BGTA) + +array_add_inB_to_add_BGTA: + $ => A :MLOAD(array_add_inA + E) + A :MSTORE(array_add_AGTB_inB + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_add_compute_BGTA, array_add_inB_to_add_BGTA) + +array_add_compute_BGTA: + :CALL(array_add_AGTB) + $ => C :MLOAD(array_add_AGTB_len_out) + C :MSTORE(array_add_len_out) + 0 => RR +array_add_assign_BGTA: + $ => A :MLOAD(array_add_AGTB_out + RR) + A :MSTORE(array_add_out + RR) + RR + 1 => RR + RR => A + C => B + $ :EQ, JMPC(array_add_end, array_add_assign_BGTA) + +; AGTB +array_add_inA_to_add_AGTB: + $ => A :MLOAD(array_add_inA + RR) + A :MSTORE(array_add_AGTB_inA + RR) + RR + 1 => RR + RR => A + C => B + $ :EQ, JMPC(array_add_inB_to_add_AGTB, array_add_inA_to_add_AGTB) + +array_add_inB_to_add_AGTB: + $ => A :MLOAD(array_add_inB + E) + A :MSTORE(array_add_AGTB_inB + E) + E + 1 => E + E => A + D => B + $ :EQ, JMPC(array_add_compute_AGTB, array_add_inB_to_add_AGTB) + +array_add_compute_AGTB: + :CALL(array_add_AGTB) + $ => C :MLOAD(array_add_AGTB_len_out) + C :MSTORE(array_add_len_out) + 0 => RR +array_add_assign_AGTB: + $ => A :MLOAD(array_add_AGTB_out + RR) + A :MSTORE(array_add_out + RR) + RR + 1 => RR + RR => A + C => B + $ :EQ, JMPC(array_add_end, array_add_assign_AGTB) + +array_add_end: + $ => RR :MLOAD(array_add_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/unused/array_is_odd.zkasm b/main/modexp/array_lib/unused/array_is_odd.zkasm new file mode 100644 index 00000000..51c6e502 --- /dev/null +++ b/main/modexp/array_lib/unused/array_is_odd.zkasm @@ -0,0 +1,23 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed. +;; +;; array_is_odd: +;; in: +;; · in ∈ [0, 2²⁵⁶ - 1]*, the input array +;; output: +;; · 1, if in is an odd number +;; · 0, otherwise +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; NOTE: The base is 2^256, so I only need to check if the first chunk is odd to conclude that the whole number is odd. + +VAR GLOBAL array_is_odd_in +VAR GLOBAL array_is_odd_result + +array_is_odd: + $ => A :MLOAD(array_is_odd_in) + 1 => B + $ => A :AND + A :MSTORE(array_is_odd_result) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/unused/array_is_one.zkasm b/main/modexp/array_lib/unused/array_is_one.zkasm new file mode 100644 index 00000000..9d37d24f --- /dev/null +++ b/main/modexp/array_lib/unused/array_is_one.zkasm @@ -0,0 +1,33 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed. +;; +;; array_is_one: +;; in: +;; · C ∈ [1, 839], the len of in +;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array +;; output: +;; · 1, if in = 1 +;; · 0, otherwise +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL array_is_one_in +VAR GLOBAL array_is_one_result + +array_is_one: + ; Is C == 1 and in == 1? + C => A + 1 => B + $ :EQ, JMPNC(array_is_one_continue) + $ => A :MLOAD(array_is_one_in) + $ :EQ, JMPC(array_is_one_sure) + array_is_one_continue: + + 0 :MSTORE(array_is_one_result) + :JMP(array_is_one_end) + +array_is_one_sure: + 1 :MSTORE(array_is_one_result) + +array_is_one_end: + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/unused/array_is_zero.zkasm b/main/modexp/array_lib/unused/array_is_zero.zkasm new file mode 100644 index 00000000..ca532aeb --- /dev/null +++ b/main/modexp/array_lib/unused/array_is_zero.zkasm @@ -0,0 +1,34 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed. +;; +;; array_is_zero: +;; in: +;; · C ∈ [1, 839], the len of in +;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array +;; output: +;; · 1, if in = 0 +;; · 0, otherwise +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL array_is_zero_in +VAR GLOBAL array_is_zero_result + +array_is_zero: + ; Is C == 1 and in == 0? + C => A + 1 => B + $ :EQ, JMPNC(array_is_zero_continue) + 0 => B + $ => A :MLOAD(array_is_zero_in) + $ :EQ, JMPC(array_is_zero_sure) + array_is_zero_continue: + + 0 :MSTORE(array_is_zero_result) + :JMP(array_is_zero_end) + +array_is_zero_sure: + 1 :MSTORE(array_is_zero_result) + +array_is_zero_end: + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm new file mode 100644 index 00000000..062af851 --- /dev/null +++ b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm @@ -0,0 +1,111 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: inA >= inB +;; +;; array_sub_AGTB: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · out = inA - inB, with len(out) <= C +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL array_sub_AGTB_inA[839] +VAR GLOBAL array_sub_AGTB_inB[839] +VAR GLOBAL array_sub_AGTB_out[839] +VAR GLOBAL array_sub_AGTB_len_inA +VAR GLOBAL array_sub_AGTB_len_inB + +VAR GLOBAL array_sub_AGTB_carry + +VAR GLOBAL array_sub_AGTB_RR + +array_sub_AGTB: + RR :MSTORE(array_sub_AGTB_RR) + C :MSTORE(array_sub_AGTB_len_inA) + D :MSTORE(array_sub_AGTB_len_inB) + + 0 => E ; index in loops + 0 :MSTORE(array_sub_AGTB_carry) + :JMP(array_sub_AGTB_loopZero2inB) + +array_sub_AGTB_add_carry: + 1 => D + :JMP(return_array_sub_AGTB_add_carry) + +array_sub_AGTB_sub_carry: + D => A + 1 => B + $ :SUB, JMPC(array_sub_AGTB_set_carry_to_1, array_sub_AGTB_set_carry_tp_0) + +array_sub_AGTB_set_carry_to_1: + 1 :MSTORE(array_sub_AGTB_carry) + :JMP(return_array_sub_AGTB_sub_carry) + +array_sub_AGTB_set_carry_tp_0: + 0 :MSTORE(array_sub_AGTB_carry) + :JMP(return_array_sub_AGTB_sub_carry) + +array_sub_AGTB_loopZero2inB: + 0 => D ; cleanup + + ; diff = a[i] - (b[i] + carry) + $ => A :MLOAD(array_sub_AGTB_inB + E) + $ => B :MLOAD(array_sub_AGTB_carry) + $ => C :ADD, JMPC(array_sub_AGTB_add_carry) + return_array_sub_AGTB_add_carry: + + $ => A :MLOAD(array_sub_AGTB_inA + E) + C => B + $ => C :SUB, JMPC(array_sub_AGTB_sub_carry) + 0 :MSTORE(array_sub_AGTB_carry) + return_array_sub_AGTB_sub_carry: + + C :MSTORE(array_sub_AGTB_out + E) + + E + 1 => E + E => A + $ => B :MLOAD(array_sub_AGTB_len_inB) + $ :EQ, JMPC(array_sub_AGTB_loop_index_check1, array_sub_AGTB_loopZero2inB) + +array_sub_AGTB_loop_index_check1: + E => A + $ => B :MLOAD(array_sub_AGTB_len_inA) + $ :EQ, JMPC(array_sub_AGTB_end) + +array_sub_AGTB_loopInB2InA: + ; diff = a[i] - carry + $ => A :MLOAD(array_sub_AGTB_inA + E) + $ => B :MLOAD(array_sub_AGTB_carry) + $ => C :SUB, JMPC(array_sub_AGTB_loopInB2InA_cont) + C :MSTORE(array_sub_AGTB_out + E) + E + 1 => E + :JMP(array_sub_AGTB_loop_index_check2) + +array_sub_AGTB_loopInB2InA_cont: + C :MSTORE(array_sub_AGTB_out + E) + + E + 1 => E + E => A + $ => B :MLOAD(array_sub_AGTB_len_inA) + $ :EQ, JMPC(array_sub_AGTB_end, array_sub_AGTB_loopInB2InA) + +array_sub_AGTB_loop_index_check2: + E => A + $ => B :MLOAD(array_sub_AGTB_len_inA) + $ :EQ, JMPC(array_sub_AGTB_end) + +array_sub_AGTB_loop_final: + $ => A :MLOAD(array_sub_AGTB_inA + E) + A :MSTORE(array_sub_AGTB_out + E) + + E + 1 => E + E => A + $ => B :MLOAD(array_sub_AGTB_len_inA) + $ :EQ, JMPC(array_sub_AGTB_end, array_sub_AGTB_loop_final) + +array_sub_AGTB_end: + $ => RR :MLOAD(array_sub_AGTB_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/unused/array_unshift.zkasm b/main/modexp/array_lib/unused/array_unshift.zkasm new file mode 100644 index 00000000..a9cbb23a --- /dev/null +++ b/main/modexp/array_lib/unused/array_unshift.zkasm @@ -0,0 +1,37 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; array_unshift: +;; in: +;; · C ∈ [1, 839], the len of in = [in[0], in[1], ..., in[C - 1]] +;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array +;; · D ∈ [0, 2²⁵⁶ - 1], the element to unshift +;; +;; output: +;; · in = [D, in[0], in[1], ..., in[C - 1]] +;; · len = C + 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL array_unshift_in[839] +VAR GLOBAL array_unshift_len + +VAR GLOBAL array_unshift_RR + +array_unshift: + RR :MSTORE(array_unshift_RR) + + C + 1 :MSTORE(array_unshift_len) + + C :JMPZ(array_unshift_end) + +array_unshift_loop: + C - 1 => E + $ => A :MLOAD(array_unshift_in + E) + C => E + A :MSTORE(array_unshift_in + E) + C - 1 => C :JMPZ(array_unshift_end) + :JMP(array_unshift_loop) + +array_unshift_end: + D :MSTORE(array_unshift_in) + $ => RR :MLOAD(array_unshift_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/utils/array_compare.zkasm b/main/modexp/array_lib/utils/array_compare.zkasm new file mode 100644 index 00000000..ea2cd5a2 --- /dev/null +++ b/main/modexp/array_lib/utils/array_compare.zkasm @@ -0,0 +1,88 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed. +;; +;; array_compare: +;; in: +;; · C ∈ [1, 839], the len of inA +;; · D ∈ [1, 839], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · 2, if inA > inB +;; · 1, if inA = inB +;; · 0, if inA < inB +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_compare(a: bigint[], b: bigint[]): number { +; const alen = a.length; +; const blen = b.length; +; if (alen !== blen) { +; return alen >= blen ? 1 : -1; +; } +; for (let i = alen - 1; i >= 0; i--) { +; if (a[i] !== b[i]) { +; return a[i] > b[i] ? 1 : -1; +; } +; } +; return 0; +; } + +; ---------------------------------- +; Five possible paths: +; · inA > inB and lenA > lenB. +; · inA > inB and lenA = lenB. +; · inA = inB. (worst case) +; · inA < inB and lenA < lenB. +; · inA < inB and lenA = lenB. +; ---------------------------------- + +VAR GLOBAL array_compare_inA[839] +VAR GLOBAL array_compare_inB[839] + +VAR GLOBAL array_compare_result + +VAR GLOBAL array_compare_RR + +array_compare: + %MAX_CNT_BINARY - CNT_BINARY - 2 - 2*C :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 8 - 8*C - 4 :JMPN(outOfCountersStep) + + RR :MSTORE(array_compare_RR) + + ; Start by comparing the lengths of the arrays + C => A + D => B + $ :LT, JMPC(array_compare_ALTB) + C => B + D => A + $ :LT, JMPC(array_compare_AGTB) + + C => E +array_compare_same_len: + E - 1 => E + $ => A :MLOAD(array_compare_inA + E) + $ => B :MLOAD(array_compare_inB + E) + $ :LT, JMPC(array_compare_ALTB) + + $ => A :MLOAD(array_compare_inB + E) + $ => B :MLOAD(array_compare_inA + E) + $ :LT, JMPC(array_compare_AGTB) + + E :JMPZ(array_compare_AEQB, array_compare_same_len) + +array_compare_AGTB: + 2 :MSTORE(array_compare_result) + :JMP(array_compare_end) + +array_compare_AEQB: + 1 :MSTORE(array_compare_result) + :JMP(array_compare_end) + +array_compare_ALTB: + 0 :MSTORE(array_compare_result) + :JMP(array_compare_end) + +array_compare_end: + $ => RR :MLOAD(array_compare_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm new file mode 100644 index 00000000..547fe78b --- /dev/null +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -0,0 +1,47 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; array_trim: +;; in: +;; · C ∈ [1, 839], the len of in +;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array +;; +;; output: +;; · C, the new length of in +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_trim(a: bigint[]): void { +; let i = a.length; +; +; while (a[--i] === 0n); +; +; a.length = i + 1; +; } + +VAR GLOBAL array_trim_in[839] + +VAR GLOBAL array_trim_RR + +array_trim: + %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) + + RR :MSTORE(array_trim_RR) + + C => E + ; scan from the last chunk to the first chunks until we find a non-zero chunk + ; in case of zero input array, we return 1 +array_trim_loop: + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + E - 1 => E :JMPZ(array_trim_end) + $ => A :MLOAD(array_trim_in + E) + 0 => B + $ :EQ, JMPZ(array_trim_end, array_trim_loop) + +array_trim_end: + %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) + + $ => RR :MLOAD(array_trim_RR) + + E + 1 => C :RETURN diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm new file mode 100644 index 00000000..86971bfc --- /dev/null +++ b/main/modexp/modexp.zkasm @@ -0,0 +1,382 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: B, E, M have been trimmed. +;; POST: out is trimmed +;; +;; modexp: +;; ---------------------------------------- +;; input: +;; · Blen ∈ [1, 839], the len of B +;; · Elen ∈ [1, 839], the len of E +;; · Mlen ∈ [1, 839], the len of M +;; · B ∈ [0, 2²⁵⁶ - 1]^Blen, the base represented in little-endian +;; · E ∈ [0, 2²⁵⁶ - 1]^Elen, the exponent represented in little-endian +;; · M ∈ [0, 2²⁵⁶ - 1]^Mlen, the modulus represented in little-endian +;; +;; output: +;; · B^E (mod M) ∈ [0, 2²⁵⁶ - 1]^Mlen +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; function modexp(b: bigint[], exp: bigint[], mod: bigint[], B: bigint): bigint[] { +;; if (array_is_zero(mod) || array_is_one(mod)) return [0n]; +;; if (array_is_zero(b)) return [0n]; +;; if (array_is_one(b)) return [1n]; +;; if (array_is_zero(e)) return [1n]; +;; +;; let r = [1n]; +;; let base = array_div_mod(b, mod, B)[1]; +;; while (!array_is_zero(exp)) { +;; if (array_is_zero(base)) return [0n]; +;; if (isOdd(exp)) { +;; r = array_div_mod(array_mul(r, base, B),mod,B)[1]; +;; } +;; exp = array_div_mod_short(exp, 2n, B)[0]; +;; base = array_div_mod(array_square(base, B),mod,B)[1]; +;; } +;; return r; +;; }; + +;; RESOURCES (assuming a worst case scenario): +;; ------------------------------------------- +;; cost(pre_loop) = 3·cost(isZero) + 2·cost(isOne) + cost(array_div_mod) +;; nIterations = ⌊log₂(E)⌋ + 1 +;; nTimesEIsOdd = HammingWeight(E) (i.e., number of 1s in the binary representation of E) +;; nTimesEIsEven = nIterations - nTimesEIsOdd +;; cost(iteration1) (if E is odd) = cost(isZero) + cost(isOdd) + 2·cost(array_div_mod) + cost(array_mul) + cost(array_div_mod_short) + cost(array_square) +;; cost(iteration2) (if E is even) = cost(isZero) + cost(isOdd) + cost(array_div_mod) + cost(array_div_mod_short) + cost(array_square) +;; ------------ +;; cost(total) = cost(pre_loop) + nTimesEIsOdd·cost(iteration1) + nTimesEIsEven·cost(iteration2) +;; ------------ + +VAR GLOBAL modexp_Blen +VAR GLOBAL modexp_Elen +VAR GLOBAL modexp_Mlen +VAR GLOBAL modexp_B[839] +VAR GLOBAL modexp_E[839] +VAR GLOBAL modexp_M[839] + +VAR GLOBAL modexp_out[839] +VAR GLOBAL modexp_outlen + +VAR GLOBAL modexp_RR + +modexp: + + %MAX_CNT_BINARY - CNT_BINARY - 10 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 42 :JMPN(outOfCountersStep) + + RR :MSTORE(modexp_RR) + + ; Edge cases + ; 1] Is M = 0? + $ => A :MLOAD(modexp_Mlen) + 1 => B + $ :EQ, JMPNC(modexp_M_continue1) + $ => A :MLOAD(modexp_M) + 0 => B + $ :EQ, JMPC(modexp_M_is_zero) + modexp_M_continue1: + ; From here, M > 0 + + ; 2] Is M = 1? + $ => A :MLOAD(modexp_Mlen) + 1 => B + $ :EQ, JMPNC(modexp_M_continue2) + $ => A :MLOAD(modexp_M) + 1 => B + $ :EQ, JMPC(modexp_M_is_one) + modexp_M_continue2: + ; From here, M > 1 + + ; 3] Is B = 0? + $ => A :MLOAD(modexp_Blen) + 1 => B + $ :EQ, JMPNC(modexp_B_continue1) + $ => A :MLOAD(modexp_B) + 0 => B + $ :EQ, JMPC(modexp_B_is_zero) + modexp_B_continue1: + ; From here, B > 0 + + ; 4] Is B = 1? + $ => A :MLOAD(modexp_Blen) + 1 => B + $ :EQ, JMPNC(modexp_B_continue2) + $ => A :MLOAD(modexp_B) + 1 => B + $ :EQ, JMPC(modexp_B_is_one) + modexp_B_continue2: + ; From here, B > 1 + + ; 5] Is E = 0? + $ => A :MLOAD(modexp_Elen) + 1 => B + $ :EQ, JMPNC(modexp_E_continue1) + $ => A :MLOAD(modexp_E) + 0 => B + $ :EQ, JMPC(modexp_E_is_zero) + modexp_E_continue1: + ; From here, E > 0 + + 1 :MSTORE(modexp_out) + 1 :MSTORE(modexp_outlen) + + ; prepare for computing B % M + $ => C :MLOAD(modexp_Blen) + $ => D :MLOAD(modexp_Mlen) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + +; Compute B = B % M +; ------------------- +modexp_B_to_divmod: + RR - 1 => RR + $ => A :MLOAD(modexp_B + RR) + A :MSTORE(array_div_mod_inA + RR) + RR :JMPZ(modexp_M_to_divmod1, modexp_B_to_divmod) + +modexp_M_to_divmod1: + E - 1 => E + $ => A :MLOAD(modexp_M + E) + A :MSTORE(array_div_mod_inB + E) + E :JMPZ(modexp_divmod_B_and_M, modexp_M_to_divmod1) + +modexp_divmod_B_and_M: + :CALL(array_div_mod) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_mod_len_rem) + C :MSTORE(modexp_Blen) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C :JMPN(outOfCountersStep) + +modexp_rem_from_divmod1: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_rem + RR) + A :MSTORE(modexp_B + RR) + RR :JMPZ(modexp_pre_loop, modexp_rem_from_divmod1) +; ------------------- + +; Begin of edge cases +modexp_M_is_zero: + ; (B^E) % 0 = 0 + 1 :MSTORE(modexp_outlen) + 0 :MSTORE(modexp_out), JMP(modexp_end) + +modexp_M_is_one: + ; (B^E) % 1 = 0 + 1 :MSTORE(modexp_outlen) + 0 :MSTORE(modexp_out), JMP(modexp_end) + +modexp_B_is_zero: + ; (0^E) % M = 0. I define 0^0 = 0 for simplicity + 1 :MSTORE(modexp_outlen) + 0 :MSTORE(modexp_out), JMP(modexp_end) + +modexp_B_is_one: + ; (1^E) % M = 1 + 1 :MSTORE(modexp_outlen) + 1 :MSTORE(modexp_out), JMP(modexp_end) + +modexp_E_is_zero: + ; (B^0) % M = 1 + 1 :MSTORE(modexp_outlen) + 1 :MSTORE(modexp_out), JMP(modexp_end) +; End of edge cases + +; Begin of branching +modexp_loop_multiply: + $ => C :MLOAD(modexp_outlen) + $ => D :MLOAD(modexp_Blen) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + +; Compute out * B +; ------------------- +modexp_out_to_mul_long: + RR - 1 => RR + $ => A :MLOAD(modexp_out + RR) + A :MSTORE(array_mul_inA + RR) + RR :JMPZ(modexp_B_to_mul_long, modexp_out_to_mul_long) + +modexp_B_to_mul_long: + E - 1 => E + $ => A :MLOAD(modexp_B + E) + A :MSTORE(array_mul_inB + E) + E :JMPZ(modexp_mul_long_out_and_B, modexp_B_to_mul_long) + +modexp_mul_long_out_and_B: + :CALL(array_mul) + + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_mul_len_out) + $ => D :MLOAD(modexp_Mlen) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + +; Compute out = (out * B) % M +modexp_out_to_divmod1: + RR - 1 => RR + $ => A :MLOAD(array_mul_out + RR) + A :MSTORE(array_div_mod_inA + RR) + RR :JMPZ(modexp_M_to_divmod, modexp_out_to_divmod1) + +modexp_M_to_divmod: + E - 1 => E + $ => A :MLOAD(modexp_M + E) + A :MSTORE(array_div_mod_inB + E) + E :JMPZ(modexp_divmod_out_and_M2, modexp_M_to_divmod) + +modexp_divmod_out_and_M2: + :CALL(array_div_mod) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_mod_len_rem) + C :MSTORE(modexp_outlen) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +modexp_rem_from_divmod2: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_rem + RR) + A :MSTORE(modexp_out + RR) + RR :JMPZ(return_modexp_loop_multiply, modexp_rem_from_divmod2) +; ------------------- +; End of branching + +modexp_pre_loop: +; In the worst case, the exponent is odd in each iteration + %MAX_CNT_BINARY - CNT_BINARY - 5 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 21 :JMPN(outOfCountersStep) + + ; Is E = 0? + $ => A :MLOAD(modexp_Elen) + 1 => B + $ :EQ, JMPNC(modexp_E_continue2) + $ => A :MLOAD(modexp_E) + 0 => B + $ :EQ, JMPC(modexp_end) + modexp_E_continue2: + +modexp_loop: + ; Is B = 0? + $ => A :MLOAD(modexp_Blen) + 1 => B + $ :EQ, JMPNC(modexp_B_continue3) + $ => A :MLOAD(modexp_B) + 0 => B + $ :EQ, JMPC(modexp_B_is_zero) + modexp_B_continue3: + + ; Is E is odd? + ; The base is 2^256, so I only need to check if the first chunk is odd to conclude that the whole number is odd. + $ => A :MLOAD(modexp_E) + 1 => B + $ :AND, JMPNZ(modexp_loop_multiply) + return_modexp_loop_multiply: + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + $ => C :MLOAD(modexp_Elen) + 2 :MSTORE(array_div_mod_short_inB) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +; Compute E = E // 2 +; ------------------- +modexp_E_to_divmod_short: + RR - 1 => RR + $ => A :MLOAD(modexp_E + RR) + A :MSTORE(array_div_mod_short_inA + RR) + RR :JMPZ(modexp_divmod_E_and_2, modexp_E_to_divmod_short) + +modexp_divmod_E_and_2: + :CALL(array_div_mod_short) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_mod_short_len_quo) + C :MSTORE(modexp_Elen) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) + +modexp_quo_from_divmod_short: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_short_quo + RR) + A :MSTORE(modexp_E + RR) + RR :JMPZ(modexp_pre_B_square, modexp_quo_from_divmod_short) +; ------------------- + +; Compute B^2 +; ------------------- +modexp_pre_B_square: + $ => C :MLOAD(modexp_Blen) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +modexp_B_to_square1: + RR - 1 => RR + $ => A :MLOAD(modexp_B + RR) + A :MSTORE(array_square_in + RR) + RR :JMPZ(modexp_square_B, modexp_B_to_square1) + +modexp_square_B: + :CALL(array_square) + + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_square_len_out) + $ => D :MLOAD(modexp_Mlen) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + +; Compute B = (B^2) % M +modexp_out_to_divmod2: + RR - 1 => RR + $ => A :MLOAD(array_square_out + RR) + A :MSTORE(array_div_mod_inA + RR) + RR :JMPZ(modexp_M_to_divmod2, modexp_out_to_divmod2) + +modexp_M_to_divmod2: + E - 1 => E + $ => A :MLOAD(modexp_M + E) + A :MSTORE(array_div_mod_inB + E) + E :JMPZ(modexp_divmod_out_and_M1, modexp_M_to_divmod2) + +modexp_divmod_out_and_M1: + :CALL(array_div_mod) + + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_mod_len_rem) + C :MSTORE(modexp_Blen) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + +modexp_rem_from_divmod3: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_rem + RR) + A :MSTORE(modexp_B + RR) + RR :JMPZ(modexp_pre_loop, modexp_rem_from_divmod3) +; ------------------- + +modexp_end: + $ => RR :MLOAD(modexp_RR) + :RETURN diff --git a/main/modexp/modexp_utils.zkasm b/main/modexp/modexp_utils.zkasm new file mode 100644 index 00000000..50343d96 --- /dev/null +++ b/main/modexp/modexp_utils.zkasm @@ -0,0 +1,213 @@ +VAR GLOBAL tmpVarAmodexp +VAR GLOBAL tmpVarBmodexp +VAR GLOBAL tmpVarCmodexp +VAR GLOBAL tmpVarDmodexp +VAR GLOBAL offsetInitModexp +VAR GLOBAL tmpVarEmodexp +VAR GLOBAL tmpZkPCmodexp +VAR GLOBAL modExpArrayIndex + +modexp_getBase: + %MAX_CNT_STEPS - STEP - 15 :JMPN(outOfCountersStep) + + RR :MSTORE(tmpZkPCmodexp) + A :MSTORE(tmpVarAmodexp) + B :MSTORE(tmpVarBmodexp) + C :MSTORE(tmpVarCmodexp) + D :MSTORE(tmpVarDmodexp) + E :MSTORE(offsetInitModexp) + E + C => E ;E = offset final + 0 :MSTORE(modExpArrayIndex) + 0 :MSTORE(modexp_Blen) + 32 :MSTORE(readXFromCalldataLength) + +modexp_getBaseLoop: + %MAX_CNT_BINARY - CNT_BINARY - 6 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + + C => A + 0 => B + $ :EQ,JMPC(modexp_saveBaseLen) + 32 => B + $ :LT,JMPC(modexp_getBaseMloadX) + E - 32 => E + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + C - 32 => C :JMP(modexp_getBaseMstore) + +modexp_getBaseMloadX: + C :MSTORE(readXFromCalldataLength) + E - C => E + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + 32 - C => D :CALL(SHRarith) + 0 => C + +modexp_getBaseMstore: + E :MSTORE(tmpVarEmodexp) + A => E + $ => B :MLOAD(modExpArrayIndex) + $ => A :ADD + 0 => B + $ :EQ,JMPC(modexp_getBaseFinal) + E => A + $ => E :MLOAD(modExpArrayIndex) + A :MSTORE(modexp_B+E) + E + 1 => B :MSTORE(modExpArrayIndex) + +modexp_getBaseFinal: + $ => E :MLOAD(tmpVarEmodexp),JMP(modexp_getBaseLoop) + +modexp_saveBaseLen: + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + + $ => A :MLOAD(modExpArrayIndex) + 0 => B + $ :EQ,JMPC(modexp_getReturn) + A - 1 => E :MSTORE(modExpArrayIndex) + $ => A :MLOAD(modexp_B + E) + $ :EQ,JMPC(modexp_saveBaseLen) + E + 1 :MSTORE(modexp_Blen),JMP(modexp_getReturn) + +modexp_getExp: + + %MAX_CNT_STEPS - STEP - 15 :JMPN(outOfCountersStep) + + RR :MSTORE(tmpZkPCmodexp) + A :MSTORE(tmpVarAmodexp) + B :MSTORE(tmpVarBmodexp) + C :MSTORE(tmpVarCmodexp) + D :MSTORE(tmpVarDmodexp) + E :MSTORE(offsetInitModexp) + E + C => E ;E = offset final + 0 :MSTORE(modExpArrayIndex) + 0 :MSTORE(modexp_Elen) + 32 :MSTORE(readXFromCalldataLength) + +modexp_getExpLoop: + + %MAX_CNT_BINARY - CNT_BINARY - 6 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + + C => A + 0 => B + $ :EQ,JMPC(modexp_saveExpLen) + 32 => B + $ :LT,JMPC(modexp_getExpMloadX) + E - 32 => E + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + C - 32 => C :JMP(modexp_getExpMstore) + +modexp_getExpMloadX: + C :MSTORE(readXFromCalldataLength) + E - C => E + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + 32 - C => D :CALL(SHRarith) + 0 => C + +modexp_getExpMstore: + E :MSTORE(tmpVarEmodexp) + A => E + $ => B :MLOAD(modExpArrayIndex) + $ => A :ADD + 0 => B + $ :EQ,JMPC(modexp_getExpFinal) + E => A + $ => E :MLOAD(modExpArrayIndex) + A :MSTORE(modexp_E+E) + E + 1 => B :MSTORE(modExpArrayIndex) + +modexp_getExpFinal: + $ => E :MLOAD(tmpVarEmodexp),JMP(modexp_getExpLoop) + +modexp_saveExpLen: + + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + + $ => A :MLOAD(modExpArrayIndex) + 0 => B + $ :EQ,JMPC(modexp_getReturn) + A - 1 => E :MSTORE(modExpArrayIndex) + $ => A :MLOAD(modexp_E + E) + $ :EQ,JMPC(modexp_saveExpLen) + E + 1 :MSTORE(modexp_Elen),JMP(modexp_getReturn) + +modexp_getMod: + + %MAX_CNT_STEPS - STEP - 15 :JMPN(outOfCountersStep) + + RR :MSTORE(tmpZkPCmodexp) + A :MSTORE(tmpVarAmodexp) + B :MSTORE(tmpVarBmodexp) + C :MSTORE(tmpVarCmodexp) + D :MSTORE(tmpVarDmodexp) + E :MSTORE(offsetInitModexp) + E + C => E ;E = offset final + 0 :MSTORE(modExpArrayIndex) + 0 :MSTORE(modexp_Mlen) + 32 :MSTORE(readXFromCalldataLength) + +modexp_getModLoop: + + %MAX_CNT_BINARY - CNT_BINARY - 6 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + + C => A + 0 => B + $ :EQ,JMPC(modexp_saveModLen) + 32 => B + $ :LT,JMPC(modexp_getModMloadX) + E - 32 => E + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + C - 32 => C :JMP(modexp_getModMstore) + +modexp_getModMloadX: + C :MSTORE(readXFromCalldataLength) + E - C => E + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + 32 - C => D :CALL(SHRarith) + 0 => C + +modexp_getModMstore: + E :MSTORE(tmpVarEmodexp) + A => E + $ => B :MLOAD(modExpArrayIndex) + $ => A :ADD + 0 => B + $ :EQ,JMPC(modexp_getModFinal) + E => A + $ => E :MLOAD(modExpArrayIndex) + A :MSTORE(modexp_M+E) + E + 1 => B :MSTORE(modExpArrayIndex) + +modexp_getModFinal: + $ => E :MLOAD(tmpVarEmodexp),JMP(modexp_getModLoop) + +modexp_saveModLen: + + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + + $ => A :MLOAD(modExpArrayIndex) + 0 => B + $ :EQ,JMPC(modexp_getReturn) + A - 1 => E :MSTORE(modExpArrayIndex) + $ => A :MLOAD(modexp_M + E) + $ :EQ,JMPC(modexp_saveModLen) + E + 1 :MSTORE(modexp_Mlen),JMP(modexp_getReturn) + +modexp_getReturn: + $ => RR :MLOAD(tmpZkPCmodexp) + $ => A :MLOAD(tmpVarAmodexp) + $ => B :MLOAD(tmpVarBmodexp) + $ => C :MLOAD(tmpVarCmodexp) + $ => D :MLOAD(tmpVarDmodexp) + $ => E :MLOAD(offsetInitModexp) + E + C => E + :RETURN diff --git a/main/opcodes/block.zkasm b/main/opcodes/block.zkasm index 174478df..78ea3e08 100644 --- a/main/opcodes/block.zkasm +++ b/main/opcodes/block.zkasm @@ -34,7 +34,7 @@ opBLOCKHASH: B :HASHK(E) %STATE_ROOT_STORAGE_POS :HASHK(E) HASHPOS :HASHKLEN(E) - ; blockhash key = hash(blockNumber, STATE_ROOT_STORAGE_POS) + ; blockhash key = hash(blockNumber, BLOCK_INFO_ROOT_STORAGE_POS) $ => C :HASHKDIGEST(E) %ADDRESS_SYSTEM => A ; set key for smt storage query @@ -94,16 +94,12 @@ opTIMESTAMP: opNUMBER: ; checks zk-counters %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; check out-of-gas GAS - %GAS_QUICK_STEP => GAS :JMPN(outOfGas) ; Get current tx count - $ => A :MLOAD(txCount) - 1 => B - - ; call binary:add state machine and push to the stack - $ :ADD, MSTORE(SP++); [blockNumber => SP] + $ => A :MLOAD(blockNum) + A :MSTORE(SP++); [blockNumber => SP] ; check stack overflow %MAX_STACK_SIZE - SP :JMPN(stackOverflow, readCode) @@ -142,7 +138,7 @@ opGASLIMIT: ; check out-of-gas GAS-%GAS_QUICK_STEP => GAS :JMPN(outOfGas) ; constant tx gas limit - %TX_GAS_LIMIT => A + %BLOCK_GAS_LIMIT => A A :MSTORE(SP++); [gasLimit => SP] ; check stack overflow %MAX_STACK_SIZE - SP :JMPN(stackOverflow, readCode) diff --git a/main/opcodes/create-terminate-context.zkasm b/main/opcodes/create-terminate-context.zkasm index febcae8e..f4f38e2c 100644 --- a/main/opcodes/create-terminate-context.zkasm +++ b/main/opcodes/create-terminate-context.zkasm @@ -148,7 +148,7 @@ opCREATE: $ => A :MLOAD(argsLengthCall) ; set calldata pointers to current CTX A :MSTORE(txCalldataLen), CALL(saveCalldataPointer) - $ => A :MLOAD(valueCall) + $ => A :MLOAD(valueCall), CALL(checkpointBlockInfoTree) ; Save touched root when a new context is created A :MSTORE(txValue), CALL(checkpointTouched) :JMP(txType) @@ -281,6 +281,7 @@ opCALLend: A :MSTORE(txCalldataLen), CALL(saveCalldataPointer) ; save touched root when a new context is created :CALL(checkpointTouched) + :CALL(checkpointBlockInfoTree) :JMP(txType) /** @@ -389,6 +390,7 @@ opCALLCODEend: A :MSTORE(txCalldataLen), CALL(saveCalldataPointer) ; Save touched root when a new context is created :CALL(checkpointTouched) + :CALL(checkpointBlockInfoTree) :JMP(txType) /** * @link [https://www.evm.codes/#f3?fork=berlin] @@ -626,6 +628,7 @@ opDELEGATECALLend: A :MSTORE(txCalldataLen), CALL(saveCalldataPointer) ; Save touched root when a new context is created :CALL(checkpointTouched) + :CALL(checkpointBlockInfoTree) :JMP(txType) /** @@ -746,7 +749,7 @@ opCREATE2: $ => A :MLOAD(argsLengthCall) ; set calldata pointers to current CTX A :MSTORE(txCalldataLen), CALL(saveCalldataPointer) - $ => A :MLOAD(valueCall) + $ => A :MLOAD(valueCall), CALL(checkpointBlockInfoTree) ; Save touched root when a new context is created A :MSTORE(txValue), CALL(checkpointTouched) :JMP(txType) @@ -831,6 +834,7 @@ opSTATICCALL: A :MSTORE(txCalldataLen), CALL(saveCalldataPointer) ; save touched root when a new context is created :CALL(checkpointTouched) + :CALL(checkpointBlockInfoTree) :JMP(txType) /** * @link [https://www.evm.codes/#fd?fork=berlin] @@ -849,7 +853,7 @@ opREVERT: ; revert touched accounts $ => SR :MLOAD(initSR), CALL(revertTouched) - $ => E :MLOAD(SP+1); [offset => E] + $ => E :MLOAD(SP+1), CALL(revertBlockInfoTree); [offset => E] $ => C :MLOAD(SP); [size => C] E :MSTORE(retDataOffset) C :MSTORE(retDataLength) @@ -863,7 +867,7 @@ opREVERT: $${eventLog(onError, revert)} 0 :MSTORE(gasRefund) ; if origin ctx is 0, end tx - B :JMPZ(handleGas) + B :JMPZ(handleGasFromError) ; decrease CTX $ => A :MLOAD(currentCTX) B => CTX diff --git a/main/opcodes/logs.zkasm b/main/opcodes/logs.zkasm index b73e1dcb..6b37991a 100644 --- a/main/opcodes/logs.zkasm +++ b/main/opcodes/logs.zkasm @@ -7,6 +7,8 @@ * - stack input: [offset, size, topic] * - stack output: none */ + VAR GLOBAL opLogAux + opLOG0: ; checks zk-counters %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) @@ -37,10 +39,7 @@ opLOG0: GAS => A ; check out-of-gas $ :LT,JMPC(outOfGas) - GAS - B => GAS - $ => B :MLOAD(nextFreeLogIndex) ; load logIndex - B + 1 :MSTORE(nextFreeLogIndex), JMP(opLOGLoop) ; store next free log index - + GAS - B => GAS :JMP(initLogLoop) opLOG1: %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) @@ -60,9 +59,7 @@ opLOG1: GAS => A ; check out-of-gas $ :LT,JMPC(outOfGas) - GAS - B => GAS - $ => B :MLOAD(nextFreeLogIndex) - B + 1 :MSTORE(nextFreeLogIndex), JMP(opLOGLoop) + GAS - B => GAS :JMP(initLogLoop) opLOG2: @@ -83,9 +80,7 @@ opLOG2: GAS => A ; check out-of-gas $ :LT,JMPC(outOfGas) - GAS - B => GAS - $ => B :MLOAD(nextFreeLogIndex) - B + 1 :MSTORE(nextFreeLogIndex), JMP(opLOGLoop) + GAS - B => GAS :JMP(initLogLoop) opLOG3: @@ -106,9 +101,7 @@ opLOG3: GAS => A ; check out-of-gas $ :LT,JMPC(outOfGas) - GAS - B => GAS - $ => B :MLOAD(nextFreeLogIndex) - B + 1 :MSTORE(nextFreeLogIndex), JMP(opLOGLoop) + GAS - B => GAS :JMP(initLogLoop) opLOG4: @@ -129,39 +122,68 @@ opLOG4: GAS => A ; check out-of-gas $ :LT,JMPC(outOfGas) - GAS - B => GAS - $ => B :MLOAD(nextFreeLogIndex) - B + 1 :MSTORE(nextFreeLogIndex), JMP(opLOGLoop) - -opLOGLoop: + GAS - B => GAS :JMP(initLogLoop) + +initLogLoop: + ; check poseidon counters + ; 56 is the value used by the prover to increment poseidon counters depending on the hash length + C :MSTORE(arithA) + 56 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => B :MLOAD(arithRes1) + ; We count B and also the number of topics, as max is 4 topics of 32 bytes each 32*4/56 = 2.2 -> 3 + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 4 - B :JMPN(outOfCountersPoseidon) + %MAX_CNT_PADDING_PG_LIMIT - CNT_PADDING_PG - 4 - B :JMPN(outOfCountersPadding) + 0 => HASHPOS + 32 => D + $ => B :MLOAD(currentLogIndex) +logLoop: ; checks zk-counters %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) C :JMPZ(opSaveTopicsInit) ; load next 32 bytes - C - 32 :JMPN(opLOGFinal) + C - 32 :JMPN(opLogFinal) :CALL(MLOAD32); in: [E: offset] out: [A: value] + E :MSTORE(opLogAux) + $ => E :MLOAD(nextHashPId) + A :HASHP(E) + $ => E :MLOAD(opLogAux) $${storeLog(B, 0, A)} ; storeLog(indexLog, isTopic, bytesToStore) - C - 32 => C :JMP(opLOGLoop) + C - 32 => C :JMP(logLoop) -opLOGFinal: +opLogFinal: ; load last C bytes :CALL(MLOADX); in: [E: offset, C: length] out: [A: value, E: new offset] $${storeLog(B, 0, A)}; storeLog(indexLog, isTopic, bytesToStore) + 32 - C => D :CALL(SHRarith); in: [A: value, D: #bytes to right shift] out: [A: shifted result] + C => D + $ => E :MLOAD(nextHashPId) + A :HASHP(E) :JMP(opSaveTopicsInit) ; instruction added to allow executing $$ function opSaveTopicsInit: ; save topics $ => A :MLOAD(numTopics) + $ => E :MLOAD(nextHashPId) + 32 => D opSaveTopicsLoop: ; checks zk-counters %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - A :JMPZ(readCode) + A :JMPZ(finishSaveTopics) ; check stack underflow SP - 1 => SP ; check out-of-gas - GAS - %LOG_TOPIC_GAS => GAS :JMPN(outOfGas) - $ => C :MLOAD(SP) ; [topic => C] + GAS - %LOG_TOPIC_GAS => GAS :JMPN(outOfGas) + $ => C :MLOAD(SP) ; [topic => C] + C :HASHP(E) $${storeLog(B, 1, C)} ; storeLog(indexLog, isTopic, bytesToStore) - A - 1 => A :JMP(opSaveTopicsLoop) + A - 1 => A :JMP(opSaveTopicsLoop) + +finishSaveTopics: + ; Update nextHashPId + E + 1 :MSTORE(nextHashPId) + ; Compute hash of the log + HASHPOS :HASHPLEN(E) + $ => D :HASHPDIGEST(E), CALL(fillBlockInfoTreeWithLog); in: [D: linearPoseidon(log_data + log_topics)] + :JMP(readCode) \ No newline at end of file diff --git a/main/pairings/BN254/addPointBN254.zkasm b/main/pairings/BN254/addPointBN254.zkasm new file mode 100644 index 00000000..bcb9e62e --- /dev/null +++ b/main/pairings/BN254/addPointBN254.zkasm @@ -0,0 +1,245 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; addPointBN254: +;; in: P1 = (P1.x1 + P1.x2·u, P1.y1 + P1.y2·u), P2 = (P2.x1 + P2.x2·u, P2.y1 + P2.y2·u) ∈ E'(Fp2) +;; out: P1 + P2 = (P3.x1 + P3.x2·u, P3.y1 + P3.y2·u) ∈ E'(Fp2) +;; +;; assumes: P1,P2 ∈ E'(Fp2) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; addPointBN254 assumes both P1 and P2 belong to E'(Fp2), since it is checked in the pairing. +; However, it must be implemented if addPointBN254 wants to be used independently. + +; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL addPointBN254_P1_x1 +VAR GLOBAL addPointBN254_P1_x2 +VAR GLOBAL addPointBN254_P1_y1 +VAR GLOBAL addPointBN254_P1_y2 +VAR GLOBAL addPointBN254_P2_x1 +VAR GLOBAL addPointBN254_P2_x2 +VAR GLOBAL addPointBN254_P2_y1 +VAR GLOBAL addPointBN254_P2_y2 +VAR GLOBAL addPointBN254_P3_x1 +VAR GLOBAL addPointBN254_P3_x2 +VAR GLOBAL addPointBN254_P3_y1 +VAR GLOBAL addPointBN254_P3_y2 +VAR GLOBAL addPointBN254_lambda_x +VAR GLOBAL addPointBN254_lambda_y +VAR GLOBAL addPointBN254_RR + +addPointBN254: + RR :MSTORE(addPointBN254_RR) + + ; Is P1 = O? + 0n => B + $ => A :MLOAD(addPointBN254_P1_x1) + $ :EQ, JMPNC(addPointBN254_P1_continue) + $ => A :MLOAD(addPointBN254_P1_x2) + $ :EQ, JMPNC(addPointBN254_P1_continue) + $ => A :MLOAD(addPointBN254_P1_y1) + $ :EQ, JMPNC(addPointBN254_P1_continue) + $ => A :MLOAD(addPointBN254_P1_y2) + $ :EQ, JMPC(addPointBN254_P1_is_zero) + addPointBN254_P1_continue: + + ; Is P2 = 0? + 0n => B + $ => A :MLOAD(addPointBN254_P2_x1) + $ :EQ, JMPNC(addPointBN254_P2_continue) + $ => A :MLOAD(addPointBN254_P2_x2) + $ :EQ, JMPNC(addPointBN254_P2_continue) + $ => A :MLOAD(addPointBN254_P2_y1) + $ :EQ, JMPNC(addPointBN254_P2_continue) + $ => A :MLOAD(addPointBN254_P2_y2) + $ :EQ, JMPC(addPointBN254_P2_is_zero) + addPointBN254_P2_continue: + + ; P1 and P2 are not 0, let's check whether they are different points, the same point or inverses of each other + ; Is P1.x == P2.x? + $ => A :MLOAD(addPointBN254_P1_x1) + $ => B :MLOAD(addPointBN254_P2_x1) + $ :EQ, JMPNC(addPointBN254_different) + $ => A :MLOAD(addPointBN254_P1_x2) + $ => B :MLOAD(addPointBN254_P2_x2) + $ :EQ, JMPNC(addPointBN254_different) + + ; Is P1.y == P2.y? + $ => A :MLOAD(addPointBN254_P1_y1) + $ => B :MLOAD(addPointBN254_P2_y1) + $ :EQ, JMPNC(addPointBN254_P1_and_P2_are_inverted) + $ => A :MLOAD(addPointBN254_P1_y2) + $ => B :MLOAD(addPointBN254_P2_y2) + $ :EQ, JMPNC(addPointBN254_P1_and_P2_are_inverted) + + ; P1 == P2 + :JMP(addPointBN254_same) + +addPointBN254_P1_is_zero: + ; P3 = P2 + $ => A :MLOAD(addPointBN254_P2_x1) + $ => B :MLOAD(addPointBN254_P2_x2) + $ => C :MLOAD(addPointBN254_P2_y1) + $ => D :MLOAD(addPointBN254_P2_y2) + A :MSTORE(addPointBN254_P3_x1) + B :MSTORE(addPointBN254_P3_x2) + C :MSTORE(addPointBN254_P3_y1) + D :MSTORE(addPointBN254_P3_y2) + + :JMP(addPointBN254_end) + +addPointBN254_P2_is_zero: + ; P3 = P1 + $ => A :MLOAD(addPointBN254_P1_x1) + $ => B :MLOAD(addPointBN254_P1_x2) + $ => C :MLOAD(addPointBN254_P1_y1) + $ => D :MLOAD(addPointBN254_P1_y2) + A :MSTORE(addPointBN254_P3_x1) + B :MSTORE(addPointBN254_P3_x2) + C :MSTORE(addPointBN254_P3_y1) + D :MSTORE(addPointBN254_P3_y2) + + :JMP(addPointBN254_end) + +addPointBN254_P1_and_P2_are_inverted: + ; Check -P1.y == P2.y + %BN254_P => A + $ => B :MLOAD(addPointBN254_P1_y1) + $ => C :SUB + $ => B :MLOAD(addPointBN254_P1_y2) + $ => D :SUB + + $ => A :MLOAD(addPointBN254_P2_y1) + C :ASSERT + $ => A :MLOAD(addPointBN254_P2_y2) + D :ASSERT + + ; P3 = O + 0n :MSTORE(addPointBN254_P3_x1) + 0n :MSTORE(addPointBN254_P3_x2) + 0n :MSTORE(addPointBN254_P3_y1) + 0n :MSTORE(addPointBN254_P3_y2) + + :JMP(addPointBN254_end) + +addPointBN254_same: + $ => A :MLOAD(addPointBN254_P1_y1) + $ => B :MLOAD(addPointBN254_P1_y2) + $ => C :MLOAD(addPointBN254_P1_y1) + $ => D :MLOAD(addPointBN254_P1_y2), CALL(addFp2BN254) + ; E + C·u = 2y + + E => A + C => B :CALL(invFp2BN254) + ; C + D·u = 1 / 2y + + 3n => A :CALL(escalarMulFp2BN254) + ; E + C·u = 3/2y + + $ => A :MLOAD(addPointBN254_P1_x1) + $ => B :MLOAD(addPointBN254_P1_x2) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = 3x/2y + + $ => A :MLOAD(addPointBN254_P1_x1) + $ => B :MLOAD(addPointBN254_P1_x2) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda = 3x²/2y + + E :MSTORE(addPointBN254_lambda_x) + C :MSTORE(addPointBN254_lambda_y) + ; E + C·u = lambda + + E => A + C => B :CALL(squareFp2BN254) + ; E + C·u = lambda² + + E => A + C => B + $ => C :MLOAD(addPointBN254_P1_x1) + $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - x + + E => A + C => B + $ => C :MLOAD(addPointBN254_P1_x1) + $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - x - x + + :JMP(addPointBN254_common_calculate) + +addPointBN254_different: + $ => A :MLOAD(addPointBN254_P2_x1) + $ => B :MLOAD(addPointBN254_P2_x2) + $ => C :MLOAD(addPointBN254_P1_x1) + $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) + ; E + C·u = P2.x - P1.x + + E => A + C => B :CALL(invFp2BN254) + ; C + D·u = 1 / (P2_x - P1_x) + C :MSTORE(addPointBN254_lambda_x) + D :MSTORE(addPointBN254_lambda_y) + + $ => A :MLOAD(addPointBN254_P2_y1) + $ => B :MLOAD(addPointBN254_P2_y2) + $ => C :MLOAD(addPointBN254_P1_y1) + $ => D :MLOAD(addPointBN254_P1_y2), CALL(subFp2BN254) + ; E + C·u = P2.y - P1.y + + $ => A :MLOAD(addPointBN254_lambda_x) + $ => B :MLOAD(addPointBN254_lambda_y) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda = (P2_y - P1_y) / (P2_x - P1_x) + E :MSTORE(addPointBN254_lambda_x) + C :MSTORE(addPointBN254_lambda_y) + + E => A + C => B :CALL(squareFp2BN254) + ; E + C·u = lambda² + + E => A + C => B + $ => C :MLOAD(addPointBN254_P1_x1) + $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - P1.x + + E => A + C => B + $ => C :MLOAD(addPointBN254_P2_x1) + $ => D :MLOAD(addPointBN254_P2_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - P1.x - P2.x + +addPointBN254_common_calculate: + E :MSTORE(addPointBN254_P3_x1) + C :MSTORE(addPointBN254_P3_x2) + ; P3.x = lambda² - P1.x - P2.x + + $ => A :MLOAD(addPointBN254_P1_x1) + $ => B :MLOAD(addPointBN254_P1_x2) + C => D + E => C :CALL(subFp2BN254) + ; E + C·u = P1.x - P3.x + + $ => A :MLOAD(addPointBN254_lambda_x) + $ => B :MLOAD(addPointBN254_lambda_y) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda·(P1.x - P3.x) + + E => A + C => B + $ => C :MLOAD(addPointBN254_P1_y1) + $ => D :MLOAD(addPointBN254_P1_y2), CALL(subFp2BN254) + ; E + C·u = lambda·(P1.x - P3.x) - P1.y + + E :MSTORE(addPointBN254_P3_y1) + C :MSTORE(addPointBN254_P3_y2) + +addPointBN254_end: + $ => RR :MLOAD(addPointBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/ecAdd.zkasm b/main/pairings/BN254/ecAdd.zkasm new file mode 100644 index 00000000..324eb7ec --- /dev/null +++ b/main/pairings/BN254/ecAdd.zkasm @@ -0,0 +1,311 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; ecAdd: +;; in: P1 = (P1.x, P1.y), P2 = (P2.x, P2.y) ∈ E(Fp) +;; out: P1 + P2 = (P3.x, P3.y) ∈ E(Fp) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Since the curve is E/Fp: y² = x³ + 3, there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL ecAdd_P1_x +VAR GLOBAL ecAdd_P1_y +VAR GLOBAL ecAdd_P1_y_inv +VAR GLOBAL ecAdd_P2_x +VAR GLOBAL ecAdd_P2_y +VAR GLOBAL ecAdd_P3_x +VAR GLOBAL ecAdd_P3_y +VAR GLOBAL ecAdd_lambda + +VAR GLOBAL ecAdd_RR + +; ERROR CODES (B) +; 0 - no error +; 1 - P1_x is too big +; 2 - P1_y is too big +; 3 - P2_x is too big +; 4 - P2_y is too big +; 5 - P1 is not in E(Fp) +; 6 - P2 is not in E(Fp) + +ecAdd: + RR :MSTORE(ecAdd_RR) + + %BN254_P_MINUS_ONE => A + $ => B :MLOAD(ecAdd_P1_x) + $ :LT, JMPC(ecAdd_P1x_too_big) + $ => B :MLOAD(ecAdd_P1_y) + $ :LT, JMPC(ecAdd_P1y_too_big) + $ => B :MLOAD(ecAdd_P2_x) + $ :LT, JMPC(ecAdd_P2x_too_big) + $ => B :MLOAD(ecAdd_P2_y) + $ :LT, JMPC(ecAdd_P2y_too_big) + + ; Is P1 = O? + 0n => B + $ => A :MLOAD(ecAdd_P1_x) + $ :EQ, JMPNC(ecAdd_P1_continue) + $ => A :MLOAD(ecAdd_P1_y) + $ :EQ, JMPC(ecAdd_P1_is_zero) + ecAdd_P1_continue: + + ; Is P2 = O? + 0n => B + $ => A :MLOAD(ecAdd_P2_x) + $ :EQ, JMPNC(ecAdd_P2_continue1) + $ => A :MLOAD(ecAdd_P2_y) + $ :EQ, JMPC(ecAdd_P2_is_zero) + ecAdd_P2_continue1: + + ; 1] Check if P1 is in E(Fp) + ; P1 in E iff (P1.y)² == (P1.x)³ + 3 (mod p) + ; 1.1] Compute LHS and RHS + $ => A :MLOAD(ecAdd_P1_x), CALL(squareFpBN254) + ; B = (P1.x)² + + $ => A :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) + ; C = (P1.x)³ + + %BN254_E_B => A :CALL(addFpBN254) + ; C = (P1.x)³ + 3 + C :MSTORE(ecAdd_P3_x) + + $ => A :MLOAD(ecAdd_P1_y), CALL(squareFpBN254) + ; B = (Py)² + + ; 1.2] Check if LHS == RHS + B => A + $ => B :MLOAD(ecAdd_P3_x) + $ :EQ, JMPNC(ecAdd_P1_is_not_in_E) + + ; 2] check if P2 is in E(Fp) + ; P2 in E iff (P2.y)² == (P2.x)³ + 3 (mod p) + ; 2.1] Compute LHS and RHS + $ => A :MLOAD(ecAdd_P2_x), CALL(squareFpBN254) + ; B = (P2.x)² + + $ => A :MLOAD(ecAdd_P2_x), CALL(mulFpBN254) + ; C = (P2.x)³ + + %BN254_E_B => A :CALL(addFpBN254) + ; C = (P2.x)³ + 3 + C :MSTORE(ecAdd_P3_x) + + $ => A :MLOAD(ecAdd_P2_y), CALL(squareFpBN254) + ; B = (Py)² + + ; 2.2] Check if LHS == RHS + B => A + $ => B :MLOAD(ecAdd_P3_x) + $ :EQ, JMPNC(ecAdd_P2_is_not_in_E) + + ; P1 and P2 are not 0, let's check whether they are different points, the same point or inverses of each other + $ => A :MLOAD(ecAdd_P1_x) + $ => B :MLOAD(ecAdd_P2_x) + + ; Is P1.x == P2.x? + $ :EQ, JMPNC(ecAdd_different) + + $ => A :MLOAD(ecAdd_P1_y) + $ => B :MLOAD(ecAdd_P2_y) + + ; Is P1.y == P2.y? + $ :EQ, JMPNC(ecAdd_P1_and_P2_are_inverted) + + ; P1 == P2 + :JMP(ecAdd_same) + +ecAdd_P1_is_zero: + ; Is P2 = 0? + 0n => B + $ => A :MLOAD(ecAdd_P2_x) + $ :EQ, JMPNC(ecAdd_P2_continue2) + $ => A :MLOAD(ecAdd_P2_y) + $ :EQ, JMPC(ecAdd_P1_and_P2_are_zero) + ecAdd_P2_continue2: + + ; P2 in E iff (P2.y)² == (P2.x)³ + 3 (mod p) + ; 1] Compute LHS and RHS + $ => A :MLOAD(ecAdd_P2_x), CALL(squareFpBN254) + ; B = (P2.x)² + + $ => A :MLOAD(ecAdd_P2_x), CALL(mulFpBN254) + ; C = (P2.x)³ + + %BN254_E_B => A :CALL(addFpBN254) + ; C = (P2.x)³ + 3 + C :MSTORE(ecAdd_P3_x) + + $ => A :MLOAD(ecAdd_P2_y), CALL(squareFpBN254) + ; B = (Py)² + + ; 2] Check if LHS == RHS + B => A + $ => B :MLOAD(ecAdd_P3_x) + $ :EQ, JMPNC(ecAdd_P2_is_not_in_E) + + ; P3 = P2 + $ => A :MLOAD(ecAdd_P2_x) + $ => B :MLOAD(ecAdd_P2_y) + A :MSTORE(ecAdd_P3_x) + B :MSTORE(ecAdd_P3_y) + + :JMP(ecAdd_correct) + +ecAdd_P2_is_zero: + ; P1 in E iff (P1.y)² == (P1.x)³ + 3 (mod p) + ; 1] Compute LHS and RHS + $ => A :MLOAD(ecAdd_P1_x), CALL(squareFpBN254) + ; B = (P1.x)² + + $ => A :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) + ; C = (P1.x)³ + + %BN254_E_B => A :CALL(addFpBN254) + ; C = (P1.x)³ + 3 + C :MSTORE(ecAdd_P3_x) + + $ => A :MLOAD(ecAdd_P1_y), CALL(squareFpBN254) + ; B = (Py)² + + ; 2] Check if LHS == RHS + B => A + $ => B :MLOAD(ecAdd_P3_x) + $ :EQ, JMPNC(ecAdd_P1_is_not_in_E) + + ; P3 = P1 + $ => A :MLOAD(ecAdd_P1_x) + $ => B :MLOAD(ecAdd_P1_y) + A :MSTORE(ecAdd_P3_x) + B :MSTORE(ecAdd_P3_y) + + :JMP(ecAdd_correct) + +ecAdd_P1_and_P2_are_zero: + ; P3 = 0 + 0n :MSTORE(ecAdd_P3_x) + 0n :MSTORE(ecAdd_P3_y) + + :JMP(ecAdd_correct) + +ecAdd_P1_and_P2_are_inverted: + ; P3 = 0 + 0n :MSTORE(ecAdd_P3_x) + 0n :MSTORE(ecAdd_P3_y) + + :JMP(ecAdd_correct) + +ecAdd_same: + $ => A :MLOAD(ecAdd_P1_y) + $ => C :MLOAD(ecAdd_P1_y), CALL(addFpBN254) + ; C = 2y + + C => A :CALL(invFpBN254) + ; B = 1 / 2y + B :MSTORE(ecAdd_P1_y_inv) + + B => A,C :CALL(addFpBN254) + C => A + $ => C :MLOAD(ecAdd_P1_y_inv), CALL(addFpBN254) + ; C = 3/2y + + C => A + $ => B :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) + ; C = 3x/2y + + C => A + $ => B :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) + ; C = lambda = 3x²/2y + + C :MSTORE(ecAdd_lambda) + ; C = lambda + + C => A :CALL(squareFpBN254) + ; B = lambda² + + B => A + $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) + ; C = lambda² - x + + C => A + $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) + ; C = lambda² - x - x + + :JMP(ecAdd_common_calculate) + +ecAdd_different: + $ => A :MLOAD(ecAdd_P2_x) + $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) + ; C = P2.x - P1.x + + C => A :CALL(invFpBN254) + ; B = 1 / (P2.x - P1.x) + B :MSTORE(ecAdd_lambda) + + $ => A :MLOAD(ecAdd_P2_y) + $ => C :MLOAD(ecAdd_P1_y), CALL(subFpBN254) + ; C = P2.y - P1.y + + C => A + $ => B :MLOAD(ecAdd_lambda), CALL(mulFpBN254) + ; C = lambda = (P2.y - P1.y) / (P2.x - P1.x) + C :MSTORE(ecAdd_lambda) + + C => A :CALL(squareFpBN254) + ; B = lambda² + + B => A + $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) + ; C = lambda² - P1.x + + C => A + $ => C :MLOAD(ecAdd_P2_x), CALL(subFpBN254) + ; C = lambda² - P1.x - P2.x + +ecAdd_common_calculate: + C :MSTORE(ecAdd_P3_x) + ; P3.x = lambda² - P1.x - P2.x + + $ => A :MLOAD(ecAdd_P1_x), CALL(subFpBN254) + ; C = P1.x - P3.x + + $ => A :MLOAD(ecAdd_lambda) + C => B :CALL(mulFpBN254) + ; C = lambda·(P1.x - P3.x) + + C => A + $ => C :MLOAD(ecAdd_P1_y), CALL(subFpBN254) + ; C = lambda·(P1.x - P3.x) - P1.y + + C :MSTORE(ecAdd_P3_y) + + :JMP(ecAdd_correct) + +; ERRORS +ecAdd_P1x_too_big: + 1 => B :JMP(ecAdd_error) + +ecAdd_P1y_too_big: + 2 => B :JMP(ecAdd_error) + +ecAdd_P2x_too_big: + 3 => B :JMP(ecAdd_error) + +ecAdd_P2y_too_big: + 4 => B :JMP(ecAdd_error) + +ecAdd_P1_is_not_in_E: + 5 => B :JMP(ecAdd_error) + +ecAdd_P2_is_not_in_E: + 6 => B :JMP(ecAdd_error) + +ecAdd_correct: + 0 => B :JMP(ecAdd_end) + +ecAdd_error: + 0 => A + +ecAdd_end: + $ => RR :MLOAD(ecAdd_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/ecMul.zkasm b/main/pairings/BN254/ecMul.zkasm new file mode 100644 index 00000000..a0d27f07 --- /dev/null +++ b/main/pairings/BN254/ecMul.zkasm @@ -0,0 +1,158 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; ecMul: +;; in: k, P = (P.x, P.y) ∈ E(Fp), where k ∈ [0,r-1] +;; out: k·P = (Q.x, Q.y) ∈ E(Fp) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Since the curve is E/Fp: y² = x³ + 3, there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL ecMul_k +VAR GLOBAL ecMul_P_x +VAR GLOBAL ecMul_P_y +VAR GLOBAL ecMul_Q_x +VAR GLOBAL ecMul_Q_y + +VAR GLOBAL ecMul_RR + +; ERROR CODES (B) +; 0 - no error +; 1 - P_x is too big +; 2 - P_y is too big +; 3 - P is not in E(Fp) + +ecMul: + RR :MSTORE(ecMul_RR) + + %BN254_P_MINUS_ONE => A + $ => B :MLOAD(ecMul_P_x) + $ :LT, JMPC(ecMul_Px_too_big) + $ => B :MLOAD(ecMul_P_y) + $ :LT, JMPC(ecMul_Py_too_big) + + ; Is P = O? + 0n => B + $ => A :MLOAD(ecMul_P_x) + $ :EQ, JMPNC(ecMul_P_continue) + $ => A :MLOAD(ecMul_P_y) + $ :EQ, JMPC(ecMul_P_is_zero) + ecMul_P_continue: + + ; 1] Check if P is in E(Fp) + ; P in E iff (P.y)² == (P.x)³ + 3 (mod p) + ; 1.1] Compute LHS and RHS + $ => A :MLOAD(ecMul_P_x), CALL(squareFpBN254) + ; B = (P.x)² + + $ => A :MLOAD(ecMul_P_x), CALL(mulFpBN254) + ; C = (P.x)³ + + %BN254_E_B => A :CALL(addFpBN254) + ; C = (P.x)³ + 3 + C :MSTORE(ecMul_Q_x) + + $ => A :MLOAD(ecMul_P_y), CALL(squareFpBN254) + ; B = (Py)² + + ; 1.2] Check if LHS == RHS + B => A + $ => B :MLOAD(ecMul_Q_x) + $ :EQ, JMPNC(ecMul_P_is_not_in_E) + + ; Is k ∈ [1,r-1]? + $ => B :MLOAD(ecMul_k), CALL(reduceFrBN254) + A :MSTORE(ecMul_k) + 0n => B + $ :EQ, JMPC(ecMul_k_is_zero) + + 257 => RCX + + $ => A :MLOAD(ecMul_P_x) + $ => C :MLOAD(ecMul_P_y) + A :MSTORE(ecMul_Q_x) + C :MSTORE(ecMul_Q_y) + + :JMP(ecMul_find_MSB_k) + +ecMul_P_is_zero: + ; Q = O + 0n :MSTORE(ecMul_Q_x) + 0n :MSTORE(ecMul_Q_y) + + :JMP(ecMul_correct) + +ecMul_k_is_zero: + ; Q = O + 0n :MSTORE(ecMul_Q_x) + 0n :MSTORE(ecMul_Q_y) + + :JMP(ecMul_correct) + +ecMul_find_MSB_k: + RCX - 1 => RCX + $ => A,B :MLOAD(ecMul_k) + ; E = 2A + $ => E :ADD,MSTORE(ecMul_k), JMPNC(ecMul_find_MSB_k) + + +ecMul_loop: + RCX - 1 => RCX :JMPZ(ecMul_correct) + + ; We always double + $ => A :MLOAD(ecMul_Q_x) + $ => B :MLOAD(ecMul_Q_y) + A :MSTORE(ecAdd_P1_x) + B :MSTORE(ecAdd_P1_y) + A :MSTORE(ecAdd_P2_x) + B :MSTORE(ecAdd_P2_y), CALL(ecAdd) + ; Q = Q + Q + + $ => A :MLOAD(ecAdd_P3_x) + $ => B :MLOAD(ecAdd_P3_y) + A :MSTORE(ecMul_Q_x) + B :MSTORE(ecMul_Q_y) + + ; We check if the MSB b of k is either 1 or 0. If b==1, we should add P to Q. + ; Then, update the value of k. + $ => A,B :MLOAD(ecMul_k) + ; E = 2A + $ => E :ADD, MSTORE(ecMul_k), JMPNC(ecMul_loop) + +ecMul_add: + ; We add + $ => A :MLOAD(ecMul_Q_x) + $ => B :MLOAD(ecMul_Q_y) + $ => C :MLOAD(ecMul_P_x) + $ => D :MLOAD(ecMul_P_y) + A :MSTORE(ecAdd_P1_x) + B :MSTORE(ecAdd_P1_y) + C :MSTORE(ecAdd_P2_x) + D :MSTORE(ecAdd_P2_y), CALL(ecAdd) + ; Q = Q + P + + $ => A :MLOAD(ecAdd_P3_x) + $ => B :MLOAD(ecAdd_P3_y) + A :MSTORE(ecMul_Q_x) + B :MSTORE(ecMul_Q_y), JMP(ecMul_loop) + + +; ERRORS +ecMul_Px_too_big: + 1 => B :JMP(ecMul_error) + +ecMul_Py_too_big: + 2 => B :JMP(ecMul_error) + +ecMul_P_is_not_in_E: + 3 => B :JMP(ecMul_error) + +ecMul_correct: + 0 => B :JMP(ecMul_end) + +ecMul_error: + 0 => A + +ecMul_end: + $ => RR :MLOAD(ecMul_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/escalarMulBN254.zkasm b/main/pairings/BN254/escalarMulBN254.zkasm new file mode 100644 index 00000000..923eac3e --- /dev/null +++ b/main/pairings/BN254/escalarMulBN254.zkasm @@ -0,0 +1,155 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; +;; escalarMulBN254: +;; in: k, P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2), where k ∈ [0,r-1] +;; out: k·P = (Q.x1 + Q.x2·u, Q.y1 + Q.y2·u) ∈ E'(Fp2) +;; +;; assumes: P ∈ E'(Fp2) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; escalarMulBN254 assumes P belong to E'(Fp2), since it is checked in the pairing. +; However, it must be implemented if escalarMulBN254 wants to be used independently. + +; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL escalarMulBN254_k +VAR GLOBAL escalarMulBN254_P_x1 +VAR GLOBAL escalarMulBN254_P_x2 +VAR GLOBAL escalarMulBN254_P_y1 +VAR GLOBAL escalarMulBN254_P_y2 +VAR GLOBAL escalarMulBN254_Q_x1 +VAR GLOBAL escalarMulBN254_Q_x2 +VAR GLOBAL escalarMulBN254_Q_y1 +VAR GLOBAL escalarMulBN254_Q_y2 + +VAR GLOBAL escalarMulBN254_RR + + +escalarMulBN254: + RR :MSTORE(escalarMulBN254_RR) + + ; Is P = O? + 0n => B + $ => A :MLOAD(escalarMulBN254_P_x1) + $ :EQ, JMPNC(escalarMulBN254_P_continue) + $ => A :MLOAD(escalarMulBN254_P_x2) + $ :EQ, JMPNC(escalarMulBN254_P_continue) + $ => A :MLOAD(escalarMulBN254_P_y1) + $ :EQ, JMPNC(escalarMulBN254_P_continue) + $ => A :MLOAD(escalarMulBN254_P_y2) + $ :EQ, JMPC(escalarMulBN254_P_is_zero) + escalarMulBN254_P_continue: + + ; Is k = 0? + $ => B :MLOAD(escalarMulBN254_k), CALL(reduceFrBN254) + A :MSTORE(escalarMulBN254_k) + 0n => B + $ :EQ, JMPC(escalarMulBN254_k_is_zero) + + 257 => RCX + + $ => A :MLOAD(escalarMulBN254_P_x1) + $ => B :MLOAD(escalarMulBN254_P_x2) + $ => C :MLOAD(escalarMulBN254_P_y1) + $ => D :MLOAD(escalarMulBN254_P_y2) + A :MSTORE(escalarMulBN254_Q_x1) + B :MSTORE(escalarMulBN254_Q_x2) + C :MSTORE(escalarMulBN254_Q_y1) + D :MSTORE(escalarMulBN254_Q_y2) + + :JMP(escalarMulBN254_find_MSB_k) + +escalarMulBN254_P_is_zero: + ; Q = O + 0n :MSTORE(escalarMulBN254_Q_x1) + 0n :MSTORE(escalarMulBN254_Q_x2) + 0n :MSTORE(escalarMulBN254_Q_y1) + 0n :MSTORE(escalarMulBN254_Q_y2) + + :JMP(escalarMulBN254_end) + +escalarMulBN254_k_is_zero: + ; Q = O + 0n :MSTORE(escalarMulBN254_Q_x1) + 0n :MSTORE(escalarMulBN254_Q_x2) + 0n :MSTORE(escalarMulBN254_Q_y1) + 0n :MSTORE(escalarMulBN254_Q_y2) + + :JMP(escalarMulBN254_end) + +escalarMulBN254_find_MSB_k: + RCX - 1 => RCX + $ => A,B :MLOAD(escalarMulBN254_k) + ; E = 2A + $ => E :ADD,MSTORE(escalarMulBN254_k), JMPNC(escalarMulBN254_find_MSB_k) + + +escalarMulBN254_loop: + RCX - 1 => RCX :JMPZ(escalarMulBN254_end) + + ; We always double + $ => A :MLOAD(escalarMulBN254_Q_x1) + $ => B :MLOAD(escalarMulBN254_Q_x2) + $ => C :MLOAD(escalarMulBN254_Q_y1) + $ => D :MLOAD(escalarMulBN254_Q_y2) + A :MSTORE(addPointBN254_P1_x1) + B :MSTORE(addPointBN254_P1_x2) + C :MSTORE(addPointBN254_P1_y1) + D :MSTORE(addPointBN254_P1_y2) + A :MSTORE(addPointBN254_P2_x1) + B :MSTORE(addPointBN254_P2_x2) + C :MSTORE(addPointBN254_P2_y1) + D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) + ; Q = Q + Q + + $ => A :MLOAD(addPointBN254_P3_x1) + $ => B :MLOAD(addPointBN254_P3_x2) + $ => C :MLOAD(addPointBN254_P3_y1) + $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(escalarMulBN254_Q_x1) + B :MSTORE(escalarMulBN254_Q_x2) + C :MSTORE(escalarMulBN254_Q_y1) + D :MSTORE(escalarMulBN254_Q_y2) + + ; We check if the MSB b of k is either 1 or 0. If b==1, we should add P to Q. + ; Then, update the value of k. + $ => A,B :MLOAD(escalarMulBN254_k) + ; E = 2A + $ => E :ADD,MSTORE(escalarMulBN254_k), JMPNC(escalarMulBN254_loop) + +escalarMulBN254_add: + ; We add + $ => A :MLOAD(escalarMulBN254_Q_x1) + $ => B :MLOAD(escalarMulBN254_Q_x2) + $ => C :MLOAD(escalarMulBN254_Q_y1) + $ => D :MLOAD(escalarMulBN254_Q_y2) + A :MSTORE(addPointBN254_P1_x1) + B :MSTORE(addPointBN254_P1_x2) + C :MSTORE(addPointBN254_P1_y1) + D :MSTORE(addPointBN254_P1_y2) + + $ => A :MLOAD(escalarMulBN254_P_x1) + $ => B :MLOAD(escalarMulBN254_P_x2) + $ => C :MLOAD(escalarMulBN254_P_y1) + $ => D :MLOAD(escalarMulBN254_P_y2) + A :MSTORE(addPointBN254_P2_x1) + B :MSTORE(addPointBN254_P2_x2) + C :MSTORE(addPointBN254_P2_y1) + D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) + ; Q = Q + P + + $ => A :MLOAD(addPointBN254_P3_x1) + $ => B :MLOAD(addPointBN254_P3_x2) + $ => C :MLOAD(addPointBN254_P3_y1) + $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(escalarMulBN254_Q_x1) + B :MSTORE(escalarMulBN254_Q_x2) + C :MSTORE(escalarMulBN254_Q_y1) + D :MSTORE(escalarMulBN254_Q_y2), JMP(escalarMulBN254_loop) + + +escalarMulBN254_end: + $ => RR :MLOAD(escalarMulBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/lineDiffPointsBN254.zkasm b/main/pairings/BN254/lineDiffPointsBN254.zkasm new file mode 100644 index 00000000..d4885dbf --- /dev/null +++ b/main/pairings/BN254/lineDiffPointsBN254.zkasm @@ -0,0 +1,80 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; lineDiffPointsBN254: +;; in: P1 = (P1.x1 + P1.x2·u, P1.y1 + P1.y2·u), P2 = (P2.x1 + P2.x2·u, P2.y1 + P2.y2·u) ∈ E'(Fp2) +;; and Q = (Q.x,Q.y) ∈ E(Fp) +;; out: line_{twist(P1), twist(P2)}(Q) = (P2.x - P1.x)·Q.y·w² + (P1.y - P2.y)·Q.x·w³ + (P1.x·P2.y - P2.x·P1.y)·w⁵ ∈ Fp12 +;; +;; assumes: P1,P2 ∈ E'(Fp2) with P1 != P2,-P2 and Q ∈ E(Fp) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL lineDiffPointsBN254_P1_x1 +VAR GLOBAL lineDiffPointsBN254_P1_x2 +VAR GLOBAL lineDiffPointsBN254_P1_y1 +VAR GLOBAL lineDiffPointsBN254_P1_y2 +VAR GLOBAL lineDiffPointsBN254_P2_x1 +VAR GLOBAL lineDiffPointsBN254_P2_x2 +VAR GLOBAL lineDiffPointsBN254_P2_y1 +VAR GLOBAL lineDiffPointsBN254_P2_y2 +VAR GLOBAL lineDiffPointsBN254_Q_x +VAR GLOBAL lineDiffPointsBN254_Q_y + +VAR GLOBAL lineDiffPointsBN254_P2x_P1y_x +VAR GLOBAL lineDiffPointsBN254_P2x_P1y_y + +VAR GLOBAL lineDiffPointsBN254_l12_x +VAR GLOBAL lineDiffPointsBN254_l12_y +VAR GLOBAL lineDiffPointsBN254_l22_x +VAR GLOBAL lineDiffPointsBN254_l22_y +VAR GLOBAL lineDiffPointsBN254_l23_x +VAR GLOBAL lineDiffPointsBN254_l23_y + +VAR GLOBAL lineDiffPointsBN254_RR + +lineDiffPointsBN254: + RR :MSTORE(lineDiffPointsBN254_RR) + + ; 1] (P2.x - P1.x)·Q.y + $ => A :MLOAD(lineDiffPointsBN254_P2_x1) + $ => B :MLOAD(lineDiffPointsBN254_P2_x2) + $ => C :MLOAD(lineDiffPointsBN254_P1_x1) + $ => D :MLOAD(lineDiffPointsBN254_P1_x2), CALL(subFp2BN254) + $ => A :MLOAD(lineDiffPointsBN254_Q_y) + C => D + E => C :CALL(escalarMulFp2BN254) + E :MSTORE(lineDiffPointsBN254_l12_x) + C :MSTORE(lineDiffPointsBN254_l12_y) + + ; 2] (P1.y - P2.y)·Q.x + $ => A :MLOAD(lineDiffPointsBN254_P1_y1) + $ => B :MLOAD(lineDiffPointsBN254_P1_y2) + $ => C :MLOAD(lineDiffPointsBN254_P2_y1) + $ => D :MLOAD(lineDiffPointsBN254_P2_y2), CALL(subFp2BN254) + $ => A :MLOAD(lineDiffPointsBN254_Q_x) + C => D + E => C :CALL(escalarMulFp2BN254) + E :MSTORE(lineDiffPointsBN254_l22_x) + C :MSTORE(lineDiffPointsBN254_l22_y) + + ; 3] (P1.x·P2.y - P2.x·P1.y) + $ => A :MLOAD(lineDiffPointsBN254_P2_x1) + $ => B :MLOAD(lineDiffPointsBN254_P2_x2) + $ => C :MLOAD(lineDiffPointsBN254_P1_y1) + $ => D :MLOAD(lineDiffPointsBN254_P1_y2), CALL(mulFp2BN254) + E :MSTORE(lineDiffPointsBN254_P2x_P1y_x) + C :MSTORE(lineDiffPointsBN254_P2x_P1y_y) + + $ => A :MLOAD(lineDiffPointsBN254_P1_x1) + $ => B :MLOAD(lineDiffPointsBN254_P1_x2) + $ => C :MLOAD(lineDiffPointsBN254_P2_y1) + $ => D :MLOAD(lineDiffPointsBN254_P2_y2), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(lineDiffPointsBN254_P2x_P1y_x) + $ => D :MLOAD(lineDiffPointsBN254_P2x_P1y_y), CALL(subFp2BN254) + E :MSTORE(lineDiffPointsBN254_l23_x) + C :MSTORE(lineDiffPointsBN254_l23_y) + + $ => RR :MLOAD(lineDiffPointsBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/lineSamePointsBN254.zkasm b/main/pairings/BN254/lineSamePointsBN254.zkasm new file mode 100644 index 00000000..2ae95b5d --- /dev/null +++ b/main/pairings/BN254/lineSamePointsBN254.zkasm @@ -0,0 +1,93 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; lineSamePointsBN254: +;; in: P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2) and Q = (Q.x,Q.y) ∈ E(Fp) +;; out: line_{twist(P), twist(P)}(Q) = (3·P.x1³ - 2·P.y1²)·(9 + u) + (2·Q.y·P.y1)·w³ + (-3·Q.x·P.x1²)·w⁴ ∈ Fp12 +;; +;; assumes: P ∈ E'(Fp2) and Q ∈ E(Fp) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL lineSamePointsBN254_P_x1 +VAR GLOBAL lineSamePointsBN254_P_x2 +VAR GLOBAL lineSamePointsBN254_P_y1 +VAR GLOBAL lineSamePointsBN254_P_y2 +VAR GLOBAL lineSamePointsBN254_Q_x +VAR GLOBAL lineSamePointsBN254_Q_y + +VAR GLOBAL lineSamePointsBN254_P_x1_square +VAR GLOBAL lineSamePointsBN254_P_x2_square +VAR GLOBAL lineSamePointsBN254_P_y1_square +VAR GLOBAL lineSamePointsBN254_P_y2_square + +VAR GLOBAL lineSamePointsBN254_l11_x +VAR GLOBAL lineSamePointsBN254_l11_y +VAR GLOBAL lineSamePointsBN254_l13_x +VAR GLOBAL lineSamePointsBN254_l13_y +VAR GLOBAL lineSamePointsBN254_l22_x +VAR GLOBAL lineSamePointsBN254_l22_y + +VAR GLOBAL lineSamePointsBN254_RR + +lineSamePointsBN254: + RR :MSTORE(lineSamePointsBN254_RR) + + ; 1] (3·P.x1³ - 2·P.y1²)·(9 + u) + $ => A :MLOAD(lineSamePointsBN254_P_y1) + $ => B :MLOAD(lineSamePointsBN254_P_y2), CALL(squareFp2BN254) + C => D + E => C + 2n => A :CALL(escalarMulFp2BN254) + E :MSTORE(lineSamePointsBN254_P_y1_square) + C :MSTORE(lineSamePointsBN254_P_y2_square) + + $ => A :MLOAD(lineSamePointsBN254_P_x1) + $ => B :MLOAD(lineSamePointsBN254_P_x2), CALL(squareFp2BN254) + ; save it for the last step + E :MSTORE(lineSamePointsBN254_P_x1_square) + C :MSTORE(lineSamePointsBN254_P_x2_square) + E => A + C => B + $ => C :MLOAD(lineSamePointsBN254_P_x1) + $ => D :MLOAD(lineSamePointsBN254_P_x2), CALL(mulFp2BN254) + C => D + E => C + 3n => A :CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(lineSamePointsBN254_P_y1_square) + $ => D :MLOAD(lineSamePointsBN254_P_y2_square), CALL(subFp2BN254) + + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + + E :MSTORE(lineSamePointsBN254_l11_x) + C :MSTORE(lineSamePointsBN254_l11_y) + + + ; 2] 2·Q.y·P.y1 + 2n => A + $ => B :MLOAD(lineSamePointsBN254_Q_y), CALL(mulFpBN254) + + C => A + $ => C :MLOAD(lineSamePointsBN254_P_y1) + $ => D :MLOAD(lineSamePointsBN254_P_y2), CALL(escalarMulFp2BN254) + + E :MSTORE(lineSamePointsBN254_l22_x) + C :MSTORE(lineSamePointsBN254_l22_y) + + ; 3] -3·Q.x·P.x1² + %BN254_P - 3n => A + $ => B :MLOAD(lineSamePointsBN254_Q_x), CALL(mulFpBN254) + C => A + $ => C :MLOAD(lineSamePointsBN254_P_x1_square) + $ => D :MLOAD(lineSamePointsBN254_P_x2_square), CALL(escalarMulFp2BN254) + + E :MSTORE(lineSamePointsBN254_l13_x) + C :MSTORE(lineSamePointsBN254_l13_y) + + $ => RR :MLOAD(lineSamePointsBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm new file mode 100644 index 00000000..68c3be83 --- /dev/null +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm @@ -0,0 +1,47 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; compressFp12BN254: +;; in: a = a0 + a2·w + a4·w² + a1·w³ + a3·w⁴ + a5·w⁵ ∈ GΦ6(p²), where ai ∈ Fp2 +;; out: C(a) = [a2,a3,a4,a5] ∈ Fp2⁴ +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL compressFp12BN254_a0_x +VAR GLOBAL compressFp12BN254_a0_y +VAR GLOBAL compressFp12BN254_a2_x +VAR GLOBAL compressFp12BN254_a2_y +VAR GLOBAL compressFp12BN254_a4_x +VAR GLOBAL compressFp12BN254_a4_y +VAR GLOBAL compressFp12BN254_a1_x +VAR GLOBAL compressFp12BN254_a1_y +VAR GLOBAL compressFp12BN254_a3_x +VAR GLOBAL compressFp12BN254_a3_y +VAR GLOBAL compressFp12BN254_a5_x +VAR GLOBAL compressFp12BN254_a5_y +VAR GLOBAL compressFp12BN254_Ca2_x +VAR GLOBAL compressFp12BN254_Ca2_y +VAR GLOBAL compressFp12BN254_Ca3_x +VAR GLOBAL compressFp12BN254_Ca3_y +VAR GLOBAL compressFp12BN254_Ca4_x +VAR GLOBAL compressFp12BN254_Ca4_y +VAR GLOBAL compressFp12BN254_Ca5_x +VAR GLOBAL compressFp12BN254_Ca5_y + +compressFp12BN254: + $ => A :MLOAD(compressFp12BN254_a2_x) + $ => B :MLOAD(compressFp12BN254_a2_y) + A :MSTORE(compressFp12BN254_Ca2_x) + B :MSTORE(compressFp12BN254_Ca2_y) + $ => A :MLOAD(compressFp12BN254_a3_x) + $ => B :MLOAD(compressFp12BN254_a3_y) + A :MSTORE(compressFp12BN254_Ca3_x) + B :MSTORE(compressFp12BN254_Ca3_y) + $ => A :MLOAD(compressFp12BN254_a4_x) + $ => B :MLOAD(compressFp12BN254_a4_y) + A :MSTORE(compressFp12BN254_Ca4_x) + B :MSTORE(compressFp12BN254_Ca4_y) + $ => A :MLOAD(compressFp12BN254_a5_x) + $ => B :MLOAD(compressFp12BN254_a5_y) + A :MSTORE(compressFp12BN254_Ca5_x) + B :MSTORE(compressFp12BN254_Ca5_y) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm new file mode 100644 index 00000000..cb030b5f --- /dev/null +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm @@ -0,0 +1,231 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; decompressFp12BN254: +;; in: [a2,a3,a4,a5] ∈ Fp2⁴, where ai ∈ Fp2 +;; out: D(a) = a0 + a2·w + a4·w² + a1·w³ + a3·w⁴ + a5·w⁵ ∈ GΦ6(p²), where: +;; - if a2 != 0, then: +;; · a1 = (a5²·(9+u) + 3·a4² - 2·a3)/(4·a2) +;; · a0 = (2·a1² + a2·a5 - 3·a3·a4)(9+u) + 1 +;; - if a2 == 0, then: +;; · a1 = (2·a4·a5)/a3 +;; · a0 = (2·a1² - 3·a3·a4)(9+u) + 1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL decompressFp12BN254_Ca2_x +VAR GLOBAL decompressFp12BN254_Ca2_y +VAR GLOBAL decompressFp12BN254_Ca3_x +VAR GLOBAL decompressFp12BN254_Ca3_y +VAR GLOBAL decompressFp12BN254_Ca4_x +VAR GLOBAL decompressFp12BN254_Ca4_y +VAR GLOBAL decompressFp12BN254_Ca5_x +VAR GLOBAL decompressFp12BN254_Ca5_y +VAR GLOBAL decompressFp12BN254_a0_x +VAR GLOBAL decompressFp12BN254_a0_y +VAR GLOBAL decompressFp12BN254_a2_x +VAR GLOBAL decompressFp12BN254_a2_y +VAR GLOBAL decompressFp12BN254_a4_x +VAR GLOBAL decompressFp12BN254_a4_y +VAR GLOBAL decompressFp12BN254_a1_x +VAR GLOBAL decompressFp12BN254_a1_y +VAR GLOBAL decompressFp12BN254_a3_x +VAR GLOBAL decompressFp12BN254_a3_y +VAR GLOBAL decompressFp12BN254_a5_x +VAR GLOBAL decompressFp12BN254_a5_y + +VAR GLOBAL decompressFp12BN254_Ca3inv_x +VAR GLOBAL decompressFp12BN254_Ca3inv_y +VAR GLOBAL decompressFp12BN254_twoCa1sq_x +VAR GLOBAL decompressFp12BN254_twoCa1sq_y +VAR GLOBAL decompressFp12BN254_threeCa3Ca4_x +VAR GLOBAL decompressFp12BN254_threeCa3Ca4_y + +VAR GLOBAL decompressFp12BN254_fourCa2inv_x +VAR GLOBAL decompressFp12BN254_fourCa2inv_y +VAR GLOBAL decompressFp12BN254_twoCa1sq2_x +VAR GLOBAL decompressFp12BN254_twoCa1sq2_y +VAR GLOBAL decompressFp12BN254_Ca5sq_x +VAR GLOBAL decompressFp12BN254_Ca5sq_y +VAR GLOBAL decompressFp12BN254_threeCa4sq_x +VAR GLOBAL decompressFp12BN254_threeCa4sq_y +VAR GLOBAL decompressFp12BN254_sum_x +VAR GLOBAL decompressFp12BN254_sum_y + +VAR GLOBAL decompressFp12BN254_RR + +decompressFp12BN254: + RR :MSTORE(decompressFp12BN254_RR) + + ; Move Ca2, Ca3, Ca4, Ca5 to a2, a3, a4, a5 + $ => A :MLOAD(decompressFp12BN254_Ca2_x) + $ => B :MLOAD(decompressFp12BN254_Ca2_y) + A :MSTORE(decompressFp12BN254_a2_x) + B :MSTORE(decompressFp12BN254_a2_y) + $ => A :MLOAD(decompressFp12BN254_Ca3_x) + $ => B :MLOAD(decompressFp12BN254_Ca3_y) + A :MSTORE(decompressFp12BN254_a3_x) + B :MSTORE(decompressFp12BN254_a3_y) + $ => A :MLOAD(decompressFp12BN254_Ca4_x) + $ => B :MLOAD(decompressFp12BN254_Ca4_y) + A :MSTORE(decompressFp12BN254_a4_x) + B :MSTORE(decompressFp12BN254_a4_y) + $ => A :MLOAD(decompressFp12BN254_Ca5_x) + $ => B :MLOAD(decompressFp12BN254_Ca5_y) + A :MSTORE(decompressFp12BN254_a5_x) + B :MSTORE(decompressFp12BN254_a5_y) + + ; Is Ca2 = 0? + 0n => B + $ => A :MLOAD(decompressFp12BN254_Ca2_x) + $ :EQ, JMPNC(decompressFp12BN254_Ca2_continue) + $ => A :MLOAD(decompressFp12BN254_Ca2_y) + $ :EQ, JMPC(decompressFp12BN254_Ca2_is_zero) + decompressFp12BN254_Ca2_continue: + + :JMP(decompressFp12BN254_Ca2_is_not_zero) + +decompressFp12BN254_Ca2_is_zero: + ; 1] Compute a1 = (2·a4·a5)/a3 + $ => A :MLOAD(decompressFp12BN254_Ca3_x) + $ => B :MLOAD(decompressFp12BN254_Ca3_y), CALL(invFp2BN254) + C :MSTORE(decompressFp12BN254_Ca3inv_x) + D :MSTORE(decompressFp12BN254_Ca3inv_y) + + 2n => A + $ => C :MLOAD(decompressFp12BN254_Ca4_x) + $ => D :MLOAD(decompressFp12BN254_Ca4_y), CALL(escalarMulFp2BN254) + E => A + C => B + $ => C :MLOAD(decompressFp12BN254_Ca5_x) + $ => D :MLOAD(decompressFp12BN254_Ca5_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(decompressFp12BN254_Ca3inv_x) + $ => D :MLOAD(decompressFp12BN254_Ca3inv_y), CALL(mulFp2BN254) + E :MSTORE(decompressFp12BN254_a1_x) + C :MSTORE(decompressFp12BN254_a1_y) + + ; 2] Compute a0 = (2·a1² - 3·a3·a4)(9+u) + 1 + $ => A :MLOAD(decompressFp12BN254_a1_x) + $ => B :MLOAD(decompressFp12BN254_a1_y), CALL(squareFp2BN254) + 2n => A + C => D + E => C :CALL(escalarMulFp2BN254) + E :MSTORE(decompressFp12BN254_twoCa1sq_x) + C :MSTORE(decompressFp12BN254_twoCa1sq_y) + + 3n => A + $ => C :MLOAD(decompressFp12BN254_Ca3_x) + $ => D :MLOAD(decompressFp12BN254_Ca3_y), CALL(escalarMulFp2BN254) + E => A + C => B + $ => C :MLOAD(decompressFp12BN254_Ca4_x) + $ => D :MLOAD(decompressFp12BN254_Ca4_y), CALL(mulFp2BN254) + E :MSTORE(decompressFp12BN254_threeCa3Ca4_x) + C :MSTORE(decompressFp12BN254_threeCa3Ca4_y) + + $ => A :MLOAD(decompressFp12BN254_twoCa1sq_x) + $ => B :MLOAD(decompressFp12BN254_twoCa1sq_y) + C => D + E => C :CALL(subFp2BN254) + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + E + 1n :MSTORE(decompressFp12BN254_a0_x) ; TODO: Take care of this sum + C :MSTORE(decompressFp12BN254_a0_y) + + :JMP(decompressFp12BN254_end) + + +decompressFp12BN254_Ca2_is_not_zero: + ; 1] Compute a1 = (a5²·(9+u) + 3·a4² - 2·a3)/(4·a2) + 4n => A + $ => C :MLOAD(decompressFp12BN254_Ca2_x) + $ => D :MLOAD(decompressFp12BN254_Ca2_y), CALL(escalarMulFp2BN254) + E => A + C => B :CALL(invFp2BN254) + C :MSTORE(decompressFp12BN254_fourCa2inv_x) + D :MSTORE(decompressFp12BN254_fourCa2inv_y) + + $ => A :MLOAD(decompressFp12BN254_Ca5_x) + $ => B :MLOAD(decompressFp12BN254_Ca5_y), CALL(squareFp2BN254) + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + E :MSTORE(decompressFp12BN254_Ca5sq_x) + C :MSTORE(decompressFp12BN254_Ca5sq_y) + + $ => A :MLOAD(decompressFp12BN254_Ca4_x) + $ => B :MLOAD(decompressFp12BN254_Ca4_y), CALL(squareFp2BN254) + 3n => A + C => D + E => C :CALL(escalarMulFp2BN254) + E :MSTORE(decompressFp12BN254_threeCa4sq_x) + C :MSTORE(decompressFp12BN254_threeCa4sq_y) + + 2n => A + $ => C :MLOAD(decompressFp12BN254_Ca3_x) + $ => D :MLOAD(decompressFp12BN254_Ca3_y), CALL(escalarMulFp2BN254) + $ => A :MLOAD(decompressFp12BN254_threeCa4sq_x) + $ => B :MLOAD(decompressFp12BN254_threeCa4sq_y) + C => D + E => C :CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(decompressFp12BN254_Ca5sq_x) + $ => D :MLOAD(decompressFp12BN254_Ca5sq_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(decompressFp12BN254_fourCa2inv_x) + $ => D :MLOAD(decompressFp12BN254_fourCa2inv_y), CALL(mulFp2BN254) + E :MSTORE(decompressFp12BN254_a1_x) + C :MSTORE(decompressFp12BN254_a1_y) + + ; 2] Compute a0 = (2·a1² + a2·a5 - 3·a3·a4)(9+u) + 1 + $ => A :MLOAD(decompressFp12BN254_a1_x) + $ => B :MLOAD(decompressFp12BN254_a1_y), CALL(squareFp2BN254) + 2n => A + C => D + E => C :CALL(escalarMulFp2BN254) + E :MSTORE(decompressFp12BN254_twoCa1sq2_x) + C :MSTORE(decompressFp12BN254_twoCa1sq2_y) + + $ => A :MLOAD(decompressFp12BN254_Ca2_x) + $ => B :MLOAD(decompressFp12BN254_Ca2_y) + $ => C :MLOAD(decompressFp12BN254_Ca5_x) + $ => D :MLOAD(decompressFp12BN254_Ca5_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(decompressFp12BN254_twoCa1sq2_x) + $ => D :MLOAD(decompressFp12BN254_twoCa1sq2_y), CALL(addFp2BN254) + + E :MSTORE(decompressFp12BN254_sum_x) + C :MSTORE(decompressFp12BN254_sum_y) + + $ => A :MLOAD(decompressFp12BN254_Ca3_x) + $ => B :MLOAD(decompressFp12BN254_Ca3_y) + $ => C :MLOAD(decompressFp12BN254_Ca4_x) + $ => D :MLOAD(decompressFp12BN254_Ca4_y), CALL(mulFp2BN254) + 3n => A + C => D + E => C :CALL(escalarMulFp2BN254) + $ => A :MLOAD(decompressFp12BN254_sum_x) + $ => B :MLOAD(decompressFp12BN254_sum_y) + C => D + E => C :CALL(subFp2BN254) + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + E + 1n :MSTORE(decompressFp12BN254_a0_x) ; TODO: Take care of this sum + C :MSTORE(decompressFp12BN254_a0_y) + + :JMP(decompressFp12BN254_end) + +decompressFp12BN254_end: + $ => RR :MLOAD(decompressFp12BN254_RR) + :RETURN + + \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm new file mode 100644 index 00000000..fb5797a7 --- /dev/null +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm @@ -0,0 +1,443 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; expByXCompCycloFp12BN254: +;; in: x, a = a0 + a2·w + a4·w² + a1·w³ + a3·w⁴ + a5·w⁵ ∈ GΦ6(p²), where x = 4965661367192848881 and ai ∈ Fp2 +;; out: a^x = c0 + c2·w + c4·w² + c1·w³ + c3·w⁴ + c5·w⁵ ∈ ∈ GΦ6(p²) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL expByXCompCycloFp12BN254_a0_x +VAR GLOBAL expByXCompCycloFp12BN254_a0_y +VAR GLOBAL expByXCompCycloFp12BN254_a2_x +VAR GLOBAL expByXCompCycloFp12BN254_a2_y +VAR GLOBAL expByXCompCycloFp12BN254_a4_x +VAR GLOBAL expByXCompCycloFp12BN254_a4_y +VAR GLOBAL expByXCompCycloFp12BN254_a1_x +VAR GLOBAL expByXCompCycloFp12BN254_a1_y +VAR GLOBAL expByXCompCycloFp12BN254_a3_x +VAR GLOBAL expByXCompCycloFp12BN254_a3_y +VAR GLOBAL expByXCompCycloFp12BN254_a5_x +VAR GLOBAL expByXCompCycloFp12BN254_a5_y +VAR GLOBAL expByXCompCycloFp12BN254_c0_x +VAR GLOBAL expByXCompCycloFp12BN254_c0_y +VAR GLOBAL expByXCompCycloFp12BN254_c2_x +VAR GLOBAL expByXCompCycloFp12BN254_c2_y +VAR GLOBAL expByXCompCycloFp12BN254_c4_x +VAR GLOBAL expByXCompCycloFp12BN254_c4_y +VAR GLOBAL expByXCompCycloFp12BN254_c1_x +VAR GLOBAL expByXCompCycloFp12BN254_c1_y +VAR GLOBAL expByXCompCycloFp12BN254_c3_x +VAR GLOBAL expByXCompCycloFp12BN254_c3_y +VAR GLOBAL expByXCompCycloFp12BN254_c5_x +VAR GLOBAL expByXCompCycloFp12BN254_c5_y + +VAR GLOBAL expByXCompCycloFp12BN254_RR + +expByXCompCycloFp12BN254: + RR :MSTORE(expByXCompCycloFp12BN254_RR) + + ; Is a = 0? + 0n => B + $ => A :MLOAD(expByXCompCycloFp12BN254_a0_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a0_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a2_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a2_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a4_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a4_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a1_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a1_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a3_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a3_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a5_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCompCycloFp12BN254_a5_y) + $ :EQ, JMPC(expByXCompCycloFp12BN254_a_is_zero) + expByXCompCycloFp12BN254_a_continue1: + + ; Is a = 1? + 1n => B + $ => A :MLOAD(expByXCompCycloFp12BN254_a0_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + 0n => B + $ => A :MLOAD(expByXCompCycloFp12BN254_a0_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a2_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a2_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a4_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a4_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a1_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a1_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a3_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a3_y) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a5_x) + $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCompCycloFp12BN254_a5_y) + $ :EQ, JMPC(expByXCompCycloFp12BN254_a_is_one) + expByXCompCycloFp12BN254_a_continue2: + + 59 => RCX + + ; We manually compute the first iterations to avoid branching: 10001 + + ; 1] First bit is 1 and second bit is 0, so set c = a, + ; compress the input and compute the compressed square C(a²) + $ => A :MLOAD(expByXCompCycloFp12BN254_a0_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_a0_y) + A :MSTORE(expByXCompCycloFp12BN254_c0_x) + B :MSTORE(expByXCompCycloFp12BN254_c0_y) + A :MSTORE(compressFp12BN254_a0_x) + B :MSTORE(compressFp12BN254_a0_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_a2_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_a2_y) + A :MSTORE(expByXCompCycloFp12BN254_c2_x) + B :MSTORE(expByXCompCycloFp12BN254_c2_y) + A :MSTORE(compressFp12BN254_a2_x) + B :MSTORE(compressFp12BN254_a2_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_a4_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_a4_y) + A :MSTORE(expByXCompCycloFp12BN254_c4_x) + B :MSTORE(expByXCompCycloFp12BN254_c4_y) + A :MSTORE(compressFp12BN254_a4_x) + B :MSTORE(compressFp12BN254_a4_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_a1_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_a1_y) + A :MSTORE(expByXCompCycloFp12BN254_c1_x) + B :MSTORE(expByXCompCycloFp12BN254_c1_y) + A :MSTORE(compressFp12BN254_a1_x) + B :MSTORE(compressFp12BN254_a1_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_a3_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_a3_y) + A :MSTORE(expByXCompCycloFp12BN254_c3_x) + B :MSTORE(expByXCompCycloFp12BN254_c3_y) + A :MSTORE(compressFp12BN254_a3_x) + B :MSTORE(compressFp12BN254_a3_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_a5_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_a5_y) + A :MSTORE(expByXCompCycloFp12BN254_c5_x) + B :MSTORE(expByXCompCycloFp12BN254_c5_y) + A :MSTORE(compressFp12BN254_a5_x) + B :MSTORE(compressFp12BN254_a5_y), CALL(compressFp12BN254) + + $ => A :MLOAD(compressFp12BN254_Ca2_x) + $ => B :MLOAD(compressFp12BN254_Ca2_y) + A :MSTORE(squareCompCycloFp12BN254_Ca2_x) + B :MSTORE(squareCompCycloFp12BN254_Ca2_y) + $ => A :MLOAD(compressFp12BN254_Ca3_x) + $ => B :MLOAD(compressFp12BN254_Ca3_y) + A :MSTORE(squareCompCycloFp12BN254_Ca3_x) + B :MSTORE(squareCompCycloFp12BN254_Ca3_y) + $ => A :MLOAD(compressFp12BN254_Ca4_x) + $ => B :MLOAD(compressFp12BN254_Ca4_y) + A :MSTORE(squareCompCycloFp12BN254_Ca4_x) + B :MSTORE(squareCompCycloFp12BN254_Ca4_y) + $ => A :MLOAD(compressFp12BN254_Ca5_x) + $ => B :MLOAD(compressFp12BN254_Ca5_y) + A :MSTORE(squareCompCycloFp12BN254_Ca5_x) + B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + + ; 2] Third bit is 0, so compute C(c⁴) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + A :MSTORE(squareCompCycloFp12BN254_Ca2_x) + B :MSTORE(squareCompCycloFp12BN254_Ca2_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(squareCompCycloFp12BN254_Ca3_x) + B :MSTORE(squareCompCycloFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + A :MSTORE(squareCompCycloFp12BN254_Ca4_x) + B :MSTORE(squareCompCycloFp12BN254_Ca4_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(squareCompCycloFp12BN254_Ca5_x) + B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + + ; 3] Fourth bit is 0, so compute C(c⁸) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + A :MSTORE(squareCompCycloFp12BN254_Ca2_x) + B :MSTORE(squareCompCycloFp12BN254_Ca2_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(squareCompCycloFp12BN254_Ca3_x) + B :MSTORE(squareCompCycloFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + A :MSTORE(squareCompCycloFp12BN254_Ca4_x) + B :MSTORE(squareCompCycloFp12BN254_Ca4_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(squareCompCycloFp12BN254_Ca5_x) + B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + + ; 4] Fifth bit is 1, so compute C(c¹⁶), decompress to obtain c¹⁶ and multiply by a + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + A :MSTORE(squareCompCycloFp12BN254_Ca2_x) + B :MSTORE(squareCompCycloFp12BN254_Ca2_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(squareCompCycloFp12BN254_Ca3_x) + B :MSTORE(squareCompCycloFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + A :MSTORE(squareCompCycloFp12BN254_Ca4_x) + B :MSTORE(squareCompCycloFp12BN254_Ca4_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(squareCompCycloFp12BN254_Ca5_x) + B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + A :MSTORE(decompressFp12BN254_Ca2_x) + B :MSTORE(decompressFp12BN254_Ca2_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(decompressFp12BN254_Ca3_x) + B :MSTORE(decompressFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + A :MSTORE(decompressFp12BN254_Ca4_x) + B :MSTORE(decompressFp12BN254_Ca4_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(decompressFp12BN254_Ca5_x) + B :MSTORE(decompressFp12BN254_Ca5_y), CALL(decompressFp12BN254) + + $ => A :MLOAD(expByXCompCycloFp12BN254_c0_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c0_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c2_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c2_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c4_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c4_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c1_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c1_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c3_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_a3_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c5_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c5_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(decompressFp12BN254_a0_x) + $ => B :MLOAD(decompressFp12BN254_a0_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(decompressFp12BN254_a2_x) + $ => B :MLOAD(decompressFp12BN254_a2_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(decompressFp12BN254_a4_x) + $ => B :MLOAD(decompressFp12BN254_a4_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(decompressFp12BN254_a1_x) + $ => B :MLOAD(decompressFp12BN254_a1_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(decompressFp12BN254_a3_x) + $ => B :MLOAD(decompressFp12BN254_a3_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(decompressFp12BN254_a5_x) + $ => B :MLOAD(decompressFp12BN254_a5_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + :JMP(expByXCompCycloFp12BN254_loop) + +expByXCompCycloFp12BN254_a_is_zero: + ; c = 0 + 0n :MSTORE(expByXCompCycloFp12BN254_c0_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c0_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c2_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c2_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c4_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c4_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c1_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c1_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c3_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c3_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c5_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c5_y) + + :JMP(expByXCompCycloFp12BN254_end) + +expByXCompCycloFp12BN254_a_is_one: + ; c = 1 + 1n :MSTORE(expByXCompCycloFp12BN254_c0_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c0_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c2_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c2_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c4_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c4_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c1_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c1_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c3_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c3_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c5_x) + 0n :MSTORE(expByXCompCycloFp12BN254_c5_y) + + :JMP(expByXCompCycloFp12BN254_end) + +expByXCompCycloFp12BN254_loop: + RCX - 1 => RCX :JMPZ(expByXCompCycloFp12BN254_last) + + ; We always square (in compressed form): C(c²) + ; We square C(c²) and store the result + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + A :MSTORE(squareCompCycloFp12BN254_Ca2_x) + B :MSTORE(squareCompCycloFp12BN254_Ca2_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(squareCompCycloFp12BN254_Ca3_x) + B :MSTORE(squareCompCycloFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + A :MSTORE(squareCompCycloFp12BN254_Ca4_x) + B :MSTORE(squareCompCycloFp12BN254_Ca4_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(squareCompCycloFp12BN254_Ca5_x) + B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + + ; We check if the MSB b of x is either 1 or 0 + RCX-1 => RR + :CALL(@xBinDecompBN254 + RR) + + ; if bit = 0, then repeat + B :JMPZ(expByXCompCycloFp12BN254_loop) + + ; else, multiply by the last result + +expByXCompCycloFp12BN254_multiply: + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + A :MSTORE(decompressFp12BN254_Ca2_x) + B :MSTORE(decompressFp12BN254_Ca2_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(decompressFp12BN254_Ca3_x) + B :MSTORE(decompressFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + A :MSTORE(decompressFp12BN254_Ca4_x) + B :MSTORE(decompressFp12BN254_Ca4_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(decompressFp12BN254_Ca5_x) + B :MSTORE(decompressFp12BN254_Ca5_y), CALL(decompressFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(decompressFp12BN254_a0_x) + $ => B :MLOAD(decompressFp12BN254_a0_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(decompressFp12BN254_a2_x) + $ => B :MLOAD(decompressFp12BN254_a2_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(decompressFp12BN254_a4_x) + $ => B :MLOAD(decompressFp12BN254_a4_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(decompressFp12BN254_a1_x) + $ => B :MLOAD(decompressFp12BN254_a1_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(decompressFp12BN254_a3_x) + $ => B :MLOAD(decompressFp12BN254_a3_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(decompressFp12BN254_a5_x) + $ => B :MLOAD(decompressFp12BN254_a5_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + :JMP(expByXCompCycloFp12BN254_loop) + +expByXCompCycloFp12BN254_last: + ; Last asignments + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(expByXCompCycloFp12BN254_c0_x) + B :MSTORE(expByXCompCycloFp12BN254_c0_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(expByXCompCycloFp12BN254_c4_x) + B :MSTORE(expByXCompCycloFp12BN254_c4_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(expByXCompCycloFp12BN254_c3_x) + B :MSTORE(expByXCompCycloFp12BN254_c3_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(expByXCompCycloFp12BN254_c2_x) + B :MSTORE(expByXCompCycloFp12BN254_c2_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(expByXCompCycloFp12BN254_c1_x) + B :MSTORE(expByXCompCycloFp12BN254_c1_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(expByXCompCycloFp12BN254_c5_x) + B :MSTORE(expByXCompCycloFp12BN254_c5_y) + +expByXCompCycloFp12BN254_end: + $ => RR :MLOAD(expByXCompCycloFp12BN254_RR) + :RETURN + + \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm new file mode 100644 index 00000000..3c9207b5 --- /dev/null +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm @@ -0,0 +1,210 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squareCompCycloFp12BN254: +;; in: [a2,a3,a4,a5] ∈ Fp2⁴, where ai ∈ Fp2 +;; out: C(a²) = [b2, b3, b4, b5] ∈ Fp2⁴, where: +;; - b2 = 2(a2 + 3·(9+u)·B45) +;; - b3 = 3·(A45 - (10+u)·B45) - 2·a3 +;; - b4 = 3·(A23 - (10+u)·B23) - 2·a4 +;; - b5 = 2·(a5 + 3·B23) +;; - A23 = (a2 + a3)·(a2 + (9+u)·a3) +;; - A45 = (a4 + a5)·(a4 + (9+u)·a5) +;; - B23 = a2·a3 +;; - B45 = a4·a5 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL squareCompCycloFp12BN254_Ca2_x +VAR GLOBAL squareCompCycloFp12BN254_Ca2_y +VAR GLOBAL squareCompCycloFp12BN254_Ca3_x +VAR GLOBAL squareCompCycloFp12BN254_Ca3_y +VAR GLOBAL squareCompCycloFp12BN254_Ca4_x +VAR GLOBAL squareCompCycloFp12BN254_Ca4_y +VAR GLOBAL squareCompCycloFp12BN254_Ca5_x +VAR GLOBAL squareCompCycloFp12BN254_Ca5_y +VAR GLOBAL squareCompCycloFp12BN254_Cb2_x +VAR GLOBAL squareCompCycloFp12BN254_Cb2_y +VAR GLOBAL squareCompCycloFp12BN254_Cb3_x +VAR GLOBAL squareCompCycloFp12BN254_Cb3_y +VAR GLOBAL squareCompCycloFp12BN254_Cb4_x +VAR GLOBAL squareCompCycloFp12BN254_Cb4_y +VAR GLOBAL squareCompCycloFp12BN254_Cb5_x +VAR GLOBAL squareCompCycloFp12BN254_Cb5_y + +VAR GLOBAL squareCompCycloFp12BN254_B23_x +VAR GLOBAL squareCompCycloFp12BN254_B23_y +VAR GLOBAL squareCompCycloFp12BN254_B45_x +VAR GLOBAL squareCompCycloFp12BN254_B45_y +VAR GLOBAL squareCompCycloFp12BN254_A23_x +VAR GLOBAL squareCompCycloFp12BN254_A23_y +VAR GLOBAL squareCompCycloFp12BN254_A45_x +VAR GLOBAL squareCompCycloFp12BN254_A45_y + +VAR GLOBAL squareCompCycloFp12BN254_A23right_x +VAR GLOBAL squareCompCycloFp12BN254_A23right_y +VAR GLOBAL squareCompCycloFp12BN254_A45right_x +VAR GLOBAL squareCompCycloFp12BN254_A45right_y + +VAR GLOBAL squareCompCycloFp12BN254_twoCa3_x +VAR GLOBAL squareCompCycloFp12BN254_twoCa3_y + +VAR GLOBAL squareCompCycloFp12BN254_twoCa4_x +VAR GLOBAL squareCompCycloFp12BN254_twoCa4_y + +VAR GLOBAL squareCompCycloFp12BN254_RR + +squareCompCycloFp12BN254: + RR :MSTORE(squareCompCycloFp12BN254_RR) + + ; 1] B23 = a2·a3, B45 = a4·a5 + $ => A :MLOAD(squareCompCycloFp12BN254_Ca2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Ca2_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Ca3_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca3_y), CALL(mulFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_B23_x) + C :MSTORE(squareCompCycloFp12BN254_B23_y) + + $ => A :MLOAD(squareCompCycloFp12BN254_Ca4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Ca4_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Ca5_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca5_y), CALL(mulFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_B45_x) + C :MSTORE(squareCompCycloFp12BN254_B45_y) + + ; 2] A23 = (a2 + a3)·(a2 + (9+u)·a3) + 9n => A + 1n => B + $ => C :MLOAD(squareCompCycloFp12BN254_Ca3_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca3_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_Ca2_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca2_y), CALL(addFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_A23right_x) + C :MSTORE(squareCompCycloFp12BN254_A23right_y) + + $ => A :MLOAD(squareCompCycloFp12BN254_Ca2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Ca2_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Ca3_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca3_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_A23right_x) + $ => D :MLOAD(squareCompCycloFp12BN254_A23right_y), CALL(mulFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_A23_x) + C :MSTORE(squareCompCycloFp12BN254_A23_y) + + ; 3] A45 = (a4 + a5)·(a4 + (9+u)·a5) + 9n => A + 1n => B + $ => C :MLOAD(squareCompCycloFp12BN254_Ca5_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca5_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_Ca4_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca4_y), CALL(addFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_A45right_x) + C :MSTORE(squareCompCycloFp12BN254_A45right_y) + + $ => A :MLOAD(squareCompCycloFp12BN254_Ca4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Ca4_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Ca5_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca5_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_A45right_x) + $ => D :MLOAD(squareCompCycloFp12BN254_A45right_y), CALL(mulFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_A45_x) + C :MSTORE(squareCompCycloFp12BN254_A45_y) + + ; 4] b2 = 2(a2 + 3·(9+u)·B45) + 9n => A + 1n => B + $ => C :MLOAD(squareCompCycloFp12BN254_B45_x) + $ => D :MLOAD(squareCompCycloFp12BN254_B45_y), CALL(mulFp2BN254) + 3n => A + C => D + E => C :CALL(escalarMulFp2BN254) + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_Ca2_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca2_y), CALL(addFp2BN254) + 2n => A + C => D + E => C :CALL(escalarMulFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_Cb2_x) + C :MSTORE(squareCompCycloFp12BN254_Cb2_y) + + ; 5] b3 = 3·(A45 - (10+u)·B45) - 2·a3 + 2n => A + $ => C :MLOAD(squareCompCycloFp12BN254_Ca3_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca3_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_twoCa3_x) + C :MSTORE(squareCompCycloFp12BN254_twoCa3_y) + + 10n => A + 1n => B + $ => C :MLOAD(squareCompCycloFp12BN254_B45_x) + $ => D :MLOAD(squareCompCycloFp12BN254_B45_y), CALL(mulFp2BN254) + $ => A :MLOAD(squareCompCycloFp12BN254_A45_x) + $ => B :MLOAD(squareCompCycloFp12BN254_A45_y) + C => D + E => C :CALL(subFp2BN254) + + 3n => A + C => D + E => C :CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_twoCa3_x) + $ => D :MLOAD(squareCompCycloFp12BN254_twoCa3_y), CALL(subFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_Cb3_x) + C :MSTORE(squareCompCycloFp12BN254_Cb3_y) + + ; 6] b4 = 3·(A23 - (10+u)·B23) - 2·a4 + 2n => A + $ => C :MLOAD(squareCompCycloFp12BN254_Ca4_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca4_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_twoCa4_x) + C :MSTORE(squareCompCycloFp12BN254_twoCa4_y) + + 10n => A + 1n => B + $ => C :MLOAD(squareCompCycloFp12BN254_B23_x) + $ => D :MLOAD(squareCompCycloFp12BN254_B23_y), CALL(mulFp2BN254) + $ => A :MLOAD(squareCompCycloFp12BN254_A23_x) + $ => B :MLOAD(squareCompCycloFp12BN254_A23_y) + C => D + E => C :CALL(subFp2BN254) + + 3n => A + C => D + E => C :CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_twoCa4_x) + $ => D :MLOAD(squareCompCycloFp12BN254_twoCa4_y), CALL(subFp2BN254) + E :MSTORE(squareCompCycloFp12BN254_Cb4_x) + C :MSTORE(squareCompCycloFp12BN254_Cb4_y) + + ; 7] b5 = 2·(a5 + 3·B23) + 3n => A + $ => C :MLOAD(squareCompCycloFp12BN254_B23_x) + $ => D :MLOAD(squareCompCycloFp12BN254_B23_y), CALL(escalarMulFp2BN254) + E => A + C => B + $ => C :MLOAD(squareCompCycloFp12BN254_Ca5_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca5_y), CALL(addFp2BN254) + 2n => A + C => D + E => C :CALL(escalarMulFp2BN254) + + E :MSTORE(squareCompCycloFp12BN254_Cb5_x) + C :MSTORE(squareCompCycloFp12BN254_Cb5_y) + + $ => RR :MLOAD(squareCompCycloFp12BN254_RR) + :RETURN + + \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm new file mode 100644 index 00000000..6f7033ab --- /dev/null +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm @@ -0,0 +1,226 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squareCycloFp12BN254: +;; in: (a1 + a2·w) ∈ GΦ6(p²), where ai ∈ Fp6 +;; out: (c1 + c2·w) = (a1 + a2·w)² ∈ GΦ6(p²) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL squareCycloFp12BN254_a11_x +VAR GLOBAL squareCycloFp12BN254_a11_y +VAR GLOBAL squareCycloFp12BN254_a12_x +VAR GLOBAL squareCycloFp12BN254_a12_y +VAR GLOBAL squareCycloFp12BN254_a13_x +VAR GLOBAL squareCycloFp12BN254_a13_y +VAR GLOBAL squareCycloFp12BN254_a21_x +VAR GLOBAL squareCycloFp12BN254_a21_y +VAR GLOBAL squareCycloFp12BN254_a22_x +VAR GLOBAL squareCycloFp12BN254_a22_y +VAR GLOBAL squareCycloFp12BN254_a23_x +VAR GLOBAL squareCycloFp12BN254_a23_y +VAR GLOBAL squareCycloFp12BN254_c11_x +VAR GLOBAL squareCycloFp12BN254_c11_y +VAR GLOBAL squareCycloFp12BN254_c12_x +VAR GLOBAL squareCycloFp12BN254_c12_y +VAR GLOBAL squareCycloFp12BN254_c13_x +VAR GLOBAL squareCycloFp12BN254_c13_y +VAR GLOBAL squareCycloFp12BN254_c21_x +VAR GLOBAL squareCycloFp12BN254_c21_y +VAR GLOBAL squareCycloFp12BN254_c22_x +VAR GLOBAL squareCycloFp12BN254_c22_y +VAR GLOBAL squareCycloFp12BN254_c23_x +VAR GLOBAL squareCycloFp12BN254_c23_y + +VAR GLOBAL squareCycloFp12BN254_t11_x +VAR GLOBAL squareCycloFp12BN254_t11_y +VAR GLOBAL squareCycloFp12BN254_t22_x +VAR GLOBAL squareCycloFp12BN254_t22_y +VAR GLOBAL squareCycloFp12BN254_t23_x +VAR GLOBAL squareCycloFp12BN254_t23_y +VAR GLOBAL squareCycloFp12BN254_t12_x +VAR GLOBAL squareCycloFp12BN254_t12_y +VAR GLOBAL squareCycloFp12BN254_t13_x +VAR GLOBAL squareCycloFp12BN254_t13_y +VAR GLOBAL squareCycloFp12BN254_aux_x +VAR GLOBAL squareCycloFp12BN254_aux_y +VAR GLOBAL squareCycloFp12BN254_t21_x +VAR GLOBAL squareCycloFp12BN254_t21_y + +VAR GLOBAL squareCycloFp12BN254_RR + +squareCycloFp12BN254: + RR :MSTORE(squareCycloFp12BN254_RR) + + ; 1] [t11,t22] = (a11 + a22·V)² + $ => A :MLOAD(squareCycloFp12BN254_a11_x) + $ => B :MLOAD(squareCycloFp12BN254_a11_y) + $ => C :MLOAD(squareCycloFp12BN254_a22_x) + $ => D :MLOAD(squareCycloFp12BN254_a22_y) + A :MSTORE(squareFp4BN254_a1_x) + B :MSTORE(squareFp4BN254_a1_y) + C :MSTORE(squareFp4BN254_a2_x) + D :MSTORE(squareFp4BN254_a2_y), CALL(squareFp4BN254) + $ => A :MLOAD(squareFp4BN254_c1_x) + $ => B :MLOAD(squareFp4BN254_c1_y) + $ => C :MLOAD(squareFp4BN254_c2_x) + $ => D :MLOAD(squareFp4BN254_c2_y) + A :MSTORE(squareCycloFp12BN254_t11_x) + B :MSTORE(squareCycloFp12BN254_t11_y) + C :MSTORE(squareCycloFp12BN254_t22_x) + D :MSTORE(squareCycloFp12BN254_t22_y) + + ; 2] [t23,t12] = (a21 + a13·V)² + $ => A :MLOAD(squareCycloFp12BN254_a21_x) + $ => B :MLOAD(squareCycloFp12BN254_a21_y) + $ => C :MLOAD(squareCycloFp12BN254_a13_x) + $ => D :MLOAD(squareCycloFp12BN254_a13_y) + A :MSTORE(squareFp4BN254_a1_x) + B :MSTORE(squareFp4BN254_a1_y) + C :MSTORE(squareFp4BN254_a2_x) + D :MSTORE(squareFp4BN254_a2_y), CALL(squareFp4BN254) + $ => A :MLOAD(squareFp4BN254_c1_x) + $ => B :MLOAD(squareFp4BN254_c1_y) + $ => C :MLOAD(squareFp4BN254_c2_x) + $ => D :MLOAD(squareFp4BN254_c2_y) + A :MSTORE(squareCycloFp12BN254_t23_x) + B :MSTORE(squareCycloFp12BN254_t23_y) + C :MSTORE(squareCycloFp12BN254_t12_x) + D :MSTORE(squareCycloFp12BN254_t12_y) + + ; 3] [t13,aux] = (a12 + a23·V)² + $ => A :MLOAD(squareCycloFp12BN254_a12_x) + $ => B :MLOAD(squareCycloFp12BN254_a12_y) + $ => C :MLOAD(squareCycloFp12BN254_a23_x) + $ => D :MLOAD(squareCycloFp12BN254_a23_y) + A :MSTORE(squareFp4BN254_a1_x) + B :MSTORE(squareFp4BN254_a1_y) + C :MSTORE(squareFp4BN254_a2_x) + D :MSTORE(squareFp4BN254_a2_y), CALL(squareFp4BN254) + $ => A :MLOAD(squareFp4BN254_c1_x) + $ => B :MLOAD(squareFp4BN254_c1_y) + $ => C :MLOAD(squareFp4BN254_c2_x) + $ => D :MLOAD(squareFp4BN254_c2_y) + A :MSTORE(squareCycloFp12BN254_t13_x) + B :MSTORE(squareCycloFp12BN254_t13_y) + C :MSTORE(squareCycloFp12BN254_aux_x) + D :MSTORE(squareCycloFp12BN254_aux_y) + + ; 4] t21 = aux·(9+u) + $ => A :MLOAD(squareCycloFp12BN254_aux_x) + $ => B :MLOAD(squareCycloFp12BN254_aux_y) + 9n => C + 1n => D :CALL(mulFp2BN254) + E :MSTORE(squareCycloFp12BN254_t21_x) + C :MSTORE(squareCycloFp12BN254_t21_y) + + ; 5] c11 = -2·a11 + 3·t11 + %BN254_P - 2n => A + $ => C :MLOAD(squareCycloFp12BN254_a11_x) + $ => D :MLOAD(squareCycloFp12BN254_a11_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCycloFp12BN254_a11_x) + C :MSTORE(squareCycloFp12BN254_a11_y) + + 3n => A + $ => C :MLOAD(squareCycloFp12BN254_t11_x) + $ => D :MLOAD(squareCycloFp12BN254_t11_y), CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCycloFp12BN254_a11_x) + $ => D :MLOAD(squareCycloFp12BN254_a11_y), CALL(addFp2BN254) + E :MSTORE(squareCycloFp12BN254_c11_x) + C :MSTORE(squareCycloFp12BN254_c11_y) + + ; 6] c12 = -2·a12 + 3·t23 + %BN254_P - 2n => A + $ => C :MLOAD(squareCycloFp12BN254_a12_x) + $ => D :MLOAD(squareCycloFp12BN254_a12_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCycloFp12BN254_a12_x) + C :MSTORE(squareCycloFp12BN254_a12_y) + + 3n => A + $ => C :MLOAD(squareCycloFp12BN254_t23_x) + $ => D :MLOAD(squareCycloFp12BN254_t23_y), CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCycloFp12BN254_a12_x) + $ => D :MLOAD(squareCycloFp12BN254_a12_y), CALL(addFp2BN254) + E :MSTORE(squareCycloFp12BN254_c12_x) + C :MSTORE(squareCycloFp12BN254_c12_y) + + ; 7] c13 = -2·a13 + 3·t13 + %BN254_P - 2n => A + $ => C :MLOAD(squareCycloFp12BN254_a13_x) + $ => D :MLOAD(squareCycloFp12BN254_a13_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCycloFp12BN254_a13_x) + C :MSTORE(squareCycloFp12BN254_a13_y) + + 3n => A + $ => C :MLOAD(squareCycloFp12BN254_t13_x) + $ => D :MLOAD(squareCycloFp12BN254_t13_y), CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCycloFp12BN254_a13_x) + $ => D :MLOAD(squareCycloFp12BN254_a13_y), CALL(addFp2BN254) + E :MSTORE(squareCycloFp12BN254_c13_x) + C :MSTORE(squareCycloFp12BN254_c13_y) + + ; 8] c21 = 2·a21 + 3·t21 + 2n => A + $ => C :MLOAD(squareCycloFp12BN254_a21_x) + $ => D :MLOAD(squareCycloFp12BN254_a21_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCycloFp12BN254_a21_x) + C :MSTORE(squareCycloFp12BN254_a21_y) + + 3n => A + $ => C :MLOAD(squareCycloFp12BN254_t21_x) + $ => D :MLOAD(squareCycloFp12BN254_t21_y), CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCycloFp12BN254_a21_x) + $ => D :MLOAD(squareCycloFp12BN254_a21_y), CALL(addFp2BN254) + E :MSTORE(squareCycloFp12BN254_c21_x) + C :MSTORE(squareCycloFp12BN254_c21_y) + + ; 9] c22 = 2·a22 + 3·t22 + 2n => A + $ => C :MLOAD(squareCycloFp12BN254_a22_x) + $ => D :MLOAD(squareCycloFp12BN254_a22_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCycloFp12BN254_a22_x) + C :MSTORE(squareCycloFp12BN254_a22_y) + + 3n => A + $ => C :MLOAD(squareCycloFp12BN254_t22_x) + $ => D :MLOAD(squareCycloFp12BN254_t22_y), CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCycloFp12BN254_a22_x) + $ => D :MLOAD(squareCycloFp12BN254_a22_y), CALL(addFp2BN254) + E :MSTORE(squareCycloFp12BN254_c22_x) + C :MSTORE(squareCycloFp12BN254_c22_y) + + ; 9] c23 = 2·a23 + 3·t12 + 2n => A + $ => C :MLOAD(squareCycloFp12BN254_a23_x) + $ => D :MLOAD(squareCycloFp12BN254_a23_y), CALL(escalarMulFp2BN254) + E :MSTORE(squareCycloFp12BN254_a23_x) + C :MSTORE(squareCycloFp12BN254_a23_y) + + 3n => A + $ => C :MLOAD(squareCycloFp12BN254_t12_x) + $ => D :MLOAD(squareCycloFp12BN254_t12_y), CALL(escalarMulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareCycloFp12BN254_a23_x) + $ => D :MLOAD(squareCycloFp12BN254_a23_y), CALL(addFp2BN254) + E :MSTORE(squareCycloFp12BN254_c23_x) + C :MSTORE(squareCycloFp12BN254_c23_y) + + + $ => RR :MLOAD(squareCycloFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm new file mode 100644 index 00000000..54359be4 --- /dev/null +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm @@ -0,0 +1,64 @@ +;; +;; parameter of BN254 x = 4965661367192848881, which can be expressed in (little-endian) binary as: +;; 100011111001000010010110010100100010110101001001100101110010001 +;; + +xBinDecompBN254: + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/frob2Fp12BN254.zkasm b/main/pairings/FP12BN254/frob2Fp12BN254.zkasm new file mode 100644 index 00000000..057b6ebb --- /dev/null +++ b/main/pairings/FP12BN254/frob2Fp12BN254.zkasm @@ -0,0 +1,79 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; frob2Fp12BN254: +;; in: (a1 + a2·w) = ((a11 + a12v + a13v²) + (a21 + a22v + a23v²)) ∈ Fp12, where ai ∈ Fp6 and aij ∈ Fp2 +;; out: (a1 + a2·w)ᵖ˙ᵖ = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = a11 + a12·γ22·v + a13·γ24·v² +;; - c2 = a21·γ21 + a22·γ23·v + a23·γ25·v² +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL frob2Fp12BN254_a11_x +VAR GLOBAL frob2Fp12BN254_a11_y +VAR GLOBAL frob2Fp12BN254_a12_x +VAR GLOBAL frob2Fp12BN254_a12_y +VAR GLOBAL frob2Fp12BN254_a13_x +VAR GLOBAL frob2Fp12BN254_a13_y +VAR GLOBAL frob2Fp12BN254_a21_x +VAR GLOBAL frob2Fp12BN254_a21_y +VAR GLOBAL frob2Fp12BN254_a22_x +VAR GLOBAL frob2Fp12BN254_a22_y +VAR GLOBAL frob2Fp12BN254_a23_x +VAR GLOBAL frob2Fp12BN254_a23_y +VAR GLOBAL frob2Fp12BN254_c11_x +VAR GLOBAL frob2Fp12BN254_c11_y +VAR GLOBAL frob2Fp12BN254_c12_x +VAR GLOBAL frob2Fp12BN254_c12_y +VAR GLOBAL frob2Fp12BN254_c13_x +VAR GLOBAL frob2Fp12BN254_c13_y +VAR GLOBAL frob2Fp12BN254_c21_x +VAR GLOBAL frob2Fp12BN254_c21_y +VAR GLOBAL frob2Fp12BN254_c22_x +VAR GLOBAL frob2Fp12BN254_c22_y +VAR GLOBAL frob2Fp12BN254_c23_x +VAR GLOBAL frob2Fp12BN254_c23_y + +VAR GLOBAL frob2Fp12BN254_RR + +frob2Fp12BN254: + RR :MSTORE(frob2Fp12BN254_RR) + + ; 1] c1 = a11 + a12·γ22·v + a13·γ24·v² + $ => A :MLOAD(frob2Fp12BN254_a11_x) + $ => B :MLOAD(frob2Fp12BN254_a11_y) + A :MSTORE(frob2Fp12BN254_c11_x) + B :MSTORE(frob2Fp12BN254_c11_y) + + %FROBENIUS_GAMMA22 => A + $ => C :MLOAD(frob2Fp12BN254_a12_x) + $ => D :MLOAD(frob2Fp12BN254_a12_y), CALL(escalarMulFp2BN254) + E :MSTORE(frob2Fp12BN254_c12_x) + C :MSTORE(frob2Fp12BN254_c12_y) + + %FROBENIUS_GAMMA24 => A + $ => C :MLOAD(frob2Fp12BN254_a13_x) + $ => D :MLOAD(frob2Fp12BN254_a13_y), CALL(escalarMulFp2BN254) + E :MSTORE(frob2Fp12BN254_c13_x) + C :MSTORE(frob2Fp12BN254_c13_y) + + ; 2] c2 = a21·γ21 + a22·γ23·v + a23·γ25·v² + %FROBENIUS_GAMMA21 => A + $ => C :MLOAD(frob2Fp12BN254_a21_x) + $ => D :MLOAD(frob2Fp12BN254_a21_y), CALL(escalarMulFp2BN254) + E :MSTORE(frob2Fp12BN254_c21_x) + C :MSTORE(frob2Fp12BN254_c21_y) + + %FROBENIUS_GAMMA23 => A + $ => C :MLOAD(frob2Fp12BN254_a22_x) + $ => D :MLOAD(frob2Fp12BN254_a22_y), CALL(escalarMulFp2BN254) + E :MSTORE(frob2Fp12BN254_c22_x) + C :MSTORE(frob2Fp12BN254_c22_y) + + %FROBENIUS_GAMMA25 => A + $ => C :MLOAD(frob2Fp12BN254_a23_x) + $ => D :MLOAD(frob2Fp12BN254_a23_y), CALL(escalarMulFp2BN254) + E :MSTORE(frob2Fp12BN254_c23_x) + C :MSTORE(frob2Fp12BN254_c23_y) + + $ => RR :MLOAD(frob2Fp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/frob3Fp12BN254.zkasm b/main/pairings/FP12BN254/frob3Fp12BN254.zkasm new file mode 100644 index 00000000..3b49a543 --- /dev/null +++ b/main/pairings/FP12BN254/frob3Fp12BN254.zkasm @@ -0,0 +1,95 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; frob3Fp12BN254: +;; in: (a1 + a2·w) = ((a11 + a12v + a13v²) + (a21 + a22v + a23v²)) ∈ Fp12, where ai ∈ Fp6 and aij ∈ Fp2 +;; out: (a1 + a2·w)ᵖ˙ᵖ˙ᵖ = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = a̅11 + a̅12·γ32·v + a̅13·γ34·v² +;; - c2 = a̅21·γ31 + a̅22·γ33·v + a̅23·γ35·v² +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL frob3Fp12BN254_a11_x +VAR GLOBAL frob3Fp12BN254_a11_y +VAR GLOBAL frob3Fp12BN254_a12_x +VAR GLOBAL frob3Fp12BN254_a12_y +VAR GLOBAL frob3Fp12BN254_a13_x +VAR GLOBAL frob3Fp12BN254_a13_y +VAR GLOBAL frob3Fp12BN254_a21_x +VAR GLOBAL frob3Fp12BN254_a21_y +VAR GLOBAL frob3Fp12BN254_a22_x +VAR GLOBAL frob3Fp12BN254_a22_y +VAR GLOBAL frob3Fp12BN254_a23_x +VAR GLOBAL frob3Fp12BN254_a23_y +VAR GLOBAL frob3Fp12BN254_c11_x +VAR GLOBAL frob3Fp12BN254_c11_y +VAR GLOBAL frob3Fp12BN254_c12_x +VAR GLOBAL frob3Fp12BN254_c12_y +VAR GLOBAL frob3Fp12BN254_c13_x +VAR GLOBAL frob3Fp12BN254_c13_y +VAR GLOBAL frob3Fp12BN254_c21_x +VAR GLOBAL frob3Fp12BN254_c21_y +VAR GLOBAL frob3Fp12BN254_c22_x +VAR GLOBAL frob3Fp12BN254_c22_y +VAR GLOBAL frob3Fp12BN254_c23_x +VAR GLOBAL frob3Fp12BN254_c23_y + +VAR GLOBAL frob3Fp12BN254_RR + +frob3Fp12BN254: + RR :MSTORE(frob3Fp12BN254_RR) + + ; 1] c1 = a̅11 + a̅12·γ32·v + a̅13·γ34·v² + $ => A :MLOAD(frob3Fp12BN254_a11_x) + A :MSTORE(frob3Fp12BN254_c11_x) + %BN254_P => A + $ => B :MLOAD(frob3Fp12BN254_a11_y) + $ :SUB, MSTORE(frob3Fp12BN254_c11_y) + + %BN254_P => A + $ => B :MLOAD(frob3Fp12BN254_a12_y) + $ => B :SUB + $ => A :MLOAD(frob3Fp12BN254_a12_x) + %FROBENIUS_GAMMA321 => C + %FROBENIUS_GAMMA322 => D :CALL(mulFp2BN254) + E :MSTORE(frob3Fp12BN254_c12_x) + C :MSTORE(frob3Fp12BN254_c12_y) + + %BN254_P => A + $ => B :MLOAD(frob3Fp12BN254_a13_y) + $ => B :SUB + $ => A :MLOAD(frob3Fp12BN254_a13_x) + %FROBENIUS_GAMMA341 => C + %FROBENIUS_GAMMA342 => D :CALL(mulFp2BN254) + E :MSTORE(frob3Fp12BN254_c13_x) + C :MSTORE(frob3Fp12BN254_c13_y) + + ; 2] c2 = a̅21·γ11 + a̅22·γ13·v + a̅23·γ15·v² + %BN254_P => A + $ => B :MLOAD(frob3Fp12BN254_a21_y) + $ => B :SUB + $ => A :MLOAD(frob3Fp12BN254_a21_x) + %FROBENIUS_GAMMA311 => C + %FROBENIUS_GAMMA312 => D :CALL(mulFp2BN254) + E :MSTORE(frob3Fp12BN254_c21_x) + C :MSTORE(frob3Fp12BN254_c21_y) + + %BN254_P => A + $ => B :MLOAD(frob3Fp12BN254_a22_y) + $ => B :SUB + $ => A :MLOAD(frob3Fp12BN254_a22_x) + %FROBENIUS_GAMMA331 => C + %FROBENIUS_GAMMA332 => D :CALL(mulFp2BN254) + E :MSTORE(frob3Fp12BN254_c22_x) + C :MSTORE(frob3Fp12BN254_c22_y) + + %BN254_P => A + $ => B :MLOAD(frob3Fp12BN254_a23_y) + $ => B :SUB + $ => A :MLOAD(frob3Fp12BN254_a23_x) + %FROBENIUS_GAMMA351 => C + %FROBENIUS_GAMMA352 => D :CALL(mulFp2BN254) + E :MSTORE(frob3Fp12BN254_c23_x) + C :MSTORE(frob3Fp12BN254_c23_y) + + $ => RR :MLOAD(frob3Fp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/frobFp12BN254.zkasm b/main/pairings/FP12BN254/frobFp12BN254.zkasm new file mode 100644 index 00000000..f879f8ea --- /dev/null +++ b/main/pairings/FP12BN254/frobFp12BN254.zkasm @@ -0,0 +1,95 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; frobFp12BN254: +;; in: (a1 + a2·w) = ((a11 + a12v + a13v²) + (a21 + a22v + a23v²)·w) ∈ Fp12, where ai ∈ Fp6 and aij ∈ Fp2 +;; out: (a1 + a2·w)ᵖ = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = a̅11 + a̅12·γ12·v + a̅13·γ14·v² +;; - c2 = a̅21·γ11 + a̅22·γ13·v + a̅23·γ15·v² +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL frobFp12BN254_a11_x +VAR GLOBAL frobFp12BN254_a11_y +VAR GLOBAL frobFp12BN254_a12_x +VAR GLOBAL frobFp12BN254_a12_y +VAR GLOBAL frobFp12BN254_a13_x +VAR GLOBAL frobFp12BN254_a13_y +VAR GLOBAL frobFp12BN254_a21_x +VAR GLOBAL frobFp12BN254_a21_y +VAR GLOBAL frobFp12BN254_a22_x +VAR GLOBAL frobFp12BN254_a22_y +VAR GLOBAL frobFp12BN254_a23_x +VAR GLOBAL frobFp12BN254_a23_y +VAR GLOBAL frobFp12BN254_c11_x +VAR GLOBAL frobFp12BN254_c11_y +VAR GLOBAL frobFp12BN254_c12_x +VAR GLOBAL frobFp12BN254_c12_y +VAR GLOBAL frobFp12BN254_c13_x +VAR GLOBAL frobFp12BN254_c13_y +VAR GLOBAL frobFp12BN254_c21_x +VAR GLOBAL frobFp12BN254_c21_y +VAR GLOBAL frobFp12BN254_c22_x +VAR GLOBAL frobFp12BN254_c22_y +VAR GLOBAL frobFp12BN254_c23_x +VAR GLOBAL frobFp12BN254_c23_y + +VAR GLOBAL frobFp12BN254_RR + +frobFp12BN254: + RR :MSTORE(frobFp12BN254_RR) + + ; 1] c1 = a̅11 + a̅12·γ12·v + a̅13·γ14·v² + $ => A :MLOAD(frobFp12BN254_a11_x) + A :MSTORE(frobFp12BN254_c11_x) + %BN254_P => A + $ => B :MLOAD(frobFp12BN254_a11_y) + $ :SUB, MSTORE(frobFp12BN254_c11_y) + + %BN254_P => A + $ => B :MLOAD(frobFp12BN254_a12_y) + $ => B :SUB + $ => A :MLOAD(frobFp12BN254_a12_x) + %FROBENIUS_GAMMA121 => C + %FROBENIUS_GAMMA122 => D :CALL(mulFp2BN254) + E :MSTORE(frobFp12BN254_c12_x) + C :MSTORE(frobFp12BN254_c12_y) + + %BN254_P => A + $ => B :MLOAD(frobFp12BN254_a13_y) + $ => B :SUB + $ => A :MLOAD(frobFp12BN254_a13_x) + %FROBENIUS_GAMMA141 => C + %FROBENIUS_GAMMA142 => D :CALL(mulFp2BN254) + E :MSTORE(frobFp12BN254_c13_x) + C :MSTORE(frobFp12BN254_c13_y) + + ; 2] c2 = a̅21·γ11 + a̅22·γ13·v + a̅23·γ15·v² + %BN254_P => A + $ => B :MLOAD(frobFp12BN254_a21_y) + $ => B :SUB + $ => A :MLOAD(frobFp12BN254_a21_x) + %FROBENIUS_GAMMA111 => C + %FROBENIUS_GAMMA112 => D :CALL(mulFp2BN254) + E :MSTORE(frobFp12BN254_c21_x) + C :MSTORE(frobFp12BN254_c21_y) + + %BN254_P => A + $ => B :MLOAD(frobFp12BN254_a22_y) + $ => B :SUB + $ => A :MLOAD(frobFp12BN254_a22_x) + %FROBENIUS_GAMMA131 => C + %FROBENIUS_GAMMA132 => D :CALL(mulFp2BN254) + E :MSTORE(frobFp12BN254_c22_x) + C :MSTORE(frobFp12BN254_c22_y) + + %BN254_P => A + $ => B :MLOAD(frobFp12BN254_a23_y) + $ => B :SUB + $ => A :MLOAD(frobFp12BN254_a23_x) + %FROBENIUS_GAMMA151 => C + %FROBENIUS_GAMMA152 => D :CALL(mulFp2BN254) + E :MSTORE(frobFp12BN254_c23_x) + C :MSTORE(frobFp12BN254_c23_y) + + $ => RR :MLOAD(frobFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/inverseFp12BN254.zkasm b/main/pairings/FP12BN254/inverseFp12BN254.zkasm new file mode 100644 index 00000000..f3016f17 --- /dev/null +++ b/main/pairings/FP12BN254/inverseFp12BN254.zkasm @@ -0,0 +1,288 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; inverseFp12BN254: +;; in: (a1 + a2·w) ∈ Fp12, where ai ∈ Fp6 +;; out: (a1 + a2·w)⁻¹ = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = a1·(a1² - a2²·v)⁻¹ +;; - c2 = -a2·(a1² - a2²·v)⁻¹ +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL inverseFp12BN254_a11_x +VAR GLOBAL inverseFp12BN254_a11_y +VAR GLOBAL inverseFp12BN254_a12_x +VAR GLOBAL inverseFp12BN254_a12_y +VAR GLOBAL inverseFp12BN254_a13_x +VAR GLOBAL inverseFp12BN254_a13_y +VAR GLOBAL inverseFp12BN254_a21_x +VAR GLOBAL inverseFp12BN254_a21_y +VAR GLOBAL inverseFp12BN254_a22_x +VAR GLOBAL inverseFp12BN254_a22_y +VAR GLOBAL inverseFp12BN254_a23_x +VAR GLOBAL inverseFp12BN254_a23_y +VAR GLOBAL inverseFp12BN254_c11_x +VAR GLOBAL inverseFp12BN254_c11_y +VAR GLOBAL inverseFp12BN254_c12_x +VAR GLOBAL inverseFp12BN254_c12_y +VAR GLOBAL inverseFp12BN254_c13_x +VAR GLOBAL inverseFp12BN254_c13_y +VAR GLOBAL inverseFp12BN254_c21_x +VAR GLOBAL inverseFp12BN254_c21_y +VAR GLOBAL inverseFp12BN254_c22_x +VAR GLOBAL inverseFp12BN254_c22_y +VAR GLOBAL inverseFp12BN254_c23_x +VAR GLOBAL inverseFp12BN254_c23_y + +VAR GLOBAL inverseFp12BN254_a1square1_x +VAR GLOBAL inverseFp12BN254_a1square1_y +VAR GLOBAL inverseFp12BN254_a1square2_x +VAR GLOBAL inverseFp12BN254_a1square2_y +VAR GLOBAL inverseFp12BN254_a1square3_x +VAR GLOBAL inverseFp12BN254_a1square3_y +VAR GLOBAL inverseFp12BN254_a2square1_x +VAR GLOBAL inverseFp12BN254_a2square1_y +VAR GLOBAL inverseFp12BN254_a2square2_x +VAR GLOBAL inverseFp12BN254_a2square2_y +VAR GLOBAL inverseFp12BN254_a2square3_x +VAR GLOBAL inverseFp12BN254_a2square3_y + +VAR GLOBAL inverseFp12BN254_a1sqsubva2sq1_x +VAR GLOBAL inverseFp12BN254_a1sqsubva2sq1_y +VAR GLOBAL inverseFp12BN254_a1sqsubva2sq2_x +VAR GLOBAL inverseFp12BN254_a1sqsubva2sq2_y +VAR GLOBAL inverseFp12BN254_a1sqsubva2sq3_x +VAR GLOBAL inverseFp12BN254_a1sqsubva2sq3_y +VAR GLOBAL inverseFp12BN254_va2square1_x +VAR GLOBAL inverseFp12BN254_va2square1_y +VAR GLOBAL inverseFp12BN254_va2square2_x +VAR GLOBAL inverseFp12BN254_va2square2_y +VAR GLOBAL inverseFp12BN254_va2square3_x +VAR GLOBAL inverseFp12BN254_va2square3_y + +VAR GLOBAL inverseFp12BN254_final1_x +VAR GLOBAL inverseFp12BN254_final1_y +VAR GLOBAL inverseFp12BN254_final2_x +VAR GLOBAL inverseFp12BN254_final2_y +VAR GLOBAL inverseFp12BN254_final3_x +VAR GLOBAL inverseFp12BN254_final3_y + +VAR GLOBAL inverseFp12BN254_RR + +inverseFp12BN254: + RR :MSTORE(inverseFp12BN254_RR) + + ; 1] a1² + $ => A :MLOAD(inverseFp12BN254_a11_x) + $ => B :MLOAD(inverseFp12BN254_a11_y) + A :MSTORE(squareFp6BN254_a1_x) + B :MSTORE(squareFp6BN254_a1_y) + $ => A :MLOAD(inverseFp12BN254_a12_x) + $ => B :MLOAD(inverseFp12BN254_a12_y) + A :MSTORE(squareFp6BN254_a2_x) + B :MSTORE(squareFp6BN254_a2_y) + $ => A :MLOAD(inverseFp12BN254_a13_x) + $ => B :MLOAD(inverseFp12BN254_a13_y) + A :MSTORE(squareFp6BN254_a3_x) + B :MSTORE(squareFp6BN254_a3_y), CALL(squareFp6BN254) + $ => A :MLOAD(squareFp6BN254_c1_x) + $ => B :MLOAD(squareFp6BN254_c1_y) + A :MSTORE(inverseFp12BN254_a1square1_x) + B :MSTORE(inverseFp12BN254_a1square1_y) + $ => A :MLOAD(squareFp6BN254_c2_x) + $ => B :MLOAD(squareFp6BN254_c2_y) + A :MSTORE(inverseFp12BN254_a1square2_x) + B :MSTORE(inverseFp12BN254_a1square2_y) + $ => A :MLOAD(squareFp6BN254_c3_x) + $ => B :MLOAD(squareFp6BN254_c3_y) + A :MSTORE(inverseFp12BN254_a1square3_x) + B :MSTORE(inverseFp12BN254_a1square3_y) + + ; 2] a2² + $ => A :MLOAD(inverseFp12BN254_a21_x) + $ => B :MLOAD(inverseFp12BN254_a21_y) + A :MSTORE(squareFp6BN254_a1_x) + B :MSTORE(squareFp6BN254_a1_y) + $ => A :MLOAD(inverseFp12BN254_a22_x) + $ => B :MLOAD(inverseFp12BN254_a22_y) + A :MSTORE(squareFp6BN254_a2_x) + B :MSTORE(squareFp6BN254_a2_y) + $ => A :MLOAD(inverseFp12BN254_a23_x) + $ => B :MLOAD(inverseFp12BN254_a23_y) + A :MSTORE(squareFp6BN254_a3_x) + B :MSTORE(squareFp6BN254_a3_y), CALL(squareFp6BN254) + $ => A :MLOAD(squareFp6BN254_c1_x) + $ => B :MLOAD(squareFp6BN254_c1_y) + A :MSTORE(inverseFp12BN254_a2square1_x) + B :MSTORE(inverseFp12BN254_a2square1_y) + $ => A :MLOAD(squareFp6BN254_c2_x) + $ => B :MLOAD(squareFp6BN254_c2_y) + A :MSTORE(inverseFp12BN254_a2square2_x) + B :MSTORE(inverseFp12BN254_a2square2_y) + $ => A :MLOAD(squareFp6BN254_c3_x) + $ => B :MLOAD(squareFp6BN254_c3_y) + A :MSTORE(inverseFp12BN254_a2square3_x) + B :MSTORE(inverseFp12BN254_a2square3_y) + + ; 3] (a1² - v·a2²)⁻¹ + $ => A :MLOAD(inverseFp12BN254_a2square1_x) + $ => B :MLOAD(inverseFp12BN254_a2square1_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(inverseFp12BN254_a2square2_x) + $ => B :MLOAD(inverseFp12BN254_a2square2_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(inverseFp12BN254_a2square3_x) + $ => B :MLOAD(inverseFp12BN254_a2square3_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + 1n :MSTORE(sparseMulAFp6BN254_b2_x) + 0n :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(inverseFp12BN254_va2square1_x) + B :MSTORE(inverseFp12BN254_va2square1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(inverseFp12BN254_va2square2_x) + B :MSTORE(inverseFp12BN254_va2square2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(inverseFp12BN254_va2square3_x) + B :MSTORE(inverseFp12BN254_va2square3_y) + + $ => A :MLOAD(inverseFp12BN254_a1square1_x) + $ => B :MLOAD(inverseFp12BN254_a1square1_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(inverseFp12BN254_a1square2_x) + $ => B :MLOAD(inverseFp12BN254_a1square2_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(inverseFp12BN254_a1square3_x) + $ => B :MLOAD(inverseFp12BN254_a1square3_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + $ => A :MLOAD(inverseFp12BN254_va2square1_x) + $ => B :MLOAD(inverseFp12BN254_va2square1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(inverseFp12BN254_va2square2_x) + $ => B :MLOAD(inverseFp12BN254_va2square2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(inverseFp12BN254_va2square3_x) + $ => B :MLOAD(inverseFp12BN254_va2square3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(inverseFp6BN254_a1_x) + B :MSTORE(inverseFp6BN254_a1_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(inverseFp6BN254_a2_x) + B :MSTORE(inverseFp6BN254_a2_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(inverseFp6BN254_a3_x) + B :MSTORE(inverseFp6BN254_a3_y), CALL(inverseFp6BN254) + $ => A :MLOAD(inverseFp6BN254_c1_x) + $ => B :MLOAD(inverseFp6BN254_c1_y) + A :MSTORE(inverseFp12BN254_final1_x) + B :MSTORE(inverseFp12BN254_final1_y) + $ => A :MLOAD(inverseFp6BN254_c2_x) + $ => B :MLOAD(inverseFp6BN254_c2_y) + A :MSTORE(inverseFp12BN254_final2_x) + B :MSTORE(inverseFp12BN254_final2_y) + $ => A :MLOAD(inverseFp6BN254_c3_x) + $ => B :MLOAD(inverseFp6BN254_c3_y) + A :MSTORE(inverseFp12BN254_final3_x) + B :MSTORE(inverseFp12BN254_final3_y) + + ; 4] c1 = a1·(a1² - a2²·v)⁻¹ + $ => A :MLOAD(inverseFp12BN254_a11_x) + $ => B :MLOAD(inverseFp12BN254_a11_y) + A :MSTORE(mulFp6BN254_a1_x) + B :MSTORE(mulFp6BN254_a1_y) + $ => A :MLOAD(inverseFp12BN254_a12_x) + $ => B :MLOAD(inverseFp12BN254_a12_y) + A :MSTORE(mulFp6BN254_a2_x) + B :MSTORE(mulFp6BN254_a2_y) + $ => A :MLOAD(inverseFp12BN254_a13_x) + $ => B :MLOAD(inverseFp12BN254_a13_y) + A :MSTORE(mulFp6BN254_a3_x) + B :MSTORE(mulFp6BN254_a3_y) + $ => A :MLOAD(inverseFp12BN254_final1_x) + $ => B :MLOAD(inverseFp12BN254_final1_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(inverseFp12BN254_final2_x) + $ => B :MLOAD(inverseFp12BN254_final2_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(inverseFp12BN254_final3_x) + $ => B :MLOAD(inverseFp12BN254_final3_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(inverseFp12BN254_c11_x) + B :MSTORE(inverseFp12BN254_c11_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(inverseFp12BN254_c12_x) + B :MSTORE(inverseFp12BN254_c12_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(inverseFp12BN254_c13_x) + B :MSTORE(inverseFp12BN254_c13_y) + + ; 4] c2 = -a2·(a1² - a2²·v)⁻¹ + %BN254_P => A + $ => B :MLOAD(inverseFp12BN254_a21_x) + $ :SUB, MSTORE(mulFp6BN254_a1_x) + %BN254_P => A + $ => B :MLOAD(inverseFp12BN254_a21_y) + $ :SUB, MSTORE(mulFp6BN254_a1_y) + %BN254_P => A + $ => B :MLOAD(inverseFp12BN254_a22_x) + $ :SUB, MSTORE(mulFp6BN254_a2_x) + %BN254_P => A + $ => B :MLOAD(inverseFp12BN254_a22_y) + $ :SUB, MSTORE(mulFp6BN254_a2_y) + %BN254_P => A + $ => B :MLOAD(inverseFp12BN254_a23_x) + $ :SUB, MSTORE(mulFp6BN254_a3_x) + %BN254_P => A + $ => B :MLOAD(inverseFp12BN254_a23_y) + $ :SUB, MSTORE(mulFp6BN254_a3_y) + + $ => A :MLOAD(inverseFp12BN254_final1_x) + $ => B :MLOAD(inverseFp12BN254_final1_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(inverseFp12BN254_final2_x) + $ => B :MLOAD(inverseFp12BN254_final2_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(inverseFp12BN254_final3_x) + $ => B :MLOAD(inverseFp12BN254_final3_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(inverseFp12BN254_c21_x) + B :MSTORE(inverseFp12BN254_c21_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(inverseFp12BN254_c22_x) + B :MSTORE(inverseFp12BN254_c22_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(inverseFp12BN254_c23_x) + B :MSTORE(inverseFp12BN254_c23_y) + + + $ => RR :MLOAD(inverseFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/mulFp12BN254.zkasm b/main/pairings/FP12BN254/mulFp12BN254.zkasm new file mode 100644 index 00000000..f773a393 --- /dev/null +++ b/main/pairings/FP12BN254/mulFp12BN254.zkasm @@ -0,0 +1,407 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; mulFp12BN254: +;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai,bi ∈ Fp6 +;; out: (a1 + a2·w)·(b1 + b2·w) = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = a1·b1 + a2·b2·v +;; - c2 = (a1+a2)·(b1+b2) - a1·b1 - a2·b2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL mulFp12BN254_a11_x +VAR GLOBAL mulFp12BN254_a11_y +VAR GLOBAL mulFp12BN254_a12_x +VAR GLOBAL mulFp12BN254_a12_y +VAR GLOBAL mulFp12BN254_a13_x +VAR GLOBAL mulFp12BN254_a13_y +VAR GLOBAL mulFp12BN254_a21_x +VAR GLOBAL mulFp12BN254_a21_y +VAR GLOBAL mulFp12BN254_a22_x +VAR GLOBAL mulFp12BN254_a22_y +VAR GLOBAL mulFp12BN254_a23_x +VAR GLOBAL mulFp12BN254_a23_y +VAR GLOBAL mulFp12BN254_b11_x +VAR GLOBAL mulFp12BN254_b11_y +VAR GLOBAL mulFp12BN254_b12_x +VAR GLOBAL mulFp12BN254_b12_y +VAR GLOBAL mulFp12BN254_b13_x +VAR GLOBAL mulFp12BN254_b13_y +VAR GLOBAL mulFp12BN254_b21_x +VAR GLOBAL mulFp12BN254_b21_y +VAR GLOBAL mulFp12BN254_b22_x +VAR GLOBAL mulFp12BN254_b22_y +VAR GLOBAL mulFp12BN254_b23_x +VAR GLOBAL mulFp12BN254_b23_y +VAR GLOBAL mulFp12BN254_c11_x +VAR GLOBAL mulFp12BN254_c11_y +VAR GLOBAL mulFp12BN254_c12_x +VAR GLOBAL mulFp12BN254_c12_y +VAR GLOBAL mulFp12BN254_c13_x +VAR GLOBAL mulFp12BN254_c13_y +VAR GLOBAL mulFp12BN254_c21_x +VAR GLOBAL mulFp12BN254_c21_y +VAR GLOBAL mulFp12BN254_c22_x +VAR GLOBAL mulFp12BN254_c22_y +VAR GLOBAL mulFp12BN254_c23_x +VAR GLOBAL mulFp12BN254_c23_y + +VAR GLOBAL mulFp12BN254_a1b1mul1_x +VAR GLOBAL mulFp12BN254_a1b1mul1_y +VAR GLOBAL mulFp12BN254_a1b1mul2_x +VAR GLOBAL mulFp12BN254_a1b1mul2_y +VAR GLOBAL mulFp12BN254_a1b1mul3_x +VAR GLOBAL mulFp12BN254_a1b1mul3_y +VAR GLOBAL mulFp12BN254_a2b2mul1_x +VAR GLOBAL mulFp12BN254_a2b2mul1_y +VAR GLOBAL mulFp12BN254_a2b2mul2_x +VAR GLOBAL mulFp12BN254_a2b2mul2_y +VAR GLOBAL mulFp12BN254_a2b2mul3_x +VAR GLOBAL mulFp12BN254_a2b2mul3_y +VAR GLOBAL mulFp12BN254_a2b2vmul1_x +VAR GLOBAL mulFp12BN254_a2b2vmul1_y +VAR GLOBAL mulFp12BN254_a2b2vmul2_x +VAR GLOBAL mulFp12BN254_a2b2vmul2_y +VAR GLOBAL mulFp12BN254_a2b2vmul3_x +VAR GLOBAL mulFp12BN254_a2b2vmul3_y + +VAR GLOBAL mulFp12BN254_a1a2sum1_x +VAR GLOBAL mulFp12BN254_a1a2sum1_y +VAR GLOBAL mulFp12BN254_a1a2sum2_x +VAR GLOBAL mulFp12BN254_a1a2sum2_y +VAR GLOBAL mulFp12BN254_a1a2sum3_x +VAR GLOBAL mulFp12BN254_a1a2sum3_y +VAR GLOBAL mulFp12BN254_b1b2sum1_x +VAR GLOBAL mulFp12BN254_b1b2sum1_y +VAR GLOBAL mulFp12BN254_b1b2sum2_x +VAR GLOBAL mulFp12BN254_b1b2sum2_y +VAR GLOBAL mulFp12BN254_b1b2sum3_x +VAR GLOBAL mulFp12BN254_b1b2sum3_y + +VAR GLOBAL mulFp12BN254_RR + +mulFp12BN254: + RR :MSTORE(mulFp12BN254_RR) + + ; 1] a1·b1 + $ => A :MLOAD(mulFp12BN254_a11_x) + $ => B :MLOAD(mulFp12BN254_a11_y) + A :MSTORE(mulFp6BN254_a1_x) + B :MSTORE(mulFp6BN254_a1_y) + $ => A :MLOAD(mulFp12BN254_a12_x) + $ => B :MLOAD(mulFp12BN254_a12_y) + A :MSTORE(mulFp6BN254_a2_x) + B :MSTORE(mulFp6BN254_a2_y) + $ => A :MLOAD(mulFp12BN254_a13_x) + $ => B :MLOAD(mulFp12BN254_a13_y) + A :MSTORE(mulFp6BN254_a3_x) + B :MSTORE(mulFp6BN254_a3_y) + + $ => A :MLOAD(mulFp12BN254_b11_x) + $ => B :MLOAD(mulFp12BN254_b11_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_b12_x) + $ => B :MLOAD(mulFp12BN254_b12_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_b13_x) + $ => B :MLOAD(mulFp12BN254_b13_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(mulFp12BN254_a1b1mul1_x) + B :MSTORE(mulFp12BN254_a1b1mul1_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(mulFp12BN254_a1b1mul2_x) + B :MSTORE(mulFp12BN254_a1b1mul2_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(mulFp12BN254_a1b1mul3_x) + B :MSTORE(mulFp12BN254_a1b1mul3_y) + + ; 2] a2·b2 + $ => A :MLOAD(mulFp12BN254_a21_x) + $ => B :MLOAD(mulFp12BN254_a21_y) + A :MSTORE(mulFp6BN254_a1_x) + B :MSTORE(mulFp6BN254_a1_y) + $ => A :MLOAD(mulFp12BN254_a22_x) + $ => B :MLOAD(mulFp12BN254_a22_y) + A :MSTORE(mulFp6BN254_a2_x) + B :MSTORE(mulFp6BN254_a2_y) + $ => A :MLOAD(mulFp12BN254_a23_x) + $ => B :MLOAD(mulFp12BN254_a23_y) + A :MSTORE(mulFp6BN254_a3_x) + B :MSTORE(mulFp6BN254_a3_y) + + $ => A :MLOAD(mulFp12BN254_b21_x) + $ => B :MLOAD(mulFp12BN254_b21_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_b22_x) + $ => B :MLOAD(mulFp12BN254_b22_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_b23_x) + $ => B :MLOAD(mulFp12BN254_b23_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(mulFp12BN254_a2b2mul1_x) + B :MSTORE(mulFp12BN254_a2b2mul1_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(mulFp12BN254_a2b2mul2_x) + B :MSTORE(mulFp12BN254_a2b2mul2_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(mulFp12BN254_a2b2mul3_x) + B :MSTORE(mulFp12BN254_a2b2mul3_y) + + ; 3] a2·b2·v + $ => A :MLOAD(mulFp12BN254_a2b2mul1_x) + $ => B :MLOAD(mulFp12BN254_a2b2mul1_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(mulFp12BN254_a2b2mul2_x) + $ => B :MLOAD(mulFp12BN254_a2b2mul2_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(mulFp12BN254_a2b2mul3_x) + $ => B :MLOAD(mulFp12BN254_a2b2mul3_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + + 1n :MSTORE(sparseMulAFp6BN254_b2_x) + 0n :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(mulFp12BN254_a2b2vmul1_x) + B :MSTORE(mulFp12BN254_a2b2vmul1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(mulFp12BN254_a2b2vmul2_x) + B :MSTORE(mulFp12BN254_a2b2vmul2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(mulFp12BN254_a2b2vmul3_x) + B :MSTORE(mulFp12BN254_a2b2vmul3_y) + + ; 4] c1 = a1·b1 + a2·b2·v + $ => A :MLOAD(mulFp12BN254_a1b1mul1_x) + $ => B :MLOAD(mulFp12BN254_a1b1mul1_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(mulFp12BN254_a1b1mul2_x) + $ => B :MLOAD(mulFp12BN254_a1b1mul2_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(mulFp12BN254_a1b1mul3_x) + $ => B :MLOAD(mulFp12BN254_a1b1mul3_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + + $ => A :MLOAD(mulFp12BN254_a2b2vmul1_x) + $ => B :MLOAD(mulFp12BN254_a2b2vmul1_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_a2b2vmul2_x) + $ => B :MLOAD(mulFp12BN254_a2b2vmul2_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_a2b2vmul3_x) + $ => B :MLOAD(mulFp12BN254_a2b2vmul3_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(mulFp12BN254_c11_x) + B :MSTORE(mulFp12BN254_c11_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(mulFp12BN254_c12_x) + B :MSTORE(mulFp12BN254_c12_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(mulFp12BN254_c13_x) + B :MSTORE(mulFp12BN254_c13_y) + + ; 4] a1+a2 + $ => A :MLOAD(mulFp12BN254_a11_x) + $ => B :MLOAD(mulFp12BN254_a11_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(mulFp12BN254_a12_x) + $ => B :MLOAD(mulFp12BN254_a12_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(mulFp12BN254_a13_x) + $ => B :MLOAD(mulFp12BN254_a13_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + + $ => A :MLOAD(mulFp12BN254_a21_x) + $ => B :MLOAD(mulFp12BN254_a21_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_a22_x) + $ => B :MLOAD(mulFp12BN254_a22_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_a23_x) + $ => B :MLOAD(mulFp12BN254_a23_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(mulFp12BN254_a1a2sum1_x) + B :MSTORE(mulFp12BN254_a1a2sum1_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(mulFp12BN254_a1a2sum2_x) + B :MSTORE(mulFp12BN254_a1a2sum2_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(mulFp12BN254_a1a2sum3_x) + B :MSTORE(mulFp12BN254_a1a2sum3_y) + + + ; 5] b1+b2 + $ => A :MLOAD(mulFp12BN254_b11_x) + $ => B :MLOAD(mulFp12BN254_b11_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(mulFp12BN254_b12_x) + $ => B :MLOAD(mulFp12BN254_b12_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(mulFp12BN254_b13_x) + $ => B :MLOAD(mulFp12BN254_b13_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + + $ => A :MLOAD(mulFp12BN254_b21_x) + $ => B :MLOAD(mulFp12BN254_b21_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_b22_x) + $ => B :MLOAD(mulFp12BN254_b22_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_b23_x) + $ => B :MLOAD(mulFp12BN254_b23_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(mulFp12BN254_b1b2sum1_x) + B :MSTORE(mulFp12BN254_b1b2sum1_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(mulFp12BN254_b1b2sum2_x) + B :MSTORE(mulFp12BN254_b1b2sum2_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(mulFp12BN254_b1b2sum3_x) + B :MSTORE(mulFp12BN254_b1b2sum3_y) + + ; 7] c2 = (a1+a2)·(b1+b2) - a1·b1 - a2·b2 + $ => A :MLOAD(mulFp12BN254_a1a2sum1_x) + $ => B :MLOAD(mulFp12BN254_a1a2sum1_y) + A :MSTORE(mulFp6BN254_a1_x) + B :MSTORE(mulFp6BN254_a1_y) + $ => A :MLOAD(mulFp12BN254_a1a2sum2_x) + $ => B :MLOAD(mulFp12BN254_a1a2sum2_y) + A :MSTORE(mulFp6BN254_a2_x) + B :MSTORE(mulFp6BN254_a2_y) + $ => A :MLOAD(mulFp12BN254_a1a2sum3_x) + $ => B :MLOAD(mulFp12BN254_a1a2sum3_y) + A :MSTORE(mulFp6BN254_a3_x) + B :MSTORE(mulFp6BN254_a3_y) + + + $ => A :MLOAD(mulFp12BN254_b1b2sum1_x) + $ => B :MLOAD(mulFp12BN254_b1b2sum1_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_b1b2sum2_x) + $ => B :MLOAD(mulFp12BN254_b1b2sum2_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_b1b2sum3_x) + $ => B :MLOAD(mulFp12BN254_b1b2sum3_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + + $ => A :MLOAD(mulFp12BN254_a1b1mul1_x) + $ => B :MLOAD(mulFp12BN254_a1b1mul1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_a1b1mul2_x) + $ => B :MLOAD(mulFp12BN254_a1b1mul2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_a1b1mul3_x) + $ => B :MLOAD(mulFp12BN254_a1b1mul3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + + $ => A :MLOAD(mulFp12BN254_a2b2mul1_x) + $ => B :MLOAD(mulFp12BN254_a2b2mul1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(mulFp12BN254_a2b2mul2_x) + $ => B :MLOAD(mulFp12BN254_a2b2mul2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(mulFp12BN254_a2b2mul3_x) + $ => B :MLOAD(mulFp12BN254_a2b2mul3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(mulFp12BN254_c21_x) + B :MSTORE(mulFp12BN254_c21_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(mulFp12BN254_c22_x) + B :MSTORE(mulFp12BN254_c22_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(mulFp12BN254_c23_x) + B :MSTORE(mulFp12BN254_c23_y) + + $ => RR :MLOAD(mulFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm b/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm new file mode 100644 index 00000000..cc73d495 --- /dev/null +++ b/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm @@ -0,0 +1,295 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; sparseMulAFp12BN254: +;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai ∈ Fp6, b1 = b12·v and b2 = b22·v + b23·v², with b12,b22,b23 ∈ Fp2 +;; out: (a1 + a2·w)·(b1 + b2·w) = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = a1·b1 + a2·b2·v +;; - c2 = (a1+a2)·[(b12+b22)·v + b23·v²] - a1·b1 - a2·b2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL sparseMulAFp12BN254_a11_x +VAR GLOBAL sparseMulAFp12BN254_a11_y +VAR GLOBAL sparseMulAFp12BN254_a12_x +VAR GLOBAL sparseMulAFp12BN254_a12_y +VAR GLOBAL sparseMulAFp12BN254_a13_x +VAR GLOBAL sparseMulAFp12BN254_a13_y +VAR GLOBAL sparseMulAFp12BN254_a21_x +VAR GLOBAL sparseMulAFp12BN254_a21_y +VAR GLOBAL sparseMulAFp12BN254_a22_x +VAR GLOBAL sparseMulAFp12BN254_a22_y +VAR GLOBAL sparseMulAFp12BN254_a23_x +VAR GLOBAL sparseMulAFp12BN254_a23_y + +VAR GLOBAL sparseMulAFp12BN254_b12_x +VAR GLOBAL sparseMulAFp12BN254_b12_y +VAR GLOBAL sparseMulAFp12BN254_b22_x +VAR GLOBAL sparseMulAFp12BN254_b22_y +VAR GLOBAL sparseMulAFp12BN254_b23_x +VAR GLOBAL sparseMulAFp12BN254_b23_y + +VAR GLOBAL sparseMulAFp12BN254_c11_x +VAR GLOBAL sparseMulAFp12BN254_c11_y +VAR GLOBAL sparseMulAFp12BN254_c12_x +VAR GLOBAL sparseMulAFp12BN254_c12_y +VAR GLOBAL sparseMulAFp12BN254_c13_x +VAR GLOBAL sparseMulAFp12BN254_c13_y +VAR GLOBAL sparseMulAFp12BN254_c21_x +VAR GLOBAL sparseMulAFp12BN254_c21_y +VAR GLOBAL sparseMulAFp12BN254_c22_x +VAR GLOBAL sparseMulAFp12BN254_c22_y +VAR GLOBAL sparseMulAFp12BN254_c23_x +VAR GLOBAL sparseMulAFp12BN254_c23_y + +VAR GLOBAL sparseMulAFp12BN254_a1b1mul1_x +VAR GLOBAL sparseMulAFp12BN254_a1b1mul1_y +VAR GLOBAL sparseMulAFp12BN254_a1b1mul2_x +VAR GLOBAL sparseMulAFp12BN254_a1b1mul2_y +VAR GLOBAL sparseMulAFp12BN254_a1b1mul3_x +VAR GLOBAL sparseMulAFp12BN254_a1b1mul3_y +VAR GLOBAL sparseMulAFp12BN254_a2b2mul1_x +VAR GLOBAL sparseMulAFp12BN254_a2b2mul1_y +VAR GLOBAL sparseMulAFp12BN254_a2b2mul2_x +VAR GLOBAL sparseMulAFp12BN254_a2b2mul2_y +VAR GLOBAL sparseMulAFp12BN254_a2b2mul3_x +VAR GLOBAL sparseMulAFp12BN254_a2b2mul3_y + +VAR GLOBAL sparseMulAFp12BN254_aux2_x +VAR GLOBAL sparseMulAFp12BN254_aux2_y + +VAR GLOBAL sparseMulAFp12BN254_RR + +sparseMulAFp12BN254: + RR :MSTORE(sparseMulAFp12BN254_RR) + + ; 1] a1·b1, a2·b2 + $ => A :MLOAD(sparseMulAFp12BN254_a11_x) + $ => B :MLOAD(sparseMulAFp12BN254_a11_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a12_x) + $ => B :MLOAD(sparseMulAFp12BN254_a12_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a13_x) + $ => B :MLOAD(sparseMulAFp12BN254_a13_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + $ => A :MLOAD(sparseMulAFp12BN254_b12_x) + $ => B :MLOAD(sparseMulAFp12BN254_b12_y) + A :MSTORE(sparseMulAFp6BN254_b2_x) + B :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(sparseMulAFp12BN254_a1b1mul1_x) + B :MSTORE(sparseMulAFp12BN254_a1b1mul1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(sparseMulAFp12BN254_a1b1mul2_x) + B :MSTORE(sparseMulAFp12BN254_a1b1mul2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(sparseMulAFp12BN254_a1b1mul3_x) + B :MSTORE(sparseMulAFp12BN254_a1b1mul3_y) + + $ => A :MLOAD(sparseMulAFp12BN254_a21_x) + $ => B :MLOAD(sparseMulAFp12BN254_a21_y) + A :MSTORE(sparseMulBFp6BN254_a1_x) + B :MSTORE(sparseMulBFp6BN254_a1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a22_x) + $ => B :MLOAD(sparseMulAFp12BN254_a22_y) + A :MSTORE(sparseMulBFp6BN254_a2_x) + B :MSTORE(sparseMulBFp6BN254_a2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a23_x) + $ => B :MLOAD(sparseMulAFp12BN254_a23_y) + A :MSTORE(sparseMulBFp6BN254_a3_x) + B :MSTORE(sparseMulBFp6BN254_a3_y) + $ => A :MLOAD(sparseMulAFp12BN254_b22_x) + $ => B :MLOAD(sparseMulAFp12BN254_b22_y) + A :MSTORE(sparseMulBFp6BN254_b2_x) + B :MSTORE(sparseMulBFp6BN254_b2_y) + $ => A :MLOAD(sparseMulAFp12BN254_b23_x) + $ => B :MLOAD(sparseMulAFp12BN254_b23_y) + A :MSTORE(sparseMulBFp6BN254_b3_x) + B :MSTORE(sparseMulBFp6BN254_b3_y), CALL(sparseMulBFp6BN254) + $ => A :MLOAD(sparseMulBFp6BN254_c1_x) + $ => B :MLOAD(sparseMulBFp6BN254_c1_y) + A :MSTORE(sparseMulAFp12BN254_a2b2mul1_x) + B :MSTORE(sparseMulAFp12BN254_a2b2mul1_y) + $ => A :MLOAD(sparseMulBFp6BN254_c2_x) + $ => B :MLOAD(sparseMulBFp6BN254_c2_y) + A :MSTORE(sparseMulAFp12BN254_a2b2mul2_x) + B :MSTORE(sparseMulAFp12BN254_a2b2mul2_y) + $ => A :MLOAD(sparseMulBFp6BN254_c3_x) + $ => B :MLOAD(sparseMulBFp6BN254_c3_y) + A :MSTORE(sparseMulAFp12BN254_a2b2mul3_x) + B :MSTORE(sparseMulAFp12BN254_a2b2mul3_y) + + ; 2] c1 = a1·b1 + a2·b2·v + $ => A :MLOAD(sparseMulAFp12BN254_a2b2mul1_x) + $ => B :MLOAD(sparseMulAFp12BN254_a2b2mul1_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a2b2mul2_x) + $ => B :MLOAD(sparseMulAFp12BN254_a2b2mul2_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a2b2mul3_x) + $ => B :MLOAD(sparseMulAFp12BN254_a2b2mul3_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + 1n :MSTORE(sparseMulAFp6BN254_b2_x) + 0n :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + $ => A :MLOAD(sparseMulAFp12BN254_a1b1mul1_x) + $ => B :MLOAD(sparseMulAFp12BN254_a1b1mul1_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a1b1mul2_x) + $ => B :MLOAD(sparseMulAFp12BN254_a1b1mul2_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a1b1mul3_x) + $ => B :MLOAD(sparseMulAFp12BN254_a1b1mul3_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(sparseMulAFp12BN254_c11_x) + B :MSTORE(sparseMulAFp12BN254_c11_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(sparseMulAFp12BN254_c12_x) + B :MSTORE(sparseMulAFp12BN254_c12_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(sparseMulAFp12BN254_c13_x) + B :MSTORE(sparseMulAFp12BN254_c13_y) + + ; 3] aux = (b12+b22)·v + b23·v² + $ => A :MLOAD(sparseMulAFp12BN254_b12_x) + $ => B :MLOAD(sparseMulAFp12BN254_b12_y) + $ => C :MLOAD(sparseMulAFp12BN254_b22_x) + $ => D :MLOAD(sparseMulAFp12BN254_b22_y), CALL(addFp2BN254) + E :MSTORE(sparseMulAFp12BN254_aux2_x) + C :MSTORE(sparseMulAFp12BN254_aux2_y) + + ; 4] c2 = (a1+a2)·aux - a1·b1 - a2·b2 + $ => A :MLOAD(sparseMulAFp12BN254_a11_x) + $ => B :MLOAD(sparseMulAFp12BN254_a11_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a12_x) + $ => B :MLOAD(sparseMulAFp12BN254_a12_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a13_x) + $ => B :MLOAD(sparseMulAFp12BN254_a13_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + $ => A :MLOAD(sparseMulAFp12BN254_a21_x) + $ => B :MLOAD(sparseMulAFp12BN254_a21_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a22_x) + $ => B :MLOAD(sparseMulAFp12BN254_a22_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a23_x) + $ => B :MLOAD(sparseMulAFp12BN254_a23_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(sparseMulBFp6BN254_a1_x) + B :MSTORE(sparseMulBFp6BN254_a1_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(sparseMulBFp6BN254_a2_x) + B :MSTORE(sparseMulBFp6BN254_a2_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(sparseMulBFp6BN254_a3_x) + B :MSTORE(sparseMulBFp6BN254_a3_y) + $ => A :MLOAD(sparseMulAFp12BN254_aux2_x) + $ => B :MLOAD(sparseMulAFp12BN254_aux2_y) + A :MSTORE(sparseMulBFp6BN254_b2_x) + B :MSTORE(sparseMulBFp6BN254_b2_y) + $ => A :MLOAD(sparseMulAFp12BN254_b23_x) + $ => B :MLOAD(sparseMulAFp12BN254_b23_y) + A :MSTORE(sparseMulBFp6BN254_b3_x) + B :MSTORE(sparseMulBFp6BN254_b3_y), CALL(sparseMulBFp6BN254) + $ => A :MLOAD(sparseMulBFp6BN254_c1_x) + $ => B :MLOAD(sparseMulBFp6BN254_c1_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(sparseMulBFp6BN254_c2_x) + $ => B :MLOAD(sparseMulBFp6BN254_c2_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(sparseMulBFp6BN254_c3_x) + $ => B :MLOAD(sparseMulBFp6BN254_c3_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + $ => A :MLOAD(sparseMulAFp12BN254_a1b1mul1_x) + $ => B :MLOAD(sparseMulAFp12BN254_a1b1mul1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a1b1mul2_x) + $ => B :MLOAD(sparseMulAFp12BN254_a1b1mul2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a1b1mul3_x) + $ => B :MLOAD(sparseMulAFp12BN254_a1b1mul3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + $ => A :MLOAD(sparseMulAFp12BN254_a2b2mul1_x) + $ => B :MLOAD(sparseMulAFp12BN254_a2b2mul1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(sparseMulAFp12BN254_a2b2mul2_x) + $ => B :MLOAD(sparseMulAFp12BN254_a2b2mul2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(sparseMulAFp12BN254_a2b2mul3_x) + $ => B :MLOAD(sparseMulAFp12BN254_a2b2mul3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(sparseMulAFp12BN254_c21_x) + B :MSTORE(sparseMulAFp12BN254_c21_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(sparseMulAFp12BN254_c22_x) + B :MSTORE(sparseMulAFp12BN254_c22_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(sparseMulAFp12BN254_c23_x) + B :MSTORE(sparseMulAFp12BN254_c23_y) + + $ => RR :MLOAD(sparseMulAFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm b/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm new file mode 100644 index 00000000..751ab5a3 --- /dev/null +++ b/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm @@ -0,0 +1,290 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; sparseMulBFp12BN254: +;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai ∈ Fp6, b1 = b11 + b13·v² and b2 = b22·v, with b11,b13,b22 ∈ Fp2 +;; out: (a1 + a2·w)·(b1 + b2·w) = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = a1·b1 + a2·b2·v +;; - c2 = (a1+a2)·(b11 + b22·v + b13·v²) - a1·b1 - a2·b2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL sparseMulBFp12BN254_a11_x +VAR GLOBAL sparseMulBFp12BN254_a11_y +VAR GLOBAL sparseMulBFp12BN254_a12_x +VAR GLOBAL sparseMulBFp12BN254_a12_y +VAR GLOBAL sparseMulBFp12BN254_a13_x +VAR GLOBAL sparseMulBFp12BN254_a13_y +VAR GLOBAL sparseMulBFp12BN254_a21_x +VAR GLOBAL sparseMulBFp12BN254_a21_y +VAR GLOBAL sparseMulBFp12BN254_a22_x +VAR GLOBAL sparseMulBFp12BN254_a22_y +VAR GLOBAL sparseMulBFp12BN254_a23_x +VAR GLOBAL sparseMulBFp12BN254_a23_y + +VAR GLOBAL sparseMulBFp12BN254_b11_x +VAR GLOBAL sparseMulBFp12BN254_b11_y +VAR GLOBAL sparseMulBFp12BN254_b13_x +VAR GLOBAL sparseMulBFp12BN254_b13_y +VAR GLOBAL sparseMulBFp12BN254_b22_x +VAR GLOBAL sparseMulBFp12BN254_b22_y + +VAR GLOBAL sparseMulBFp12BN254_c11_x +VAR GLOBAL sparseMulBFp12BN254_c11_y +VAR GLOBAL sparseMulBFp12BN254_c12_x +VAR GLOBAL sparseMulBFp12BN254_c12_y +VAR GLOBAL sparseMulBFp12BN254_c13_x +VAR GLOBAL sparseMulBFp12BN254_c13_y +VAR GLOBAL sparseMulBFp12BN254_c21_x +VAR GLOBAL sparseMulBFp12BN254_c21_y +VAR GLOBAL sparseMulBFp12BN254_c22_x +VAR GLOBAL sparseMulBFp12BN254_c22_y +VAR GLOBAL sparseMulBFp12BN254_c23_x +VAR GLOBAL sparseMulBFp12BN254_c23_y + +VAR GLOBAL sparseMulBFp12BN254_a1b1mul1_x +VAR GLOBAL sparseMulBFp12BN254_a1b1mul1_y +VAR GLOBAL sparseMulBFp12BN254_a1b1mul2_x +VAR GLOBAL sparseMulBFp12BN254_a1b1mul2_y +VAR GLOBAL sparseMulBFp12BN254_a1b1mul3_x +VAR GLOBAL sparseMulBFp12BN254_a1b1mul3_y +VAR GLOBAL sparseMulBFp12BN254_a2b2mul1_x +VAR GLOBAL sparseMulBFp12BN254_a2b2mul1_y +VAR GLOBAL sparseMulBFp12BN254_a2b2mul2_x +VAR GLOBAL sparseMulBFp12BN254_a2b2mul2_y +VAR GLOBAL sparseMulBFp12BN254_a2b2mul3_x +VAR GLOBAL sparseMulBFp12BN254_a2b2mul3_y + +VAR GLOBAL sparseMulBFp12BN254_RR + +sparseMulBFp12BN254: + RR :MSTORE(sparseMulBFp12BN254_RR) + + ; 1] a1·b1, a2·b2 + $ => A :MLOAD(sparseMulBFp12BN254_a11_x) + $ => B :MLOAD(sparseMulBFp12BN254_a11_y) + A :MSTORE(sparseMulCFp6BN254_a1_x) + B :MSTORE(sparseMulCFp6BN254_a1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a12_x) + $ => B :MLOAD(sparseMulBFp12BN254_a12_y) + A :MSTORE(sparseMulCFp6BN254_a2_x) + B :MSTORE(sparseMulCFp6BN254_a2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a13_x) + $ => B :MLOAD(sparseMulBFp12BN254_a13_y) + A :MSTORE(sparseMulCFp6BN254_a3_x) + B :MSTORE(sparseMulCFp6BN254_a3_y) + $ => A :MLOAD(sparseMulBFp12BN254_b11_x) + $ => B :MLOAD(sparseMulBFp12BN254_b11_y) + A :MSTORE(sparseMulCFp6BN254_b1_x) + B :MSTORE(sparseMulCFp6BN254_b1_y) + $ => A :MLOAD(sparseMulBFp12BN254_b13_x) + $ => B :MLOAD(sparseMulBFp12BN254_b13_y) + A :MSTORE(sparseMulCFp6BN254_b3_x) + B :MSTORE(sparseMulCFp6BN254_b3_y), CALL(sparseMulCFp6BN254) + $ => A :MLOAD(sparseMulCFp6BN254_c1_x) + $ => B :MLOAD(sparseMulCFp6BN254_c1_y) + A :MSTORE(sparseMulBFp12BN254_a1b1mul1_x) + B :MSTORE(sparseMulBFp12BN254_a1b1mul1_y) + $ => A :MLOAD(sparseMulCFp6BN254_c2_x) + $ => B :MLOAD(sparseMulCFp6BN254_c2_y) + A :MSTORE(sparseMulBFp12BN254_a1b1mul2_x) + B :MSTORE(sparseMulBFp12BN254_a1b1mul2_y) + $ => A :MLOAD(sparseMulCFp6BN254_c3_x) + $ => B :MLOAD(sparseMulCFp6BN254_c3_y) + A :MSTORE(sparseMulBFp12BN254_a1b1mul3_x) + B :MSTORE(sparseMulBFp12BN254_a1b1mul3_y) + + $ => A :MLOAD(sparseMulBFp12BN254_a21_x) + $ => B :MLOAD(sparseMulBFp12BN254_a21_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a22_x) + $ => B :MLOAD(sparseMulBFp12BN254_a22_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a23_x) + $ => B :MLOAD(sparseMulBFp12BN254_a23_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + $ => A :MLOAD(sparseMulBFp12BN254_b22_x) + $ => B :MLOAD(sparseMulBFp12BN254_b22_y) + A :MSTORE(sparseMulAFp6BN254_b2_x) + B :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(sparseMulBFp12BN254_a2b2mul1_x) + B :MSTORE(sparseMulBFp12BN254_a2b2mul1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(sparseMulBFp12BN254_a2b2mul2_x) + B :MSTORE(sparseMulBFp12BN254_a2b2mul2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(sparseMulBFp12BN254_a2b2mul3_x) + B :MSTORE(sparseMulBFp12BN254_a2b2mul3_y) + + ; 2] c1 = a1·b1 + a2·b2·v + $ => A :MLOAD(sparseMulBFp12BN254_a2b2mul1_x) + $ => B :MLOAD(sparseMulBFp12BN254_a2b2mul1_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a2b2mul2_x) + $ => B :MLOAD(sparseMulBFp12BN254_a2b2mul2_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a2b2mul3_x) + $ => B :MLOAD(sparseMulBFp12BN254_a2b2mul3_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + 1n :MSTORE(sparseMulAFp6BN254_b2_x) + 0n :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + $ => A :MLOAD(sparseMulBFp12BN254_a1b1mul1_x) + $ => B :MLOAD(sparseMulBFp12BN254_a1b1mul1_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a1b1mul2_x) + $ => B :MLOAD(sparseMulBFp12BN254_a1b1mul2_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a1b1mul3_x) + $ => B :MLOAD(sparseMulBFp12BN254_a1b1mul3_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(sparseMulBFp12BN254_c11_x) + B :MSTORE(sparseMulBFp12BN254_c11_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(sparseMulBFp12BN254_c12_x) + B :MSTORE(sparseMulBFp12BN254_c12_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(sparseMulBFp12BN254_c13_x) + B :MSTORE(sparseMulBFp12BN254_c13_y) + + ; aux = b11 + b22·v + b13·v² + + ; 3] c2 = (a1+a2)·aux - a1·b1 - a2·b2 + $ => A :MLOAD(sparseMulBFp12BN254_a11_x) + $ => B :MLOAD(sparseMulBFp12BN254_a11_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a12_x) + $ => B :MLOAD(sparseMulBFp12BN254_a12_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a13_x) + $ => B :MLOAD(sparseMulBFp12BN254_a13_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + $ => A :MLOAD(sparseMulBFp12BN254_a21_x) + $ => B :MLOAD(sparseMulBFp12BN254_a21_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a22_x) + $ => B :MLOAD(sparseMulBFp12BN254_a22_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a23_x) + $ => B :MLOAD(sparseMulBFp12BN254_a23_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(mulFp6BN254_a1_x) + B :MSTORE(mulFp6BN254_a1_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(mulFp6BN254_a2_x) + B :MSTORE(mulFp6BN254_a2_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(mulFp6BN254_a3_x) + B :MSTORE(mulFp6BN254_a3_y) + $ => A :MLOAD(sparseMulBFp12BN254_b11_x) + $ => B :MLOAD(sparseMulBFp12BN254_b11_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(sparseMulBFp12BN254_b22_x) + $ => B :MLOAD(sparseMulBFp12BN254_b22_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(sparseMulBFp12BN254_b13_x) + $ => B :MLOAD(sparseMulBFp12BN254_b13_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + $ => A :MLOAD(sparseMulBFp12BN254_a1b1mul1_x) + $ => B :MLOAD(sparseMulBFp12BN254_a1b1mul1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a1b1mul2_x) + $ => B :MLOAD(sparseMulBFp12BN254_a1b1mul2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a1b1mul3_x) + $ => B :MLOAD(sparseMulBFp12BN254_a1b1mul3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + $ => A :MLOAD(sparseMulBFp12BN254_a2b2mul1_x) + $ => B :MLOAD(sparseMulBFp12BN254_a2b2mul1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(sparseMulBFp12BN254_a2b2mul2_x) + $ => B :MLOAD(sparseMulBFp12BN254_a2b2mul2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(sparseMulBFp12BN254_a2b2mul3_x) + $ => B :MLOAD(sparseMulBFp12BN254_a2b2mul3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(sparseMulBFp12BN254_c21_x) + B :MSTORE(sparseMulBFp12BN254_c21_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(sparseMulBFp12BN254_c22_x) + B :MSTORE(sparseMulBFp12BN254_c22_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(sparseMulBFp12BN254_c23_x) + B :MSTORE(sparseMulBFp12BN254_c23_y) + + $ => RR :MLOAD(sparseMulBFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/squareFp12BN254.zkasm b/main/pairings/FP12BN254/squareFp12BN254.zkasm new file mode 100644 index 00000000..7d351abd --- /dev/null +++ b/main/pairings/FP12BN254/squareFp12BN254.zkasm @@ -0,0 +1,375 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squareFp12BN254: +;; in: (a1 + a2·w) ∈ Fp12, where ai ∈ Fp6 +;; out: (a1 + a2·w)² = (c1 + c2·w) ∈ Fp12, where: +;; - c1 = (a1-a2)·(a1-a2·v) + a1·a2 + a1·a2·v +;; - c2 = 2·a1·a2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL squareFp12BN254_a11_x +VAR GLOBAL squareFp12BN254_a11_y +VAR GLOBAL squareFp12BN254_a12_x +VAR GLOBAL squareFp12BN254_a12_y +VAR GLOBAL squareFp12BN254_a13_x +VAR GLOBAL squareFp12BN254_a13_y +VAR GLOBAL squareFp12BN254_a21_x +VAR GLOBAL squareFp12BN254_a21_y +VAR GLOBAL squareFp12BN254_a22_x +VAR GLOBAL squareFp12BN254_a22_y +VAR GLOBAL squareFp12BN254_a23_x +VAR GLOBAL squareFp12BN254_a23_y +VAR GLOBAL squareFp12BN254_c11_x +VAR GLOBAL squareFp12BN254_c11_y +VAR GLOBAL squareFp12BN254_c12_x +VAR GLOBAL squareFp12BN254_c12_y +VAR GLOBAL squareFp12BN254_c13_x +VAR GLOBAL squareFp12BN254_c13_y +VAR GLOBAL squareFp12BN254_c21_x +VAR GLOBAL squareFp12BN254_c21_y +VAR GLOBAL squareFp12BN254_c22_x +VAR GLOBAL squareFp12BN254_c22_y +VAR GLOBAL squareFp12BN254_c23_x +VAR GLOBAL squareFp12BN254_c23_y + +VAR GLOBAL squareFp12BN254_a1a2mul1_x +VAR GLOBAL squareFp12BN254_a1a2mul1_y +VAR GLOBAL squareFp12BN254_a1a2mul2_x +VAR GLOBAL squareFp12BN254_a1a2mul2_y +VAR GLOBAL squareFp12BN254_a1a2mul3_x +VAR GLOBAL squareFp12BN254_a1a2mul3_y + +VAR GLOBAL squareFp12BN254_a2vmul1_x +VAR GLOBAL squareFp12BN254_a2vmul1_y +VAR GLOBAL squareFp12BN254_a2vmul2_x +VAR GLOBAL squareFp12BN254_a2vmul2_y +VAR GLOBAL squareFp12BN254_a2vmul3_x +VAR GLOBAL squareFp12BN254_a2vmul3_y + +VAR GLOBAL squareFp12BN254_a1a2vmul1_x +VAR GLOBAL squareFp12BN254_a1a2vmul1_y +VAR GLOBAL squareFp12BN254_a1a2vmul2_x +VAR GLOBAL squareFp12BN254_a1a2vmul2_y +VAR GLOBAL squareFp12BN254_a1a2vmul3_x +VAR GLOBAL squareFp12BN254_a1a2vmul3_y + +VAR GLOBAL squareFp12BN254_a1a2sub1_x +VAR GLOBAL squareFp12BN254_a1a2sub1_y +VAR GLOBAL squareFp12BN254_a1a2sub2_x +VAR GLOBAL squareFp12BN254_a1a2sub2_y +VAR GLOBAL squareFp12BN254_a1a2sub3_x +VAR GLOBAL squareFp12BN254_a1a2sub3_y +VAR GLOBAL squareFp12BN254_a1a2vsub1_x +VAR GLOBAL squareFp12BN254_a1a2vsub1_y +VAR GLOBAL squareFp12BN254_a1a2vsub2_x +VAR GLOBAL squareFp12BN254_a1a2vsub2_y +VAR GLOBAL squareFp12BN254_a1a2vsub3_x +VAR GLOBAL squareFp12BN254_a1a2vsub3_y + +VAR GLOBAL squareFp12BN254_RR + +squareFp12BN254: + RR :MSTORE(squareFp12BN254_RR) + + ; 1] a1·a2 + $ => A :MLOAD(squareFp12BN254_a11_x) + $ => B :MLOAD(squareFp12BN254_a11_y) + A :MSTORE(mulFp6BN254_a1_x) + B :MSTORE(mulFp6BN254_a1_y) + $ => A :MLOAD(squareFp12BN254_a12_x) + $ => B :MLOAD(squareFp12BN254_a12_y) + A :MSTORE(mulFp6BN254_a2_x) + B :MSTORE(mulFp6BN254_a2_y) + $ => A :MLOAD(squareFp12BN254_a13_x) + $ => B :MLOAD(squareFp12BN254_a13_y) + A :MSTORE(mulFp6BN254_a3_x) + B :MSTORE(mulFp6BN254_a3_y) + + $ => A :MLOAD(squareFp12BN254_a21_x) + $ => B :MLOAD(squareFp12BN254_a21_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(squareFp12BN254_a22_x) + $ => B :MLOAD(squareFp12BN254_a22_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(squareFp12BN254_a23_x) + $ => B :MLOAD(squareFp12BN254_a23_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(squareFp12BN254_a1a2mul1_x) + B :MSTORE(squareFp12BN254_a1a2mul1_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(squareFp12BN254_a1a2mul2_x) + B :MSTORE(squareFp12BN254_a1a2mul2_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(squareFp12BN254_a1a2mul3_x) + B :MSTORE(squareFp12BN254_a1a2mul3_y) + + ; 2] a2·v + $ => A :MLOAD(squareFp12BN254_a21_x) + $ => B :MLOAD(squareFp12BN254_a21_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(squareFp12BN254_a22_x) + $ => B :MLOAD(squareFp12BN254_a22_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(squareFp12BN254_a23_x) + $ => B :MLOAD(squareFp12BN254_a23_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + + 1n :MSTORE(sparseMulAFp6BN254_b2_x) + 0n :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(squareFp12BN254_a2vmul1_x) + B :MSTORE(squareFp12BN254_a2vmul1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(squareFp12BN254_a2vmul2_x) + B :MSTORE(squareFp12BN254_a2vmul2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(squareFp12BN254_a2vmul3_x) + B :MSTORE(squareFp12BN254_a2vmul3_y) + + ; 2] a1·a2·v + $ => A :MLOAD(squareFp12BN254_a1a2mul1_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul1_y) + A :MSTORE(sparseMulAFp6BN254_a1_x) + B :MSTORE(sparseMulAFp6BN254_a1_y) + $ => A :MLOAD(squareFp12BN254_a1a2mul2_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul2_y) + A :MSTORE(sparseMulAFp6BN254_a2_x) + B :MSTORE(sparseMulAFp6BN254_a2_y) + $ => A :MLOAD(squareFp12BN254_a1a2mul3_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul3_y) + A :MSTORE(sparseMulAFp6BN254_a3_x) + B :MSTORE(sparseMulAFp6BN254_a3_y) + + 1n :MSTORE(sparseMulAFp6BN254_b2_x) + 0n :MSTORE(sparseMulAFp6BN254_b2_y), CALL(sparseMulAFp6BN254) + $ => A :MLOAD(sparseMulAFp6BN254_c1_x) + $ => B :MLOAD(sparseMulAFp6BN254_c1_y) + A :MSTORE(squareFp12BN254_a1a2vmul1_x) + B :MSTORE(squareFp12BN254_a1a2vmul1_y) + $ => A :MLOAD(sparseMulAFp6BN254_c2_x) + $ => B :MLOAD(sparseMulAFp6BN254_c2_y) + A :MSTORE(squareFp12BN254_a1a2vmul2_x) + B :MSTORE(squareFp12BN254_a1a2vmul2_y) + $ => A :MLOAD(sparseMulAFp6BN254_c3_x) + $ => B :MLOAD(sparseMulAFp6BN254_c3_y) + A :MSTORE(squareFp12BN254_a1a2vmul3_x) + B :MSTORE(squareFp12BN254_a1a2vmul3_y) + + ; 3] c2 = 2·a1·a2 + $ => A :MLOAD(squareFp12BN254_a1a2mul1_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul1_y) + A :MSTORE(escalarMulFp6BN254_a1_x) + B :MSTORE(escalarMulFp6BN254_a1_y) + $ => A :MLOAD(squareFp12BN254_a1a2mul2_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul2_y) + A :MSTORE(escalarMulFp6BN254_a2_x) + B :MSTORE(escalarMulFp6BN254_a2_y) + $ => A :MLOAD(squareFp12BN254_a1a2mul3_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul3_y) + A :MSTORE(escalarMulFp6BN254_a3_x) + B :MSTORE(escalarMulFp6BN254_a3_y) + + 2n :MSTORE(escalarMulFp6BN254_b), CALL(escalarMulFp6BN254) + $ => A :MLOAD(escalarMulFp6BN254_c1_x) + $ => B :MLOAD(escalarMulFp6BN254_c1_y) + A :MSTORE(squareFp12BN254_c21_x) + B :MSTORE(squareFp12BN254_c21_y) + $ => A :MLOAD(escalarMulFp6BN254_c2_x) + $ => B :MLOAD(escalarMulFp6BN254_c2_y) + A :MSTORE(squareFp12BN254_c22_x) + B :MSTORE(squareFp12BN254_c22_y) + $ => A :MLOAD(escalarMulFp6BN254_c3_x) + $ => B :MLOAD(escalarMulFp6BN254_c3_y) + A :MSTORE(squareFp12BN254_c23_x) + B :MSTORE(squareFp12BN254_c23_y) + + ; 4] a1-a2 + $ => A :MLOAD(squareFp12BN254_a11_x) + $ => B :MLOAD(squareFp12BN254_a11_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(squareFp12BN254_a12_x) + $ => B :MLOAD(squareFp12BN254_a12_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(squareFp12BN254_a13_x) + $ => B :MLOAD(squareFp12BN254_a13_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + + $ => A :MLOAD(squareFp12BN254_a21_x) + $ => B :MLOAD(squareFp12BN254_a21_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(squareFp12BN254_a22_x) + $ => B :MLOAD(squareFp12BN254_a22_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(squareFp12BN254_a23_x) + $ => B :MLOAD(squareFp12BN254_a23_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(squareFp12BN254_a1a2sub1_x) + B :MSTORE(squareFp12BN254_a1a2sub1_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(squareFp12BN254_a1a2sub2_x) + B :MSTORE(squareFp12BN254_a1a2sub2_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(squareFp12BN254_a1a2sub3_x) + B :MSTORE(squareFp12BN254_a1a2sub3_y) + + + ; 5] a1-a2·v + $ => A :MLOAD(squareFp12BN254_a11_x) + $ => B :MLOAD(squareFp12BN254_a11_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(squareFp12BN254_a12_x) + $ => B :MLOAD(squareFp12BN254_a12_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(squareFp12BN254_a13_x) + $ => B :MLOAD(squareFp12BN254_a13_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + + $ => A :MLOAD(squareFp12BN254_a2vmul1_x) + $ => B :MLOAD(squareFp12BN254_a2vmul1_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(squareFp12BN254_a2vmul2_x) + $ => B :MLOAD(squareFp12BN254_a2vmul2_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(squareFp12BN254_a2vmul3_x) + $ => B :MLOAD(squareFp12BN254_a2vmul3_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(squareFp12BN254_a1a2vsub1_x) + B :MSTORE(squareFp12BN254_a1a2vsub1_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(squareFp12BN254_a1a2vsub2_x) + B :MSTORE(squareFp12BN254_a1a2vsub2_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(squareFp12BN254_a1a2vsub3_x) + B :MSTORE(squareFp12BN254_a1a2vsub3_y) + + ; 7] c1 = (a1-a2)·(a1-a2·v) + a1·a2 + a1·a2·v + $ => A :MLOAD(squareFp12BN254_a1a2sub1_x) + $ => B :MLOAD(squareFp12BN254_a1a2sub1_y) + A :MSTORE(mulFp6BN254_a1_x) + B :MSTORE(mulFp6BN254_a1_y) + $ => A :MLOAD(squareFp12BN254_a1a2sub2_x) + $ => B :MLOAD(squareFp12BN254_a1a2sub2_y) + A :MSTORE(mulFp6BN254_a2_x) + B :MSTORE(mulFp6BN254_a2_y) + $ => A :MLOAD(squareFp12BN254_a1a2sub3_x) + $ => B :MLOAD(squareFp12BN254_a1a2sub3_y) + A :MSTORE(mulFp6BN254_a3_x) + B :MSTORE(mulFp6BN254_a3_y) + + + $ => A :MLOAD(squareFp12BN254_a1a2vsub1_x) + $ => B :MLOAD(squareFp12BN254_a1a2vsub1_y) + A :MSTORE(mulFp6BN254_b1_x) + B :MSTORE(mulFp6BN254_b1_y) + $ => A :MLOAD(squareFp12BN254_a1a2vsub2_x) + $ => B :MLOAD(squareFp12BN254_a1a2vsub2_y) + A :MSTORE(mulFp6BN254_b2_x) + B :MSTORE(mulFp6BN254_b2_y) + $ => A :MLOAD(squareFp12BN254_a1a2vsub3_x) + $ => B :MLOAD(squareFp12BN254_a1a2vsub3_y) + A :MSTORE(mulFp6BN254_b3_x) + B :MSTORE(mulFp6BN254_b3_y), CALL(mulFp6BN254) + + $ => A :MLOAD(mulFp6BN254_c1_x) + $ => B :MLOAD(mulFp6BN254_c1_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(mulFp6BN254_c2_x) + $ => B :MLOAD(mulFp6BN254_c2_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(mulFp6BN254_c3_x) + $ => B :MLOAD(mulFp6BN254_c3_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + + $ => A :MLOAD(squareFp12BN254_a1a2mul1_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul1_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(squareFp12BN254_a1a2mul2_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul2_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(squareFp12BN254_a1a2mul3_x) + $ => B :MLOAD(squareFp12BN254_a1a2mul3_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + + $ => A :MLOAD(squareFp12BN254_a1a2vmul1_x) + $ => B :MLOAD(squareFp12BN254_a1a2vmul1_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(squareFp12BN254_a1a2vmul2_x) + $ => B :MLOAD(squareFp12BN254_a1a2vmul2_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(squareFp12BN254_a1a2vmul3_x) + $ => B :MLOAD(squareFp12BN254_a1a2vmul3_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(squareFp12BN254_c11_x) + B :MSTORE(squareFp12BN254_c11_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(squareFp12BN254_c12_x) + B :MSTORE(squareFp12BN254_c12_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(squareFp12BN254_c13_x) + B :MSTORE(squareFp12BN254_c13_y) + + $ => RR :MLOAD(squareFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/addFp2BN254.zkasm b/main/pairings/FP2BN254/addFp2BN254.zkasm new file mode 100644 index 00000000..36f61df4 --- /dev/null +++ b/main/pairings/FP2BN254/addFp2BN254.zkasm @@ -0,0 +1,18 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; addFp2BN254: +;; in: (A + B·u), (C + D·u) ∈ Fp2, where A,B,C,D ∈ Fp +;; out: E + C·u = (A + C) + (B + D)·u ∈ Fp2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL addFp2BN254_i + +addFp2BN254: + ; Compute and check the mul + ; A + C = [E] + (q0·BN254_P) + ; B + D = [OP] + (q1·BN254_P) + ${ARITH_BN254_ADDFP2_X(A,B,C,D)} => E + ${ARITH_BN254_ADDFP2_Y(A,B,C,D)} :MSTORE(addFp2BN254_i), ARITH_BN254_ADDFP2 + + $ => C :MLOAD(addFp2BN254_i), RETURN diff --git a/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm b/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm new file mode 100644 index 00000000..867be4f6 --- /dev/null +++ b/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm @@ -0,0 +1,19 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; escalarMulFp2BN254: +;; in: A ∈ Fp, (C + D·u) ∈ Fp2, where C,D ∈ Fp +;; out: E + C·u = (A·C) + (A·D)·u ∈ Fp2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL escalarMulFp2BN254_i + +escalarMulFp2BN254: + ; Compute and check the mul + ; A·C - 0·D = [E] + (q0·BN254_P) + ; A·D + 0·C = [OP] + (q1·BN254_P) + 0n => B + ${ARITH_BN254_MULFP2_X(A,B,C,D)} => E + ${ARITH_BN254_MULFP2_Y(A,B,C,D)} :MSTORE(escalarMulFp2BN254_i), ARITH_BN254_MULFP2 + + $ => C :MLOAD(escalarMulFp2BN254_i), RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/invFp2BN254.zkasm b/main/pairings/FP2BN254/invFp2BN254.zkasm new file mode 100644 index 00000000..4fbd696f --- /dev/null +++ b/main/pairings/FP2BN254/invFp2BN254.zkasm @@ -0,0 +1,17 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; invFp2BN254 +;; in: (A + B·u) ∈ Fp2, where A,B ∈ Fp +;; out: C + D·u = (A·(A² + B²)⁻¹) + (-B·(A² + B²)⁻¹)·u ∈ Fp2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +invFp2BN254: + ; Remember that an element y ∈ Fp2 is the inverse of x ∈ Fp2 if and only if x·y = 1 in Fp2 + ; We therefore check that (A + B·u)·(C + D·u) = 1 + 0·u + ; A·[C] - B·[D] = 1 + (q0·BN254_P) + ; A·[D] + B·[C] = 0 + (q1·BN254_P) + ${fp2InvBN254_x(A,B)} => C + ${fp2InvBN254_y(A,B)} => D + 1n => E + 0n :ARITH_BN254_MULFP2, RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/mulFp2BN254.zkasm b/main/pairings/FP2BN254/mulFp2BN254.zkasm new file mode 100644 index 00000000..dc7981df --- /dev/null +++ b/main/pairings/FP2BN254/mulFp2BN254.zkasm @@ -0,0 +1,18 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; mulFp2BN254: +;; in: (A + B·u), (C + D·u) ∈ Fp2, where A,B,C,D ∈ Fp +;; out: E + C·u = (A·C - B·D) + (A·D + B·C)·u ∈ Fp2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL mulFp2BN254_i + +mulFp2BN254: + ; Compute and check the mul + ; A·C - B·D = [E] + (q0·BN254_P) + ; A·D + B·C = [OP] + (q1·BN254_P) + ${ARITH_BN254_MULFP2_X(A,B,C,D)} => E + ${ARITH_BN254_MULFP2_Y(A,B,C,D)} :MSTORE(mulFp2BN254_i), ARITH_BN254_MULFP2 + + $ => C :MLOAD(mulFp2BN254_i), RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/squareFp2BN254.zkasm b/main/pairings/FP2BN254/squareFp2BN254.zkasm new file mode 100644 index 00000000..ebfda250 --- /dev/null +++ b/main/pairings/FP2BN254/squareFp2BN254.zkasm @@ -0,0 +1,20 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squareFp2BN254: +;; in: (A + B·u) ∈ Fp2, where A,B ∈ Fp +;; out: E + C·u = (A - B)·(A + B) + (2·A·B)·u ∈ Fp2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL squareFp2BN254_i + +squareFp2BN254: + ; Compute and check the squaring + ; A·A - B·B = [E] + (q0·BN254_P) + ; A·B + B·A = [OP] + (q1·BN254_P) + A => C + B => D + ${ARITH_BN254_MULFP2_X(A,B,A,B)} => E + ${ARITH_BN254_MULFP2_Y(A,B,A,B)} :MSTORE(squareFp2BN254_i), ARITH_BN254_MULFP2 + + $ => C :MLOAD(squareFp2BN254_i), RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/subFp2BN254.zkasm b/main/pairings/FP2BN254/subFp2BN254.zkasm new file mode 100644 index 00000000..852a318b --- /dev/null +++ b/main/pairings/FP2BN254/subFp2BN254.zkasm @@ -0,0 +1,18 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; subFp2BN254: +;; in: (A + B·u), (C + D·u) ∈ Fp2, where A,B,C,D ∈ Fp +;; out: E + C·u = (A - C) + (B - D)·u ∈ Fp2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL subFp2BN254_i + +subFp2BN254: + ; Compute and check the mul + ; A - C = [E] + (q0·BN254_P) + ; B - D = [OP] + (q1·BN254_P) + ${ARITH_BN254_SUBFP2_X(A,B,C,D)} => E + ${ARITH_BN254_SUBFP2_Y(A,B,C,D)} :MSTORE(subFp2BN254_i), ARITH_BN254_SUBFP2 + + $ => C :MLOAD(subFp2BN254_i), RETURN diff --git a/main/pairings/FP4BN254/squareFp4BN254.zkasm b/main/pairings/FP4BN254/squareFp4BN254.zkasm new file mode 100644 index 00000000..10940f4f --- /dev/null +++ b/main/pairings/FP4BN254/squareFp4BN254.zkasm @@ -0,0 +1,75 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squareFp4BN254: +;; in: (a1 + a2·V) ∈ Fp4, where ai ∈ Fp2 +;; out: (c1 + c2·V) ∈ Fp4, where: +;; - c1 = a2²·(9 + u) + a1² +;; - c2 = (a1 + a2)² - a1² - a2² +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL squareFp4BN254_a1_x +VAR GLOBAL squareFp4BN254_a1_y +VAR GLOBAL squareFp4BN254_a2_x +VAR GLOBAL squareFp4BN254_a2_y +VAR GLOBAL squareFp4BN254_c1_x +VAR GLOBAL squareFp4BN254_c1_y +VAR GLOBAL squareFp4BN254_c2_x +VAR GLOBAL squareFp4BN254_c2_y + +VAR GLOBAL squareFp4BN254_a1square_x +VAR GLOBAL squareFp4BN254_a1square_y +VAR GLOBAL squareFp4BN254_a2square_x +VAR GLOBAL squareFp4BN254_a2square_y + +VAR GLOBAL squareFp4BN254_RR + +squareFp4BN254: + RR :MSTORE(squareFp4BN254_RR) + + ; 1] a1² + $ => A :MLOAD(squareFp4BN254_a1_x) + $ => B :MLOAD(squareFp4BN254_a1_y), CALL(squareFp2BN254) + E :MSTORE(squareFp4BN254_a1square_x) + C :MSTORE(squareFp4BN254_a1square_y) + + ; 2] a2² + $ => A :MLOAD(squareFp4BN254_a2_x) + $ => B :MLOAD(squareFp4BN254_a2_y), CALL(squareFp2BN254) + E :MSTORE(squareFp4BN254_a2square_x) + C :MSTORE(squareFp4BN254_a2square_y) + + ; 3] c1 = a2²·(9 + u) + a1² + $ => A :MLOAD(squareFp4BN254_a2square_x) + $ => B :MLOAD(squareFp4BN254_a2square_y) + 9n => C + 1n => D :CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareFp4BN254_a1square_x) + $ => D :MLOAD(squareFp4BN254_a1square_y), CALL(addFp2BN254) + E :MSTORE(squareFp4BN254_c1_x) + C :MSTORE(squareFp4BN254_c1_y) + + ; 4] c2 = (a1 + a2)² - a1² - a2² + $ => A :MLOAD(squareFp4BN254_a1_x) + $ => B :MLOAD(squareFp4BN254_a1_y) + $ => C :MLOAD(squareFp4BN254_a2_x) + $ => D :MLOAD(squareFp4BN254_a2_y), CALL(addFp2BN254) + E => A + C => B :CALL(squareFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareFp4BN254_a1square_x) + $ => D :MLOAD(squareFp4BN254_a1square_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(squareFp4BN254_a2square_x) + $ => D :MLOAD(squareFp4BN254_a2square_y), CALL(subFp2BN254) + E :MSTORE(squareFp4BN254_c2_x) + C :MSTORE(squareFp4BN254_c2_y) + + $ => RR :MLOAD(squareFp4BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/addFp6BN254.zkasm b/main/pairings/FP6BN254/addFp6BN254.zkasm new file mode 100644 index 00000000..c4a4a0a5 --- /dev/null +++ b/main/pairings/FP6BN254/addFp6BN254.zkasm @@ -0,0 +1,58 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; addFp6BN254: +;; in: (a1 + a2·v + a3·v²),(b1 + b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) = (a1+b1) + (a2+b2)·v + (a3+b3)·v² ∈ Fp6 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL addFp6BN254_a1_x +VAR GLOBAL addFp6BN254_a1_y +VAR GLOBAL addFp6BN254_a2_x +VAR GLOBAL addFp6BN254_a2_y +VAR GLOBAL addFp6BN254_a3_x +VAR GLOBAL addFp6BN254_a3_y +VAR GLOBAL addFp6BN254_b1_x +VAR GLOBAL addFp6BN254_b1_y +VAR GLOBAL addFp6BN254_b2_x +VAR GLOBAL addFp6BN254_b2_y +VAR GLOBAL addFp6BN254_b3_x +VAR GLOBAL addFp6BN254_b3_y +VAR GLOBAL addFp6BN254_c1_x +VAR GLOBAL addFp6BN254_c1_y +VAR GLOBAL addFp6BN254_c2_x +VAR GLOBAL addFp6BN254_c2_y +VAR GLOBAL addFp6BN254_c3_x +VAR GLOBAL addFp6BN254_c3_y + +VAR GLOBAL addFp6BN254_RR + +addFp6BN254: + RR :MSTORE(addFp6BN254_RR) + + ; 1] c1 = a1+b1 + $ => A :MLOAD(addFp6BN254_a1_x) + $ => B :MLOAD(addFp6BN254_a1_y) + $ => C :MLOAD(addFp6BN254_b1_x) + $ => D :MLOAD(addFp6BN254_b1_y), CALL(addFp2BN254) + E :MSTORE(addFp6BN254_c1_x) + C :MSTORE(addFp6BN254_c1_y) + + ; 2] c2 = a2+b2 + $ => A :MLOAD(addFp6BN254_a2_x) + $ => B :MLOAD(addFp6BN254_a2_y) + $ => C :MLOAD(addFp6BN254_b2_x) + $ => D :MLOAD(addFp6BN254_b2_y), CALL(addFp2BN254) + E :MSTORE(addFp6BN254_c2_x) + C :MSTORE(addFp6BN254_c2_y) + + ; 3] c3 = a3+b3 + $ => A :MLOAD(addFp6BN254_a3_x) + $ => B :MLOAD(addFp6BN254_a3_y) + $ => C :MLOAD(addFp6BN254_b3_x) + $ => D :MLOAD(addFp6BN254_b3_y), CALL(addFp2BN254) + E :MSTORE(addFp6BN254_c3_x) + C :MSTORE(addFp6BN254_c3_y) + + $ => RR :MLOAD(addFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm b/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm new file mode 100644 index 00000000..3e64ca87 --- /dev/null +++ b/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm @@ -0,0 +1,50 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; escalarMulFp6BN254: +;; in: b ∈ Fp, (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) = (a1·b) + (a2·b)·v + (a3·b)·v² ∈ Fp6 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL escalarMulFp6BN254_a1_x +VAR GLOBAL escalarMulFp6BN254_a1_y +VAR GLOBAL escalarMulFp6BN254_a2_x +VAR GLOBAL escalarMulFp6BN254_a2_y +VAR GLOBAL escalarMulFp6BN254_a3_x +VAR GLOBAL escalarMulFp6BN254_a3_y +VAR GLOBAL escalarMulFp6BN254_b +VAR GLOBAL escalarMulFp6BN254_c1_x +VAR GLOBAL escalarMulFp6BN254_c1_y +VAR GLOBAL escalarMulFp6BN254_c2_x +VAR GLOBAL escalarMulFp6BN254_c2_y +VAR GLOBAL escalarMulFp6BN254_c3_x +VAR GLOBAL escalarMulFp6BN254_c3_y + +VAR GLOBAL escalarMulFp6BN254_RR + +escalarMulFp6BN254: + RR :MSTORE(escalarMulFp6BN254_RR) + + ; 1] c1 = a1·b + $ => A :MLOAD(escalarMulFp6BN254_b) + $ => C :MLOAD(escalarMulFp6BN254_a1_x) + $ => D :MLOAD(escalarMulFp6BN254_a1_y), CALL(escalarMulFp2BN254) + E :MSTORE(escalarMulFp6BN254_c1_x) + C :MSTORE(escalarMulFp6BN254_c1_y) + + ; 2] c2 = a2·b + $ => A :MLOAD(escalarMulFp6BN254_b) + $ => C :MLOAD(escalarMulFp6BN254_a2_x) + $ => D :MLOAD(escalarMulFp6BN254_a2_y), CALL(escalarMulFp2BN254) + E :MSTORE(escalarMulFp6BN254_c2_x) + C :MSTORE(escalarMulFp6BN254_c2_y) + + ; 3] c3 = a3·b + $ => A :MLOAD(escalarMulFp6BN254_b) + $ => C :MLOAD(escalarMulFp6BN254_a3_x) + $ => D :MLOAD(escalarMulFp6BN254_a3_y), CALL(escalarMulFp2BN254) + E :MSTORE(escalarMulFp6BN254_c3_x) + C :MSTORE(escalarMulFp6BN254_c3_y) + + $ => RR :MLOAD(escalarMulFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/inverseFp6BN254.zkasm b/main/pairings/FP6BN254/inverseFp6BN254.zkasm new file mode 100644 index 00000000..884bb80b --- /dev/null +++ b/main/pairings/FP6BN254/inverseFp6BN254.zkasm @@ -0,0 +1,207 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; inverseFp6BN254: +;; in: (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) ∈ Fp6, where: +;; - c1 = (a1² - (9 + u)·(a2·a3))·(a1·c1mid + xi·(a3·c2mid + a2·c3mid))⁻¹ +;; - c2 = ((9 + u)·a3² - (a1·a2))·(a1·c1mid + xi·(a3·c2mid + a2·c3mid))⁻¹ +;; - c3 = (a2²-a1·a3)·(a1·c1mid + xi·(a3·c2mid + a2·c3mid))⁻¹ +;; with +;; * c1mid = a1² - (9 + u)·(a2·a3) +;; * c2mid = (9 + u)·a3² - (a1·a2) +;; * c3mid = a2² - (a1·a3) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL inverseFp6BN254_a1_x +VAR GLOBAL inverseFp6BN254_a1_y +VAR GLOBAL inverseFp6BN254_a2_x +VAR GLOBAL inverseFp6BN254_a2_y +VAR GLOBAL inverseFp6BN254_a3_x +VAR GLOBAL inverseFp6BN254_a3_y +VAR GLOBAL inverseFp6BN254_c1_x +VAR GLOBAL inverseFp6BN254_c1_y +VAR GLOBAL inverseFp6BN254_c2_x +VAR GLOBAL inverseFp6BN254_c2_y +VAR GLOBAL inverseFp6BN254_c3_x +VAR GLOBAL inverseFp6BN254_c3_y + +VAR GLOBAL inverseFp6BN254_a1square_x +VAR GLOBAL inverseFp6BN254_a1square_y +VAR GLOBAL inverseFp6BN254_a2square_x +VAR GLOBAL inverseFp6BN254_a2square_y +VAR GLOBAL inverseFp6BN254_a3square_x +VAR GLOBAL inverseFp6BN254_a3square_y +VAR GLOBAL inverseFp6BN254_a1a2mul_x +VAR GLOBAL inverseFp6BN254_a1a2mul_y +VAR GLOBAL inverseFp6BN254_a1a3mul_x +VAR GLOBAL inverseFp6BN254_a1a3mul_y +VAR GLOBAL inverseFp6BN254_a2a3mul_x +VAR GLOBAL inverseFp6BN254_a2a3mul_y +VAR GLOBAL inverseFp6BN254_c1mid_x +VAR GLOBAL inverseFp6BN254_c1mid_y +VAR GLOBAL inverseFp6BN254_c2mid_x +VAR GLOBAL inverseFp6BN254_c2mid_y +VAR GLOBAL inverseFp6BN254_c3mid_x +VAR GLOBAL inverseFp6BN254_c3mid_y +VAR GLOBAL inverseFp6BN254_im_x +VAR GLOBAL inverseFp6BN254_im_y + +VAR GLOBAL inverseFp6BN254_a3c2mid_x +VAR GLOBAL inverseFp6BN254_a3c2mid_y + +VAR GLOBAL inverseFp6BN254_xia2c3mid_x +VAR GLOBAL inverseFp6BN254_xia2c3mid_y +VAR GLOBAL inverseFp6BN254_last_x +VAR GLOBAL inverseFp6BN254_last_y + +VAR GLOBAL inverseFp6BN254_RR + +inverseFp6BN254: + RR :MSTORE(inverseFp6BN254_RR) + + ; 1] a1² + $ => A :MLOAD(inverseFp6BN254_a1_x) + $ => B :MLOAD(inverseFp6BN254_a1_y), CALL(squareFp2BN254) + E :MSTORE(inverseFp6BN254_a1square_x) + C :MSTORE(inverseFp6BN254_a1square_y) + + ; 2] a2² + $ => A :MLOAD(inverseFp6BN254_a2_x) + $ => B :MLOAD(inverseFp6BN254_a2_y), CALL(squareFp2BN254) + E :MSTORE(inverseFp6BN254_a2square_x) + C :MSTORE(inverseFp6BN254_a2square_y) + + ; 3] a3² + $ => A :MLOAD(inverseFp6BN254_a3_x) + $ => B :MLOAD(inverseFp6BN254_a3_y), CALL(squareFp2BN254) + E :MSTORE(inverseFp6BN254_a3square_x) + C :MSTORE(inverseFp6BN254_a3square_y) + + ; 4] a1·a2 + $ => A :MLOAD(inverseFp6BN254_a1_x) + $ => B :MLOAD(inverseFp6BN254_a1_y) + $ => C :MLOAD(inverseFp6BN254_a2_x) + $ => D :MLOAD(inverseFp6BN254_a2_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_a1a2mul_x) + C :MSTORE(inverseFp6BN254_a1a2mul_y) + + ; 5] a1·a3 + $ => A :MLOAD(inverseFp6BN254_a1_x) + $ => B :MLOAD(inverseFp6BN254_a1_y) + $ => C :MLOAD(inverseFp6BN254_a3_x) + $ => D :MLOAD(inverseFp6BN254_a3_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_a1a3mul_x) + C :MSTORE(inverseFp6BN254_a1a3mul_y) + + ; 6] a2·a3 + $ => A :MLOAD(inverseFp6BN254_a2_x) + $ => B :MLOAD(inverseFp6BN254_a2_y) + $ => C :MLOAD(inverseFp6BN254_a3_x) + $ => D :MLOAD(inverseFp6BN254_a3_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_a2a3mul_x) + C :MSTORE(inverseFp6BN254_a2a3mul_y) + + ; 7] c1mid = a1² - (9 + u)·(a2·a3) + 9n => A + 1n => B + $ => C :MLOAD(inverseFp6BN254_a2a3mul_x) + $ => D :MLOAD(inverseFp6BN254_a2a3mul_y), CALL(mulFp2BN254) + $ => A :MLOAD(inverseFp6BN254_a1square_x) + $ => B :MLOAD(inverseFp6BN254_a1square_y) + C => D + E => C :CALL(subFp2BN254) + + E :MSTORE(inverseFp6BN254_c1mid_x) + C :MSTORE(inverseFp6BN254_c1mid_y) + + ; 8] c2mid = (9 + u)·a3² - (a1·a2) + 9n => A + 1n => B + $ => C :MLOAD(inverseFp6BN254_a3square_x) + $ => D :MLOAD(inverseFp6BN254_a3square_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(inverseFp6BN254_a1a2mul_x) + $ => D :MLOAD(inverseFp6BN254_a1a2mul_y), CALL(subFp2BN254) + E :MSTORE(inverseFp6BN254_c2mid_x) + C :MSTORE(inverseFp6BN254_c2mid_y) + + ; 9] c3mid = a2² - (a1·a3) + $ => A :MLOAD(inverseFp6BN254_a2square_x) + $ => B :MLOAD(inverseFp6BN254_a2square_y) + $ => C :MLOAD(inverseFp6BN254_a1a3mul_x) + $ => D :MLOAD(inverseFp6BN254_a1a3mul_y), CALL(subFp2BN254) + E :MSTORE(inverseFp6BN254_c3mid_x) + C :MSTORE(inverseFp6BN254_c3mid_y) + + ; 10] im = a1·c1mid + $ => A :MLOAD(inverseFp6BN254_a1_x) + $ => B :MLOAD(inverseFp6BN254_a1_y) + $ => C :MLOAD(inverseFp6BN254_c1mid_x) + $ => D :MLOAD(inverseFp6BN254_c1mid_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_im_x) + C :MSTORE(inverseFp6BN254_im_y) + + ; 11] last = (im + xi·(a3·c2mid + a2·c3mid))⁻¹ + $ => A :MLOAD(inverseFp6BN254_a3_x) + $ => B :MLOAD(inverseFp6BN254_a3_y) + $ => C :MLOAD(inverseFp6BN254_c2mid_x) + $ => D :MLOAD(inverseFp6BN254_c2mid_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_a3c2mid_x) + C :MSTORE(inverseFp6BN254_a3c2mid_y) + + $ => A :MLOAD(inverseFp6BN254_a2_x) + $ => B :MLOAD(inverseFp6BN254_a2_y) + $ => C :MLOAD(inverseFp6BN254_c3mid_x) + $ => D :MLOAD(inverseFp6BN254_c3mid_y), CALL(mulFp2BN254) + + $ => A :MLOAD(inverseFp6BN254_a3c2mid_x) + $ => B :MLOAD(inverseFp6BN254_a3c2mid_y) + C => D + E => C :CALL(addFp2BN254) + + 9n => A + 1n => B + C => D + E => C :CALL(mulFp2BN254) + + $ => A :MLOAD(inverseFp6BN254_im_x) + $ => B :MLOAD(inverseFp6BN254_im_y) + C => D + E => C :CALL(addFp2BN254) + + E => A + C => B + $ => C :MLOAD(inverseFp6BN254_xia2c3mid_x) + $ => D :MLOAD(inverseFp6BN254_xia2c3mid_y), CALL(addFp2BN254) + E => A + C => B :CALL(invFp2BN254) + + C :MSTORE(inverseFp6BN254_last_x) + D :MSTORE(inverseFp6BN254_last_y) + + ; 12] c1 = c1mid·last, c2 = c2mid·last, c3 = c3mid·last + $ => A :MLOAD(inverseFp6BN254_c1mid_x) + $ => B :MLOAD(inverseFp6BN254_c1mid_y) + $ => C :MLOAD(inverseFp6BN254_last_x) + $ => D :MLOAD(inverseFp6BN254_last_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_c1_x) + C :MSTORE(inverseFp6BN254_c1_y) + + $ => A :MLOAD(inverseFp6BN254_c2mid_x) + $ => B :MLOAD(inverseFp6BN254_c2mid_y) + $ => C :MLOAD(inverseFp6BN254_last_x) + $ => D :MLOAD(inverseFp6BN254_last_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_c2_x) + C :MSTORE(inverseFp6BN254_c2_y) + + $ => A :MLOAD(inverseFp6BN254_c3mid_x) + $ => B :MLOAD(inverseFp6BN254_c3mid_y) + $ => C :MLOAD(inverseFp6BN254_last_x) + $ => D :MLOAD(inverseFp6BN254_last_y), CALL(mulFp2BN254) + E :MSTORE(inverseFp6BN254_c3_x) + C :MSTORE(inverseFp6BN254_c3_y) + + $ => RR :MLOAD(inverseFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/mulFp6BN254.zkasm b/main/pairings/FP6BN254/mulFp6BN254.zkasm new file mode 100644 index 00000000..6469c823 --- /dev/null +++ b/main/pairings/FP6BN254/mulFp6BN254.zkasm @@ -0,0 +1,200 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; mulFp6BN254: +;; in: (a1 + a2·v + a3·v²),(b1 + b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) ∈ Fp6, where: +;; - c1 = [(a2+a3)·(b2+b3) - a2·b2 - a3·b3]·(9+u) + a1·b1 +;; - c2 = (a1+a2)·(b1+b2) - a1·b1 - a2·b2 + (9+u)·(a3·b3) +;; - c3 = (a1+a3)·(b1+b3) - a1·b1 + a2·b2 - a3·b3 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL mulFp6BN254_a1_x +VAR GLOBAL mulFp6BN254_a1_y +VAR GLOBAL mulFp6BN254_a2_x +VAR GLOBAL mulFp6BN254_a2_y +VAR GLOBAL mulFp6BN254_a3_x +VAR GLOBAL mulFp6BN254_a3_y +VAR GLOBAL mulFp6BN254_b1_x +VAR GLOBAL mulFp6BN254_b1_y +VAR GLOBAL mulFp6BN254_b2_x +VAR GLOBAL mulFp6BN254_b2_y +VAR GLOBAL mulFp6BN254_b3_x +VAR GLOBAL mulFp6BN254_b3_y +VAR GLOBAL mulFp6BN254_c1_x +VAR GLOBAL mulFp6BN254_c1_y +VAR GLOBAL mulFp6BN254_c2_x +VAR GLOBAL mulFp6BN254_c2_y +VAR GLOBAL mulFp6BN254_c3_x +VAR GLOBAL mulFp6BN254_c3_y + +VAR GLOBAL mulFp6BN254_a1b1mul_x +VAR GLOBAL mulFp6BN254_a1b1mul_y +VAR GLOBAL mulFp6BN254_a2b2mul_x +VAR GLOBAL mulFp6BN254_a2b2mul_y +VAR GLOBAL mulFp6BN254_a3b3mul_x +VAR GLOBAL mulFp6BN254_a3b3mul_y +VAR GLOBAL mulFp6BN254_a3b3ximul_x +VAR GLOBAL mulFp6BN254_a3b3ximul_y + +VAR GLOBAL mulFp6BN254_a2a3sum_x +VAR GLOBAL mulFp6BN254_a2a3sum_y +VAR GLOBAL mulFp6BN254_b2b3sum_x +VAR GLOBAL mulFp6BN254_b2b3sum_y +VAR GLOBAL mulFp6BN254_a1a2sum_x +VAR GLOBAL mulFp6BN254_a1a2sum_y +VAR GLOBAL mulFp6BN254_b1b2sum_x +VAR GLOBAL mulFp6BN254_b1b2sum_y +VAR GLOBAL mulFp6BN254_a1a3sum_x +VAR GLOBAL mulFp6BN254_a1a3sum_y +VAR GLOBAL mulFp6BN254_b1b3sum_x +VAR GLOBAL mulFp6BN254_b1b3sum_y + +VAR GLOBAL mulFp6BN254_RR + +mulFp6BN254: + RR :MSTORE(mulFp6BN254_RR) + + ; 1] a1·b1, a2·b2, a3·b3, a3·b3·(9+u) + $ => A :MLOAD(mulFp6BN254_a1_x) + $ => B :MLOAD(mulFp6BN254_a1_y) + $ => C :MLOAD(mulFp6BN254_b1_x) + $ => D :MLOAD(mulFp6BN254_b1_y), CALL(mulFp2BN254) + E :MSTORE(mulFp6BN254_a1b1mul_x) + C :MSTORE(mulFp6BN254_a1b1mul_y) + + $ => A :MLOAD(mulFp6BN254_a2_x) + $ => B :MLOAD(mulFp6BN254_a2_y) + $ => C :MLOAD(mulFp6BN254_b2_x) + $ => D :MLOAD(mulFp6BN254_b2_y), CALL(mulFp2BN254) + E :MSTORE(mulFp6BN254_a2b2mul_x) + C :MSTORE(mulFp6BN254_a2b2mul_y) + + $ => A :MLOAD(mulFp6BN254_a3_x) + $ => B :MLOAD(mulFp6BN254_a3_y) + $ => C :MLOAD(mulFp6BN254_b3_x) + $ => D :MLOAD(mulFp6BN254_b3_y), CALL(mulFp2BN254) + E :MSTORE(mulFp6BN254_a3b3mul_x) + C :MSTORE(mulFp6BN254_a3b3mul_y) + + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + + E :MSTORE(mulFp6BN254_a3b3ximul_x) + C :MSTORE(mulFp6BN254_a3b3ximul_y) + + ; 2] a2+a3, b2+b3, a1+a2, b1+b2, a1+a3, b1+b3 + $ => A :MLOAD(mulFp6BN254_a2_x) + $ => B :MLOAD(mulFp6BN254_a2_y) + $ => C :MLOAD(mulFp6BN254_a3_x) + $ => D :MLOAD(mulFp6BN254_a3_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_a2a3sum_x) + C :MSTORE(mulFp6BN254_a2a3sum_y) + + $ => A :MLOAD(mulFp6BN254_b2_x) + $ => B :MLOAD(mulFp6BN254_b2_y) + $ => C :MLOAD(mulFp6BN254_b3_x) + $ => D :MLOAD(mulFp6BN254_b3_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_b2b3sum_x) + C :MSTORE(mulFp6BN254_b2b3sum_y) + + $ => A :MLOAD(mulFp6BN254_a1_x) + $ => B :MLOAD(mulFp6BN254_a1_y) + $ => C :MLOAD(mulFp6BN254_a2_x) + $ => D :MLOAD(mulFp6BN254_a2_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_a1a2sum_x) + C :MSTORE(mulFp6BN254_a1a2sum_y) + + $ => A :MLOAD(mulFp6BN254_b1_x) + $ => B :MLOAD(mulFp6BN254_b1_y) + $ => C :MLOAD(mulFp6BN254_b2_x) + $ => D :MLOAD(mulFp6BN254_b2_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_b1b2sum_x) + C :MSTORE(mulFp6BN254_b1b2sum_y) + + $ => A :MLOAD(mulFp6BN254_a1_x) + $ => B :MLOAD(mulFp6BN254_a1_y) + $ => C :MLOAD(mulFp6BN254_a3_x) + $ => D :MLOAD(mulFp6BN254_a3_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_a1a3sum_x) + C :MSTORE(mulFp6BN254_a1a3sum_y) + + $ => A :MLOAD(mulFp6BN254_b1_x) + $ => B :MLOAD(mulFp6BN254_b1_y) + $ => C :MLOAD(mulFp6BN254_b3_x) + $ => D :MLOAD(mulFp6BN254_b3_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_b1b3sum_x) + C :MSTORE(mulFp6BN254_b1b3sum_y) + + ; 3] c1 + $ => A :MLOAD(mulFp6BN254_a2a3sum_x) + $ => B :MLOAD(mulFp6BN254_a2a3sum_y) + $ => C :MLOAD(mulFp6BN254_b2b3sum_x) + $ => D :MLOAD(mulFp6BN254_b2b3sum_y), CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a2b2mul_x) + $ => D :MLOAD(mulFp6BN254_a2b2mul_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a3b3mul_x) + $ => D :MLOAD(mulFp6BN254_a3b3mul_y), CALL(subFp2BN254) + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a1b1mul_x) + $ => D :MLOAD(mulFp6BN254_a1b1mul_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_c1_x) + C :MSTORE(mulFp6BN254_c1_y) + + ; 4] c2 + $ => A :MLOAD(mulFp6BN254_a1a2sum_x) + $ => B :MLOAD(mulFp6BN254_a1a2sum_y) + $ => C :MLOAD(mulFp6BN254_b1b2sum_x) + $ => D :MLOAD(mulFp6BN254_b1b2sum_y), CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a1b1mul_x) + $ => D :MLOAD(mulFp6BN254_a1b1mul_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a2b2mul_x) + $ => D :MLOAD(mulFp6BN254_a2b2mul_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a3b3ximul_x) + $ => D :MLOAD(mulFp6BN254_a3b3ximul_y), CALL(addFp2BN254) + E :MSTORE(mulFp6BN254_c2_x) + C :MSTORE(mulFp6BN254_c2_y) + + ; 5] c3 + $ => A :MLOAD(mulFp6BN254_a1a3sum_x) + $ => B :MLOAD(mulFp6BN254_a1a3sum_y) + $ => C :MLOAD(mulFp6BN254_b1b3sum_x) + $ => D :MLOAD(mulFp6BN254_b1b3sum_y), CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a1b1mul_x) + $ => D :MLOAD(mulFp6BN254_a1b1mul_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a2b2mul_x) + $ => D :MLOAD(mulFp6BN254_a2b2mul_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(mulFp6BN254_a3b3mul_x) + $ => D :MLOAD(mulFp6BN254_a3b3mul_y), CALL(subFp2BN254) + E :MSTORE(mulFp6BN254_c3_x) + C :MSTORE(mulFp6BN254_c3_y) + + $ => RR :MLOAD(mulFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm new file mode 100644 index 00000000..10379a90 --- /dev/null +++ b/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm @@ -0,0 +1,64 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; sparseMulAFp6BN254: +;; in: (a1 + a2·v + a3·v²),b2·v ∈ Fp6, where ai,b2 ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) ∈ Fp6, where: +;; - c1 = b2·a3·(9+u) +;; - c2 = b2·a1 +;; - c3 = b2·a2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL sparseMulAFp6BN254_a1_x +VAR GLOBAL sparseMulAFp6BN254_a1_y +VAR GLOBAL sparseMulAFp6BN254_a2_x +VAR GLOBAL sparseMulAFp6BN254_a2_y +VAR GLOBAL sparseMulAFp6BN254_a3_x +VAR GLOBAL sparseMulAFp6BN254_a3_y + +VAR GLOBAL sparseMulAFp6BN254_b2_x +VAR GLOBAL sparseMulAFp6BN254_b2_y + +VAR GLOBAL sparseMulAFp6BN254_c1_x +VAR GLOBAL sparseMulAFp6BN254_c1_y +VAR GLOBAL sparseMulAFp6BN254_c2_x +VAR GLOBAL sparseMulAFp6BN254_c2_y +VAR GLOBAL sparseMulAFp6BN254_c3_x +VAR GLOBAL sparseMulAFp6BN254_c3_y + +VAR GLOBAL sparseMulAFp6BN254_RR + +sparseMulAFp6BN254: + RR :MSTORE(sparseMulAFp6BN254_RR) + + ; 1] c1 = b2·a3·(9+u) + $ => A :MLOAD(sparseMulAFp6BN254_b2_x) + $ => B :MLOAD(sparseMulAFp6BN254_b2_y) + $ => C :MLOAD(sparseMulAFp6BN254_a3_x) + $ => D :MLOAD(sparseMulAFp6BN254_a3_y), CALL(mulFp2BN254) + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + + E :MSTORE(sparseMulAFp6BN254_c1_x) + C :MSTORE(sparseMulAFp6BN254_c1_y) + + ; 2] c2 = b2·a1 + $ => A :MLOAD(sparseMulAFp6BN254_b2_x) + $ => B :MLOAD(sparseMulAFp6BN254_b2_y) + $ => C :MLOAD(sparseMulAFp6BN254_a1_x) + $ => D :MLOAD(sparseMulAFp6BN254_a1_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulAFp6BN254_c2_x) + C :MSTORE(sparseMulAFp6BN254_c2_y) + + ; 3] c3 = b2·a2 + $ => A :MLOAD(sparseMulAFp6BN254_b2_x) + $ => B :MLOAD(sparseMulAFp6BN254_b2_y) + $ => C :MLOAD(sparseMulAFp6BN254_a2_x) + $ => D :MLOAD(sparseMulAFp6BN254_a2_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulAFp6BN254_c3_x) + C :MSTORE(sparseMulAFp6BN254_c3_y) + + $ => RR :MLOAD(sparseMulAFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm new file mode 100644 index 00000000..094e7b32 --- /dev/null +++ b/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm @@ -0,0 +1,133 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; sparseMulBFp6BN254: +;; in: (a1 + a2·v + a3·v²),(b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) ∈ Fp6, where: +;; - c1 = [(a2 + a3)·(b2 + b3) - a2·b2 - a3·b3]·(9+u) +;; - c2 = a1·b2 + a3·b3·(9+u) +;; - c3 = (a1 + a3)·b3 - a3·b3 + a2·b2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL sparseMulBFp6BN254_a1_x +VAR GLOBAL sparseMulBFp6BN254_a1_y +VAR GLOBAL sparseMulBFp6BN254_a2_x +VAR GLOBAL sparseMulBFp6BN254_a2_y +VAR GLOBAL sparseMulBFp6BN254_a3_x +VAR GLOBAL sparseMulBFp6BN254_a3_y + +VAR GLOBAL sparseMulBFp6BN254_b2_x +VAR GLOBAL sparseMulBFp6BN254_b2_y +VAR GLOBAL sparseMulBFp6BN254_b3_x +VAR GLOBAL sparseMulBFp6BN254_b3_y + +VAR GLOBAL sparseMulBFp6BN254_c1_x +VAR GLOBAL sparseMulBFp6BN254_c1_y +VAR GLOBAL sparseMulBFp6BN254_c2_x +VAR GLOBAL sparseMulBFp6BN254_c2_y +VAR GLOBAL sparseMulBFp6BN254_c3_x +VAR GLOBAL sparseMulBFp6BN254_c3_y + +VAR GLOBAL sparseMulBFp6BN254_a2b2_x +VAR GLOBAL sparseMulBFp6BN254_a2b2_y +VAR GLOBAL sparseMulBFp6BN254_a3b3_x +VAR GLOBAL sparseMulBFp6BN254_a3b3_y +VAR GLOBAL sparseMulBFp6BN254_a2a3sum_x +VAR GLOBAL sparseMulBFp6BN254_a2a3sum_y +VAR GLOBAL sparseMulBFp6BN254_a1b2_x +VAR GLOBAL sparseMulBFp6BN254_a1b2_y + +VAR GLOBAL sparseMulBFp6BN254_RR + +sparseMulBFp6BN254: + RR :MSTORE(sparseMulBFp6BN254_RR) + + ; 1] a2·b2, a3·b3 + $ => A :MLOAD(sparseMulBFp6BN254_a2_x) + $ => B :MLOAD(sparseMulBFp6BN254_a2_y) + $ => C :MLOAD(sparseMulBFp6BN254_b2_x) + $ => D :MLOAD(sparseMulBFp6BN254_b2_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulBFp6BN254_a2b2_x) + C :MSTORE(sparseMulBFp6BN254_a2b2_y) + + $ => A :MLOAD(sparseMulBFp6BN254_a3_x) + $ => B :MLOAD(sparseMulBFp6BN254_a3_y) + $ => C :MLOAD(sparseMulBFp6BN254_b3_x) + $ => D :MLOAD(sparseMulBFp6BN254_b3_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulBFp6BN254_a3b3_x) + C :MSTORE(sparseMulBFp6BN254_a3b3_y) + + ; 2] c1 = ((a2 + a3)·(b2 + b3) - a2·b2 - a3·b3)·(9+u) + $ => A :MLOAD(sparseMulBFp6BN254_a2_x) + $ => B :MLOAD(sparseMulBFp6BN254_a2_y) + $ => C :MLOAD(sparseMulBFp6BN254_a3_x) + $ => D :MLOAD(sparseMulBFp6BN254_a3_y), CALL(addFp2BN254) + E :MSTORE(sparseMulBFp6BN254_a2a3sum_x) + C :MSTORE(sparseMulBFp6BN254_a2a3sum_y) + + $ => A :MLOAD(sparseMulBFp6BN254_b2_x) + $ => B :MLOAD(sparseMulBFp6BN254_b2_y) + $ => C :MLOAD(sparseMulBFp6BN254_b3_x) + $ => D :MLOAD(sparseMulBFp6BN254_b3_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulBFp6BN254_a2a3sum_x) + $ => D :MLOAD(sparseMulBFp6BN254_a2a3sum_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulBFp6BN254_a2b2_x) + $ => D :MLOAD(sparseMulBFp6BN254_a2b2_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulBFp6BN254_a3b3_x) + $ => D :MLOAD(sparseMulBFp6BN254_a3b3_y), CALL(subFp2BN254) + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + + E :MSTORE(sparseMulBFp6BN254_c1_x) + C :MSTORE(sparseMulBFp6BN254_c1_y) + + ; 3] c2 = a1·b2 + a3·b3·(9+u) + $ => A :MLOAD(sparseMulBFp6BN254_a1_x) + $ => B :MLOAD(sparseMulBFp6BN254_a1_y) + $ => C :MLOAD(sparseMulBFp6BN254_b2_x) + $ => D :MLOAD(sparseMulBFp6BN254_b2_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulBFp6BN254_a1b2_x) + C :MSTORE(sparseMulBFp6BN254_a1b2_y) + + $ => A :MLOAD(sparseMulBFp6BN254_a3b3_x) + $ => B :MLOAD(sparseMulBFp6BN254_a3b3_y) + 9n => C + 1n => D :CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(sparseMulBFp6BN254_a1b2_x) + $ => D :MLOAD(sparseMulBFp6BN254_a1b2_y), CALL(addFp2BN254) + E :MSTORE(sparseMulBFp6BN254_c2_x) + C :MSTORE(sparseMulBFp6BN254_c2_y) + + ; 4] c3 = (a1 + a3)·b3 - a3·b3 + a2·b2 + $ => A :MLOAD(sparseMulBFp6BN254_a1_x) + $ => B :MLOAD(sparseMulBFp6BN254_a1_y) + $ => C :MLOAD(sparseMulBFp6BN254_a3_x) + $ => D :MLOAD(sparseMulBFp6BN254_a3_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulBFp6BN254_b3_x) + $ => D :MLOAD(sparseMulBFp6BN254_b3_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulBFp6BN254_a3b3_x) + $ => D :MLOAD(sparseMulBFp6BN254_a3b3_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulBFp6BN254_a2b2_x) + $ => D :MLOAD(sparseMulBFp6BN254_a2b2_y), CALL(addFp2BN254) + E :MSTORE(sparseMulBFp6BN254_c3_x) + C :MSTORE(sparseMulBFp6BN254_c3_y) + + $ => RR :MLOAD(sparseMulBFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm new file mode 100644 index 00000000..d4246cb6 --- /dev/null +++ b/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm @@ -0,0 +1,127 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; sparseMulCFp6BN254: +;; in: (a1 + a2·v + a3·v²),(b1 + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) ∈ Fp6, where: +;; - c1 = a1·b1 + a2·b3·(9+u) +;; - c2 = a2·b1 + a3·b3·(9+u) +;; - c3 = (a1 + a3)·(b1 + b3) - a1·b1 - a3·b3 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL sparseMulCFp6BN254_a1_x +VAR GLOBAL sparseMulCFp6BN254_a1_y +VAR GLOBAL sparseMulCFp6BN254_a2_x +VAR GLOBAL sparseMulCFp6BN254_a2_y +VAR GLOBAL sparseMulCFp6BN254_a3_x +VAR GLOBAL sparseMulCFp6BN254_a3_y + +VAR GLOBAL sparseMulCFp6BN254_b1_x +VAR GLOBAL sparseMulCFp6BN254_b1_y +VAR GLOBAL sparseMulCFp6BN254_b3_x +VAR GLOBAL sparseMulCFp6BN254_b3_y + +VAR GLOBAL sparseMulCFp6BN254_c1_x +VAR GLOBAL sparseMulCFp6BN254_c1_y +VAR GLOBAL sparseMulCFp6BN254_c2_x +VAR GLOBAL sparseMulCFp6BN254_c2_y +VAR GLOBAL sparseMulCFp6BN254_c3_x +VAR GLOBAL sparseMulCFp6BN254_c3_y + +VAR GLOBAL sparseMulCFp6BN254_a1b1_x +VAR GLOBAL sparseMulCFp6BN254_a1b1_y +VAR GLOBAL sparseMulCFp6BN254_a3b3_x +VAR GLOBAL sparseMulCFp6BN254_a3b3_y +VAR GLOBAL sparseMulCFp6BN254_a2b1_x +VAR GLOBAL sparseMulCFp6BN254_a2b1_y +VAR GLOBAL sparseMulCFp6BN254_a1a3sum_x +VAR GLOBAL sparseMulCFp6BN254_a1a3sum_y + +VAR GLOBAL sparseMulCFp6BN254_RR + +sparseMulCFp6BN254: + RR :MSTORE(sparseMulCFp6BN254_RR) + + ; 1] a1·b1, a3·b3 + $ => A :MLOAD(sparseMulCFp6BN254_a1_x) + $ => B :MLOAD(sparseMulCFp6BN254_a1_y) + $ => C :MLOAD(sparseMulCFp6BN254_b1_x) + $ => D :MLOAD(sparseMulCFp6BN254_b1_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulCFp6BN254_a1b1_x) + C :MSTORE(sparseMulCFp6BN254_a1b1_y) + + $ => A :MLOAD(sparseMulCFp6BN254_a3_x) + $ => B :MLOAD(sparseMulCFp6BN254_a3_y) + $ => C :MLOAD(sparseMulCFp6BN254_b3_x) + $ => D :MLOAD(sparseMulCFp6BN254_b3_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulCFp6BN254_a3b3_x) + C :MSTORE(sparseMulCFp6BN254_a3b3_y) + + ; 2] c1 = a1·b1 + a2·b3·(9+u) + $ => A :MLOAD(sparseMulCFp6BN254_a2_x) + $ => B :MLOAD(sparseMulCFp6BN254_a2_y) + $ => C :MLOAD(sparseMulCFp6BN254_b3_x) + $ => D :MLOAD(sparseMulCFp6BN254_b3_y), CALL(mulFp2BN254) + E => A + C => B + 9n => C + 1n => D :CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(sparseMulCFp6BN254_a1b1_x) + $ => D :MLOAD(sparseMulCFp6BN254_a1b1_y), CALL(addFp2BN254) + E :MSTORE(sparseMulCFp6BN254_c1_x) + C :MSTORE(sparseMulCFp6BN254_c1_y) + + ; 3] c2 = a2·b1 + a3·b3·(9+u) + $ => A :MLOAD(sparseMulCFp6BN254_a2_x) + $ => B :MLOAD(sparseMulCFp6BN254_a2_y) + $ => C :MLOAD(sparseMulCFp6BN254_b1_x) + $ => D :MLOAD(sparseMulCFp6BN254_b1_y), CALL(mulFp2BN254) + E :MSTORE(sparseMulCFp6BN254_a2b1_x) + C :MSTORE(sparseMulCFp6BN254_a2b1_y) + + $ => A :MLOAD(sparseMulCFp6BN254_a3b3_x) + $ => B :MLOAD(sparseMulCFp6BN254_a3b3_y) + 9n => C + 1n => D :CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(sparseMulCFp6BN254_a2b1_x) + $ => D :MLOAD(sparseMulCFp6BN254_a2b1_y), CALL(addFp2BN254) + E :MSTORE(sparseMulCFp6BN254_c2_x) + C :MSTORE(sparseMulCFp6BN254_c2_y) + + + ; 4] c3 = (a1 + a3)·(b1 + b3) - a1·b1 - a3·b3 + $ => A :MLOAD(sparseMulCFp6BN254_a1_x) + $ => B :MLOAD(sparseMulCFp6BN254_a1_y) + $ => C :MLOAD(sparseMulCFp6BN254_a3_x) + $ => D :MLOAD(sparseMulCFp6BN254_a3_y), CALL(addFp2BN254) + E :MSTORE(sparseMulCFp6BN254_a1a3sum_x) + C :MSTORE(sparseMulCFp6BN254_a1a3sum_y) + + $ => A :MLOAD(sparseMulCFp6BN254_b1_x) + $ => B :MLOAD(sparseMulCFp6BN254_b1_y) + $ => C :MLOAD(sparseMulCFp6BN254_b3_x) + $ => D :MLOAD(sparseMulCFp6BN254_b3_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulCFp6BN254_a1a3sum_x) + $ => D :MLOAD(sparseMulCFp6BN254_a1a3sum_y), CALL(mulFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulCFp6BN254_a1b1_x) + $ => D :MLOAD(sparseMulCFp6BN254_a1b1_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(sparseMulCFp6BN254_a3b3_x) + $ => D :MLOAD(sparseMulCFp6BN254_a3b3_y), CALL(subFp2BN254) + E :MSTORE(sparseMulCFp6BN254_c3_x) + C :MSTORE(sparseMulCFp6BN254_c3_y) + + + $ => RR :MLOAD(sparseMulCFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/squareFp6BN254.zkasm b/main/pairings/FP6BN254/squareFp6BN254.zkasm new file mode 100644 index 00000000..4c3e1fd3 --- /dev/null +++ b/main/pairings/FP6BN254/squareFp6BN254.zkasm @@ -0,0 +1,146 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squareFp6BN254: +;; in: (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) ∈ Fp6, where: +;; - c1 = 2·a2·a3·(9 + u) + a1² +;; - c2 = a3²·(9 + u) + 2·a1·a2 +;; - c3 = 2·a1·a2 - a3² + (a1 - a2 + a3)² + 2·a2·a3 - a1² +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL squareFp6BN254_a1_x +VAR GLOBAL squareFp6BN254_a1_y +VAR GLOBAL squareFp6BN254_a2_x +VAR GLOBAL squareFp6BN254_a2_y +VAR GLOBAL squareFp6BN254_a3_x +VAR GLOBAL squareFp6BN254_a3_y +VAR GLOBAL squareFp6BN254_c1_x +VAR GLOBAL squareFp6BN254_c1_y +VAR GLOBAL squareFp6BN254_c2_x +VAR GLOBAL squareFp6BN254_c2_y +VAR GLOBAL squareFp6BN254_c3_x +VAR GLOBAL squareFp6BN254_c3_y + +VAR GLOBAL squareFp6BN254_2a1a2mul_x +VAR GLOBAL squareFp6BN254_2a1a2mul_y +VAR GLOBAL squareFp6BN254_a3square_x +VAR GLOBAL squareFp6BN254_a3square_y +VAR GLOBAL squareFp6BN254_2a1a2a3sqsub_x +VAR GLOBAL squareFp6BN254_2a1a2a3sqsub_y +VAR GLOBAL squareFp6BN254_a1square_x +VAR GLOBAL squareFp6BN254_a1square_y +VAR GLOBAL squareFp6BN254_a1a2a3sub_x +VAR GLOBAL squareFp6BN254_a1a2a3sub_y +VAR GLOBAL squareFp6BN254_2a2a3mul_x +VAR GLOBAL squareFp6BN254_2a2a3mul_y + +VAR GLOBAL squareFp6BN254_RR + +squareFp6BN254: + RR :MSTORE(squareFp6BN254_RR) + + ; 1] 2·a1·a2 + $ => A :MLOAD(squareFp6BN254_a1_x) + $ => B :MLOAD(squareFp6BN254_a1_y) + $ => C :MLOAD(squareFp6BN254_a2_x) + $ => D :MLOAD(squareFp6BN254_a2_y), CALL(mulFp2BN254) + 2n => A + C => D + E => C :CALL(escalarMulFp2BN254) + + E :MSTORE(squareFp6BN254_2a1a2mul_x) + C :MSTORE(squareFp6BN254_2a1a2mul_y) + + ; 2] a3² + $ => A :MLOAD(squareFp6BN254_a3_x) + $ => B :MLOAD(squareFp6BN254_a3_y), CALL(squareFp2BN254) + E :MSTORE(squareFp6BN254_a3square_x) + C :MSTORE(squareFp6BN254_a3square_y) + + ; 3] c2 = a3²·(9 + u) + 2·a1·a2 + $ => A :MLOAD(squareFp6BN254_a3square_x) + $ => B :MLOAD(squareFp6BN254_a3square_y) + 9n => C + 1n => D :CALL(mulFp2BN254) + + $ => A :MLOAD(squareFp6BN254_2a1a2mul_x) + $ => B :MLOAD(squareFp6BN254_2a1a2mul_y) + C => D + E => C :CALL(addFp2BN254) + + E :MSTORE(squareFp6BN254_c2_x) + C :MSTORE(squareFp6BN254_c2_y) + + ; 4] 2·a1·a2 - a3² + $ => A :MLOAD(squareFp6BN254_2a1a2mul_x) + $ => B :MLOAD(squareFp6BN254_2a1a2mul_y) + $ => C :MLOAD(squareFp6BN254_a3square_x) + $ => D :MLOAD(squareFp6BN254_a3square_y), CALL(subFp2BN254) + E :MSTORE(squareFp6BN254_2a1a2a3sqsub_x) + C :MSTORE(squareFp6BN254_2a1a2a3sqsub_y) + + ; 5] a1² + $ => A :MLOAD(squareFp6BN254_a1_x) + $ => B :MLOAD(squareFp6BN254_a1_y), CALL(squareFp2BN254) + E :MSTORE(squareFp6BN254_a1square_x) + C :MSTORE(squareFp6BN254_a1square_y) + + ; 6] (a1 - a2 + a3)² + $ => A :MLOAD(squareFp6BN254_a1_x) + $ => B :MLOAD(squareFp6BN254_a1_y) + $ => C :MLOAD(squareFp6BN254_a2_x) + $ => D :MLOAD(squareFp6BN254_a2_y), CALL(subFp2BN254) + E => A + C => B + $ => C :MLOAD(squareFp6BN254_a3_x) + $ => D :MLOAD(squareFp6BN254_a3_y), CALL(addFp2BN254) + E => A + C => B :CALL(squareFp2BN254) + + E :MSTORE(squareFp6BN254_a1a2a3sub_x) + C :MSTORE(squareFp6BN254_a1a2a3sub_y) + + ; 7] 2·a2·a3 + $ => A :MLOAD(squareFp6BN254_a2_x) + $ => B :MLOAD(squareFp6BN254_a2_y) + $ => C :MLOAD(squareFp6BN254_a3_x) + $ => D :MLOAD(squareFp6BN254_a3_y), CALL(mulFp2BN254) + 2n => A + C => D + E => C :CALL(escalarMulFp2BN254) + + E :MSTORE(squareFp6BN254_2a2a3mul_x) + C :MSTORE(squareFp6BN254_2a2a3mul_y) + + ; 8] c1 = 2·a2·a3·(9 + u) + a1² + $ => A :MLOAD(squareFp6BN254_2a2a3mul_x) + $ => B :MLOAD(squareFp6BN254_2a2a3mul_y) + 9n => C + 1n => D :CALL(mulFp2BN254) + + E => A + C => B + $ => C :MLOAD(squareFp6BN254_a1square_x) + $ => D :MLOAD(squareFp6BN254_a1square_y), CALL(addFp2BN254) + E :MSTORE(squareFp6BN254_c1_x) + C :MSTORE(squareFp6BN254_c1_y) + + ; 9] c3 = 2·a1·a2 - a3² + (a1 - a2 + a3)² + 2·a2·a3 - a1² + $ => A :MLOAD(squareFp6BN254_2a1a2a3sqsub_x) + $ => B :MLOAD(squareFp6BN254_2a1a2a3sqsub_y) + $ => C :MLOAD(squareFp6BN254_a1a2a3sub_x) + $ => D :MLOAD(squareFp6BN254_a1a2a3sub_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(squareFp6BN254_2a2a3mul_x) + $ => D :MLOAD(squareFp6BN254_2a2a3mul_y), CALL(addFp2BN254) + E => A + C => B + $ => C :MLOAD(squareFp6BN254_a1square_x) + $ => D :MLOAD(squareFp6BN254_a1square_y), CALL(subFp2BN254) + E :MSTORE(squareFp6BN254_c3_x) + C :MSTORE(squareFp6BN254_c3_y) + + $ => RR :MLOAD(squareFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/subFp6BN254.zkasm b/main/pairings/FP6BN254/subFp6BN254.zkasm new file mode 100644 index 00000000..2109d69b --- /dev/null +++ b/main/pairings/FP6BN254/subFp6BN254.zkasm @@ -0,0 +1,58 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; subFp6BN254: +;; in: (a1 + a2·v + a3·v²),(b1 + b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) = (a1-b1) + (a2-b2)·v + (a3-b3)·v² ∈ Fp6 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL subFp6BN254_a1_x +VAR GLOBAL subFp6BN254_a1_y +VAR GLOBAL subFp6BN254_a2_x +VAR GLOBAL subFp6BN254_a2_y +VAR GLOBAL subFp6BN254_a3_x +VAR GLOBAL subFp6BN254_a3_y +VAR GLOBAL subFp6BN254_b1_x +VAR GLOBAL subFp6BN254_b1_y +VAR GLOBAL subFp6BN254_b2_x +VAR GLOBAL subFp6BN254_b2_y +VAR GLOBAL subFp6BN254_b3_x +VAR GLOBAL subFp6BN254_b3_y +VAR GLOBAL subFp6BN254_c1_x +VAR GLOBAL subFp6BN254_c1_y +VAR GLOBAL subFp6BN254_c2_x +VAR GLOBAL subFp6BN254_c2_y +VAR GLOBAL subFp6BN254_c3_x +VAR GLOBAL subFp6BN254_c3_y + +VAR GLOBAL subFp6BN254_RR + +subFp6BN254: + RR :MSTORE(subFp6BN254_RR) + + ; 1] c1 = a1-b1 + $ => A :MLOAD(subFp6BN254_a1_x) + $ => B :MLOAD(subFp6BN254_a1_y) + $ => C :MLOAD(subFp6BN254_b1_x) + $ => D :MLOAD(subFp6BN254_b1_y), CALL(subFp2BN254) + E :MSTORE(subFp6BN254_c1_x) + C :MSTORE(subFp6BN254_c1_y) + + ; 2] c2 = a2-b2 + $ => A :MLOAD(subFp6BN254_a2_x) + $ => B :MLOAD(subFp6BN254_a2_y) + $ => C :MLOAD(subFp6BN254_b2_x) + $ => D :MLOAD(subFp6BN254_b2_y), CALL(subFp2BN254) + E :MSTORE(subFp6BN254_c2_x) + C :MSTORE(subFp6BN254_c2_y) + + ; 3] c3 = a3-b3 + $ => A :MLOAD(subFp6BN254_a3_x) + $ => B :MLOAD(subFp6BN254_a3_y) + $ => C :MLOAD(subFp6BN254_b3_x) + $ => D :MLOAD(subFp6BN254_b3_y), CALL(subFp2BN254) + E :MSTORE(subFp6BN254_c3_x) + C :MSTORE(subFp6BN254_c3_y) + + $ => RR :MLOAD(subFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/addFpBN254.zkasm b/main/pairings/FPBN254/addFpBN254.zkasm new file mode 100644 index 00000000..e347cfc4 --- /dev/null +++ b/main/pairings/FPBN254/addFpBN254.zkasm @@ -0,0 +1,27 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; addFpBN254: +;; in: A,C ∈ Fp +;; out: C = A + C (mod BN254_P) ∈ Fp +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +addFpBN254: + ; 1] Compute and check the sum over Z + ; A·[1] + C = [D]·2²⁵⁶ + [E] + 1 => B + $${var _addFpBN254_AC = A + C} + ${_addFpBN254_AC >> 256} => D + ${_addFpBN254_AC} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; [BN254_P]·[A+C] + [C] = D·2²⁵⁶ + E + ; where C < BN254_P + %BN254_P => A + ${_addFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) + ${_addFpBN254_AC % const.BN254_P} => C ; residue (256 bits) + E :ARITH + + A => B + C => A + 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/invFpBN254.zkasm b/main/pairings/FPBN254/invFpBN254.zkasm new file mode 100644 index 00000000..0d2547e2 --- /dev/null +++ b/main/pairings/FPBN254/invFpBN254.zkasm @@ -0,0 +1,49 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; invFpBN254: +;; in: A ∈ Fp +;; out: B = A⁻¹ (mod BN254_P) ∈ Fp +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL invFpBN254_tmp +VAR GLOBAL invFpBN254_RR + +invFpBN254: + RR :MSTORE(invFpBN254_RR) + + ; If A >= BN254_P, then normalize so that A ∈ [0,BN254_P) + %BN254_P => B + $ :LT, JMPC(invFpBN254_iz_zero) + :CALL(reduceFpBN254) + +invFpBN254_iz_zero: + ; Check if A = 0 + A :JMPZ(invFpBN254_A_is_zero) + +invFpBN254_normalized: + ; 1] Compute and check the inverse over Z + ; A·B + [0] = [D]·2²⁵⁶ + [E] + 0 => C + ${var _invFpBN254_A = fpBN254inv(A)} => B :MSTORE(invFpBN254_tmp); + $${var _invFpBN254_AB = A * _invFpBN254_A} + ${_invFpBN254_AB >> 256} => D + ${_invFpBN254_AB} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; [BN254_P]·[A·A⁻¹] + [1] = D·2²⁵⁶ + E + %BN254_P => A + ${_invFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) + 1n => C ; residue (1 bit) + + E :ARITH + + $ => RR :MLOAD(invFpBN254_RR) + $ => B :MLOAD(invFpBN254_tmp), JMP(invFpBN254_end) + +invFpBN254_A_is_zero: + 0 => B + +invFpBN254_end: + $ => RR :MLOAD(invFpBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/mulFpBN254.zkasm b/main/pairings/FPBN254/mulFpBN254.zkasm new file mode 100644 index 00000000..a5d87e89 --- /dev/null +++ b/main/pairings/FPBN254/mulFpBN254.zkasm @@ -0,0 +1,27 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; mulFpBN254: +;; in: A,B ∈ Fp +;; out: C = A·B (mod BN254_P) ∈ Fp +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +mulFpBN254: + ; 1] Compute and check the sum over Z + ; A·B + [0] = [D]·2²⁵⁶ + [E] + 0 => C + $${var _mulFpBN254_AB = A*B} + ${_mulFpBN254_AB >> 256} => D + ${_mulFpBN254_AB} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; [BN254_P]·[A+C] + [C] = D·2²⁵⁶ + E + ; where C < BN254_P + %BN254_P => A + ${_mulFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) + ${_mulFpBN254_AB % const.BN254_P} => C ; residue (256 bits) + E :ARITH + + A => B + C => A + 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/reduceFpBN254.zkasm b/main/pairings/FPBN254/reduceFpBN254.zkasm new file mode 100644 index 00000000..551fc031 --- /dev/null +++ b/main/pairings/FPBN254/reduceFpBN254.zkasm @@ -0,0 +1,24 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; reduceFpBN254: +;; in: A ∈ [0, 2²⁵⁶-1] +;; out: A (mod BN254_P) ∈ Fp +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL reduceFpBN254_tmp + +reduceFpBN254: + ; 1] It must be satisfied that: + ; [BN254_P]·[A / p] + [A % p] = [0]·2²⁵⁶ + A + A :MSTORE(reduceFpBN254_tmp) + ${A / const.BN254_P} => B ; quotient (256 bits) + ${A % const.BN254_P} => C ; residue (256 bits) + %BN254_P => A + 0n => D + $ :MLOAD(reduceFpBN254_tmp), ARITH + + ; 2] Check the the residue is less than p + A => B + C => A + 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/squareFpBN254.zkasm b/main/pairings/FPBN254/squareFpBN254.zkasm new file mode 100644 index 00000000..f7c9c1ce --- /dev/null +++ b/main/pairings/FPBN254/squareFpBN254.zkasm @@ -0,0 +1,29 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squareFpBN254: +;; in: A ∈ Fp +;; out: B = A² (mod BN254_P) ∈ Fp +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +squareFpBN254: + ; 1] Compute and check the inverse over Z + ; A·A + [0] = [D]·2²⁵⁶ + [E] + A => B + 0 => C + $${var _squareFpBN254_AA = A * A} + ${_squareFpBN254_AA >> 256} => D + ${_squareFpBN254_AA} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; [BN254_P]·[A²] + [C] = D·2²⁵⁶ + E + ; where C < BN254_P + %BN254_P => A + ${_squareFpBN254_AA / const.BN254_P} => B ; quotient (256 bits) + ${_squareFpBN254_AA % const.BN254_P} => C ; residue (256 bits) + E :ARITH + + A => B + C => A + 1 :LT + A => B :RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/subFpBN254.zkasm b/main/pairings/FPBN254/subFpBN254.zkasm new file mode 100644 index 00000000..e36037c3 --- /dev/null +++ b/main/pairings/FPBN254/subFpBN254.zkasm @@ -0,0 +1,28 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; subFpBN254: +;; in: A,C ∈ Fp +;; out: C = A - C (mod BN254_P) ∈ Fp +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +subFpBN254: + ; 1] Compute and check the sub over Z + ; A·[1] + [BN254_P-C] = [D]·2²⁵⁶ + [E] + 1 => B + ${const.BN254_P - C} => C + $${var _subFpBN254_AC = A + C} + ${_subFpBN254_AC >> 256} => D + ${_subFpBN254_AC} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; [BN254_P]·[A+(BN254_P-C)] + [C] = D·2²⁵⁶ + E + ; where C < BN254_P + %BN254_P => A + ${_subFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) + ${_subFpBN254_AC % const.BN254_P} => C ; residue (256 bits) + E :ARITH + + A => B + C => A + 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FRBN254/reduceFrBN254.zkasm b/main/pairings/FRBN254/reduceFrBN254.zkasm new file mode 100644 index 00000000..63530f60 --- /dev/null +++ b/main/pairings/FRBN254/reduceFrBN254.zkasm @@ -0,0 +1,24 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; reduceFrBN254: +;; in: B ∈ [0, 2²⁵⁶-1] +;; out: A = B (mod BN254_R) ∈ Fr +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL reduceFrBN254_tmp + +reduceFrBN254: + ; 1] It must be satisfied that: + ; [BN254_R]·[B / r] + [B % r] = [0]·2²⁵⁶ + E + B :MSTORE(reduceFrBN254_tmp) + ${B % const.BN254_R} => C ; residue (256 bits) + ${B / const.BN254_R} => B ; quotient (256 bits) + %BN254_R => A + 0n => D + $ :MLOAD(reduceFrBN254_tmp), ARITH + + ; 2] Check the the residue is less than r + A => B + C => A + 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/constants.zkasm b/main/pairings/constants.zkasm new file mode 100644 index 00000000..8327fddb --- /dev/null +++ b/main/pairings/constants.zkasm @@ -0,0 +1,62 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Constants of the optimal Ate pairing over the BN254 curve +;; e: G1 x G2 --> GT +;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over (Fp12)^*) over the curves: +;; E/Fp: y² = x³ + 3, E'/Fp2: y² = x³ + 3/(9+u) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Basic constants: X = "BN family parameter", P = "base field order", R = "scalar field order" +CONSTL %BN254_X = 4965661367192848881n ; Unused, just for reference +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n ; 36n * X ** 4n + 36n * X ** 3n + 24n * X ** 2n + 6n * X + 1n +; NOTE: It is satisfied that 5·p < 2²⁵⁶ < 6·p +CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n +CONSTL %BN254_R = 21888242871839275222246405745257275088548364400416034343698204186575808495617n ; 36n * X ** 4n + 36n * X ** 3n + 18n * X ** 2n + 6n * X + 1n +CONSTL %BN254_R_MINUS_ONE = 21888242871839275222246405745257275088548364400416034343698204186575808495616n + +; Precomputed values: 3/(9+u) and 6x² +CONSTL %BN254_E_B = 3n +CONSTL %BN254_ETWISTED_B_X = 19485874751759354771024239261021720505790618469301721065564631296452457478373n +CONSTL %BN254_ETWISTED_B_Y = 266929791119991161246907387137283842545076965332900288569378510910307636690n +CONSTL %BN254_SIX_TIMES_X_SQ = 147946756881789318990833708069417712966n + +; Coordinates of the generator of the group G1 +CONSTL %PAIRING_P1X = 1n +CONSTL %PAIRING_P1Y = 2n + +; Coordinates of the generator of the group G2 +CONSTL %PAIRING_P2X1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781n +CONSTL %PAIRING_P2X2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634n +CONSTL %PAIRING_P2Y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930n +CONSTL %PAIRING_P2Y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531n + +; Precomputed frobenius operator constants. These are used to compute f^p, f^p2 and f^p3 cheaply, where f ∈ Fp12 +; See: https://hackmd.io/kcEJAWISQ56eE6YpBnurgw#Frobenius-Operator +CONSTL %FROBENIUS_GAMMA111 = 8376118865763821496583973867626364092589906065868298776909617916018768340080n +CONSTL %FROBENIUS_GAMMA112 = 16469823323077808223889137241176536799009286646108169935659301613961712198316n +CONSTL %FROBENIUS_GAMMA121 = 21575463638280843010398324269430826099269044274347216827212613867836435027261n +CONSTL %FROBENIUS_GAMMA122 = 10307601595873709700152284273816112264069230130616436755625194854815875713954n +CONSTL %FROBENIUS_GAMMA131 = 2821565182194536844548159561693502659359617185244120367078079554186484126554n +CONSTL %FROBENIUS_GAMMA132 = 3505843767911556378687030309984248845540243509899259641013678093033130930403n +CONSTL %FROBENIUS_GAMMA131_NEGATED = %BN254_P - %FROBENIUS_GAMMA131 +CONSTL %FROBENIUS_GAMMA132_NEGATED = %BN254_P - %FROBENIUS_GAMMA132 +CONSTL %FROBENIUS_GAMMA141 = 2581911344467009335267311115468803099551665605076196740867805258568234346338n +CONSTL %FROBENIUS_GAMMA142 = 19937756971775647987995932169929341994314640652964949448313374472400716661030n +CONSTL %FROBENIUS_GAMMA151 = 685108087231508774477564247770172212460312782337200605669322048753928464687n +CONSTL %FROBENIUS_GAMMA152 = 8447204650696766136447902020341177575205426561248465145919723016860428151883n +CONSTL %FROBENIUS_GAMMA21 = 21888242871839275220042445260109153167277707414472061641714758635765020556617n +CONSTL %FROBENIUS_GAMMA22 = 21888242871839275220042445260109153167277707414472061641714758635765020556616n +CONSTL %FROBENIUS_GAMMA23 = 21888242871839275222246405745257275088696311157297823662689037894645226208582n +CONSTL %FROBENIUS_GAMMA24 = 2203960485148121921418603742825762020974279258880205651966n +CONSTL %FROBENIUS_GAMMA25 = 2203960485148121921418603742825762020974279258880205651967n +CONSTL %FROBENIUS_GAMMA311 = 11697423496358154304825782922584725312912383441159505038794027105778954184319n +CONSTL %FROBENIUS_GAMMA312 = 303847389135065887422783454877609941456349188919719272345083954437860409601n +CONSTL %FROBENIUS_GAMMA321 = 3772000881919853776433695186713858239009073593817195771773381919316419345261n +CONSTL %FROBENIUS_GAMMA322 = 2236595495967245188281701248203181795121068902605861227855261137820944008926n +CONSTL %FROBENIUS_GAMMA331 = 19066677689644738377698246183563772429336693972053703295610958340458742082029n +CONSTL %FROBENIUS_GAMMA332 = 18382399103927718843559375435273026243156067647398564021675359801612095278180n +CONSTL %FROBENIUS_GAMMA341 = 5324479202449903542726783395506214481928257762400643279780343368557297135718n +CONSTL %FROBENIUS_GAMMA342 = 16208900380737693084919495127334387981393726419856888799917914180988844123039n +CONSTL %FROBENIUS_GAMMA351 = 8941241848238582420466759817324047081148088512956452953208002715982955420483n +CONSTL %FROBENIUS_GAMMA352 = 10338197737521362862238855242243140895517409139741313354160881284257516364953n \ No newline at end of file diff --git a/main/pairings/ecPairing.zkasm b/main/pairings/ecPairing.zkasm new file mode 100644 index 00000000..41701079 --- /dev/null +++ b/main/pairings/ecPairing.zkasm @@ -0,0 +1,240 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; ecPairing: +;; input: P1,...,Pn ∈ G1 and Q1,...,Qn ∈ G2, where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and +;; the curves are E/Fp: y² = x³ + 3 and E'/Fp2: y² = x³ + 3/(9+u) +;; output: 1 if e(P1,Q1)·...·e(Pn,Qn) = 1, 0 otherwise; where e: G1 x G2 -> GT is +;; the optimal Ate pairing over the BN254 curve and GT = mu_r (the r-th roots of unity over (Fp12)^*) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL ecPairing_ninputs + +VAR GLOBAL ecPairing_mul_f11_x +VAR GLOBAL ecPairing_mul_f11_y +VAR GLOBAL ecPairing_mul_f12_x +VAR GLOBAL ecPairing_mul_f12_y +VAR GLOBAL ecPairing_mul_f13_x +VAR GLOBAL ecPairing_mul_f13_y +VAR GLOBAL ecPairing_mul_f21_x +VAR GLOBAL ecPairing_mul_f21_y +VAR GLOBAL ecPairing_mul_f22_x +VAR GLOBAL ecPairing_mul_f22_y +VAR GLOBAL ecPairing_mul_f23_x +VAR GLOBAL ecPairing_mul_f23_y + +VAR GLOBAL ecPairing_result + +VAR GLOBAL ecPairing_RR + +; ERROR CODES (B) +; 0 - no error +; 1 - error found in some input + +ecPairing: + RR :MSTORE(ecPairing_RR) + + $ => A :MLOAD(ecPairing_ninputs), JMPZ(ecPairing_0_inputs) + + ; Initialize the multiplication with 1 + 1n :MSTORE(ecPairing_mul_f11_x) + 0n :MSTORE(ecPairing_mul_f11_y) + 0n :MSTORE(ecPairing_mul_f12_x) + 0n :MSTORE(ecPairing_mul_f12_y) + 0n :MSTORE(ecPairing_mul_f13_x) + 0n :MSTORE(ecPairing_mul_f13_y) + 0n :MSTORE(ecPairing_mul_f21_x) + 0n :MSTORE(ecPairing_mul_f21_y) + 0n :MSTORE(ecPairing_mul_f22_x) + 0n :MSTORE(ecPairing_mul_f22_y) + 0n :MSTORE(ecPairing_mul_f23_x) + 0n :MSTORE(ecPairing_mul_f23_y) + + :JMP(ecPairing_Miller_loop) + +ecPairing_0_inputs: + 1 :MSTORE(ecPairing_result) + :JMP(ecPairing_correct) + +ecPairing_Miller_loop: + $ => E :MLOAD(readXFromCalldataOffset) + 32 :MSTORE(readXFromCalldataLength) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(halfPairingBN254_P_x) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(halfPairingBN254_P_y) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(halfPairingBN254_Q_x2) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(halfPairingBN254_Q_x1) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(halfPairingBN254_Q_y2) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(halfPairingBN254_Q_y1), CALL(halfPairingBN254) + + ; Check if the error code (B) of halfPairingBN254 is not 0, meaning there is an error in some of the inputs + B :JMPNZ(ecPairing_input_error) + + ; Multiply the current value of mul by the result of the Miller loop of the current 6-tuple + $ => A :MLOAD(ecPairing_mul_f11_x) + $ => B :MLOAD(ecPairing_mul_f11_y) + $ => C :MLOAD(ecPairing_mul_f12_x) + $ => D :MLOAD(ecPairing_mul_f12_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + C :MSTORE(mulFp12BN254_a12_x) + D :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(ecPairing_mul_f13_x) + $ => B :MLOAD(ecPairing_mul_f13_y) + $ => C :MLOAD(ecPairing_mul_f21_x) + $ => D :MLOAD(ecPairing_mul_f21_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + C :MSTORE(mulFp12BN254_a21_x) + D :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(ecPairing_mul_f22_x) + $ => B :MLOAD(ecPairing_mul_f22_y) + $ => C :MLOAD(ecPairing_mul_f23_x) + $ => D :MLOAD(ecPairing_mul_f23_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + C :MSTORE(mulFp12BN254_a23_x) + D :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(halfPairingBN254_f11_x) + $ => B :MLOAD(halfPairingBN254_f11_y) + $ => C :MLOAD(halfPairingBN254_f12_x) + $ => D :MLOAD(halfPairingBN254_f12_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + C :MSTORE(mulFp12BN254_b12_x) + D :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(halfPairingBN254_f13_x) + $ => B :MLOAD(halfPairingBN254_f13_y) + $ => C :MLOAD(halfPairingBN254_f21_x) + $ => D :MLOAD(halfPairingBN254_f21_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + C :MSTORE(mulFp12BN254_b21_x) + D :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(halfPairingBN254_f22_x) + $ => B :MLOAD(halfPairingBN254_f22_y) + $ => C :MLOAD(halfPairingBN254_f23_x) + $ => D :MLOAD(halfPairingBN254_f23_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + C :MSTORE(mulFp12BN254_b23_x) + D :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + $ => C :MLOAD(mulFp12BN254_c12_x) + $ => D :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(ecPairing_mul_f11_x) + B :MSTORE(ecPairing_mul_f11_y) + C :MSTORE(ecPairing_mul_f12_x) + D :MSTORE(ecPairing_mul_f12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + $ => C :MLOAD(mulFp12BN254_c21_x) + $ => D :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(ecPairing_mul_f13_x) + B :MSTORE(ecPairing_mul_f13_y) + C :MSTORE(ecPairing_mul_f21_x) + D :MSTORE(ecPairing_mul_f21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + $ => C :MLOAD(mulFp12BN254_c23_x) + $ => D :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(ecPairing_mul_f22_x) + B :MSTORE(ecPairing_mul_f22_y) + C :MSTORE(ecPairing_mul_f23_x) + D :MSTORE(ecPairing_mul_f23_y) + + $ => A :MLOAD(ecPairing_ninputs) + A - 1 => A :JMPZ(ecPairing_final_exponentiation) + A :MSTORE(ecPairing_ninputs) + :JMP(ecPairing_Miller_loop) + +ecPairing_final_exponentiation: + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + $ => C :MLOAD(mulFp12BN254_c12_x) + $ => D :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_f11_x) + B :MSTORE(finalExpBN254_f11_y) + C :MSTORE(finalExpBN254_f12_x) + D :MSTORE(finalExpBN254_f12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + $ => C :MLOAD(mulFp12BN254_c21_x) + $ => D :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_f13_x) + B :MSTORE(finalExpBN254_f13_y) + C :MSTORE(finalExpBN254_f21_x) + D :MSTORE(finalExpBN254_f21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + $ => C :MLOAD(mulFp12BN254_c23_x) + $ => D :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_f22_x) + B :MSTORE(finalExpBN254_f22_y) + C :MSTORE(finalExpBN254_f23_x) + D :MSTORE(finalExpBN254_f23_y), CALL(finalExpBN254) + + ; Check whether the result is 1 or not + 1n => B + $ => A :MLOAD(finalExpBN254_f11_x) + $ :EQ, JMPNC(finalExpBN254_result_continue) + 0n => B + $ => A :MLOAD(finalExpBN254_f11_y) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f12_x) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f12_y) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f13_x) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f13_y) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f21_x) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f21_y) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f22_x) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f22_y) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f23_x) + $ :EQ, JMPNC(finalExpBN254_result_continue) + $ => A :MLOAD(finalExpBN254_f23_y) + $ :EQ, JMPC(ecPairing_equation_is_satisfied) + finalExpBN254_result_continue: + + ; the pairing equation is not satisfied, then output 0 + 0 :MSTORE(ecPairing_result) + :JMP(ecPairing_correct) + +ecPairing_equation_is_satisfied: + ; the pairing equation is satisfied, then output 1 + 1 :MSTORE(ecPairing_result) + :JMP(ecPairing_correct) + +; ERRORS +ecPairing_input_error: + 1 => B :JMP(ecPairing_error) + +ecPairing_correct: + 0 => B :JMP(ecPairing_end) + +ecPairing_error: + 0 => A + +ecPairing_end: + $ => RR :MLOAD(ecPairing_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/finalExpBN254.zkasm b/main/pairings/finalExpBN254.zkasm new file mode 100644 index 00000000..dde67154 --- /dev/null +++ b/main/pairings/finalExpBN254.zkasm @@ -0,0 +1,2094 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; finalExpBN254: +;; input: f ∈ Fp12 +;; output: f^((p¹²-1)/r) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL finalExpBN254_f11_x +VAR GLOBAL finalExpBN254_f11_y +VAR GLOBAL finalExpBN254_f12_x +VAR GLOBAL finalExpBN254_f12_y +VAR GLOBAL finalExpBN254_f13_x +VAR GLOBAL finalExpBN254_f13_y +VAR GLOBAL finalExpBN254_f21_x +VAR GLOBAL finalExpBN254_f21_y +VAR GLOBAL finalExpBN254_f22_x +VAR GLOBAL finalExpBN254_f22_y +VAR GLOBAL finalExpBN254_f23_x +VAR GLOBAL finalExpBN254_f23_y + +VAR GLOBAL finalExpBN254_mx11_x +VAR GLOBAL finalExpBN254_mx11_y +VAR GLOBAL finalExpBN254_mx12_x +VAR GLOBAL finalExpBN254_mx12_y +VAR GLOBAL finalExpBN254_mx13_x +VAR GLOBAL finalExpBN254_mx13_y +VAR GLOBAL finalExpBN254_mx21_x +VAR GLOBAL finalExpBN254_mx21_y +VAR GLOBAL finalExpBN254_mx22_x +VAR GLOBAL finalExpBN254_mx22_y +VAR GLOBAL finalExpBN254_mx23_x +VAR GLOBAL finalExpBN254_mx23_y +VAR GLOBAL finalExpBN254_mxx11_x +VAR GLOBAL finalExpBN254_mxx11_y +VAR GLOBAL finalExpBN254_mxx12_x +VAR GLOBAL finalExpBN254_mxx12_y +VAR GLOBAL finalExpBN254_mxx13_x +VAR GLOBAL finalExpBN254_mxx13_y +VAR GLOBAL finalExpBN254_mxx21_x +VAR GLOBAL finalExpBN254_mxx21_y +VAR GLOBAL finalExpBN254_mxx22_x +VAR GLOBAL finalExpBN254_mxx22_y +VAR GLOBAL finalExpBN254_mxx23_x +VAR GLOBAL finalExpBN254_mxx23_y +VAR GLOBAL finalExpBN254_mxxx11_x +VAR GLOBAL finalExpBN254_mxxx11_y +VAR GLOBAL finalExpBN254_mxxx12_x +VAR GLOBAL finalExpBN254_mxxx12_y +VAR GLOBAL finalExpBN254_mxxx13_x +VAR GLOBAL finalExpBN254_mxxx13_y +VAR GLOBAL finalExpBN254_mxxx21_x +VAR GLOBAL finalExpBN254_mxxx21_y +VAR GLOBAL finalExpBN254_mxxx22_x +VAR GLOBAL finalExpBN254_mxxx22_y +VAR GLOBAL finalExpBN254_mxxx23_x +VAR GLOBAL finalExpBN254_mxxx23_y +VAR GLOBAL finalExpBN254_mp11_x +VAR GLOBAL finalExpBN254_mp11_y +VAR GLOBAL finalExpBN254_mp12_x +VAR GLOBAL finalExpBN254_mp12_y +VAR GLOBAL finalExpBN254_mp13_x +VAR GLOBAL finalExpBN254_mp13_y +VAR GLOBAL finalExpBN254_mp21_x +VAR GLOBAL finalExpBN254_mp21_y +VAR GLOBAL finalExpBN254_mp22_x +VAR GLOBAL finalExpBN254_mp22_y +VAR GLOBAL finalExpBN254_mp23_x +VAR GLOBAL finalExpBN254_mp23_y +VAR GLOBAL finalExpBN254_mpp11_x +VAR GLOBAL finalExpBN254_mpp11_y +VAR GLOBAL finalExpBN254_mpp12_x +VAR GLOBAL finalExpBN254_mpp12_y +VAR GLOBAL finalExpBN254_mpp13_x +VAR GLOBAL finalExpBN254_mpp13_y +VAR GLOBAL finalExpBN254_mpp21_x +VAR GLOBAL finalExpBN254_mpp21_y +VAR GLOBAL finalExpBN254_mpp22_x +VAR GLOBAL finalExpBN254_mpp22_y +VAR GLOBAL finalExpBN254_mpp23_x +VAR GLOBAL finalExpBN254_mpp23_y +VAR GLOBAL finalExpBN254_mppp11_x +VAR GLOBAL finalExpBN254_mppp11_y +VAR GLOBAL finalExpBN254_mppp12_x +VAR GLOBAL finalExpBN254_mppp12_y +VAR GLOBAL finalExpBN254_mppp13_x +VAR GLOBAL finalExpBN254_mppp13_y +VAR GLOBAL finalExpBN254_mppp21_x +VAR GLOBAL finalExpBN254_mppp21_y +VAR GLOBAL finalExpBN254_mppp22_x +VAR GLOBAL finalExpBN254_mppp22_y +VAR GLOBAL finalExpBN254_mppp23_x +VAR GLOBAL finalExpBN254_mppp23_y +VAR GLOBAL finalExpBN254_mxp11_x +VAR GLOBAL finalExpBN254_mxp11_y +VAR GLOBAL finalExpBN254_mxp12_x +VAR GLOBAL finalExpBN254_mxp12_y +VAR GLOBAL finalExpBN254_mxp13_x +VAR GLOBAL finalExpBN254_mxp13_y +VAR GLOBAL finalExpBN254_mxp21_x +VAR GLOBAL finalExpBN254_mxp21_y +VAR GLOBAL finalExpBN254_mxp22_x +VAR GLOBAL finalExpBN254_mxp22_y +VAR GLOBAL finalExpBN254_mxp23_x +VAR GLOBAL finalExpBN254_mxp23_y +VAR GLOBAL finalExpBN254_mxxp11_x +VAR GLOBAL finalExpBN254_mxxp11_y +VAR GLOBAL finalExpBN254_mxxp12_x +VAR GLOBAL finalExpBN254_mxxp12_y +VAR GLOBAL finalExpBN254_mxxp13_x +VAR GLOBAL finalExpBN254_mxxp13_y +VAR GLOBAL finalExpBN254_mxxp21_x +VAR GLOBAL finalExpBN254_mxxp21_y +VAR GLOBAL finalExpBN254_mxxp22_x +VAR GLOBAL finalExpBN254_mxxp22_y +VAR GLOBAL finalExpBN254_mxxp23_x +VAR GLOBAL finalExpBN254_mxxp23_y +VAR GLOBAL finalExpBN254_mxxxp11_x +VAR GLOBAL finalExpBN254_mxxxp11_y +VAR GLOBAL finalExpBN254_mxxxp12_x +VAR GLOBAL finalExpBN254_mxxxp12_y +VAR GLOBAL finalExpBN254_mxxxp13_x +VAR GLOBAL finalExpBN254_mxxxp13_y +VAR GLOBAL finalExpBN254_mxxxp21_x +VAR GLOBAL finalExpBN254_mxxxp21_y +VAR GLOBAL finalExpBN254_mxxxp22_x +VAR GLOBAL finalExpBN254_mxxxp22_y +VAR GLOBAL finalExpBN254_mxxxp23_x +VAR GLOBAL finalExpBN254_mxxxp23_y +VAR GLOBAL finalExpBN254_mxxpp11_x +VAR GLOBAL finalExpBN254_mxxpp11_y +VAR GLOBAL finalExpBN254_mxxpp12_x +VAR GLOBAL finalExpBN254_mxxpp12_y +VAR GLOBAL finalExpBN254_mxxpp13_x +VAR GLOBAL finalExpBN254_mxxpp13_y +VAR GLOBAL finalExpBN254_mxxpp21_x +VAR GLOBAL finalExpBN254_mxxpp21_y +VAR GLOBAL finalExpBN254_mxxpp22_x +VAR GLOBAL finalExpBN254_mxxpp22_y +VAR GLOBAL finalExpBN254_mxxpp23_x +VAR GLOBAL finalExpBN254_mxxpp23_y + +VAR GLOBAL finalExpBN254_y1_11_x +VAR GLOBAL finalExpBN254_y1_11_y +VAR GLOBAL finalExpBN254_y1_12_x +VAR GLOBAL finalExpBN254_y1_12_y +VAR GLOBAL finalExpBN254_y1_13_x +VAR GLOBAL finalExpBN254_y1_13_y +VAR GLOBAL finalExpBN254_y1_21_x +VAR GLOBAL finalExpBN254_y1_21_y +VAR GLOBAL finalExpBN254_y1_22_x +VAR GLOBAL finalExpBN254_y1_22_y +VAR GLOBAL finalExpBN254_y1_23_x +VAR GLOBAL finalExpBN254_y1_23_y +VAR GLOBAL finalExpBN254_y2_11_x +VAR GLOBAL finalExpBN254_y2_11_y +VAR GLOBAL finalExpBN254_y2_12_x +VAR GLOBAL finalExpBN254_y2_12_y +VAR GLOBAL finalExpBN254_y2_13_x +VAR GLOBAL finalExpBN254_y2_13_y +VAR GLOBAL finalExpBN254_y2_21_x +VAR GLOBAL finalExpBN254_y2_21_y +VAR GLOBAL finalExpBN254_y2_22_x +VAR GLOBAL finalExpBN254_y2_22_y +VAR GLOBAL finalExpBN254_y2_23_x +VAR GLOBAL finalExpBN254_y2_23_y + +VAR GLOBAL finalExpBN254_y4_11_x +VAR GLOBAL finalExpBN254_y4_11_y +VAR GLOBAL finalExpBN254_y4_12_x +VAR GLOBAL finalExpBN254_y4_12_y +VAR GLOBAL finalExpBN254_y4_13_x +VAR GLOBAL finalExpBN254_y4_13_y +VAR GLOBAL finalExpBN254_y4_21_x +VAR GLOBAL finalExpBN254_y4_21_y +VAR GLOBAL finalExpBN254_y4_22_x +VAR GLOBAL finalExpBN254_y4_22_y +VAR GLOBAL finalExpBN254_y4_23_x +VAR GLOBAL finalExpBN254_y4_23_y +VAR GLOBAL finalExpBN254_y5_11_x +VAR GLOBAL finalExpBN254_y5_11_y +VAR GLOBAL finalExpBN254_y5_12_x +VAR GLOBAL finalExpBN254_y5_12_y +VAR GLOBAL finalExpBN254_y5_13_x +VAR GLOBAL finalExpBN254_y5_13_y +VAR GLOBAL finalExpBN254_y5_21_x +VAR GLOBAL finalExpBN254_y5_21_y +VAR GLOBAL finalExpBN254_y5_22_x +VAR GLOBAL finalExpBN254_y5_22_y +VAR GLOBAL finalExpBN254_y5_23_x +VAR GLOBAL finalExpBN254_y5_23_y +VAR GLOBAL finalExpBN254_y6_11_x +VAR GLOBAL finalExpBN254_y6_11_y +VAR GLOBAL finalExpBN254_y6_12_x +VAR GLOBAL finalExpBN254_y6_12_y +VAR GLOBAL finalExpBN254_y6_13_x +VAR GLOBAL finalExpBN254_y6_13_y +VAR GLOBAL finalExpBN254_y6_21_x +VAR GLOBAL finalExpBN254_y6_21_y +VAR GLOBAL finalExpBN254_y6_22_x +VAR GLOBAL finalExpBN254_y6_22_y +VAR GLOBAL finalExpBN254_y6_23_x +VAR GLOBAL finalExpBN254_y6_23_y +VAR GLOBAL finalExpBN254_y7_11_x +VAR GLOBAL finalExpBN254_y7_11_y +VAR GLOBAL finalExpBN254_y7_12_x +VAR GLOBAL finalExpBN254_y7_12_y +VAR GLOBAL finalExpBN254_y7_13_x +VAR GLOBAL finalExpBN254_y7_13_y +VAR GLOBAL finalExpBN254_y7_21_x +VAR GLOBAL finalExpBN254_y7_21_y +VAR GLOBAL finalExpBN254_y7_22_x +VAR GLOBAL finalExpBN254_y7_22_y +VAR GLOBAL finalExpBN254_y7_23_x +VAR GLOBAL finalExpBN254_y7_23_y + +VAR GLOBAL finalExpBN254_T11_11_x +VAR GLOBAL finalExpBN254_T11_11_y +VAR GLOBAL finalExpBN254_T11_12_x +VAR GLOBAL finalExpBN254_T11_12_y +VAR GLOBAL finalExpBN254_T11_13_x +VAR GLOBAL finalExpBN254_T11_13_y +VAR GLOBAL finalExpBN254_T11_21_x +VAR GLOBAL finalExpBN254_T11_21_y +VAR GLOBAL finalExpBN254_T11_22_x +VAR GLOBAL finalExpBN254_T11_22_y +VAR GLOBAL finalExpBN254_T11_23_x +VAR GLOBAL finalExpBN254_T11_23_y +VAR GLOBAL finalExpBN254_T21_11_x +VAR GLOBAL finalExpBN254_T21_11_y +VAR GLOBAL finalExpBN254_T21_12_x +VAR GLOBAL finalExpBN254_T21_12_y +VAR GLOBAL finalExpBN254_T21_13_x +VAR GLOBAL finalExpBN254_T21_13_y +VAR GLOBAL finalExpBN254_T21_21_x +VAR GLOBAL finalExpBN254_T21_21_y +VAR GLOBAL finalExpBN254_T21_22_x +VAR GLOBAL finalExpBN254_T21_22_y +VAR GLOBAL finalExpBN254_T21_23_x +VAR GLOBAL finalExpBN254_T21_23_y +VAR GLOBAL finalExpBN254_T12_11_x +VAR GLOBAL finalExpBN254_T12_11_y +VAR GLOBAL finalExpBN254_T12_12_x +VAR GLOBAL finalExpBN254_T12_12_y +VAR GLOBAL finalExpBN254_T12_13_x +VAR GLOBAL finalExpBN254_T12_13_y +VAR GLOBAL finalExpBN254_T12_21_x +VAR GLOBAL finalExpBN254_T12_21_y +VAR GLOBAL finalExpBN254_T12_22_x +VAR GLOBAL finalExpBN254_T12_22_y +VAR GLOBAL finalExpBN254_T12_23_x +VAR GLOBAL finalExpBN254_T12_23_y +VAR GLOBAL finalExpBN254_T23_11_x +VAR GLOBAL finalExpBN254_T23_11_y +VAR GLOBAL finalExpBN254_T23_12_x +VAR GLOBAL finalExpBN254_T23_12_y +VAR GLOBAL finalExpBN254_T23_13_x +VAR GLOBAL finalExpBN254_T23_13_y +VAR GLOBAL finalExpBN254_T23_21_x +VAR GLOBAL finalExpBN254_T23_21_y +VAR GLOBAL finalExpBN254_T23_22_x +VAR GLOBAL finalExpBN254_T23_22_y +VAR GLOBAL finalExpBN254_T23_23_x +VAR GLOBAL finalExpBN254_T23_23_y +VAR GLOBAL finalExpBN254_T24_11_x +VAR GLOBAL finalExpBN254_T24_11_y +VAR GLOBAL finalExpBN254_T24_12_x +VAR GLOBAL finalExpBN254_T24_12_y +VAR GLOBAL finalExpBN254_T24_13_x +VAR GLOBAL finalExpBN254_T24_13_y +VAR GLOBAL finalExpBN254_T24_21_x +VAR GLOBAL finalExpBN254_T24_21_y +VAR GLOBAL finalExpBN254_T24_22_x +VAR GLOBAL finalExpBN254_T24_22_y +VAR GLOBAL finalExpBN254_T24_23_x +VAR GLOBAL finalExpBN254_T24_23_y + +VAR GLOBAL finalExpBN254_RR + +finalExpBN254: + RR :MSTORE(finalExpBN254_RR) + + ; The easy part: + ; =========================================== + ; 1] f^(p⁶-1) = f̅·f⁻¹ + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(inverseFp12BN254_a11_x) + B :MSTORE(inverseFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(inverseFp12BN254_a12_x) + B :MSTORE(inverseFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(inverseFp12BN254_a13_x) + B :MSTORE(inverseFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(inverseFp12BN254_a21_x) + B :MSTORE(inverseFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(inverseFp12BN254_a22_x) + B :MSTORE(inverseFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(inverseFp12BN254_a23_x) + B :MSTORE(inverseFp12BN254_a23_y), CALL(inverseFp12BN254) + + $ => A :MLOAD(inverseFp12BN254_c11_x) + $ => B :MLOAD(inverseFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(inverseFp12BN254_c12_x) + $ => B :MLOAD(inverseFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(inverseFp12BN254_c13_x) + $ => B :MLOAD(inverseFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(inverseFp12BN254_c21_x) + $ => B :MLOAD(inverseFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(inverseFp12BN254_c22_x) + $ => B :MLOAD(inverseFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(inverseFp12BN254_c23_x) + $ => B :MLOAD(inverseFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y) + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f21_x) + $ :SUB, MSTORE(mulFp12BN254_a21_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f21_y) + $ :SUB, MSTORE(mulFp12BN254_a21_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f22_x) + $ :SUB, MSTORE(mulFp12BN254_a22_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f22_y) + $ :SUB, MSTORE(mulFp12BN254_a22_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f23_x) + $ :SUB, MSTORE(mulFp12BN254_a23_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f23_y) + $ :SUB, MSTORE(mulFp12BN254_a23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_f11_x) + B :MSTORE(finalExpBN254_f11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_f12_x) + B :MSTORE(finalExpBN254_f12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_f13_x) + B :MSTORE(finalExpBN254_f13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_f21_x) + B :MSTORE(finalExpBN254_f21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_f22_x) + B :MSTORE(finalExpBN254_f22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_f23_x) + B :MSTORE(finalExpBN254_f23_y) + + ; 2] f^(p⁶-1)(p²-1) = (f^(p⁶-1))^p²·f^(p⁶-1) + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(frob2Fp12BN254_a11_x) + B :MSTORE(frob2Fp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(frob2Fp12BN254_a12_x) + B :MSTORE(frob2Fp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(frob2Fp12BN254_a13_x) + B :MSTORE(frob2Fp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(frob2Fp12BN254_a21_x) + B :MSTORE(frob2Fp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(frob2Fp12BN254_a22_x) + B :MSTORE(frob2Fp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(frob2Fp12BN254_a23_x) + B :MSTORE(frob2Fp12BN254_a23_y), CALL(frob2Fp12BN254) + + $ => A :MLOAD(frob2Fp12BN254_c11_x) + $ => B :MLOAD(frob2Fp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(frob2Fp12BN254_c12_x) + $ => B :MLOAD(frob2Fp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(frob2Fp12BN254_c13_x) + $ => B :MLOAD(frob2Fp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(frob2Fp12BN254_c21_x) + $ => B :MLOAD(frob2Fp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(frob2Fp12BN254_c22_x) + $ => B :MLOAD(frob2Fp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(frob2Fp12BN254_c23_x) + $ => B :MLOAD(frob2Fp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_f11_x) + B :MSTORE(finalExpBN254_f11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_f12_x) + B :MSTORE(finalExpBN254_f12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_f13_x) + B :MSTORE(finalExpBN254_f13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_f21_x) + B :MSTORE(finalExpBN254_f21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_f22_x) + B :MSTORE(finalExpBN254_f22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_f23_x) + B :MSTORE(finalExpBN254_f23_y) + ; =========================================== + + ; The hard part: + ; =========================================== + ; 1] m^x, (m^x)^x, (m^{x²})^x + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(expByXCompCycloFp12BN254_a0_x) + B :MSTORE(expByXCompCycloFp12BN254_a0_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(expByXCompCycloFp12BN254_a4_x) + B :MSTORE(expByXCompCycloFp12BN254_a4_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(expByXCompCycloFp12BN254_a3_x) + B :MSTORE(expByXCompCycloFp12BN254_a3_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(expByXCompCycloFp12BN254_a2_x) + B :MSTORE(expByXCompCycloFp12BN254_a2_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(expByXCompCycloFp12BN254_a1_x) + B :MSTORE(expByXCompCycloFp12BN254_a1_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(expByXCompCycloFp12BN254_a5_x) + B :MSTORE(expByXCompCycloFp12BN254_a5_y), CALL(expByXCompCycloFp12BN254) + + $ => A :MLOAD(expByXCompCycloFp12BN254_c0_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c0_y) + A :MSTORE(finalExpBN254_mx11_x) + B :MSTORE(finalExpBN254_mx11_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c2_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c2_y) + A :MSTORE(finalExpBN254_mx21_x) + B :MSTORE(finalExpBN254_mx21_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c4_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c4_y) + A :MSTORE(finalExpBN254_mx12_x) + B :MSTORE(finalExpBN254_mx12_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c1_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c1_y) + A :MSTORE(finalExpBN254_mx22_x) + B :MSTORE(finalExpBN254_mx22_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c3_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c3_y) + A :MSTORE(finalExpBN254_mx13_x) + B :MSTORE(finalExpBN254_mx13_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c5_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c5_y) + A :MSTORE(finalExpBN254_mx23_x) + B :MSTORE(finalExpBN254_mx23_y) + + $ => A :MLOAD(finalExpBN254_mx11_x) + $ => B :MLOAD(finalExpBN254_mx11_y) + A :MSTORE(expByXCompCycloFp12BN254_a0_x) + B :MSTORE(expByXCompCycloFp12BN254_a0_y) + $ => A :MLOAD(finalExpBN254_mx12_x) + $ => B :MLOAD(finalExpBN254_mx12_y) + A :MSTORE(expByXCompCycloFp12BN254_a4_x) + B :MSTORE(expByXCompCycloFp12BN254_a4_y) + $ => A :MLOAD(finalExpBN254_mx13_x) + $ => B :MLOAD(finalExpBN254_mx13_y) + A :MSTORE(expByXCompCycloFp12BN254_a3_x) + B :MSTORE(expByXCompCycloFp12BN254_a3_y) + $ => A :MLOAD(finalExpBN254_mx21_x) + $ => B :MLOAD(finalExpBN254_mx21_y) + A :MSTORE(expByXCompCycloFp12BN254_a2_x) + B :MSTORE(expByXCompCycloFp12BN254_a2_y) + $ => A :MLOAD(finalExpBN254_mx22_x) + $ => B :MLOAD(finalExpBN254_mx22_y) + A :MSTORE(expByXCompCycloFp12BN254_a1_x) + B :MSTORE(expByXCompCycloFp12BN254_a1_y) + $ => A :MLOAD(finalExpBN254_mx23_x) + $ => B :MLOAD(finalExpBN254_mx23_y) + A :MSTORE(expByXCompCycloFp12BN254_a5_x) + B :MSTORE(expByXCompCycloFp12BN254_a5_y), CALL(expByXCompCycloFp12BN254) + + $ => A :MLOAD(expByXCompCycloFp12BN254_c0_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c0_y) + A :MSTORE(finalExpBN254_mxx11_x) + B :MSTORE(finalExpBN254_mxx11_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c2_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c2_y) + A :MSTORE(finalExpBN254_mxx21_x) + B :MSTORE(finalExpBN254_mxx21_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c4_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c4_y) + A :MSTORE(finalExpBN254_mxx12_x) + B :MSTORE(finalExpBN254_mxx12_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c1_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c1_y) + A :MSTORE(finalExpBN254_mxx22_x) + B :MSTORE(finalExpBN254_mxx22_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c3_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c3_y) + A :MSTORE(finalExpBN254_mxx13_x) + B :MSTORE(finalExpBN254_mxx13_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c5_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c5_y) + A :MSTORE(finalExpBN254_mxx23_x) + B :MSTORE(finalExpBN254_mxx23_y) + + $ => A :MLOAD(finalExpBN254_mxx11_x) + $ => B :MLOAD(finalExpBN254_mxx11_y) + A :MSTORE(expByXCompCycloFp12BN254_a0_x) + B :MSTORE(expByXCompCycloFp12BN254_a0_y) + $ => A :MLOAD(finalExpBN254_mxx12_x) + $ => B :MLOAD(finalExpBN254_mxx12_y) + A :MSTORE(expByXCompCycloFp12BN254_a4_x) + B :MSTORE(expByXCompCycloFp12BN254_a4_y) + $ => A :MLOAD(finalExpBN254_mxx13_x) + $ => B :MLOAD(finalExpBN254_mxx13_y) + A :MSTORE(expByXCompCycloFp12BN254_a3_x) + B :MSTORE(expByXCompCycloFp12BN254_a3_y) + $ => A :MLOAD(finalExpBN254_mxx21_x) + $ => B :MLOAD(finalExpBN254_mxx21_y) + A :MSTORE(expByXCompCycloFp12BN254_a2_x) + B :MSTORE(expByXCompCycloFp12BN254_a2_y) + $ => A :MLOAD(finalExpBN254_mxx22_x) + $ => B :MLOAD(finalExpBN254_mxx22_y) + A :MSTORE(expByXCompCycloFp12BN254_a1_x) + B :MSTORE(expByXCompCycloFp12BN254_a1_y) + $ => A :MLOAD(finalExpBN254_mxx23_x) + $ => B :MLOAD(finalExpBN254_mxx23_y) + A :MSTORE(expByXCompCycloFp12BN254_a5_x) + B :MSTORE(expByXCompCycloFp12BN254_a5_y), CALL(expByXCompCycloFp12BN254) + + $ => A :MLOAD(expByXCompCycloFp12BN254_c0_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c0_y) + A :MSTORE(finalExpBN254_mxxx11_x) + B :MSTORE(finalExpBN254_mxxx11_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c2_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c2_y) + A :MSTORE(finalExpBN254_mxxx21_x) + B :MSTORE(finalExpBN254_mxxx21_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c4_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c4_y) + A :MSTORE(finalExpBN254_mxxx12_x) + B :MSTORE(finalExpBN254_mxxx12_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c1_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c1_y) + A :MSTORE(finalExpBN254_mxxx22_x) + B :MSTORE(finalExpBN254_mxxx22_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c3_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c3_y) + A :MSTORE(finalExpBN254_mxxx13_x) + B :MSTORE(finalExpBN254_mxxx13_y) + $ => A :MLOAD(expByXCompCycloFp12BN254_c5_x) + $ => B :MLOAD(expByXCompCycloFp12BN254_c5_y) + A :MSTORE(finalExpBN254_mxxx23_x) + B :MSTORE(finalExpBN254_mxxx23_y) + + ; 2] m^p, m^p², m^p³, (m^x)^p, (m^x²)^p, (m^x³)^p, (m^x²)^p² + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(frobFp12BN254_a11_x) + B :MSTORE(frobFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(frobFp12BN254_a12_x) + B :MSTORE(frobFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(frobFp12BN254_a13_x) + B :MSTORE(frobFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(frobFp12BN254_a21_x) + B :MSTORE(frobFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(frobFp12BN254_a22_x) + B :MSTORE(frobFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(frobFp12BN254_a23_x) + B :MSTORE(frobFp12BN254_a23_y), CALL(frobFp12BN254) + + $ => A :MLOAD(frobFp12BN254_c11_x) + $ => B :MLOAD(frobFp12BN254_c11_y) + A :MSTORE(finalExpBN254_mp11_x) + B :MSTORE(finalExpBN254_mp11_y) + $ => A :MLOAD(frobFp12BN254_c12_x) + $ => B :MLOAD(frobFp12BN254_c12_y) + A :MSTORE(finalExpBN254_mp12_x) + B :MSTORE(finalExpBN254_mp12_y) + $ => A :MLOAD(frobFp12BN254_c13_x) + $ => B :MLOAD(frobFp12BN254_c13_y) + A :MSTORE(finalExpBN254_mp13_x) + B :MSTORE(finalExpBN254_mp13_y) + $ => A :MLOAD(frobFp12BN254_c21_x) + $ => B :MLOAD(frobFp12BN254_c21_y) + A :MSTORE(finalExpBN254_mp21_x) + B :MSTORE(finalExpBN254_mp21_y) + $ => A :MLOAD(frobFp12BN254_c22_x) + $ => B :MLOAD(frobFp12BN254_c22_y) + A :MSTORE(finalExpBN254_mp22_x) + B :MSTORE(finalExpBN254_mp22_y) + $ => A :MLOAD(frobFp12BN254_c23_x) + $ => B :MLOAD(frobFp12BN254_c23_y) + A :MSTORE(finalExpBN254_mp23_x) + B :MSTORE(finalExpBN254_mp23_y) + + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(frob2Fp12BN254_a11_x) + B :MSTORE(frob2Fp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(frob2Fp12BN254_a12_x) + B :MSTORE(frob2Fp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(frob2Fp12BN254_a13_x) + B :MSTORE(frob2Fp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(frob2Fp12BN254_a21_x) + B :MSTORE(frob2Fp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(frob2Fp12BN254_a22_x) + B :MSTORE(frob2Fp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(frob2Fp12BN254_a23_x) + B :MSTORE(frob2Fp12BN254_a23_y), CALL(frob2Fp12BN254) + + $ => A :MLOAD(frob2Fp12BN254_c11_x) + $ => B :MLOAD(frob2Fp12BN254_c11_y) + A :MSTORE(finalExpBN254_mpp11_x) + B :MSTORE(finalExpBN254_mpp11_y) + $ => A :MLOAD(frob2Fp12BN254_c12_x) + $ => B :MLOAD(frob2Fp12BN254_c12_y) + A :MSTORE(finalExpBN254_mpp12_x) + B :MSTORE(finalExpBN254_mpp12_y) + $ => A :MLOAD(frob2Fp12BN254_c13_x) + $ => B :MLOAD(frob2Fp12BN254_c13_y) + A :MSTORE(finalExpBN254_mpp13_x) + B :MSTORE(finalExpBN254_mpp13_y) + $ => A :MLOAD(frob2Fp12BN254_c21_x) + $ => B :MLOAD(frob2Fp12BN254_c21_y) + A :MSTORE(finalExpBN254_mpp21_x) + B :MSTORE(finalExpBN254_mpp21_y) + $ => A :MLOAD(frob2Fp12BN254_c22_x) + $ => B :MLOAD(frob2Fp12BN254_c22_y) + A :MSTORE(finalExpBN254_mpp22_x) + B :MSTORE(finalExpBN254_mpp22_y) + $ => A :MLOAD(frob2Fp12BN254_c23_x) + $ => B :MLOAD(frob2Fp12BN254_c23_y) + A :MSTORE(finalExpBN254_mpp23_x) + B :MSTORE(finalExpBN254_mpp23_y) + + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(frob3Fp12BN254_a11_x) + B :MSTORE(frob3Fp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(frob3Fp12BN254_a12_x) + B :MSTORE(frob3Fp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(frob3Fp12BN254_a13_x) + B :MSTORE(frob3Fp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(frob3Fp12BN254_a21_x) + B :MSTORE(frob3Fp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(frob3Fp12BN254_a22_x) + B :MSTORE(frob3Fp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(frob3Fp12BN254_a23_x) + B :MSTORE(frob3Fp12BN254_a23_y), CALL(frob3Fp12BN254) + + $ => A :MLOAD(frob3Fp12BN254_c11_x) + $ => B :MLOAD(frob3Fp12BN254_c11_y) + A :MSTORE(finalExpBN254_mppp11_x) + B :MSTORE(finalExpBN254_mppp11_y) + $ => A :MLOAD(frob3Fp12BN254_c12_x) + $ => B :MLOAD(frob3Fp12BN254_c12_y) + A :MSTORE(finalExpBN254_mppp12_x) + B :MSTORE(finalExpBN254_mppp12_y) + $ => A :MLOAD(frob3Fp12BN254_c13_x) + $ => B :MLOAD(frob3Fp12BN254_c13_y) + A :MSTORE(finalExpBN254_mppp13_x) + B :MSTORE(finalExpBN254_mppp13_y) + $ => A :MLOAD(frob3Fp12BN254_c21_x) + $ => B :MLOAD(frob3Fp12BN254_c21_y) + A :MSTORE(finalExpBN254_mppp21_x) + B :MSTORE(finalExpBN254_mppp21_y) + $ => A :MLOAD(frob3Fp12BN254_c22_x) + $ => B :MLOAD(frob3Fp12BN254_c22_y) + A :MSTORE(finalExpBN254_mppp22_x) + B :MSTORE(finalExpBN254_mppp22_y) + $ => A :MLOAD(frob3Fp12BN254_c23_x) + $ => B :MLOAD(frob3Fp12BN254_c23_y) + A :MSTORE(finalExpBN254_mppp23_x) + B :MSTORE(finalExpBN254_mppp23_y) + + $ => A :MLOAD(finalExpBN254_mx11_x) + $ => B :MLOAD(finalExpBN254_mx11_y) + A :MSTORE(frobFp12BN254_a11_x) + B :MSTORE(frobFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_mx12_x) + $ => B :MLOAD(finalExpBN254_mx12_y) + A :MSTORE(frobFp12BN254_a12_x) + B :MSTORE(frobFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_mx13_x) + $ => B :MLOAD(finalExpBN254_mx13_y) + A :MSTORE(frobFp12BN254_a13_x) + B :MSTORE(frobFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_mx21_x) + $ => B :MLOAD(finalExpBN254_mx21_y) + A :MSTORE(frobFp12BN254_a21_x) + B :MSTORE(frobFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_mx22_x) + $ => B :MLOAD(finalExpBN254_mx22_y) + A :MSTORE(frobFp12BN254_a22_x) + B :MSTORE(frobFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_mx23_x) + $ => B :MLOAD(finalExpBN254_mx23_y) + A :MSTORE(frobFp12BN254_a23_x) + B :MSTORE(frobFp12BN254_a23_y), CALL(frobFp12BN254) + + $ => A :MLOAD(frobFp12BN254_c11_x) + $ => B :MLOAD(frobFp12BN254_c11_y) + A :MSTORE(finalExpBN254_mxp11_x) + B :MSTORE(finalExpBN254_mxp11_y) + $ => A :MLOAD(frobFp12BN254_c12_x) + $ => B :MLOAD(frobFp12BN254_c12_y) + A :MSTORE(finalExpBN254_mxp12_x) + B :MSTORE(finalExpBN254_mxp12_y) + $ => A :MLOAD(frobFp12BN254_c13_x) + $ => B :MLOAD(frobFp12BN254_c13_y) + A :MSTORE(finalExpBN254_mxp13_x) + B :MSTORE(finalExpBN254_mxp13_y) + $ => A :MLOAD(frobFp12BN254_c21_x) + $ => B :MLOAD(frobFp12BN254_c21_y) + A :MSTORE(finalExpBN254_mxp21_x) + B :MSTORE(finalExpBN254_mxp21_y) + $ => A :MLOAD(frobFp12BN254_c22_x) + $ => B :MLOAD(frobFp12BN254_c22_y) + A :MSTORE(finalExpBN254_mxp22_x) + B :MSTORE(finalExpBN254_mxp22_y) + $ => A :MLOAD(frobFp12BN254_c23_x) + $ => B :MLOAD(frobFp12BN254_c23_y) + A :MSTORE(finalExpBN254_mxp23_x) + B :MSTORE(finalExpBN254_mxp23_y) + + $ => A :MLOAD(finalExpBN254_mxx11_x) + $ => B :MLOAD(finalExpBN254_mxx11_y) + A :MSTORE(frobFp12BN254_a11_x) + B :MSTORE(frobFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_mxx12_x) + $ => B :MLOAD(finalExpBN254_mxx12_y) + A :MSTORE(frobFp12BN254_a12_x) + B :MSTORE(frobFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_mxx13_x) + $ => B :MLOAD(finalExpBN254_mxx13_y) + A :MSTORE(frobFp12BN254_a13_x) + B :MSTORE(frobFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_mxx21_x) + $ => B :MLOAD(finalExpBN254_mxx21_y) + A :MSTORE(frobFp12BN254_a21_x) + B :MSTORE(frobFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_mxx22_x) + $ => B :MLOAD(finalExpBN254_mxx22_y) + A :MSTORE(frobFp12BN254_a22_x) + B :MSTORE(frobFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_mxx23_x) + $ => B :MLOAD(finalExpBN254_mxx23_y) + A :MSTORE(frobFp12BN254_a23_x) + B :MSTORE(frobFp12BN254_a23_y), CALL(frobFp12BN254) + + $ => A :MLOAD(frobFp12BN254_c11_x) + $ => B :MLOAD(frobFp12BN254_c11_y) + A :MSTORE(finalExpBN254_mxxp11_x) + B :MSTORE(finalExpBN254_mxxp11_y) + $ => A :MLOAD(frobFp12BN254_c12_x) + $ => B :MLOAD(frobFp12BN254_c12_y) + A :MSTORE(finalExpBN254_mxxp12_x) + B :MSTORE(finalExpBN254_mxxp12_y) + $ => A :MLOAD(frobFp12BN254_c13_x) + $ => B :MLOAD(frobFp12BN254_c13_y) + A :MSTORE(finalExpBN254_mxxp13_x) + B :MSTORE(finalExpBN254_mxxp13_y) + $ => A :MLOAD(frobFp12BN254_c21_x) + $ => B :MLOAD(frobFp12BN254_c21_y) + A :MSTORE(finalExpBN254_mxxp21_x) + B :MSTORE(finalExpBN254_mxxp21_y) + $ => A :MLOAD(frobFp12BN254_c22_x) + $ => B :MLOAD(frobFp12BN254_c22_y) + A :MSTORE(finalExpBN254_mxxp22_x) + B :MSTORE(finalExpBN254_mxxp22_y) + $ => A :MLOAD(frobFp12BN254_c23_x) + $ => B :MLOAD(frobFp12BN254_c23_y) + A :MSTORE(finalExpBN254_mxxp23_x) + B :MSTORE(finalExpBN254_mxxp23_y) + + $ => A :MLOAD(finalExpBN254_mxxx11_x) + $ => B :MLOAD(finalExpBN254_mxxx11_y) + A :MSTORE(frobFp12BN254_a11_x) + B :MSTORE(frobFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_mxxx12_x) + $ => B :MLOAD(finalExpBN254_mxxx12_y) + A :MSTORE(frobFp12BN254_a12_x) + B :MSTORE(frobFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_mxxx13_x) + $ => B :MLOAD(finalExpBN254_mxxx13_y) + A :MSTORE(frobFp12BN254_a13_x) + B :MSTORE(frobFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_mxxx21_x) + $ => B :MLOAD(finalExpBN254_mxxx21_y) + A :MSTORE(frobFp12BN254_a21_x) + B :MSTORE(frobFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_mxxx22_x) + $ => B :MLOAD(finalExpBN254_mxxx22_y) + A :MSTORE(frobFp12BN254_a22_x) + B :MSTORE(frobFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_mxxx23_x) + $ => B :MLOAD(finalExpBN254_mxxx23_y) + A :MSTORE(frobFp12BN254_a23_x) + B :MSTORE(frobFp12BN254_a23_y), CALL(frobFp12BN254) + + $ => A :MLOAD(frobFp12BN254_c11_x) + $ => B :MLOAD(frobFp12BN254_c11_y) + A :MSTORE(finalExpBN254_mxxxp11_x) + B :MSTORE(finalExpBN254_mxxxp11_y) + $ => A :MLOAD(frobFp12BN254_c12_x) + $ => B :MLOAD(frobFp12BN254_c12_y) + A :MSTORE(finalExpBN254_mxxxp12_x) + B :MSTORE(finalExpBN254_mxxxp12_y) + $ => A :MLOAD(frobFp12BN254_c13_x) + $ => B :MLOAD(frobFp12BN254_c13_y) + A :MSTORE(finalExpBN254_mxxxp13_x) + B :MSTORE(finalExpBN254_mxxxp13_y) + $ => A :MLOAD(frobFp12BN254_c21_x) + $ => B :MLOAD(frobFp12BN254_c21_y) + A :MSTORE(finalExpBN254_mxxxp21_x) + B :MSTORE(finalExpBN254_mxxxp21_y) + $ => A :MLOAD(frobFp12BN254_c22_x) + $ => B :MLOAD(frobFp12BN254_c22_y) + A :MSTORE(finalExpBN254_mxxxp22_x) + B :MSTORE(finalExpBN254_mxxxp22_y) + $ => A :MLOAD(frobFp12BN254_c23_x) + $ => B :MLOAD(frobFp12BN254_c23_y) + A :MSTORE(finalExpBN254_mxxxp23_x) + B :MSTORE(finalExpBN254_mxxxp23_y) + + $ => A :MLOAD(finalExpBN254_mxx11_x) + $ => B :MLOAD(finalExpBN254_mxx11_y) + A :MSTORE(frob2Fp12BN254_a11_x) + B :MSTORE(frob2Fp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_mxx12_x) + $ => B :MLOAD(finalExpBN254_mxx12_y) + A :MSTORE(frob2Fp12BN254_a12_x) + B :MSTORE(frob2Fp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_mxx13_x) + $ => B :MLOAD(finalExpBN254_mxx13_y) + A :MSTORE(frob2Fp12BN254_a13_x) + B :MSTORE(frob2Fp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_mxx21_x) + $ => B :MLOAD(finalExpBN254_mxx21_y) + A :MSTORE(frob2Fp12BN254_a21_x) + B :MSTORE(frob2Fp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_mxx22_x) + $ => B :MLOAD(finalExpBN254_mxx22_y) + A :MSTORE(frob2Fp12BN254_a22_x) + B :MSTORE(frob2Fp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_mxx23_x) + $ => B :MLOAD(finalExpBN254_mxx23_y) + A :MSTORE(frob2Fp12BN254_a23_x) + B :MSTORE(frob2Fp12BN254_a23_y), CALL(frob2Fp12BN254) + + $ => A :MLOAD(frob2Fp12BN254_c11_x) + $ => B :MLOAD(frob2Fp12BN254_c11_y) + A :MSTORE(finalExpBN254_mxxpp11_x) + B :MSTORE(finalExpBN254_mxxpp11_y) + $ => A :MLOAD(frob2Fp12BN254_c12_x) + $ => B :MLOAD(frob2Fp12BN254_c12_y) + A :MSTORE(finalExpBN254_mxxpp12_x) + B :MSTORE(finalExpBN254_mxxpp12_y) + $ => A :MLOAD(frob2Fp12BN254_c13_x) + $ => B :MLOAD(frob2Fp12BN254_c13_y) + A :MSTORE(finalExpBN254_mxxpp13_x) + B :MSTORE(finalExpBN254_mxxpp13_y) + $ => A :MLOAD(frob2Fp12BN254_c21_x) + $ => B :MLOAD(frob2Fp12BN254_c21_y) + A :MSTORE(finalExpBN254_mxxpp21_x) + B :MSTORE(finalExpBN254_mxxpp21_y) + $ => A :MLOAD(frob2Fp12BN254_c22_x) + $ => B :MLOAD(frob2Fp12BN254_c22_y) + A :MSTORE(finalExpBN254_mxxpp22_x) + B :MSTORE(finalExpBN254_mxxpp22_y) + $ => A :MLOAD(frob2Fp12BN254_c23_x) + $ => B :MLOAD(frob2Fp12BN254_c23_y) + A :MSTORE(finalExpBN254_mxxpp23_x) + B :MSTORE(finalExpBN254_mxxpp23_y) + + ; 3] y1 = m^p·m^p²·m^p³ + $ => A :MLOAD(finalExpBN254_mp11_x) + $ => B :MLOAD(finalExpBN254_mp11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_mp12_x) + $ => B :MLOAD(finalExpBN254_mp12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_mp13_x) + $ => B :MLOAD(finalExpBN254_mp13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_mp21_x) + $ => B :MLOAD(finalExpBN254_mp21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_mp22_x) + $ => B :MLOAD(finalExpBN254_mp22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_mp23_x) + $ => B :MLOAD(finalExpBN254_mp23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_mpp11_x) + $ => B :MLOAD(finalExpBN254_mpp11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_mpp12_x) + $ => B :MLOAD(finalExpBN254_mpp12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_mpp13_x) + $ => B :MLOAD(finalExpBN254_mpp13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_mpp21_x) + $ => B :MLOAD(finalExpBN254_mpp21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_mpp22_x) + $ => B :MLOAD(finalExpBN254_mpp22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_mpp23_x) + $ => B :MLOAD(finalExpBN254_mpp23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_mppp11_x) + $ => B :MLOAD(finalExpBN254_mppp11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_mppp12_x) + $ => B :MLOAD(finalExpBN254_mppp12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_mppp13_x) + $ => B :MLOAD(finalExpBN254_mppp13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_mppp21_x) + $ => B :MLOAD(finalExpBN254_mppp21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_mppp22_x) + $ => B :MLOAD(finalExpBN254_mppp22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_mppp23_x) + $ => B :MLOAD(finalExpBN254_mppp23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_y1_11_x) + B :MSTORE(finalExpBN254_y1_11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_y1_12_x) + B :MSTORE(finalExpBN254_y1_12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_y1_13_x) + B :MSTORE(finalExpBN254_y1_13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_y1_21_x) + B :MSTORE(finalExpBN254_y1_21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_y1_22_x) + B :MSTORE(finalExpBN254_y1_22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_y1_23_x) + B :MSTORE(finalExpBN254_y1_23_y) + + ; 4] y2 = m̅ + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(finalExpBN254_y2_11_x) + B :MSTORE(finalExpBN254_y2_11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(finalExpBN254_y2_12_x) + B :MSTORE(finalExpBN254_y2_12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(finalExpBN254_y2_13_x) + B :MSTORE(finalExpBN254_y2_13_y) + + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f21_x) + $ :SUB, MSTORE(finalExpBN254_y2_21_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f21_y) + $ :SUB, MSTORE(finalExpBN254_y2_21_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f22_x) + $ :SUB, MSTORE(finalExpBN254_y2_22_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f22_y) + $ :SUB, MSTORE(finalExpBN254_y2_22_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f23_x) + $ :SUB, MSTORE(finalExpBN254_y2_23_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_f23_y) + $ :SUB, MSTORE(finalExpBN254_y2_23_y) + + ; 5] y3 = (m^x²)^p² + ; This has already been computed + + ; 6] y4 = \bar{(m^x)^p} + $ => A :MLOAD(finalExpBN254_mxp11_x) + $ => B :MLOAD(finalExpBN254_mxp11_y) + A :MSTORE(finalExpBN254_y4_11_x) + B :MSTORE(finalExpBN254_y4_11_y) + $ => A :MLOAD(finalExpBN254_mxp12_x) + $ => B :MLOAD(finalExpBN254_mxp12_y) + A :MSTORE(finalExpBN254_y4_12_x) + B :MSTORE(finalExpBN254_y4_12_y) + $ => A :MLOAD(finalExpBN254_mxp13_x) + $ => B :MLOAD(finalExpBN254_mxp13_y) + A :MSTORE(finalExpBN254_y4_13_x) + B :MSTORE(finalExpBN254_y4_13_y) + + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxp21_x) + $ :SUB, MSTORE(finalExpBN254_y4_21_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxp21_y) + $ :SUB, MSTORE(finalExpBN254_y4_21_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxp22_x) + $ :SUB, MSTORE(finalExpBN254_y4_22_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxp22_y) + $ :SUB, MSTORE(finalExpBN254_y4_22_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxp23_x) + $ :SUB, MSTORE(finalExpBN254_y4_23_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxp23_y) + $ :SUB, MSTORE(finalExpBN254_y4_23_y) + + ; 7] y5 = \bar{m^x·(m^x²)^p} + $ => A :MLOAD(finalExpBN254_mx11_x) + $ => B :MLOAD(finalExpBN254_mx11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_mx12_x) + $ => B :MLOAD(finalExpBN254_mx12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_mx13_x) + $ => B :MLOAD(finalExpBN254_mx13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_mx21_x) + $ => B :MLOAD(finalExpBN254_mx21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_mx22_x) + $ => B :MLOAD(finalExpBN254_mx22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_mx23_x) + $ => B :MLOAD(finalExpBN254_mx23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_mxxp11_x) + $ => B :MLOAD(finalExpBN254_mxxp11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_mxxp12_x) + $ => B :MLOAD(finalExpBN254_mxxp12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_mxxp13_x) + $ => B :MLOAD(finalExpBN254_mxxp13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_mxxp21_x) + $ => B :MLOAD(finalExpBN254_mxxp21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_mxxp22_x) + $ => B :MLOAD(finalExpBN254_mxxp22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_mxxp23_x) + $ => B :MLOAD(finalExpBN254_mxxp23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_y5_11_x) + B :MSTORE(finalExpBN254_y5_11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_y5_12_x) + B :MSTORE(finalExpBN254_y5_12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_y5_13_x) + B :MSTORE(finalExpBN254_y5_13_y) + + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c21_x) + $ :SUB, MSTORE(finalExpBN254_y5_21_x) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c21_y) + $ :SUB, MSTORE(finalExpBN254_y5_21_y) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c22_x) + $ :SUB, MSTORE(finalExpBN254_y5_22_x) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c22_y) + $ :SUB, MSTORE(finalExpBN254_y5_22_y) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c23_x) + $ :SUB, MSTORE(finalExpBN254_y5_23_x) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c23_y) + $ :SUB, MSTORE(finalExpBN254_y5_23_y) + + ; 8] y6 = \bar{m^x²} + $ => A :MLOAD(finalExpBN254_mxx11_x) + $ => B :MLOAD(finalExpBN254_mxx11_y) + A :MSTORE(finalExpBN254_y6_11_x) + B :MSTORE(finalExpBN254_y6_11_y) + $ => A :MLOAD(finalExpBN254_mxx12_x) + $ => B :MLOAD(finalExpBN254_mxx12_y) + A :MSTORE(finalExpBN254_y6_12_x) + B :MSTORE(finalExpBN254_y6_12_y) + $ => A :MLOAD(finalExpBN254_mxx13_x) + $ => B :MLOAD(finalExpBN254_mxx13_y) + A :MSTORE(finalExpBN254_y6_13_x) + B :MSTORE(finalExpBN254_y6_13_y) + + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxx21_x) + $ :SUB, MSTORE(finalExpBN254_y6_21_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxx21_y) + $ :SUB, MSTORE(finalExpBN254_y6_21_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxx22_x) + $ :SUB, MSTORE(finalExpBN254_y6_22_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxx22_y) + $ :SUB, MSTORE(finalExpBN254_y6_22_y) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxx23_x) + $ :SUB, MSTORE(finalExpBN254_y6_23_x) + %BN254_P => A + $ => B :MLOAD(finalExpBN254_mxx23_y) + $ :SUB, MSTORE(finalExpBN254_y6_23_y) + + ; 9] y7 = \bar{m^x³·(m^x³)^p} + $ => A :MLOAD(finalExpBN254_mxxx11_x) + $ => B :MLOAD(finalExpBN254_mxxx11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_mxxx12_x) + $ => B :MLOAD(finalExpBN254_mxxx12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_mxxx13_x) + $ => B :MLOAD(finalExpBN254_mxxx13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_mxxx21_x) + $ => B :MLOAD(finalExpBN254_mxxx21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_mxxx22_x) + $ => B :MLOAD(finalExpBN254_mxxx22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_mxxx23_x) + $ => B :MLOAD(finalExpBN254_mxxx23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_mxxxp11_x) + $ => B :MLOAD(finalExpBN254_mxxxp11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_mxxxp12_x) + $ => B :MLOAD(finalExpBN254_mxxxp12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_mxxxp13_x) + $ => B :MLOAD(finalExpBN254_mxxxp13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_mxxxp21_x) + $ => B :MLOAD(finalExpBN254_mxxxp21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_mxxxp22_x) + $ => B :MLOAD(finalExpBN254_mxxxp22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_mxxxp23_x) + $ => B :MLOAD(finalExpBN254_mxxxp23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_y7_11_x) + B :MSTORE(finalExpBN254_y7_11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_y7_12_x) + B :MSTORE(finalExpBN254_y7_12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_y7_13_x) + B :MSTORE(finalExpBN254_y7_13_y) + + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c21_x) + $ :SUB, MSTORE(finalExpBN254_y7_21_x) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c21_y) + $ :SUB, MSTORE(finalExpBN254_y7_21_y) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c22_x) + $ :SUB, MSTORE(finalExpBN254_y7_22_x) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c22_y) + $ :SUB, MSTORE(finalExpBN254_y7_22_y) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c23_x) + $ :SUB, MSTORE(finalExpBN254_y7_23_x) + %BN254_P => A + $ => B :MLOAD(mulFp12BN254_c23_y) + $ :SUB, MSTORE(finalExpBN254_y7_23_y) + + ; 10] Compute y1·y2²·y3⁶·y4¹²·y5¹⁸·y6³⁰·y7³⁶ as follows + + ; 10.1] T11 = y7²·y5·y6 + $ => A :MLOAD(finalExpBN254_y7_11_x) + $ => B :MLOAD(finalExpBN254_y7_11_y) + A :MSTORE(squareCycloFp12BN254_a11_x) + B :MSTORE(squareCycloFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_y7_12_x) + $ => B :MLOAD(finalExpBN254_y7_12_y) + A :MSTORE(squareCycloFp12BN254_a12_x) + B :MSTORE(squareCycloFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_y7_13_x) + $ => B :MLOAD(finalExpBN254_y7_13_y) + A :MSTORE(squareCycloFp12BN254_a13_x) + B :MSTORE(squareCycloFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_y7_21_x) + $ => B :MLOAD(finalExpBN254_y7_21_y) + A :MSTORE(squareCycloFp12BN254_a21_x) + B :MSTORE(squareCycloFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_y7_22_x) + $ => B :MLOAD(finalExpBN254_y7_22_y) + A :MSTORE(squareCycloFp12BN254_a22_x) + B :MSTORE(squareCycloFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_y7_23_x) + $ => B :MLOAD(finalExpBN254_y7_23_y) + A :MSTORE(squareCycloFp12BN254_a23_x) + B :MSTORE(squareCycloFp12BN254_a23_y), CALL(squareCycloFp12BN254) + + $ => A :MLOAD(squareCycloFp12BN254_c11_x) + $ => B :MLOAD(squareCycloFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(squareCycloFp12BN254_c12_x) + $ => B :MLOAD(squareCycloFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(squareCycloFp12BN254_c13_x) + $ => B :MLOAD(squareCycloFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(squareCycloFp12BN254_c21_x) + $ => B :MLOAD(squareCycloFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(squareCycloFp12BN254_c22_x) + $ => B :MLOAD(squareCycloFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(squareCycloFp12BN254_c23_x) + $ => B :MLOAD(squareCycloFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_y5_11_x) + $ => B :MLOAD(finalExpBN254_y5_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_y5_12_x) + $ => B :MLOAD(finalExpBN254_y5_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_y5_13_x) + $ => B :MLOAD(finalExpBN254_y5_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_y5_21_x) + $ => B :MLOAD(finalExpBN254_y5_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_y5_22_x) + $ => B :MLOAD(finalExpBN254_y5_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_y5_23_x) + $ => B :MLOAD(finalExpBN254_y5_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_y6_11_x) + $ => B :MLOAD(finalExpBN254_y6_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_y6_12_x) + $ => B :MLOAD(finalExpBN254_y6_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_y6_13_x) + $ => B :MLOAD(finalExpBN254_y6_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_y6_21_x) + $ => B :MLOAD(finalExpBN254_y6_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_y6_22_x) + $ => B :MLOAD(finalExpBN254_y6_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_y6_23_x) + $ => B :MLOAD(finalExpBN254_y6_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_T11_11_x) + B :MSTORE(finalExpBN254_T11_11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_T11_12_x) + B :MSTORE(finalExpBN254_T11_12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_T11_13_x) + B :MSTORE(finalExpBN254_T11_13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_T11_21_x) + B :MSTORE(finalExpBN254_T11_21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_T11_22_x) + B :MSTORE(finalExpBN254_T11_22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_T11_23_x) + B :MSTORE(finalExpBN254_T11_23_y) + + ; 10.2] T21 = T11·y4·y6 + $ => A :MLOAD(finalExpBN254_T11_11_x) + $ => B :MLOAD(finalExpBN254_T11_11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_T11_12_x) + $ => B :MLOAD(finalExpBN254_T11_12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_T11_13_x) + $ => B :MLOAD(finalExpBN254_T11_13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_T11_21_x) + $ => B :MLOAD(finalExpBN254_T11_21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_T11_22_x) + $ => B :MLOAD(finalExpBN254_T11_22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_T11_23_x) + $ => B :MLOAD(finalExpBN254_T11_23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_y4_11_x) + $ => B :MLOAD(finalExpBN254_y4_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_y4_12_x) + $ => B :MLOAD(finalExpBN254_y4_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_y4_13_x) + $ => B :MLOAD(finalExpBN254_y4_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_y4_21_x) + $ => B :MLOAD(finalExpBN254_y4_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_y4_22_x) + $ => B :MLOAD(finalExpBN254_y4_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_y4_23_x) + $ => B :MLOAD(finalExpBN254_y4_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_y6_11_x) + $ => B :MLOAD(finalExpBN254_y6_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_y6_12_x) + $ => B :MLOAD(finalExpBN254_y6_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_y6_13_x) + $ => B :MLOAD(finalExpBN254_y6_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_y6_21_x) + $ => B :MLOAD(finalExpBN254_y6_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_y6_22_x) + $ => B :MLOAD(finalExpBN254_y6_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_y6_23_x) + $ => B :MLOAD(finalExpBN254_y6_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_T21_11_x) + B :MSTORE(finalExpBN254_T21_11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_T21_12_x) + B :MSTORE(finalExpBN254_T21_12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_T21_13_x) + B :MSTORE(finalExpBN254_T21_13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_T21_21_x) + B :MSTORE(finalExpBN254_T21_21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_T21_22_x) + B :MSTORE(finalExpBN254_T21_22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_T21_23_x) + B :MSTORE(finalExpBN254_T21_23_y) + + ; 10.3] T12 = T11·y3 + $ => A :MLOAD(finalExpBN254_T11_11_x) + $ => B :MLOAD(finalExpBN254_T11_11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_T11_12_x) + $ => B :MLOAD(finalExpBN254_T11_12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_T11_13_x) + $ => B :MLOAD(finalExpBN254_T11_13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_T11_21_x) + $ => B :MLOAD(finalExpBN254_T11_21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_T11_22_x) + $ => B :MLOAD(finalExpBN254_T11_22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_T11_23_x) + $ => B :MLOAD(finalExpBN254_T11_23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_mxxpp11_x) + $ => B :MLOAD(finalExpBN254_mxxpp11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_mxxpp12_x) + $ => B :MLOAD(finalExpBN254_mxxpp12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_mxxpp13_x) + $ => B :MLOAD(finalExpBN254_mxxpp13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_mxxpp21_x) + $ => B :MLOAD(finalExpBN254_mxxpp21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_mxxpp22_x) + $ => B :MLOAD(finalExpBN254_mxxpp22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_mxxpp23_x) + $ => B :MLOAD(finalExpBN254_mxxpp23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_T12_11_x) + B :MSTORE(finalExpBN254_T12_11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_T12_12_x) + B :MSTORE(finalExpBN254_T12_12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_T12_13_x) + B :MSTORE(finalExpBN254_T12_13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_T12_21_x) + B :MSTORE(finalExpBN254_T12_21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_T12_22_x) + B :MSTORE(finalExpBN254_T12_22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_T12_23_x) + B :MSTORE(finalExpBN254_T12_23_y) + + ; 10.4] T22 = T21²·T12 + $ => A :MLOAD(finalExpBN254_T21_11_x) + $ => B :MLOAD(finalExpBN254_T21_11_y) + A :MSTORE(squareCycloFp12BN254_a11_x) + B :MSTORE(squareCycloFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_T21_12_x) + $ => B :MLOAD(finalExpBN254_T21_12_y) + A :MSTORE(squareCycloFp12BN254_a12_x) + B :MSTORE(squareCycloFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_T21_13_x) + $ => B :MLOAD(finalExpBN254_T21_13_y) + A :MSTORE(squareCycloFp12BN254_a13_x) + B :MSTORE(squareCycloFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_T21_21_x) + $ => B :MLOAD(finalExpBN254_T21_21_y) + A :MSTORE(squareCycloFp12BN254_a21_x) + B :MSTORE(squareCycloFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_T21_22_x) + $ => B :MLOAD(finalExpBN254_T21_22_y) + A :MSTORE(squareCycloFp12BN254_a22_x) + B :MSTORE(squareCycloFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_T21_23_x) + $ => B :MLOAD(finalExpBN254_T21_23_y) + A :MSTORE(squareCycloFp12BN254_a23_x) + B :MSTORE(squareCycloFp12BN254_a23_y), CALL(squareCycloFp12BN254) + + $ => A :MLOAD(squareCycloFp12BN254_c11_x) + $ => B :MLOAD(squareCycloFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(squareCycloFp12BN254_c12_x) + $ => B :MLOAD(squareCycloFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(squareCycloFp12BN254_c13_x) + $ => B :MLOAD(squareCycloFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(squareCycloFp12BN254_c21_x) + $ => B :MLOAD(squareCycloFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(squareCycloFp12BN254_c22_x) + $ => B :MLOAD(squareCycloFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(squareCycloFp12BN254_c23_x) + $ => B :MLOAD(squareCycloFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_T12_11_x) + $ => B :MLOAD(finalExpBN254_T12_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_T12_12_x) + $ => B :MLOAD(finalExpBN254_T12_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_T12_13_x) + $ => B :MLOAD(finalExpBN254_T12_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_T12_21_x) + $ => B :MLOAD(finalExpBN254_T12_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_T12_22_x) + $ => B :MLOAD(finalExpBN254_T12_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_T12_23_x) + $ => B :MLOAD(finalExpBN254_T12_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + ; 10.5] T23 = T22² + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(squareCycloFp12BN254_a11_x) + B :MSTORE(squareCycloFp12BN254_a11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(squareCycloFp12BN254_a12_x) + B :MSTORE(squareCycloFp12BN254_a12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(squareCycloFp12BN254_a13_x) + B :MSTORE(squareCycloFp12BN254_a13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(squareCycloFp12BN254_a21_x) + B :MSTORE(squareCycloFp12BN254_a21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(squareCycloFp12BN254_a22_x) + B :MSTORE(squareCycloFp12BN254_a22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(squareCycloFp12BN254_a23_x) + B :MSTORE(squareCycloFp12BN254_a23_y), CALL(squareCycloFp12BN254) + + $ => A :MLOAD(squareCycloFp12BN254_c11_x) + $ => B :MLOAD(squareCycloFp12BN254_c11_y) + A :MSTORE(finalExpBN254_T23_11_x) + B :MSTORE(finalExpBN254_T23_11_y) + $ => A :MLOAD(squareCycloFp12BN254_c12_x) + $ => B :MLOAD(squareCycloFp12BN254_c12_y) + A :MSTORE(finalExpBN254_T23_12_x) + B :MSTORE(finalExpBN254_T23_12_y) + $ => A :MLOAD(squareCycloFp12BN254_c13_x) + $ => B :MLOAD(squareCycloFp12BN254_c13_y) + A :MSTORE(finalExpBN254_T23_13_x) + B :MSTORE(finalExpBN254_T23_13_y) + $ => A :MLOAD(squareCycloFp12BN254_c21_x) + $ => B :MLOAD(squareCycloFp12BN254_c21_y) + A :MSTORE(finalExpBN254_T23_21_x) + B :MSTORE(finalExpBN254_T23_21_y) + $ => A :MLOAD(squareCycloFp12BN254_c22_x) + $ => B :MLOAD(squareCycloFp12BN254_c22_y) + A :MSTORE(finalExpBN254_T23_22_x) + B :MSTORE(finalExpBN254_T23_22_y) + $ => A :MLOAD(squareCycloFp12BN254_c23_x) + $ => B :MLOAD(squareCycloFp12BN254_c23_y) + A :MSTORE(finalExpBN254_T23_23_x) + B :MSTORE(finalExpBN254_T23_23_y) + + ; 10.6] T24 = T23·y1 + $ => A :MLOAD(finalExpBN254_T23_11_x) + $ => B :MLOAD(finalExpBN254_T23_11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_T23_12_x) + $ => B :MLOAD(finalExpBN254_T23_12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_T23_13_x) + $ => B :MLOAD(finalExpBN254_T23_13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_T23_21_x) + $ => B :MLOAD(finalExpBN254_T23_21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_T23_22_x) + $ => B :MLOAD(finalExpBN254_T23_22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_T23_23_x) + $ => B :MLOAD(finalExpBN254_T23_23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_y1_11_x) + $ => B :MLOAD(finalExpBN254_y1_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_y1_12_x) + $ => B :MLOAD(finalExpBN254_y1_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_y1_13_x) + $ => B :MLOAD(finalExpBN254_y1_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_y1_21_x) + $ => B :MLOAD(finalExpBN254_y1_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_y1_22_x) + $ => B :MLOAD(finalExpBN254_y1_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_y1_23_x) + $ => B :MLOAD(finalExpBN254_y1_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_T24_11_x) + B :MSTORE(finalExpBN254_T24_11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_T24_12_x) + B :MSTORE(finalExpBN254_T24_12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_T24_13_x) + B :MSTORE(finalExpBN254_T24_13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_T24_21_x) + B :MSTORE(finalExpBN254_T24_21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_T24_22_x) + B :MSTORE(finalExpBN254_T24_22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_T24_23_x) + B :MSTORE(finalExpBN254_T24_23_y) + + + ; 10.7] T13 = T23·y2 + $ => A :MLOAD(finalExpBN254_T23_11_x) + $ => B :MLOAD(finalExpBN254_T23_11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(finalExpBN254_T23_12_x) + $ => B :MLOAD(finalExpBN254_T23_12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(finalExpBN254_T23_13_x) + $ => B :MLOAD(finalExpBN254_T23_13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(finalExpBN254_T23_21_x) + $ => B :MLOAD(finalExpBN254_T23_21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(finalExpBN254_T23_22_x) + $ => B :MLOAD(finalExpBN254_T23_22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(finalExpBN254_T23_23_x) + $ => B :MLOAD(finalExpBN254_T23_23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_y2_11_x) + $ => B :MLOAD(finalExpBN254_y2_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_y2_12_x) + $ => B :MLOAD(finalExpBN254_y2_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_y2_13_x) + $ => B :MLOAD(finalExpBN254_y2_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_y2_21_x) + $ => B :MLOAD(finalExpBN254_y2_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_y2_22_x) + $ => B :MLOAD(finalExpBN254_y2_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_y2_23_x) + $ => B :MLOAD(finalExpBN254_y2_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + + ; 10.8] T14 = T13²·T24 + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(squareCycloFp12BN254_a11_x) + B :MSTORE(squareCycloFp12BN254_a11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(squareCycloFp12BN254_a12_x) + B :MSTORE(squareCycloFp12BN254_a12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(squareCycloFp12BN254_a13_x) + B :MSTORE(squareCycloFp12BN254_a13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(squareCycloFp12BN254_a21_x) + B :MSTORE(squareCycloFp12BN254_a21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(squareCycloFp12BN254_a22_x) + B :MSTORE(squareCycloFp12BN254_a22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(squareCycloFp12BN254_a23_x) + B :MSTORE(squareCycloFp12BN254_a23_y), CALL(squareCycloFp12BN254) + + $ => A :MLOAD(squareCycloFp12BN254_c11_x) + $ => B :MLOAD(squareCycloFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(squareCycloFp12BN254_c12_x) + $ => B :MLOAD(squareCycloFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(squareCycloFp12BN254_c13_x) + $ => B :MLOAD(squareCycloFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(squareCycloFp12BN254_c21_x) + $ => B :MLOAD(squareCycloFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(squareCycloFp12BN254_c22_x) + $ => B :MLOAD(squareCycloFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(squareCycloFp12BN254_c23_x) + $ => B :MLOAD(squareCycloFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(finalExpBN254_T24_11_x) + $ => B :MLOAD(finalExpBN254_T24_11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(finalExpBN254_T24_12_x) + $ => B :MLOAD(finalExpBN254_T24_12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(finalExpBN254_T24_13_x) + $ => B :MLOAD(finalExpBN254_T24_13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(finalExpBN254_T24_21_x) + $ => B :MLOAD(finalExpBN254_T24_21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(finalExpBN254_T24_22_x) + $ => B :MLOAD(finalExpBN254_T24_22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(finalExpBN254_T24_23_x) + $ => B :MLOAD(finalExpBN254_T24_23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + ; =========================================== + + ; Assing the result. + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(finalExpBN254_f11_x) + B :MSTORE(finalExpBN254_f11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(finalExpBN254_f12_x) + B :MSTORE(finalExpBN254_f12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(finalExpBN254_f13_x) + B :MSTORE(finalExpBN254_f13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(finalExpBN254_f21_x) + B :MSTORE(finalExpBN254_f21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(finalExpBN254_f22_x) + B :MSTORE(finalExpBN254_f22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(finalExpBN254_f23_x) + B :MSTORE(finalExpBN254_f23_y) + +finalExpBN254_end: + $ => RR :MLOAD(finalExpBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/halfPairingBN254.zkasm b/main/pairings/halfPairingBN254.zkasm new file mode 100644 index 00000000..82c84149 --- /dev/null +++ b/main/pairings/halfPairingBN254.zkasm @@ -0,0 +1,428 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; halfPairingBN254: +;; input: P ∈ G1 and Q ∈ G2 +;; output: It returns 1 if either P = 0 or Q = 0 and f_{r,Q}(P) ∈ Fp12 otherwise +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL halfPairingBN254_P_x +VAR GLOBAL halfPairingBN254_P_y +VAR GLOBAL halfPairingBN254_Q_x1 +VAR GLOBAL halfPairingBN254_Q_x2 +VAR GLOBAL halfPairingBN254_Q_y1 +VAR GLOBAL halfPairingBN254_Q_y2 + +VAR GLOBAL halfPairingBN254_f11_x +VAR GLOBAL halfPairingBN254_f11_y +VAR GLOBAL halfPairingBN254_f12_x +VAR GLOBAL halfPairingBN254_f12_y +VAR GLOBAL halfPairingBN254_f13_x +VAR GLOBAL halfPairingBN254_f13_y +VAR GLOBAL halfPairingBN254_f21_x +VAR GLOBAL halfPairingBN254_f21_y +VAR GLOBAL halfPairingBN254_f22_x +VAR GLOBAL halfPairingBN254_f22_y +VAR GLOBAL halfPairingBN254_f23_x +VAR GLOBAL halfPairingBN254_f23_y + +VAR GLOBAL halfPairingBN254_RR + +VAR GLOBAL halfPairingBN254_P_x3 +VAR GLOBAL halfPairingBN254_Q_RHS_x +VAR GLOBAL halfPairingBN254_Q_RHS_y +VAR GLOBAL halfPairingBN254_psi_x1 +VAR GLOBAL halfPairingBN254_psi_x2 +VAR GLOBAL halfPairingBN254_psi_y1 +VAR GLOBAL halfPairingBN254_psi_y2 + +; ERROR CODES (B) +; 0 - no error +; 1 - P_x is too big +; 2 - P_y is too big +; 3 - Q_x1 is too big +; 4 - Q_x2 is too big +; 5 - Q_y1 is too big +; 6 - Q_y2 is too big +; 7 - P is not in G1 +; 8 - Q is not in G2 + +halfPairingBN254: + RR :MSTORE(halfPairingBN254_RR) + + %BN254_P_MINUS_ONE => A + $ => B :MLOAD(halfPairingBN254_P_x) + $ :LT, JMPC(halfPairingBN254_Px_too_big) + $ => B :MLOAD(halfPairingBN254_P_y) + $ :LT, JMPC(halfPairingBN254_Py_too_big) + $ => B :MLOAD(halfPairingBN254_Q_x1) + $ :LT, JMPC(halfPairingBN254_Qx1_too_big) + $ => B :MLOAD(halfPairingBN254_Q_x2) + $ :LT, JMPC(halfPairingBN254_Qx2_too_big) + $ => B :MLOAD(halfPairingBN254_Q_y1) + $ :LT, JMPC(halfPairingBN254_Qy1_too_big) + $ => B :MLOAD(halfPairingBN254_Q_y2) + $ :LT, JMPC(halfPairingBN254_Qy2_too_big) + + ; Is P = O? + 0n => B + $ => A :MLOAD(halfPairingBN254_P_x) + $ :EQ, JMPNC(halfPairingBN254_P_continue) + $ => A :MLOAD(halfPairingBN254_P_y) + $ :EQ, JMPC(halfPairingBN254_P_is_zero) + halfPairingBN254_P_continue: + + ; Is Q = O? + $ => A :MLOAD(halfPairingBN254_Q_x1) + $ :EQ, JMPNC(halfPairingBN254_Q_continue1) + $ => A :MLOAD(halfPairingBN254_Q_x2) + $ :EQ, JMPNC(halfPairingBN254_Q_continue1) + $ => A :MLOAD(halfPairingBN254_Q_y1) + $ :EQ, JMPNC(halfPairingBN254_Q_continue1) + $ => A :MLOAD(halfPairingBN254_Q_y2) + $ :EQ, JMPC(halfPairingBN254_Q_is_zero) + halfPairingBN254_Q_continue1: + + :JMP(halfPairingBN254_P_subgroup_check) + +halfPairingBN254_P_is_zero: + ; Is Q = O? + $ => A :MLOAD(halfPairingBN254_Q_x1) + $ :EQ, JMPNC(halfPairingBN254_Q_continue2) + $ => A :MLOAD(halfPairingBN254_Q_x2) + $ :EQ, JMPNC(halfPairingBN254_Q_continue2) + $ => A :MLOAD(halfPairingBN254_Q_y1) + $ :EQ, JMPNC(halfPairingBN254_Q_continue2) + $ => A :MLOAD(halfPairingBN254_Q_y2) + $ :EQ, JMPC(halfPairingBN254_P_and_Q_are_zero) + halfPairingBN254_Q_continue2: + + ; Check that Q is in G2 + ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 + + ; 1] Check if Q is in E'(Fp2) + ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) + ; 1.1] Compute LHS and RHS + $ => A :MLOAD(halfPairingBN254_Q_x1) + $ => B :MLOAD(halfPairingBN254_Q_x2), CALL(squareFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)² + + E => A + C => B + $ => C :MLOAD(halfPairingBN254_Q_x1) + $ => D :MLOAD(halfPairingBN254_Q_x2), CALL(mulFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + + E => A + C => B + %BN254_ETWISTED_B_X => C + %BN254_ETWISTED_B_Y => D :CALL(addFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + 3/(9+u) + E :MSTORE(halfPairingBN254_Q_RHS_x) + C :MSTORE(halfPairingBN254_Q_RHS_y) + + $ => A :MLOAD(halfPairingBN254_Q_y1) + $ => B :MLOAD(halfPairingBN254_Q_y2), CALL(squareFp2BN254) + ; E + C·u = (Q.y1 + Q.y2·u)² + + ; 1.2] Check if LHS == RHS + E => A + $ => B :MLOAD(halfPairingBN254_Q_RHS_x) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + C => A + $ => B :MLOAD(halfPairingBN254_Q_RHS_y) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + ; 2] Check if psi(Q) == [6x²]Q + ; 2.1] Compute psi(Q) + %BN254_P => A + $ => B :MLOAD(halfPairingBN254_Q_x2) + $ => D :SUB ; D = -Qx2 + %FROBENIUS_GAMMA121 => A + %FROBENIUS_GAMMA122 => B + $ => C :MLOAD(halfPairingBN254_Q_x1), CALL(mulFp2BN254) + E :MSTORE(halfPairingBN254_psi_x1) + C :MSTORE(halfPairingBN254_psi_x2) + + %BN254_P => A + $ => B :MLOAD(halfPairingBN254_Q_y2) + $ => D :SUB ; D = -Qy2 + %FROBENIUS_GAMMA131 => A + %FROBENIUS_GAMMA132 => B + $ => C :MLOAD(halfPairingBN254_Q_y1), CALL(mulFp2BN254) + E :MSTORE(halfPairingBN254_psi_y1) + C :MSTORE(halfPairingBN254_psi_y2) + + ; 2.2] Compute [6x²]Q + $ => A :MLOAD(halfPairingBN254_Q_x1) + $ => B :MLOAD(halfPairingBN254_Q_x2) + $ => C :MLOAD(halfPairingBN254_Q_y1) + $ => D :MLOAD(halfPairingBN254_Q_y2) + A :MSTORE(escalarMulBN254_P_x1) + B :MSTORE(escalarMulBN254_P_x2) + C :MSTORE(escalarMulBN254_P_y1) + D :MSTORE(escalarMulBN254_P_y2) + %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) + + + ; 2.3] Check if psi(Q) == [6x²]Q + $ => A :MLOAD(halfPairingBN254_psi_x1) + $ => B :MLOAD(escalarMulBN254_Q_x1) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(halfPairingBN254_psi_x2) + $ => B :MLOAD(escalarMulBN254_Q_x2) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(halfPairingBN254_psi_y1) + $ => B :MLOAD(escalarMulBN254_Q_y1) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(halfPairingBN254_psi_y2) + $ => B :MLOAD(escalarMulBN254_Q_y2) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + ; e(O,Q) = 1 + 1n :MSTORE(halfPairingBN254_f11_x) + 0n :MSTORE(halfPairingBN254_f11_y) + 0n :MSTORE(halfPairingBN254_f12_x) + 0n :MSTORE(halfPairingBN254_f12_y) + 0n :MSTORE(halfPairingBN254_f13_x) + 0n :MSTORE(halfPairingBN254_f13_y) + 0n :MSTORE(halfPairingBN254_f21_x) + 0n :MSTORE(halfPairingBN254_f21_y) + 0n :MSTORE(halfPairingBN254_f22_x) + 0n :MSTORE(halfPairingBN254_f22_y) + 0n :MSTORE(halfPairingBN254_f23_x) + 0n :MSTORE(halfPairingBN254_f23_y) + + 0 => B :JMP(halfPairingBN254_end) + +halfPairingBN254_Q_is_zero: + ; Check that P is in G1 + ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) + ; 1] Compute LHS and RHS + $ => A,B :MLOAD(halfPairingBN254_P_x), CALL(mulFpBN254); C = (Px)² + C => A ; A = (Px)² + $ => B :MLOAD(halfPairingBN254_P_x), CALL(mulFpBN254); C = (Px)³ + + %BN254_E_B => A :CALL(addFpBN254) ; C = (Px)³ + 3 + C :MSTORE(halfPairingBN254_P_x3) ; halfPairingBN254_P_x3 = (Px)³ + 3 + + $ => A,B :MLOAD(halfPairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + + ; 2] Check if LHS == RHS + C => A + $ => B :MLOAD(halfPairingBN254_P_x3) + $ :EQ, JMPNC(halfPairingBN254_P_is_not_in_G1) + + ; e(P,O) = 1 + 1n :MSTORE(halfPairingBN254_f11_x) + 0n :MSTORE(halfPairingBN254_f11_y) + 0n :MSTORE(halfPairingBN254_f12_x) + 0n :MSTORE(halfPairingBN254_f12_y) + 0n :MSTORE(halfPairingBN254_f13_x) + 0n :MSTORE(halfPairingBN254_f13_y) + 0n :MSTORE(halfPairingBN254_f21_x) + 0n :MSTORE(halfPairingBN254_f21_y) + 0n :MSTORE(halfPairingBN254_f22_x) + 0n :MSTORE(halfPairingBN254_f22_y) + 0n :MSTORE(halfPairingBN254_f23_x) + 0n :MSTORE(halfPairingBN254_f23_y) + + 0 => B :JMP(halfPairingBN254_end) + +halfPairingBN254_P_and_Q_are_zero: + ; e(O,O) = 1 + 1n :MSTORE(halfPairingBN254_f11_x) + 0n :MSTORE(halfPairingBN254_f11_y) + 0n :MSTORE(halfPairingBN254_f12_x) + 0n :MSTORE(halfPairingBN254_f12_y) + 0n :MSTORE(halfPairingBN254_f13_x) + 0n :MSTORE(halfPairingBN254_f13_y) + 0n :MSTORE(halfPairingBN254_f21_x) + 0n :MSTORE(halfPairingBN254_f21_y) + 0n :MSTORE(halfPairingBN254_f22_x) + 0n :MSTORE(halfPairingBN254_f22_y) + 0n :MSTORE(halfPairingBN254_f23_x) + 0n :MSTORE(halfPairingBN254_f23_y) + + 0 => B :JMP(halfPairingBN254_end) + +halfPairingBN254_P_subgroup_check: + ; Check that P is in G1 + ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) + ; 1] Compute LHS and RHS + $ => A,B :MLOAD(halfPairingBN254_P_x), CALL(mulFpBN254); C = (Px)² + C => A ; A = (Px)² + $ => B :MLOAD(halfPairingBN254_P_x), CALL(mulFpBN254); C = (Px)³ + + %BN254_E_B => A :CALL(addFpBN254) ; C = (Px)³ + 3 + C :MSTORE(halfPairingBN254_P_x3) ; halfPairingBN254_P_x3 = (Px)³ + 3 + + $ => A,B :MLOAD(halfPairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + + ; 2] Check if LHS == RHS + C => A + $ => B :MLOAD(halfPairingBN254_P_x3) + $ :EQ, JMPNC(halfPairingBN254_P_is_not_in_G1) + +halfPairingBN254_Q_subgroup_check: + ; Check that Q is in G2 + ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 + + ; 1] Check if Q is in E'(Fp2) + ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) + ; 1.1] Compute LHS and RHS + $ => A :MLOAD(halfPairingBN254_Q_x1) + $ => B :MLOAD(halfPairingBN254_Q_x2), CALL(squareFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)² + + E => A + C => B + $ => C :MLOAD(halfPairingBN254_Q_x1) + $ => D :MLOAD(halfPairingBN254_Q_x2), CALL(mulFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + + E => A + C => B + %BN254_ETWISTED_B_X => C + %BN254_ETWISTED_B_Y => D :CALL(addFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + 3/(9+u) + E :MSTORE(halfPairingBN254_Q_RHS_x) + C :MSTORE(halfPairingBN254_Q_RHS_y) + + $ => A :MLOAD(halfPairingBN254_Q_y1) + $ => B :MLOAD(halfPairingBN254_Q_y2), CALL(squareFp2BN254) + ; E + C·u = (Q.y1 + Q.y2·u)² + + ; 1.2] Check if LHS == RHS + E => A + $ => B :MLOAD(halfPairingBN254_Q_RHS_x) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + C => A + $ => B :MLOAD(halfPairingBN254_Q_RHS_y) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + ; 2] Check if psi(Q) == [6x²]Q + ; 2.1] Compute psi(Q) + %BN254_P => A + $ => B :MLOAD(halfPairingBN254_Q_x2) + $ => D :SUB ; D = -Qx2 + %FROBENIUS_GAMMA121 => A + %FROBENIUS_GAMMA122 => B + $ => C :MLOAD(halfPairingBN254_Q_x1), CALL(mulFp2BN254) + E :MSTORE(halfPairingBN254_psi_x1) + C :MSTORE(halfPairingBN254_psi_x2) + + %BN254_P => A + $ => B :MLOAD(halfPairingBN254_Q_y2) + $ => D :SUB ; D = -Qx2 + %FROBENIUS_GAMMA131 => A + %FROBENIUS_GAMMA132 => B + $ => C :MLOAD(halfPairingBN254_Q_y1), CALL(mulFp2BN254) + E :MSTORE(halfPairingBN254_psi_y1) + C :MSTORE(halfPairingBN254_psi_y2) + + ; 2.2] Compute [6x²]Q + $ => A :MLOAD(halfPairingBN254_Q_x1) + $ => B :MLOAD(halfPairingBN254_Q_x2) + $ => C :MLOAD(halfPairingBN254_Q_y1) + $ => D :MLOAD(halfPairingBN254_Q_y2) + A :MSTORE(escalarMulBN254_P_x1) + B :MSTORE(escalarMulBN254_P_x2) + C :MSTORE(escalarMulBN254_P_y1) + D :MSTORE(escalarMulBN254_P_y2) + %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) + + + ; 2.3] Check if psi(Q) == [6x²]Q + $ => A :MLOAD(halfPairingBN254_psi_x1) + $ => B :MLOAD(escalarMulBN254_Q_x1) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(halfPairingBN254_psi_x2) + $ => B :MLOAD(escalarMulBN254_Q_x2) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(halfPairingBN254_psi_y1) + $ => B :MLOAD(escalarMulBN254_Q_y1) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(halfPairingBN254_psi_y2) + $ => B :MLOAD(escalarMulBN254_Q_y2) + $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + +halfPairingBN254_Miller_loop: + $ => A :MLOAD(halfPairingBN254_P_x) + $ => B :MLOAD(halfPairingBN254_P_y) + A :MSTORE(millerLoopBN254_P_x) + B :MSTORE(millerLoopBN254_P_y) + $ => A :MLOAD(halfPairingBN254_Q_x1) + $ => B :MLOAD(halfPairingBN254_Q_x2) + $ => C :MLOAD(halfPairingBN254_Q_y1) + $ => D :MLOAD(halfPairingBN254_Q_y2) + A :MSTORE(millerLoopBN254_Q_x1) + B :MSTORE(millerLoopBN254_Q_x2) + C :MSTORE(millerLoopBN254_Q_y1) + D :MSTORE(millerLoopBN254_Q_y2), CALL(millerLoopBN254) + $ => A :MLOAD(millerLoopBN254_f11_x) + $ => B :MLOAD(millerLoopBN254_f11_y) + A :MSTORE(halfPairingBN254_f11_x) + B :MSTORE(halfPairingBN254_f11_y) + $ => A :MLOAD(millerLoopBN254_f12_x) + $ => B :MLOAD(millerLoopBN254_f12_y) + A :MSTORE(halfPairingBN254_f12_x) + B :MSTORE(halfPairingBN254_f12_y) + $ => A :MLOAD(millerLoopBN254_f13_x) + $ => B :MLOAD(millerLoopBN254_f13_y) + A :MSTORE(halfPairingBN254_f13_x) + B :MSTORE(halfPairingBN254_f13_y) + $ => A :MLOAD(millerLoopBN254_f21_x) + $ => B :MLOAD(millerLoopBN254_f21_y) + A :MSTORE(halfPairingBN254_f21_x) + B :MSTORE(halfPairingBN254_f21_y) + $ => A :MLOAD(millerLoopBN254_f22_x) + $ => B :MLOAD(millerLoopBN254_f22_y) + A :MSTORE(halfPairingBN254_f22_x) + B :MSTORE(halfPairingBN254_f22_y) + $ => A :MLOAD(millerLoopBN254_f23_x) + $ => B :MLOAD(millerLoopBN254_f23_y) + A :MSTORE(halfPairingBN254_f23_x) + B :MSTORE(halfPairingBN254_f23_y) + + 0 => B :JMP(halfPairingBN254_end) + +; ERRORS +halfPairingBN254_Px_too_big: + 1 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_Py_too_big: + 2 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_Qx1_too_big: + 3 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_Qx2_too_big: + 4 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_Qy1_too_big: + 5 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_Qy2_too_big: + 6 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_P_is_not_in_G1: + 7 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_Q_is_not_in_G2: + 8 => B :JMP(halfPairingBN254_error) + +halfPairingBN254_error: + 0 => A + +halfPairingBN254_end: + $ => RR :MLOAD(halfPairingBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/loopLengthBN254.zkasm b/main/pairings/loopLengthBN254.zkasm new file mode 100644 index 00000000..3f07d384 --- /dev/null +++ b/main/pairings/loopLengthBN254.zkasm @@ -0,0 +1,75 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; loopLengthBN254: +;; output: A digit of the (little-endian) pseudobinary representation of the loop length +;; of the optimal ate pairing over the BN254. The loop length is precisely 6·x + 2. +;; and is represented as follows: +;; 0001010-1001-100100110-10010-1000011100-100100000-1001100-1000110-1001011 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +loopLengthBN254: + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN \ No newline at end of file diff --git a/main/pairings/millerLoopBN254.zkasm b/main/pairings/millerLoopBN254.zkasm new file mode 100644 index 00000000..10f09505 --- /dev/null +++ b/main/pairings/millerLoopBN254.zkasm @@ -0,0 +1,740 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; millerLoopBN254: +;; input: P ∈ G1 and Q ∈ G2 +;; output: f_{r,Q}(P) ∈ Fp12 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL millerLoopBN254_P_x +VAR GLOBAL millerLoopBN254_P_y +VAR GLOBAL millerLoopBN254_Q_x1 +VAR GLOBAL millerLoopBN254_Q_x2 +VAR GLOBAL millerLoopBN254_Q_y1 +VAR GLOBAL millerLoopBN254_Q_y2 + +VAR GLOBAL millerLoopBN254_Frobenius1_Q_x1 +VAR GLOBAL millerLoopBN254_Frobenius1_Q_x2 +VAR GLOBAL millerLoopBN254_Frobenius1_Q_y1 +VAR GLOBAL millerLoopBN254_Frobenius1_Q_y2 +VAR GLOBAL millerLoopBN254_nFrobenius2_Q_x1 +VAR GLOBAL millerLoopBN254_nFrobenius2_Q_x2 + +VAR GLOBAL millerLoopBN254_R_x1 +VAR GLOBAL millerLoopBN254_R_x2 +VAR GLOBAL millerLoopBN254_R_y1 +VAR GLOBAL millerLoopBN254_R_y2 +VAR GLOBAL millerLoopBN254_f11_x +VAR GLOBAL millerLoopBN254_f11_y +VAR GLOBAL millerLoopBN254_f12_x +VAR GLOBAL millerLoopBN254_f12_y +VAR GLOBAL millerLoopBN254_f13_x +VAR GLOBAL millerLoopBN254_f13_y +VAR GLOBAL millerLoopBN254_f21_x +VAR GLOBAL millerLoopBN254_f21_y +VAR GLOBAL millerLoopBN254_f22_x +VAR GLOBAL millerLoopBN254_f22_y +VAR GLOBAL millerLoopBN254_f23_x +VAR GLOBAL millerLoopBN254_f23_y +VAR GLOBAL millerLoopBN254_fsquare11_x +VAR GLOBAL millerLoopBN254_fsquare11_y +VAR GLOBAL millerLoopBN254_fsquare12_x +VAR GLOBAL millerLoopBN254_fsquare12_y +VAR GLOBAL millerLoopBN254_fsquare13_x +VAR GLOBAL millerLoopBN254_fsquare13_y +VAR GLOBAL millerLoopBN254_fsquare21_x +VAR GLOBAL millerLoopBN254_fsquare21_y +VAR GLOBAL millerLoopBN254_fsquare22_x +VAR GLOBAL millerLoopBN254_fsquare22_y +VAR GLOBAL millerLoopBN254_fsquare23_x +VAR GLOBAL millerLoopBN254_fsquare23_y + +VAR GLOBAL millerLoopBN254_RR + +millerLoopBN254: + RR :MSTORE(millerLoopBN254_RR) + + 65 => RCX + + ; Initiliaze Miller loop with R = Q and f = 1 + $ => A :MLOAD(millerLoopBN254_Q_x1) + $ => B :MLOAD(millerLoopBN254_Q_x2) + $ => C :MLOAD(millerLoopBN254_Q_y1) + $ => D :MLOAD(millerLoopBN254_Q_y2) + A :MSTORE(millerLoopBN254_R_x1) + B :MSTORE(millerLoopBN254_R_x2) + C :MSTORE(millerLoopBN254_R_y1) + D :MSTORE(millerLoopBN254_R_y2) + 1n :MSTORE(millerLoopBN254_f11_x) + 0n :MSTORE(millerLoopBN254_f11_y) + 0n :MSTORE(millerLoopBN254_f12_x) + 0n :MSTORE(millerLoopBN254_f12_y) + 0n :MSTORE(millerLoopBN254_f13_x) + 0n :MSTORE(millerLoopBN254_f13_y) + 0n :MSTORE(millerLoopBN254_f21_x) + 0n :MSTORE(millerLoopBN254_f21_y) + 0n :MSTORE(millerLoopBN254_f22_x) + 0n :MSTORE(millerLoopBN254_f22_y) + 0n :MSTORE(millerLoopBN254_f23_x) + 0n :MSTORE(millerLoopBN254_f23_y) + +millerLoopBN254_loop: + RCX - 1 => RCX :JMPZ(millerLoopBN254_last_two_lines) + + ; 1] f = f² · line_{twist(R),twist(R)}(P) + + ; f² + $ => A :MLOAD(millerLoopBN254_f11_x) + $ => B :MLOAD(millerLoopBN254_f11_y) + A :MSTORE(squareFp12BN254_a11_x) + B :MSTORE(squareFp12BN254_a11_y) + $ => A :MLOAD(millerLoopBN254_f12_x) + $ => B :MLOAD(millerLoopBN254_f12_y) + A :MSTORE(squareFp12BN254_a12_x) + B :MSTORE(squareFp12BN254_a12_y) + $ => A :MLOAD(millerLoopBN254_f13_x) + $ => B :MLOAD(millerLoopBN254_f13_y) + A :MSTORE(squareFp12BN254_a13_x) + B :MSTORE(squareFp12BN254_a13_y) + $ => A :MLOAD(millerLoopBN254_f21_x) + $ => B :MLOAD(millerLoopBN254_f21_y) + A :MSTORE(squareFp12BN254_a21_x) + B :MSTORE(squareFp12BN254_a21_y) + $ => A :MLOAD(millerLoopBN254_f22_x) + $ => B :MLOAD(millerLoopBN254_f22_y) + A :MSTORE(squareFp12BN254_a22_x) + B :MSTORE(squareFp12BN254_a22_y) + $ => A :MLOAD(millerLoopBN254_f23_x) + $ => B :MLOAD(millerLoopBN254_f23_y) + A :MSTORE(squareFp12BN254_a23_x) + B :MSTORE(squareFp12BN254_a23_y), CALL(squareFp12BN254) + + $ => A :MLOAD(squareFp12BN254_c11_x) + $ => B :MLOAD(squareFp12BN254_c11_y) + A :MSTORE(millerLoopBN254_fsquare11_x) + B :MSTORE(millerLoopBN254_fsquare11_y) + $ => A :MLOAD(squareFp12BN254_c12_x) + $ => B :MLOAD(squareFp12BN254_c12_y) + A :MSTORE(millerLoopBN254_fsquare12_x) + B :MSTORE(millerLoopBN254_fsquare12_y) + $ => A :MLOAD(squareFp12BN254_c13_x) + $ => B :MLOAD(squareFp12BN254_c13_y) + A :MSTORE(millerLoopBN254_fsquare13_x) + B :MSTORE(millerLoopBN254_fsquare13_y) + $ => A :MLOAD(squareFp12BN254_c21_x) + $ => B :MLOAD(squareFp12BN254_c21_y) + A :MSTORE(millerLoopBN254_fsquare21_x) + B :MSTORE(millerLoopBN254_fsquare21_y) + $ => A :MLOAD(squareFp12BN254_c22_x) + $ => B :MLOAD(squareFp12BN254_c22_y) + A :MSTORE(millerLoopBN254_fsquare22_x) + B :MSTORE(millerLoopBN254_fsquare22_y) + $ => A :MLOAD(squareFp12BN254_c23_x) + $ => B :MLOAD(squareFp12BN254_c23_y) + A :MSTORE(millerLoopBN254_fsquare23_x) + B :MSTORE(millerLoopBN254_fsquare23_y) + + ; line_{twist(R),twist(R)}(P) + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(lineSamePointsBN254_P_x1) + B :MSTORE(lineSamePointsBN254_P_x2) + C :MSTORE(lineSamePointsBN254_P_y1) + D :MSTORE(lineSamePointsBN254_P_y2) + $ => A :MLOAD(millerLoopBN254_P_x) + $ => B :MLOAD(millerLoopBN254_P_y) + A :MSTORE(lineSamePointsBN254_Q_x) + B :MSTORE(lineSamePointsBN254_Q_y), CALL(lineSamePointsBN254) + + $ => A :MLOAD(millerLoopBN254_fsquare11_x) + $ => B :MLOAD(millerLoopBN254_fsquare11_y) + A :MSTORE(sparseMulBFp12BN254_a11_x) + B :MSTORE(sparseMulBFp12BN254_a11_y) + $ => A :MLOAD(millerLoopBN254_fsquare12_x) + $ => B :MLOAD(millerLoopBN254_fsquare12_y) + A :MSTORE(sparseMulBFp12BN254_a12_x) + B :MSTORE(sparseMulBFp12BN254_a12_y) + $ => A :MLOAD(millerLoopBN254_fsquare13_x) + $ => B :MLOAD(millerLoopBN254_fsquare13_y) + A :MSTORE(sparseMulBFp12BN254_a13_x) + B :MSTORE(sparseMulBFp12BN254_a13_y) + $ => A :MLOAD(millerLoopBN254_fsquare21_x) + $ => B :MLOAD(millerLoopBN254_fsquare21_y) + A :MSTORE(sparseMulBFp12BN254_a21_x) + B :MSTORE(sparseMulBFp12BN254_a21_y) + $ => A :MLOAD(millerLoopBN254_fsquare22_x) + $ => B :MLOAD(millerLoopBN254_fsquare22_y) + A :MSTORE(sparseMulBFp12BN254_a22_x) + B :MSTORE(sparseMulBFp12BN254_a22_y) + $ => A :MLOAD(millerLoopBN254_fsquare23_x) + $ => B :MLOAD(millerLoopBN254_fsquare23_y) + A :MSTORE(sparseMulBFp12BN254_a23_x) + B :MSTORE(sparseMulBFp12BN254_a23_y) + + ; f² · line_{twist(R),twist(R)}(P) + $ => A :MLOAD(lineSamePointsBN254_l11_x) + $ => B :MLOAD(lineSamePointsBN254_l11_y) + A :MSTORE(sparseMulBFp12BN254_b11_x) + B :MSTORE(sparseMulBFp12BN254_b11_y) + $ => A :MLOAD(lineSamePointsBN254_l13_x) + $ => B :MLOAD(lineSamePointsBN254_l13_y) + A :MSTORE(sparseMulBFp12BN254_b13_x) + B :MSTORE(sparseMulBFp12BN254_b13_y) + $ => A :MLOAD(lineSamePointsBN254_l22_x) + $ => B :MLOAD(lineSamePointsBN254_l22_y) + A :MSTORE(sparseMulBFp12BN254_b22_x) + B :MSTORE(sparseMulBFp12BN254_b22_y), CALL(sparseMulBFp12BN254) + + $ => A :MLOAD(sparseMulBFp12BN254_c11_x) + $ => B :MLOAD(sparseMulBFp12BN254_c11_y) + A :MSTORE(millerLoopBN254_f11_x) + B :MSTORE(millerLoopBN254_f11_y) + $ => A :MLOAD(sparseMulBFp12BN254_c12_x) + $ => B :MLOAD(sparseMulBFp12BN254_c12_y) + A :MSTORE(millerLoopBN254_f12_x) + B :MSTORE(millerLoopBN254_f12_y) + $ => A :MLOAD(sparseMulBFp12BN254_c13_x) + $ => B :MLOAD(sparseMulBFp12BN254_c13_y) + A :MSTORE(millerLoopBN254_f13_x) + B :MSTORE(millerLoopBN254_f13_y) + $ => A :MLOAD(sparseMulBFp12BN254_c21_x) + $ => B :MLOAD(sparseMulBFp12BN254_c21_y) + A :MSTORE(millerLoopBN254_f21_x) + B :MSTORE(millerLoopBN254_f21_y) + $ => A :MLOAD(sparseMulBFp12BN254_c22_x) + $ => B :MLOAD(sparseMulBFp12BN254_c22_y) + A :MSTORE(millerLoopBN254_f22_x) + B :MSTORE(millerLoopBN254_f22_y) + $ => A :MLOAD(sparseMulBFp12BN254_c23_x) + $ => B :MLOAD(sparseMulBFp12BN254_c23_y) + A :MSTORE(millerLoopBN254_f23_x) + B :MSTORE(millerLoopBN254_f23_y) + + ; 2] R = 2·R + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(addPointBN254_P1_x1) + A :MSTORE(addPointBN254_P2_x1) + B :MSTORE(addPointBN254_P1_x2) + B :MSTORE(addPointBN254_P2_x2) + C :MSTORE(addPointBN254_P1_y1) + C :MSTORE(addPointBN254_P2_y1) + D :MSTORE(addPointBN254_P1_y2) + D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) + + $ => A :MLOAD(addPointBN254_P3_x1) + $ => B :MLOAD(addPointBN254_P3_x2) + $ => C :MLOAD(addPointBN254_P3_y1) + $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(millerLoopBN254_R_x1) + B :MSTORE(millerLoopBN254_R_x2) + C :MSTORE(millerLoopBN254_R_y1) + D :MSTORE(millerLoopBN254_R_y2) + + RCX-1 => RR + :CALL(@loopLengthBN254 + RR) + + ; if bit = -1, then "sub" + B :JMPN(millerLoopBN254_sub) + + ; if bit = 0, then repeat + B :JMPZ(millerLoopBN254_loop) + + ; if bit = -1, then "add" + +millerLoopBN254_add: + ; 1] f = f · line_{twist(R),twist(Q)}(P) + ; line_{twist(R),twist(Q)}(P) + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(lineDiffPointsBN254_P1_x1) + B :MSTORE(lineDiffPointsBN254_P1_x2) + C :MSTORE(lineDiffPointsBN254_P1_y1) + D :MSTORE(lineDiffPointsBN254_P1_y2) + $ => A :MLOAD(millerLoopBN254_Q_x1) + $ => B :MLOAD(millerLoopBN254_Q_x2) + $ => C :MLOAD(millerLoopBN254_Q_y1) + $ => D :MLOAD(millerLoopBN254_Q_y2) + A :MSTORE(lineDiffPointsBN254_P2_x1) + B :MSTORE(lineDiffPointsBN254_P2_x2) + C :MSTORE(lineDiffPointsBN254_P2_y1) + D :MSTORE(lineDiffPointsBN254_P2_y2) + $ => A :MLOAD(millerLoopBN254_P_x) + $ => B :MLOAD(millerLoopBN254_P_y) + A :MSTORE(lineDiffPointsBN254_Q_x) + B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + + $ => A :MLOAD(millerLoopBN254_f11_x) + $ => B :MLOAD(millerLoopBN254_f11_y) + A :MSTORE(sparseMulAFp12BN254_a11_x) + B :MSTORE(sparseMulAFp12BN254_a11_y) + $ => A :MLOAD(millerLoopBN254_f12_x) + $ => B :MLOAD(millerLoopBN254_f12_y) + A :MSTORE(sparseMulAFp12BN254_a12_x) + B :MSTORE(sparseMulAFp12BN254_a12_y) + $ => A :MLOAD(millerLoopBN254_f13_x) + $ => B :MLOAD(millerLoopBN254_f13_y) + A :MSTORE(sparseMulAFp12BN254_a13_x) + B :MSTORE(sparseMulAFp12BN254_a13_y) + $ => A :MLOAD(millerLoopBN254_f21_x) + $ => B :MLOAD(millerLoopBN254_f21_y) + A :MSTORE(sparseMulAFp12BN254_a21_x) + B :MSTORE(sparseMulAFp12BN254_a21_y) + $ => A :MLOAD(millerLoopBN254_f22_x) + $ => B :MLOAD(millerLoopBN254_f22_y) + A :MSTORE(sparseMulAFp12BN254_a22_x) + B :MSTORE(sparseMulAFp12BN254_a22_y) + $ => A :MLOAD(millerLoopBN254_f23_x) + $ => B :MLOAD(millerLoopBN254_f23_y) + A :MSTORE(sparseMulAFp12BN254_a23_x) + B :MSTORE(sparseMulAFp12BN254_a23_y) + + ; f · line_{twist(R),twist(Q)}(P) + $ => A :MLOAD(lineDiffPointsBN254_l12_x) + $ => B :MLOAD(lineDiffPointsBN254_l12_y) + A :MSTORE(sparseMulAFp12BN254_b12_x) + B :MSTORE(sparseMulAFp12BN254_b12_y) + $ => A :MLOAD(lineDiffPointsBN254_l22_x) + $ => B :MLOAD(lineDiffPointsBN254_l22_y) + A :MSTORE(sparseMulAFp12BN254_b22_x) + B :MSTORE(sparseMulAFp12BN254_b22_y) + $ => A :MLOAD(lineDiffPointsBN254_l23_x) + $ => B :MLOAD(lineDiffPointsBN254_l23_y) + A :MSTORE(sparseMulAFp12BN254_b23_x) + B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + + $ => A :MLOAD(sparseMulAFp12BN254_c11_x) + $ => B :MLOAD(sparseMulAFp12BN254_c11_y) + A :MSTORE(millerLoopBN254_f11_x) + B :MSTORE(millerLoopBN254_f11_y) + $ => A :MLOAD(sparseMulAFp12BN254_c12_x) + $ => B :MLOAD(sparseMulAFp12BN254_c12_y) + A :MSTORE(millerLoopBN254_f12_x) + B :MSTORE(millerLoopBN254_f12_y) + $ => A :MLOAD(sparseMulAFp12BN254_c13_x) + $ => B :MLOAD(sparseMulAFp12BN254_c13_y) + A :MSTORE(millerLoopBN254_f13_x) + B :MSTORE(millerLoopBN254_f13_y) + $ => A :MLOAD(sparseMulAFp12BN254_c21_x) + $ => B :MLOAD(sparseMulAFp12BN254_c21_y) + A :MSTORE(millerLoopBN254_f21_x) + B :MSTORE(millerLoopBN254_f21_y) + $ => A :MLOAD(sparseMulAFp12BN254_c22_x) + $ => B :MLOAD(sparseMulAFp12BN254_c22_y) + A :MSTORE(millerLoopBN254_f22_x) + B :MSTORE(millerLoopBN254_f22_y) + $ => A :MLOAD(sparseMulAFp12BN254_c23_x) + $ => B :MLOAD(sparseMulAFp12BN254_c23_y) + A :MSTORE(millerLoopBN254_f23_x) + B :MSTORE(millerLoopBN254_f23_y) + + ; 2] R = R + Q + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(addPointBN254_P1_x1) + B :MSTORE(addPointBN254_P1_x2) + C :MSTORE(addPointBN254_P1_y1) + D :MSTORE(addPointBN254_P1_y2) + $ => A :MLOAD(millerLoopBN254_Q_x1) + $ => B :MLOAD(millerLoopBN254_Q_x2) + $ => C :MLOAD(millerLoopBN254_Q_y1) + $ => D :MLOAD(millerLoopBN254_Q_y2) + A :MSTORE(addPointBN254_P2_x1) + B :MSTORE(addPointBN254_P2_x2) + C :MSTORE(addPointBN254_P2_y1) + D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) + + $ => A :MLOAD(addPointBN254_P3_x1) + $ => B :MLOAD(addPointBN254_P3_x2) + $ => C :MLOAD(addPointBN254_P3_y1) + $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(millerLoopBN254_R_x1) + B :MSTORE(millerLoopBN254_R_x2) + C :MSTORE(millerLoopBN254_R_y1) + D :MSTORE(millerLoopBN254_R_y2) + + :JMP(millerLoopBN254_loop) + + +millerLoopBN254_sub: + ; 1] f = f · line_{twist(R),twist(-Q)}(P) + ; line_{twist(R),twist(-Q)}(P) + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(lineDiffPointsBN254_P1_x1) + B :MSTORE(lineDiffPointsBN254_P1_x2) + C :MSTORE(lineDiffPointsBN254_P1_y1) + D :MSTORE(lineDiffPointsBN254_P1_y2) + $ => A :MLOAD(millerLoopBN254_Q_x1) + $ => B :MLOAD(millerLoopBN254_Q_x2) + A :MSTORE(lineDiffPointsBN254_P2_x1) + B :MSTORE(lineDiffPointsBN254_P2_x2) + + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Q_y1) + $ :SUB, MSTORE(lineDiffPointsBN254_P2_y1) + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Q_y2) + $ :SUB, MSTORE(lineDiffPointsBN254_P2_y2) + + $ => A :MLOAD(millerLoopBN254_P_x) + $ => B :MLOAD(millerLoopBN254_P_y) + A :MSTORE(lineDiffPointsBN254_Q_x) + B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + + $ => A :MLOAD(millerLoopBN254_f11_x) + $ => B :MLOAD(millerLoopBN254_f11_y) + A :MSTORE(sparseMulAFp12BN254_a11_x) + B :MSTORE(sparseMulAFp12BN254_a11_y) + $ => A :MLOAD(millerLoopBN254_f12_x) + $ => B :MLOAD(millerLoopBN254_f12_y) + A :MSTORE(sparseMulAFp12BN254_a12_x) + B :MSTORE(sparseMulAFp12BN254_a12_y) + $ => A :MLOAD(millerLoopBN254_f13_x) + $ => B :MLOAD(millerLoopBN254_f13_y) + A :MSTORE(sparseMulAFp12BN254_a13_x) + B :MSTORE(sparseMulAFp12BN254_a13_y) + $ => A :MLOAD(millerLoopBN254_f21_x) + $ => B :MLOAD(millerLoopBN254_f21_y) + A :MSTORE(sparseMulAFp12BN254_a21_x) + B :MSTORE(sparseMulAFp12BN254_a21_y) + $ => A :MLOAD(millerLoopBN254_f22_x) + $ => B :MLOAD(millerLoopBN254_f22_y) + A :MSTORE(sparseMulAFp12BN254_a22_x) + B :MSTORE(sparseMulAFp12BN254_a22_y) + $ => A :MLOAD(millerLoopBN254_f23_x) + $ => B :MLOAD(millerLoopBN254_f23_y) + A :MSTORE(sparseMulAFp12BN254_a23_x) + B :MSTORE(sparseMulAFp12BN254_a23_y) + + ; ; f · line_{twist(R),twist(-Q)}(P) + $ => A :MLOAD(lineDiffPointsBN254_l12_x) + $ => B :MLOAD(lineDiffPointsBN254_l12_y) + A :MSTORE(sparseMulAFp12BN254_b12_x) + B :MSTORE(sparseMulAFp12BN254_b12_y) + $ => A :MLOAD(lineDiffPointsBN254_l22_x) + $ => B :MLOAD(lineDiffPointsBN254_l22_y) + A :MSTORE(sparseMulAFp12BN254_b22_x) + B :MSTORE(sparseMulAFp12BN254_b22_y) + $ => A :MLOAD(lineDiffPointsBN254_l23_x) + $ => B :MLOAD(lineDiffPointsBN254_l23_y) + A :MSTORE(sparseMulAFp12BN254_b23_x) + B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + + $ => A :MLOAD(sparseMulAFp12BN254_c11_x) + $ => B :MLOAD(sparseMulAFp12BN254_c11_y) + A :MSTORE(millerLoopBN254_f11_x) + B :MSTORE(millerLoopBN254_f11_y) + $ => A :MLOAD(sparseMulAFp12BN254_c12_x) + $ => B :MLOAD(sparseMulAFp12BN254_c12_y) + A :MSTORE(millerLoopBN254_f12_x) + B :MSTORE(millerLoopBN254_f12_y) + $ => A :MLOAD(sparseMulAFp12BN254_c13_x) + $ => B :MLOAD(sparseMulAFp12BN254_c13_y) + A :MSTORE(millerLoopBN254_f13_x) + B :MSTORE(millerLoopBN254_f13_y) + $ => A :MLOAD(sparseMulAFp12BN254_c21_x) + $ => B :MLOAD(sparseMulAFp12BN254_c21_y) + A :MSTORE(millerLoopBN254_f21_x) + B :MSTORE(millerLoopBN254_f21_y) + $ => A :MLOAD(sparseMulAFp12BN254_c22_x) + $ => B :MLOAD(sparseMulAFp12BN254_c22_y) + A :MSTORE(millerLoopBN254_f22_x) + B :MSTORE(millerLoopBN254_f22_y) + $ => A :MLOAD(sparseMulAFp12BN254_c23_x) + $ => B :MLOAD(sparseMulAFp12BN254_c23_y) + A :MSTORE(millerLoopBN254_f23_x) + B :MSTORE(millerLoopBN254_f23_y) + + ; 2] R = R - Q + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(addPointBN254_P1_x1) + B :MSTORE(addPointBN254_P1_x2) + C :MSTORE(addPointBN254_P1_y1) + D :MSTORE(addPointBN254_P1_y2) + $ => A :MLOAD(millerLoopBN254_Q_x1) + $ => B :MLOAD(millerLoopBN254_Q_x2) + A :MSTORE(addPointBN254_P2_x1) + B :MSTORE(addPointBN254_P2_x2) + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Q_y1) + $ :SUB, MSTORE(addPointBN254_P2_y1) + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Q_y2) + $ :SUB, MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) + + + $ => A :MLOAD(addPointBN254_P3_x1) + $ => B :MLOAD(addPointBN254_P3_x2) + $ => C :MLOAD(addPointBN254_P3_y1) + $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(millerLoopBN254_R_x1) + B :MSTORE(millerLoopBN254_R_x2) + C :MSTORE(millerLoopBN254_R_y1) + D :MSTORE(millerLoopBN254_R_y2) + + :JMP(millerLoopBN254_loop) + +millerLoopBN254_last_two_lines: + ; 1] Given Q = (x,y) with x,y ∈ Fp2, compute Frobenius1(Q) = (\gamma12·x̄, \gamma13·ȳ) + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Q_x2) + $ => B :SUB + $ => A :MLOAD(millerLoopBN254_Q_x1) + %FROBENIUS_GAMMA121 => C + %FROBENIUS_GAMMA122 => D :CALL(mulFp2BN254) + + E :MSTORE(millerLoopBN254_Frobenius1_Q_x1) + C :MSTORE(millerLoopBN254_Frobenius1_Q_x2) + + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Q_y2) + $ => B :SUB + $ => A :MLOAD(millerLoopBN254_Q_y1) + %FROBENIUS_GAMMA131 => C + %FROBENIUS_GAMMA132 => D :CALL(mulFp2BN254) + + E :MSTORE(millerLoopBN254_Frobenius1_Q_y1) + C :MSTORE(millerLoopBN254_Frobenius1_Q_y2) + + + ; 2] f = f · line_{twist(R),twist(Frobenius1(Q))}(P) + ; line_{twist(R),twist(Frobenius1(Q))}(P) + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(lineDiffPointsBN254_P1_x1) + B :MSTORE(lineDiffPointsBN254_P1_x2) + C :MSTORE(lineDiffPointsBN254_P1_y1) + D :MSTORE(lineDiffPointsBN254_P1_y2) + $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_x1) + $ => B :MLOAD(millerLoopBN254_Frobenius1_Q_x2) + $ => C :MLOAD(millerLoopBN254_Frobenius1_Q_y1) + $ => D :MLOAD(millerLoopBN254_Frobenius1_Q_y2) + A :MSTORE(lineDiffPointsBN254_P2_x1) + B :MSTORE(lineDiffPointsBN254_P2_x2) + C :MSTORE(lineDiffPointsBN254_P2_y1) + D :MSTORE(lineDiffPointsBN254_P2_y2) + + $ => A :MLOAD(millerLoopBN254_P_x) + $ => B :MLOAD(millerLoopBN254_P_y) + A :MSTORE(lineDiffPointsBN254_Q_x) + B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + + $ => A :MLOAD(millerLoopBN254_f11_x) + $ => B :MLOAD(millerLoopBN254_f11_y) + A :MSTORE(sparseMulAFp12BN254_a11_x) + B :MSTORE(sparseMulAFp12BN254_a11_y) + $ => A :MLOAD(millerLoopBN254_f12_x) + $ => B :MLOAD(millerLoopBN254_f12_y) + A :MSTORE(sparseMulAFp12BN254_a12_x) + B :MSTORE(sparseMulAFp12BN254_a12_y) + $ => A :MLOAD(millerLoopBN254_f13_x) + $ => B :MLOAD(millerLoopBN254_f13_y) + A :MSTORE(sparseMulAFp12BN254_a13_x) + B :MSTORE(sparseMulAFp12BN254_a13_y) + $ => A :MLOAD(millerLoopBN254_f21_x) + $ => B :MLOAD(millerLoopBN254_f21_y) + A :MSTORE(sparseMulAFp12BN254_a21_x) + B :MSTORE(sparseMulAFp12BN254_a21_y) + $ => A :MLOAD(millerLoopBN254_f22_x) + $ => B :MLOAD(millerLoopBN254_f22_y) + A :MSTORE(sparseMulAFp12BN254_a22_x) + B :MSTORE(sparseMulAFp12BN254_a22_y) + $ => A :MLOAD(millerLoopBN254_f23_x) + $ => B :MLOAD(millerLoopBN254_f23_y) + A :MSTORE(sparseMulAFp12BN254_a23_x) + B :MSTORE(sparseMulAFp12BN254_a23_y) + + ; f · line_{twist(R),twist(Frobenius1(Q))}(P) + $ => A :MLOAD(lineDiffPointsBN254_l12_x) + $ => B :MLOAD(lineDiffPointsBN254_l12_y) + A :MSTORE(sparseMulAFp12BN254_b12_x) + B :MSTORE(sparseMulAFp12BN254_b12_y) + $ => A :MLOAD(lineDiffPointsBN254_l22_x) + $ => B :MLOAD(lineDiffPointsBN254_l22_y) + A :MSTORE(sparseMulAFp12BN254_b22_x) + B :MSTORE(sparseMulAFp12BN254_b22_y) + $ => A :MLOAD(lineDiffPointsBN254_l23_x) + $ => B :MLOAD(lineDiffPointsBN254_l23_y) + A :MSTORE(sparseMulAFp12BN254_b23_x) + B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + + $ => A :MLOAD(sparseMulAFp12BN254_c11_x) + $ => B :MLOAD(sparseMulAFp12BN254_c11_y) + A :MSTORE(millerLoopBN254_f11_x) + B :MSTORE(millerLoopBN254_f11_y) + $ => A :MLOAD(sparseMulAFp12BN254_c12_x) + $ => B :MLOAD(sparseMulAFp12BN254_c12_y) + A :MSTORE(millerLoopBN254_f12_x) + B :MSTORE(millerLoopBN254_f12_y) + $ => A :MLOAD(sparseMulAFp12BN254_c13_x) + $ => B :MLOAD(sparseMulAFp12BN254_c13_y) + A :MSTORE(millerLoopBN254_f13_x) + B :MSTORE(millerLoopBN254_f13_y) + $ => A :MLOAD(sparseMulAFp12BN254_c21_x) + $ => B :MLOAD(sparseMulAFp12BN254_c21_y) + A :MSTORE(millerLoopBN254_f21_x) + B :MSTORE(millerLoopBN254_f21_y) + $ => A :MLOAD(sparseMulAFp12BN254_c22_x) + $ => B :MLOAD(sparseMulAFp12BN254_c22_y) + A :MSTORE(millerLoopBN254_f22_x) + B :MSTORE(millerLoopBN254_f22_y) + $ => A :MLOAD(sparseMulAFp12BN254_c23_x) + $ => B :MLOAD(sparseMulAFp12BN254_c23_y) + A :MSTORE(millerLoopBN254_f23_x) + B :MSTORE(millerLoopBN254_f23_y) + + ; 3] R = R + Frobenius1(Q) + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(addPointBN254_P1_x1) + B :MSTORE(addPointBN254_P1_x2) + C :MSTORE(addPointBN254_P1_y1) + D :MSTORE(addPointBN254_P1_y2) + $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_x1) + $ => B :MLOAD(millerLoopBN254_Frobenius1_Q_x2) + $ => C :MLOAD(millerLoopBN254_Frobenius1_Q_y1) + $ => D :MLOAD(millerLoopBN254_Frobenius1_Q_y2) + A :MSTORE(addPointBN254_P2_x1) + B :MSTORE(addPointBN254_P2_x2) + C :MSTORE(addPointBN254_P2_y1) + D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) + + $ => A :MLOAD(addPointBN254_P3_x1) + $ => B :MLOAD(addPointBN254_P3_x2) + $ => C :MLOAD(addPointBN254_P3_y1) + $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(millerLoopBN254_R_x1) + B :MSTORE(millerLoopBN254_R_x2) + C :MSTORE(millerLoopBN254_R_y1) + D :MSTORE(millerLoopBN254_R_y2) + + ; 4] Given Frobenius1(Q) = (x,y) with x,y ∈ Fp2, compute -Frobenius2(Q) = (\gamma12·x̄, -\gamma13·ȳ) + + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Frobenius1_Q_x2) + $ => B :SUB + $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_x1) + %FROBENIUS_GAMMA121 => C + %FROBENIUS_GAMMA122 => D :CALL(mulFp2BN254) + + E :MSTORE(millerLoopBN254_nFrobenius2_Q_x1) + C :MSTORE(millerLoopBN254_nFrobenius2_Q_x2) + + + %BN254_P => A + $ => B :MLOAD(millerLoopBN254_Frobenius1_Q_y2) + $ => B :SUB + $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_y1) + %FROBENIUS_GAMMA131_NEGATED => C + %FROBENIUS_GAMMA132_NEGATED => D :CALL(mulFp2BN254) + + + ; 5] f = f · line_{twist(R),twist(-Frobenius2(Q))}(P) + ; line_{twist(R),twist(-Frobenius2(Q))}(P) + $ => A :MLOAD(millerLoopBN254_nFrobenius2_Q_x1) + $ => B :MLOAD(millerLoopBN254_nFrobenius2_Q_x2) + C => D + E => C + A :MSTORE(lineDiffPointsBN254_P2_x1) + B :MSTORE(lineDiffPointsBN254_P2_x2) + C :MSTORE(lineDiffPointsBN254_P2_y1) + D :MSTORE(lineDiffPointsBN254_P2_y2) + $ => A :MLOAD(millerLoopBN254_R_x1) + $ => B :MLOAD(millerLoopBN254_R_x2) + $ => C :MLOAD(millerLoopBN254_R_y1) + $ => D :MLOAD(millerLoopBN254_R_y2) + A :MSTORE(lineDiffPointsBN254_P1_x1) + B :MSTORE(lineDiffPointsBN254_P1_x2) + C :MSTORE(lineDiffPointsBN254_P1_y1) + D :MSTORE(lineDiffPointsBN254_P1_y2) + + $ => A :MLOAD(millerLoopBN254_P_x) + $ => B :MLOAD(millerLoopBN254_P_y) + A :MSTORE(lineDiffPointsBN254_Q_x) + B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + + $ => A :MLOAD(millerLoopBN254_f11_x) + $ => B :MLOAD(millerLoopBN254_f11_y) + A :MSTORE(sparseMulAFp12BN254_a11_x) + B :MSTORE(sparseMulAFp12BN254_a11_y) + $ => A :MLOAD(millerLoopBN254_f12_x) + $ => B :MLOAD(millerLoopBN254_f12_y) + A :MSTORE(sparseMulAFp12BN254_a12_x) + B :MSTORE(sparseMulAFp12BN254_a12_y) + $ => A :MLOAD(millerLoopBN254_f13_x) + $ => B :MLOAD(millerLoopBN254_f13_y) + A :MSTORE(sparseMulAFp12BN254_a13_x) + B :MSTORE(sparseMulAFp12BN254_a13_y) + $ => A :MLOAD(millerLoopBN254_f21_x) + $ => B :MLOAD(millerLoopBN254_f21_y) + A :MSTORE(sparseMulAFp12BN254_a21_x) + B :MSTORE(sparseMulAFp12BN254_a21_y) + $ => A :MLOAD(millerLoopBN254_f22_x) + $ => B :MLOAD(millerLoopBN254_f22_y) + A :MSTORE(sparseMulAFp12BN254_a22_x) + B :MSTORE(sparseMulAFp12BN254_a22_y) + $ => A :MLOAD(millerLoopBN254_f23_x) + $ => B :MLOAD(millerLoopBN254_f23_y) + A :MSTORE(sparseMulAFp12BN254_a23_x) + B :MSTORE(sparseMulAFp12BN254_a23_y) + + ; f · line_{twist(R),twist(-Frobenius2(Q))}(P) + $ => A :MLOAD(lineDiffPointsBN254_l12_x) + $ => B :MLOAD(lineDiffPointsBN254_l12_y) + A :MSTORE(sparseMulAFp12BN254_b12_x) + B :MSTORE(sparseMulAFp12BN254_b12_y) + $ => A :MLOAD(lineDiffPointsBN254_l22_x) + $ => B :MLOAD(lineDiffPointsBN254_l22_y) + A :MSTORE(sparseMulAFp12BN254_b22_x) + B :MSTORE(sparseMulAFp12BN254_b22_y) + $ => A :MLOAD(lineDiffPointsBN254_l23_x) + $ => B :MLOAD(lineDiffPointsBN254_l23_y) + A :MSTORE(sparseMulAFp12BN254_b23_x) + B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + + $ => A :MLOAD(sparseMulAFp12BN254_c11_x) + $ => B :MLOAD(sparseMulAFp12BN254_c11_y) + A :MSTORE(millerLoopBN254_f11_x) + B :MSTORE(millerLoopBN254_f11_y) + $ => A :MLOAD(sparseMulAFp12BN254_c12_x) + $ => B :MLOAD(sparseMulAFp12BN254_c12_y) + A :MSTORE(millerLoopBN254_f12_x) + B :MSTORE(millerLoopBN254_f12_y) + $ => A :MLOAD(sparseMulAFp12BN254_c13_x) + $ => B :MLOAD(sparseMulAFp12BN254_c13_y) + A :MSTORE(millerLoopBN254_f13_x) + B :MSTORE(millerLoopBN254_f13_y) + $ => A :MLOAD(sparseMulAFp12BN254_c21_x) + $ => B :MLOAD(sparseMulAFp12BN254_c21_y) + A :MSTORE(millerLoopBN254_f21_x) + B :MSTORE(millerLoopBN254_f21_y) + $ => A :MLOAD(sparseMulAFp12BN254_c22_x) + $ => B :MLOAD(sparseMulAFp12BN254_c22_y) + A :MSTORE(millerLoopBN254_f22_x) + B :MSTORE(millerLoopBN254_f22_y) + $ => A :MLOAD(sparseMulAFp12BN254_c23_x) + $ => B :MLOAD(sparseMulAFp12BN254_c23_y) + A :MSTORE(millerLoopBN254_f23_x) + B :MSTORE(millerLoopBN254_f23_y) + +millerLoopBN254_end: + $ => RR :MLOAD(millerLoopBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/pairingBN254.zkasm b/main/pairings/pairingBN254.zkasm new file mode 100644 index 00000000..68ca252b --- /dev/null +++ b/main/pairings/pairingBN254.zkasm @@ -0,0 +1,481 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Optimal Ate Pairing e: G1 x G2 -> GT over the BN254 curve +;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over (Fp12)^*) +;; the involved curves are E/Fp: y² = x³ + 3 and E'/Fp2: y² = x³ + 3/(9+u) +;; pairingBN254: +;; input: P ∈ G1 and Q ∈ G2 +;; output: e(P,Q) ∈ GT +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL pairingBN254_P_x +VAR GLOBAL pairingBN254_P_y +VAR GLOBAL pairingBN254_Q_x1 +VAR GLOBAL pairingBN254_Q_x2 +VAR GLOBAL pairingBN254_Q_y1 +VAR GLOBAL pairingBN254_Q_y2 + +VAR GLOBAL pairingBN254_f11_x +VAR GLOBAL pairingBN254_f11_y +VAR GLOBAL pairingBN254_f12_x +VAR GLOBAL pairingBN254_f12_y +VAR GLOBAL pairingBN254_f13_x +VAR GLOBAL pairingBN254_f13_y +VAR GLOBAL pairingBN254_f21_x +VAR GLOBAL pairingBN254_f21_y +VAR GLOBAL pairingBN254_f22_x +VAR GLOBAL pairingBN254_f22_y +VAR GLOBAL pairingBN254_f23_x +VAR GLOBAL pairingBN254_f23_y + +VAR GLOBAL pairingBN254_RR + +VAR GLOBAL pairingBN254_P_x3 +VAR GLOBAL pairingBN254_Q_RHS_x +VAR GLOBAL pairingBN254_Q_RHS_y +VAR GLOBAL pairingBN254_psi_x1 +VAR GLOBAL pairingBN254_psi_x2 +VAR GLOBAL pairingBN254_psi_y1 +VAR GLOBAL pairingBN254_psi_y2 + +; ERROR CODES (B) +; 0 - no error +; 1 - P_x is too big +; 2 - P_y is too big +; 3 - Q_x1 is too big +; 4 - Q_x2 is too big +; 5 - Q_y1 is too big +; 6 - Q_y2 is too big +; 7 - P is not in G1 +; 8 - Q is not in G2 + +pairingBN254: + RR :MSTORE(pairingBN254_RR) + + %BN254_P_MINUS_ONE => A + $ => B :MLOAD(pairingBN254_P_x) + $ :LT, JMPC(pairingBN254_Px_too_big) + $ => B :MLOAD(pairingBN254_P_y) + $ :LT, JMPC(pairingBN254_Py_too_big) + $ => B :MLOAD(pairingBN254_Q_x1) + $ :LT, JMPC(pairingBN254_Qx1_too_big) + $ => B :MLOAD(pairingBN254_Q_x2) + $ :LT, JMPC(pairingBN254_Qx2_too_big) + $ => B :MLOAD(pairingBN254_Q_y1) + $ :LT, JMPC(pairingBN254_Qy1_too_big) + $ => B :MLOAD(pairingBN254_Q_y2) + $ :LT, JMPC(pairingBN254_Qy2_too_big) + + ; Is P = O? + 0n => B + $ => A :MLOAD(pairingBN254_P_x) + $ :EQ, JMPNC(pairingBN254_P_continue) + $ => A :MLOAD(pairingBN254_P_y) + $ :EQ, JMPC(pairingBN254_P_is_zero) + pairingBN254_P_continue: + + ; Is Q = O? + $ => A :MLOAD(pairingBN254_Q_x1) + $ :EQ, JMPNC(pairingBN254_Q_continue1) + $ => A :MLOAD(pairingBN254_Q_x2) + $ :EQ, JMPNC(pairingBN254_Q_continue1) + $ => A :MLOAD(pairingBN254_Q_y1) + $ :EQ, JMPNC(pairingBN254_Q_continue1) + $ => A :MLOAD(pairingBN254_Q_y2) + $ :EQ, JMPC(pairingBN254_Q_is_zero) + pairingBN254_Q_continue1: + + :JMP(pairingBN254_P_subgroup_check) + + +pairingBN254_P_is_zero: + ; Is Q = O? + $ => A :MLOAD(pairingBN254_Q_x1) + $ :EQ, JMPNC(pairingBN254_Q_continue2) + $ => A :MLOAD(pairingBN254_Q_x2) + $ :EQ, JMPNC(pairingBN254_Q_continue2) + $ => A :MLOAD(pairingBN254_Q_y1) + $ :EQ, JMPNC(pairingBN254_Q_continue2) + $ => A :MLOAD(pairingBN254_Q_y2) + $ :EQ, JMPC(pairingBN254_P_and_Q_are_zero) + pairingBN254_Q_continue2: + + ; Check that Q is in G2 + ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 + + ; 1] Check if Q is in E'(Fp2) + ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) + ; 1.1] Compute LHS and RHS + $ => A :MLOAD(pairingBN254_Q_x1) + $ => B :MLOAD(pairingBN254_Q_x2), CALL(squareFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)² + + E => A + C => B + $ => C :MLOAD(pairingBN254_Q_x1) + $ => D :MLOAD(pairingBN254_Q_x2), CALL(mulFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + + E => A + C => B + %BN254_ETWISTED_B_X => C + %BN254_ETWISTED_B_Y => D :CALL(addFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + 3/(9+u) + E :MSTORE(pairingBN254_Q_RHS_x) + C :MSTORE(pairingBN254_Q_RHS_y) + + $ => A :MLOAD(pairingBN254_Q_y1) + $ => B :MLOAD(pairingBN254_Q_y2), CALL(squareFp2BN254) + ; E + C·u = (Q.y1 + Q.y2·u)² + + ; 1.2] Check if LHS == RHS + E => A + $ => B :MLOAD(pairingBN254_Q_RHS_x) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + C => A + $ => B :MLOAD(pairingBN254_Q_RHS_y) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + ; 2] Check if psi(Q) == [6x²]Q + ; 2.1] Compute psi(Q) + %BN254_P => A + $ => B :MLOAD(pairingBN254_Q_x2) + $ => D :SUB ; D = -Qx2 + %FROBENIUS_GAMMA121 => A + %FROBENIUS_GAMMA122 => B + $ => C :MLOAD(pairingBN254_Q_x1), CALL(mulFp2BN254) + E :MSTORE(pairingBN254_psi_x1) + C :MSTORE(pairingBN254_psi_x2) + + %BN254_P => A + $ => B :MLOAD(pairingBN254_Q_y2) + $ => D :SUB ; D = -Qy2 + %FROBENIUS_GAMMA131 => A + %FROBENIUS_GAMMA132 => B + $ => C :MLOAD(pairingBN254_Q_y1), CALL(mulFp2BN254) + E :MSTORE(pairingBN254_psi_y1) + C :MSTORE(pairingBN254_psi_y2) + + ; 2.2] Compute [6x²]Q + $ => A :MLOAD(pairingBN254_Q_x1) + $ => B :MLOAD(pairingBN254_Q_x2) + $ => C :MLOAD(pairingBN254_Q_y1) + $ => D :MLOAD(pairingBN254_Q_y2) + A :MSTORE(escalarMulBN254_P_x1) + B :MSTORE(escalarMulBN254_P_x2) + C :MSTORE(escalarMulBN254_P_y1) + D :MSTORE(escalarMulBN254_P_y2) + %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) + + + ; 2.3] Check if psi(Q) == [6x²]Q + $ => A :MLOAD(pairingBN254_psi_x1) + $ => B :MLOAD(escalarMulBN254_Q_x1) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(pairingBN254_psi_x2) + $ => B :MLOAD(escalarMulBN254_Q_x2) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(pairingBN254_psi_y1) + $ => B :MLOAD(escalarMulBN254_Q_y1) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(pairingBN254_psi_y2) + $ => B :MLOAD(escalarMulBN254_Q_y2) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + ; e(O,Q) = 1 + 1n :MSTORE(pairingBN254_f11_x) + 0n :MSTORE(pairingBN254_f11_y) + 0n :MSTORE(pairingBN254_f12_x) + 0n :MSTORE(pairingBN254_f12_y) + 0n :MSTORE(pairingBN254_f13_x) + 0n :MSTORE(pairingBN254_f13_y) + 0n :MSTORE(pairingBN254_f21_x) + 0n :MSTORE(pairingBN254_f21_y) + 0n :MSTORE(pairingBN254_f22_x) + 0n :MSTORE(pairingBN254_f22_y) + 0n :MSTORE(pairingBN254_f23_x) + 0n :MSTORE(pairingBN254_f23_y) + + 0 => B :JMP(pairingBN254_end) + +pairingBN254_Q_is_zero: + ; Check that P is in G1 + ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) + ; 1] Compute LHS and RHS + $ => A,B :MLOAD(pairingBN254_P_x), CALL(mulFpBN254); C = (Px)² + C => A ; A = (Px)² + $ => B :MLOAD(pairingBN254_P_x), CALL(mulFpBN254); C = (Px)³ + + %BN254_E_B => A :CALL(addFpBN254) ; C = (Px)³ + 3 + C :MSTORE(pairingBN254_P_x3) ; pairingBN254_P_x3 = (Px)³ + 3 + + $ => A,B :MLOAD(pairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + + ; 2] Check if LHS == RHS + C => A + $ => B :MLOAD(pairingBN254_P_x3) + $ :EQ, JMPNC(pairingBN254_P_is_not_in_G1) + + ; e(P,O) = 1 + 1n :MSTORE(pairingBN254_f11_x) + 0n :MSTORE(pairingBN254_f11_y) + 0n :MSTORE(pairingBN254_f12_x) + 0n :MSTORE(pairingBN254_f12_y) + 0n :MSTORE(pairingBN254_f13_x) + 0n :MSTORE(pairingBN254_f13_y) + 0n :MSTORE(pairingBN254_f21_x) + 0n :MSTORE(pairingBN254_f21_y) + 0n :MSTORE(pairingBN254_f22_x) + 0n :MSTORE(pairingBN254_f22_y) + 0n :MSTORE(pairingBN254_f23_x) + 0n :MSTORE(pairingBN254_f23_y) + + 0 => B :JMP(pairingBN254_end) + +pairingBN254_P_and_Q_are_zero: + ; e(O,O) = 1 + 1n :MSTORE(pairingBN254_f11_x) + 0n :MSTORE(pairingBN254_f11_y) + 0n :MSTORE(pairingBN254_f12_x) + 0n :MSTORE(pairingBN254_f12_y) + 0n :MSTORE(pairingBN254_f13_x) + 0n :MSTORE(pairingBN254_f13_y) + 0n :MSTORE(pairingBN254_f21_x) + 0n :MSTORE(pairingBN254_f21_y) + 0n :MSTORE(pairingBN254_f22_x) + 0n :MSTORE(pairingBN254_f22_y) + 0n :MSTORE(pairingBN254_f23_x) + 0n :MSTORE(pairingBN254_f23_y) + +pairingBN254_P_subgroup_check: + ; Check that P is in G1 + ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) + ; 1] Compute LHS and RHS + $ => A,B :MLOAD(pairingBN254_P_x), CALL(mulFpBN254); C = (Px)² + C => A ; A = (Px)² + $ => B :MLOAD(pairingBN254_P_x), CALL(mulFpBN254); C = (Px)³ + + %BN254_E_B => A :CALL(addFpBN254) ; C = (Px)³ + 3 + C :MSTORE(pairingBN254_P_x3) ; pairingBN254_P_x3 = (Px)³ + 3 + + $ => A,B :MLOAD(pairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + + ; 2] Check if LHS == RHS + C => A + $ => B :MLOAD(pairingBN254_P_x3) + $ :EQ, JMPNC(pairingBN254_P_is_not_in_G1) + +pairingBN254_Q_subgroup_check: + ; Check that Q is in G2 + ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 + + ; 1] Check if Q is in E'(Fp2) + ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) + ; 1.1] Compute LHS and RHS + $ => A :MLOAD(pairingBN254_Q_x1) + $ => B :MLOAD(pairingBN254_Q_x2), CALL(squareFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)² + + E => A + C => B + $ => C :MLOAD(pairingBN254_Q_x1) + $ => D :MLOAD(pairingBN254_Q_x2), CALL(mulFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + + E => A + C => B + %BN254_ETWISTED_B_X => C + %BN254_ETWISTED_B_Y => D :CALL(addFp2BN254) + ; E + C·u = (Q.x1 + Q.x2·u)³ + 3/(9+u) + E :MSTORE(pairingBN254_Q_RHS_x) + C :MSTORE(pairingBN254_Q_RHS_y) + + $ => A :MLOAD(pairingBN254_Q_y1) + $ => B :MLOAD(pairingBN254_Q_y2), CALL(squareFp2BN254) + ; E + C·u = (Q.y1 + Q.y2·u)² + + ; 1.2] Check if LHS == RHS + E => A + $ => B :MLOAD(pairingBN254_Q_RHS_x) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + C => A + $ => B :MLOAD(pairingBN254_Q_RHS_y) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + ; 2] Check if psi(Q) == [6x²]Q + ; 2.1] Compute psi(Q) + %BN254_P => A + $ => B :MLOAD(pairingBN254_Q_x2) + $ => D :SUB ; D = -Qx2 + %FROBENIUS_GAMMA121 => A + %FROBENIUS_GAMMA122 => B + $ => C :MLOAD(pairingBN254_Q_x1), CALL(mulFp2BN254) + E :MSTORE(pairingBN254_psi_x1) + C :MSTORE(pairingBN254_psi_x2) + + %BN254_P => A + $ => B :MLOAD(pairingBN254_Q_y2) + $ => D :SUB ; D = -Qx2 + %FROBENIUS_GAMMA131 => A + %FROBENIUS_GAMMA132 => B + $ => C :MLOAD(pairingBN254_Q_y1), CALL(mulFp2BN254) + E :MSTORE(pairingBN254_psi_y1) + C :MSTORE(pairingBN254_psi_y2) + + ; 2.2] Compute [6x²]Q + $ => A :MLOAD(pairingBN254_Q_x1) + $ => B :MLOAD(pairingBN254_Q_x2) + $ => C :MLOAD(pairingBN254_Q_y1) + $ => D :MLOAD(pairingBN254_Q_y2) + A :MSTORE(escalarMulBN254_P_x1) + B :MSTORE(escalarMulBN254_P_x2) + C :MSTORE(escalarMulBN254_P_y1) + D :MSTORE(escalarMulBN254_P_y2) + %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) + + + ; 2.3] Check if psi(Q) == [6x²]Q + $ => A :MLOAD(pairingBN254_psi_x1) + $ => B :MLOAD(escalarMulBN254_Q_x1) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(pairingBN254_psi_x2) + $ => B :MLOAD(escalarMulBN254_Q_x2) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(pairingBN254_psi_y1) + $ => B :MLOAD(escalarMulBN254_Q_y1) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + + $ => A :MLOAD(pairingBN254_psi_y2) + $ => B :MLOAD(escalarMulBN254_Q_y2) + $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + +pairingBN254_Miller_loop: + $ => A :MLOAD(pairingBN254_P_x) + $ => B :MLOAD(pairingBN254_P_y) + A :MSTORE(millerLoopBN254_P_x) + B :MSTORE(millerLoopBN254_P_y) + $ => A :MLOAD(pairingBN254_Q_x1) + $ => B :MLOAD(pairingBN254_Q_x2) + $ => C :MLOAD(pairingBN254_Q_y1) + $ => D :MLOAD(pairingBN254_Q_y2) + A :MSTORE(millerLoopBN254_Q_x1) + B :MSTORE(millerLoopBN254_Q_x2) + C :MSTORE(millerLoopBN254_Q_y1) + D :MSTORE(millerLoopBN254_Q_y2), CALL(millerLoopBN254) + $ => A :MLOAD(millerLoopBN254_f11_x) + $ => B :MLOAD(millerLoopBN254_f11_y) + A :MSTORE(pairingBN254_f11_x) + B :MSTORE(pairingBN254_f11_y) + $ => A :MLOAD(millerLoopBN254_f12_x) + $ => B :MLOAD(millerLoopBN254_f12_y) + A :MSTORE(pairingBN254_f12_x) + B :MSTORE(pairingBN254_f12_y) + $ => A :MLOAD(millerLoopBN254_f13_x) + $ => B :MLOAD(millerLoopBN254_f13_y) + A :MSTORE(pairingBN254_f13_x) + B :MSTORE(pairingBN254_f13_y) + $ => A :MLOAD(millerLoopBN254_f21_x) + $ => B :MLOAD(millerLoopBN254_f21_y) + A :MSTORE(pairingBN254_f21_x) + B :MSTORE(pairingBN254_f21_y) + $ => A :MLOAD(millerLoopBN254_f22_x) + $ => B :MLOAD(millerLoopBN254_f22_y) + A :MSTORE(pairingBN254_f22_x) + B :MSTORE(pairingBN254_f22_y) + $ => A :MLOAD(millerLoopBN254_f23_x) + $ => B :MLOAD(millerLoopBN254_f23_y) + A :MSTORE(pairingBN254_f23_x) + B :MSTORE(pairingBN254_f23_y) + + +pairingBN254_final_exponentiation: + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(finalExpBN254_f11_x) + B :MSTORE(finalExpBN254_f11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(finalExpBN254_f12_x) + B :MSTORE(finalExpBN254_f12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(finalExpBN254_f13_x) + B :MSTORE(finalExpBN254_f13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(finalExpBN254_f21_x) + B :MSTORE(finalExpBN254_f21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(finalExpBN254_f22_x) + B :MSTORE(finalExpBN254_f22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(finalExpBN254_f23_x) + B :MSTORE(finalExpBN254_f23_y), CALL(finalExpBN254) + $ => A :MLOAD(finalExpBN254_f11_x) + $ => B :MLOAD(finalExpBN254_f11_y) + A :MSTORE(pairingBN254_f11_x) + B :MSTORE(pairingBN254_f11_y) + $ => A :MLOAD(finalExpBN254_f12_x) + $ => B :MLOAD(finalExpBN254_f12_y) + A :MSTORE(pairingBN254_f12_x) + B :MSTORE(pairingBN254_f12_y) + $ => A :MLOAD(finalExpBN254_f13_x) + $ => B :MLOAD(finalExpBN254_f13_y) + A :MSTORE(pairingBN254_f13_x) + B :MSTORE(pairingBN254_f13_y) + $ => A :MLOAD(finalExpBN254_f21_x) + $ => B :MLOAD(finalExpBN254_f21_y) + A :MSTORE(pairingBN254_f21_x) + B :MSTORE(pairingBN254_f21_y) + $ => A :MLOAD(finalExpBN254_f22_x) + $ => B :MLOAD(finalExpBN254_f22_y) + A :MSTORE(pairingBN254_f22_x) + B :MSTORE(pairingBN254_f22_y) + $ => A :MLOAD(finalExpBN254_f23_x) + $ => B :MLOAD(finalExpBN254_f23_y) + A :MSTORE(pairingBN254_f23_x) + B :MSTORE(pairingBN254_f23_y) + + 0 => B :JMP(pairingBN254_end) + +; ERRORS +pairingBN254_Px_too_big: + 1 => B :JMP(pairingBN254_error) + +pairingBN254_Py_too_big: + 2 => B :JMP(pairingBN254_error) + +pairingBN254_Qx1_too_big: + 3 => B :JMP(pairingBN254_error) + +pairingBN254_Qx2_too_big: + 4 => B :JMP(pairingBN254_error) + +pairingBN254_Qy1_too_big: + 5 => B :JMP(pairingBN254_error) + +pairingBN254_Qy2_too_big: + 6 => B :JMP(pairingBN254_error) + +pairingBN254_P_is_not_in_G1: + 7 => B :JMP(pairingBN254_error) + +pairingBN254_Q_is_not_in_G2: + 8 => B :JMP(pairingBN254_error) + +pairingBN254_error: + 0 => A + +pairingBN254_end: + $ => RR :MLOAD(pairingBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/unused/addFp12BN254.zkasm b/main/pairings/unused/addFp12BN254.zkasm new file mode 100644 index 00000000..2aa760cd --- /dev/null +++ b/main/pairings/unused/addFp12BN254.zkasm @@ -0,0 +1,130 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; addFp12BN254: +;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai,bi ∈ Fp6 +;; out: (c1 + c2·w) = (a1+b1) + (a2+b2)·w ∈ Fp12 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL addFp12BN254_a11_x +VAR GLOBAL addFp12BN254_a11_y +VAR GLOBAL addFp12BN254_a12_x +VAR GLOBAL addFp12BN254_a12_y +VAR GLOBAL addFp12BN254_a13_x +VAR GLOBAL addFp12BN254_a13_y +VAR GLOBAL addFp12BN254_a21_x +VAR GLOBAL addFp12BN254_a21_y +VAR GLOBAL addFp12BN254_a22_x +VAR GLOBAL addFp12BN254_a22_y +VAR GLOBAL addFp12BN254_a23_x +VAR GLOBAL addFp12BN254_a23_y +VAR GLOBAL addFp12BN254_b11_x +VAR GLOBAL addFp12BN254_b11_y +VAR GLOBAL addFp12BN254_b12_x +VAR GLOBAL addFp12BN254_b12_y +VAR GLOBAL addFp12BN254_b13_x +VAR GLOBAL addFp12BN254_b13_y +VAR GLOBAL addFp12BN254_b21_x +VAR GLOBAL addFp12BN254_b21_y +VAR GLOBAL addFp12BN254_b22_x +VAR GLOBAL addFp12BN254_b22_y +VAR GLOBAL addFp12BN254_b23_x +VAR GLOBAL addFp12BN254_b23_y +VAR GLOBAL addFp12BN254_c11_x +VAR GLOBAL addFp12BN254_c11_y +VAR GLOBAL addFp12BN254_c12_x +VAR GLOBAL addFp12BN254_c12_y +VAR GLOBAL addFp12BN254_c13_x +VAR GLOBAL addFp12BN254_c13_y +VAR GLOBAL addFp12BN254_c21_x +VAR GLOBAL addFp12BN254_c21_y +VAR GLOBAL addFp12BN254_c22_x +VAR GLOBAL addFp12BN254_c22_y +VAR GLOBAL addFp12BN254_c23_x +VAR GLOBAL addFp12BN254_c23_y + +VAR GLOBAL addFp12BN254_RR + +addFp12BN254: + RR :MSTORE(addFp12BN254_RR) + + ; 1] c1 = a1 + b1 + $ => A :MLOAD(addFp12BN254_a11_x) + $ => B :MLOAD(addFp12BN254_a11_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(addFp12BN254_a12_x) + $ => B :MLOAD(addFp12BN254_a12_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(addFp12BN254_a13_x) + $ => B :MLOAD(addFp12BN254_a13_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + + $ => A :MLOAD(addFp12BN254_b11_x) + $ => B :MLOAD(addFp12BN254_b11_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(addFp12BN254_b12_x) + $ => B :MLOAD(addFp12BN254_b12_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(addFp12BN254_b13_x) + $ => B :MLOAD(addFp12BN254_b13_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(addFp12BN254_c11_x) + B :MSTORE(addFp12BN254_c11_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(addFp12BN254_c12_x) + B :MSTORE(addFp12BN254_c12_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(addFp12BN254_c13_x) + B :MSTORE(addFp12BN254_c13_y) + + ; 2] c2 = a2 + b2 + $ => A :MLOAD(addFp12BN254_a21_x) + $ => B :MLOAD(addFp12BN254_a21_y) + A :MSTORE(addFp6BN254_a1_x) + B :MSTORE(addFp6BN254_a1_y) + $ => A :MLOAD(addFp12BN254_a22_x) + $ => B :MLOAD(addFp12BN254_a22_y) + A :MSTORE(addFp6BN254_a2_x) + B :MSTORE(addFp6BN254_a2_y) + $ => A :MLOAD(addFp12BN254_a23_x) + $ => B :MLOAD(addFp12BN254_a23_y) + A :MSTORE(addFp6BN254_a3_x) + B :MSTORE(addFp6BN254_a3_y) + + $ => A :MLOAD(addFp12BN254_b21_x) + $ => B :MLOAD(addFp12BN254_b21_y) + A :MSTORE(addFp6BN254_b1_x) + B :MSTORE(addFp6BN254_b1_y) + $ => A :MLOAD(addFp12BN254_b22_x) + $ => B :MLOAD(addFp12BN254_b22_y) + A :MSTORE(addFp6BN254_b2_x) + B :MSTORE(addFp6BN254_b2_y) + $ => A :MLOAD(addFp12BN254_b23_x) + $ => B :MLOAD(addFp12BN254_b23_y) + A :MSTORE(addFp6BN254_b3_x) + B :MSTORE(addFp6BN254_b3_y), CALL(addFp6BN254) + $ => A :MLOAD(addFp6BN254_c1_x) + $ => B :MLOAD(addFp6BN254_c1_y) + A :MSTORE(addFp12BN254_c21_x) + B :MSTORE(addFp12BN254_c21_y) + $ => A :MLOAD(addFp6BN254_c2_x) + $ => B :MLOAD(addFp6BN254_c2_y) + A :MSTORE(addFp12BN254_c22_x) + B :MSTORE(addFp12BN254_c22_y) + $ => A :MLOAD(addFp6BN254_c3_x) + $ => B :MLOAD(addFp6BN254_c3_y) + A :MSTORE(addFp12BN254_c23_x) + B :MSTORE(addFp12BN254_c23_y) + + $ => RR :MLOAD(addFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/unused/expByXCycloFp12BN254.zkasm b/main/pairings/unused/expByXCycloFp12BN254.zkasm new file mode 100644 index 00000000..da0ffcc1 --- /dev/null +++ b/main/pairings/unused/expByXCycloFp12BN254.zkasm @@ -0,0 +1,411 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; expByXCycloFp12BN254: +;; in: x, (a1 + a2·w) ∈ GΦ6(p²), where ai ∈ Fp6 and x = 4965661367192848881 +;; out: (c1 + c2·w) = (a1 + a2·w)^x ∈ GΦ6(p²) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL expByXCycloFp12BN254_a11_x +VAR GLOBAL expByXCycloFp12BN254_a11_y +VAR GLOBAL expByXCycloFp12BN254_a12_x +VAR GLOBAL expByXCycloFp12BN254_a12_y +VAR GLOBAL expByXCycloFp12BN254_a13_x +VAR GLOBAL expByXCycloFp12BN254_a13_y +VAR GLOBAL expByXCycloFp12BN254_a21_x +VAR GLOBAL expByXCycloFp12BN254_a21_y +VAR GLOBAL expByXCycloFp12BN254_a22_x +VAR GLOBAL expByXCycloFp12BN254_a22_y +VAR GLOBAL expByXCycloFp12BN254_a23_x +VAR GLOBAL expByXCycloFp12BN254_a23_y +VAR GLOBAL expByXCycloFp12BN254_c11_x +VAR GLOBAL expByXCycloFp12BN254_c11_y +VAR GLOBAL expByXCycloFp12BN254_c12_x +VAR GLOBAL expByXCycloFp12BN254_c12_y +VAR GLOBAL expByXCycloFp12BN254_c13_x +VAR GLOBAL expByXCycloFp12BN254_c13_y +VAR GLOBAL expByXCycloFp12BN254_c21_x +VAR GLOBAL expByXCycloFp12BN254_c21_y +VAR GLOBAL expByXCycloFp12BN254_c22_x +VAR GLOBAL expByXCycloFp12BN254_c22_y +VAR GLOBAL expByXCycloFp12BN254_c23_x +VAR GLOBAL expByXCycloFp12BN254_c23_y + +VAR GLOBAL expByXCycloFp12BN254_neg_a21_x +VAR GLOBAL expByXCycloFp12BN254_neg_a21_y +VAR GLOBAL expByXCycloFp12BN254_neg_a22_x +VAR GLOBAL expByXCycloFp12BN254_neg_a22_y +VAR GLOBAL expByXCycloFp12BN254_neg_a23_x +VAR GLOBAL expByXCycloFp12BN254_neg_a23_y + +VAR GLOBAL expByXCycloFp12BN254_RR + +expByXCycloFp12BN254: + RR :MSTORE(expByXCycloFp12BN254_RR) + + ; Is a = 0? + 0n => B + $ => A :MLOAD(expByXCycloFp12BN254_a11_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a11_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a12_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a12_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a13_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a13_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a21_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a21_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a22_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a22_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a23_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ => A :MLOAD(expByXCycloFp12BN254_a23_y) + $ :EQ, JMPC(expByXCycloFp12BN254_a_is_zero) + expByXCycloFp12BN254_a_continue1: + + ; Is a = 1? + 1n => B + $ => A :MLOAD(expByXCycloFp12BN254_a11_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + 0n => B + $ => A :MLOAD(expByXCycloFp12BN254_a11_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a12_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a12_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a13_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a13_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a21_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a21_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a22_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a22_y) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a23_x) + $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ => A :MLOAD(expByXCycloFp12BN254_a23_y) + $ :EQ, JMPC(expByXCycloFp12BN254_a_is_one) + expByXCycloFp12BN254_a_continue2: + + 63 => RCX + + ; Initiliaze the loop with c = a and compute the conjugate of a + $ => A :MLOAD(expByXCycloFp12BN254_a11_x) + $ => B :MLOAD(expByXCycloFp12BN254_a11_y) + A :MSTORE(expByXCycloFp12BN254_c11_x) + B :MSTORE(expByXCycloFp12BN254_c11_y) + $ => A :MLOAD(expByXCycloFp12BN254_a12_x) + $ => B :MLOAD(expByXCycloFp12BN254_a12_y) + A :MSTORE(expByXCycloFp12BN254_c12_x) + B :MSTORE(expByXCycloFp12BN254_c12_y) + $ => A :MLOAD(expByXCycloFp12BN254_a13_x) + $ => B :MLOAD(expByXCycloFp12BN254_a13_y) + A :MSTORE(expByXCycloFp12BN254_c13_x) + B :MSTORE(expByXCycloFp12BN254_c13_y) + + %BN254_P => A + $ => B :MLOAD(expByXCycloFp12BN254_a21_x) + B :MSTORE(expByXCycloFp12BN254_c21_x) + $ :SUB, MSTORE(expByXCycloFp12BN254_neg_a21_x) + %BN254_P => A + $ => B :MLOAD(expByXCycloFp12BN254_a21_y) + B :MSTORE(expByXCycloFp12BN254_c21_y) + $ :SUB, MSTORE(expByXCycloFp12BN254_neg_a21_y) + %BN254_P => A + $ => B :MLOAD(expByXCycloFp12BN254_a22_x) + B :MSTORE(expByXCycloFp12BN254_c22_x) + $ :SUB, MSTORE(expByXCycloFp12BN254_neg_a22_x) + %BN254_P => A + $ => B :MLOAD(expByXCycloFp12BN254_a22_y) + B :MSTORE(expByXCycloFp12BN254_c22_y) + $ :SUB, MSTORE(expByXCycloFp12BN254_neg_a22_y) + %BN254_P => A + $ => B :MLOAD(expByXCycloFp12BN254_a23_x) + B :MSTORE(expByXCycloFp12BN254_c23_x) + $ :SUB, MSTORE(expByXCycloFp12BN254_neg_a23_x) + %BN254_P => A + $ => B :MLOAD(expByXCycloFp12BN254_a23_y) + B :MSTORE(expByXCycloFp12BN254_c23_y) + $ :SUB, MSTORE(expByXCycloFp12BN254_neg_a23_y) + + :JMP(expByXCycloFp12BN254_loop) + +expByXCycloFp12BN254_a_is_zero: + ; c = 0 + 0n :MSTORE(expByXCycloFp12BN254_c11_x) + 0n :MSTORE(expByXCycloFp12BN254_c11_y) + 0n :MSTORE(expByXCycloFp12BN254_c12_x) + 0n :MSTORE(expByXCycloFp12BN254_c12_y) + 0n :MSTORE(expByXCycloFp12BN254_c13_x) + 0n :MSTORE(expByXCycloFp12BN254_c13_y) + 0n :MSTORE(expByXCycloFp12BN254_c21_x) + 0n :MSTORE(expByXCycloFp12BN254_c21_y) + 0n :MSTORE(expByXCycloFp12BN254_c22_x) + 0n :MSTORE(expByXCycloFp12BN254_c22_y) + 0n :MSTORE(expByXCycloFp12BN254_c23_x) + 0n :MSTORE(expByXCycloFp12BN254_c23_y) + + :JMP(expByXCycloFp12BN254_end) + +expByXCycloFp12BN254_a_is_one: + ; c = 1 + 1n :MSTORE(expByXCycloFp12BN254_c11_x) + 0n :MSTORE(expByXCycloFp12BN254_c11_y) + 0n :MSTORE(expByXCycloFp12BN254_c12_x) + 0n :MSTORE(expByXCycloFp12BN254_c12_y) + 0n :MSTORE(expByXCycloFp12BN254_c13_x) + 0n :MSTORE(expByXCycloFp12BN254_c13_y) + 0n :MSTORE(expByXCycloFp12BN254_c21_x) + 0n :MSTORE(expByXCycloFp12BN254_c21_y) + 0n :MSTORE(expByXCycloFp12BN254_c22_x) + 0n :MSTORE(expByXCycloFp12BN254_c22_y) + 0n :MSTORE(expByXCycloFp12BN254_c23_x) + 0n :MSTORE(expByXCycloFp12BN254_c23_y) + + :JMP(expByXCycloFp12BN254_end) + +expByXCycloFp12BN254_loop: + RCX - 1 => RCX :JMPZ(expByXCycloFp12BN254_end) + + ; We always square: c = c^2 + $ => A :MLOAD(expByXCycloFp12BN254_c11_x) + $ => B :MLOAD(expByXCycloFp12BN254_c11_y) + A :MSTORE(squareCycloFp12BN254_a11_x) + B :MSTORE(squareCycloFp12BN254_a11_y) + $ => A :MLOAD(expByXCycloFp12BN254_c12_x) + $ => B :MLOAD(expByXCycloFp12BN254_c12_y) + A :MSTORE(squareCycloFp12BN254_a12_x) + B :MSTORE(squareCycloFp12BN254_a12_y) + $ => A :MLOAD(expByXCycloFp12BN254_c13_x) + $ => B :MLOAD(expByXCycloFp12BN254_c13_y) + A :MSTORE(squareCycloFp12BN254_a13_x) + B :MSTORE(squareCycloFp12BN254_a13_y) + $ => A :MLOAD(expByXCycloFp12BN254_c21_x) + $ => B :MLOAD(expByXCycloFp12BN254_c21_y) + A :MSTORE(squareCycloFp12BN254_a21_x) + B :MSTORE(squareCycloFp12BN254_a21_y) + $ => A :MLOAD(expByXCycloFp12BN254_c22_x) + $ => B :MLOAD(expByXCycloFp12BN254_c22_y) + A :MSTORE(squareCycloFp12BN254_a22_x) + B :MSTORE(squareCycloFp12BN254_a22_y) + $ => A :MLOAD(expByXCycloFp12BN254_c23_x) + $ => B :MLOAD(expByXCycloFp12BN254_c23_y) + A :MSTORE(squareCycloFp12BN254_a23_x) + B :MSTORE(squareCycloFp12BN254_a23_y), CALL(squareCycloFp12BN254) + + ; c = c^2 + $ => A :MLOAD(squareCycloFp12BN254_c11_x) + $ => B :MLOAD(squareCycloFp12BN254_c11_y) + A :MSTORE(expByXCycloFp12BN254_c11_x) + B :MSTORE(expByXCycloFp12BN254_c11_y) + $ => A :MLOAD(squareCycloFp12BN254_c12_x) + $ => B :MLOAD(squareCycloFp12BN254_c12_y) + A :MSTORE(expByXCycloFp12BN254_c12_x) + B :MSTORE(expByXCycloFp12BN254_c12_y) + $ => A :MLOAD(squareCycloFp12BN254_c13_x) + $ => B :MLOAD(squareCycloFp12BN254_c13_y) + A :MSTORE(expByXCycloFp12BN254_c13_x) + B :MSTORE(expByXCycloFp12BN254_c13_y) + $ => A :MLOAD(squareCycloFp12BN254_c21_x) + $ => B :MLOAD(squareCycloFp12BN254_c21_y) + A :MSTORE(expByXCycloFp12BN254_c21_x) + B :MSTORE(expByXCycloFp12BN254_c21_y) + $ => A :MLOAD(squareCycloFp12BN254_c22_x) + $ => B :MLOAD(squareCycloFp12BN254_c22_y) + A :MSTORE(expByXCycloFp12BN254_c22_x) + B :MSTORE(expByXCycloFp12BN254_c22_y) + $ => A :MLOAD(squareCycloFp12BN254_c23_x) + $ => B :MLOAD(squareCycloFp12BN254_c23_y) + A :MSTORE(expByXCycloFp12BN254_c23_x) + B :MSTORE(expByXCycloFp12BN254_c23_y) + + ; For the following, keep in mind that a ∈ GΦ6(p²) and therefore + ; computing the conjugate is the same as computing the inverse. + + ; We check if the MSB b of x is either 1, 0 or -1. + ; - If b == 1, we should multiply a to c. + ; - If b == -1, we should multiply a̅ to c. + + RCX-1 => RR + :CALL(@xPseudoBinDecompBN254 + RR) + + ; if bit = -1, then multiply by conjugate + B :JMPN(expByXCycloFp12BN254_multiply_by_conjugate) + + ; if bit = 0, then repeat + B :JMPZ(expByXCycloFp12BN254_loop) + + ; else, multiply by a + +expByXCycloFp12BN254_multiply: + ; c·a + $ => A :MLOAD(expByXCycloFp12BN254_a11_x) + $ => B :MLOAD(expByXCycloFp12BN254_a11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(expByXCycloFp12BN254_a12_x) + $ => B :MLOAD(expByXCycloFp12BN254_a12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(expByXCycloFp12BN254_a13_x) + $ => B :MLOAD(expByXCycloFp12BN254_a13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(expByXCycloFp12BN254_a21_x) + $ => B :MLOAD(expByXCycloFp12BN254_a21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(expByXCycloFp12BN254_a22_x) + $ => B :MLOAD(expByXCycloFp12BN254_a22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(expByXCycloFp12BN254_a23_x) + $ => B :MLOAD(expByXCycloFp12BN254_a23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(expByXCycloFp12BN254_c11_x) + $ => B :MLOAD(expByXCycloFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(expByXCycloFp12BN254_c12_x) + $ => B :MLOAD(expByXCycloFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(expByXCycloFp12BN254_c13_x) + $ => B :MLOAD(expByXCycloFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(expByXCycloFp12BN254_c21_x) + $ => B :MLOAD(expByXCycloFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(expByXCycloFp12BN254_c22_x) + $ => B :MLOAD(expByXCycloFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(expByXCycloFp12BN254_c23_x) + $ => B :MLOAD(expByXCycloFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + ; c = c·a + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(expByXCycloFp12BN254_c11_x) + B :MSTORE(expByXCycloFp12BN254_c11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(expByXCycloFp12BN254_c12_x) + B :MSTORE(expByXCycloFp12BN254_c12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(expByXCycloFp12BN254_c13_x) + B :MSTORE(expByXCycloFp12BN254_c13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(expByXCycloFp12BN254_c21_x) + B :MSTORE(expByXCycloFp12BN254_c21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(expByXCycloFp12BN254_c22_x) + B :MSTORE(expByXCycloFp12BN254_c22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(expByXCycloFp12BN254_c23_x) + B :MSTORE(expByXCycloFp12BN254_c23_y) + :JMP(expByXCycloFp12BN254_loop) + +expByXCycloFp12BN254_multiply_by_conjugate: + ; c·a̅ + $ => A :MLOAD(expByXCycloFp12BN254_a11_x) + $ => B :MLOAD(expByXCycloFp12BN254_a11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(expByXCycloFp12BN254_a12_x) + $ => B :MLOAD(expByXCycloFp12BN254_a12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(expByXCycloFp12BN254_a13_x) + $ => B :MLOAD(expByXCycloFp12BN254_a13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(expByXCycloFp12BN254_neg_a21_x) + $ => B :MLOAD(expByXCycloFp12BN254_neg_a21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(expByXCycloFp12BN254_neg_a22_x) + $ => B :MLOAD(expByXCycloFp12BN254_neg_a22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(expByXCycloFp12BN254_neg_a23_x) + $ => B :MLOAD(expByXCycloFp12BN254_neg_a23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(expByXCycloFp12BN254_c11_x) + $ => B :MLOAD(expByXCycloFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(expByXCycloFp12BN254_c12_x) + $ => B :MLOAD(expByXCycloFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(expByXCycloFp12BN254_c13_x) + $ => B :MLOAD(expByXCycloFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(expByXCycloFp12BN254_c21_x) + $ => B :MLOAD(expByXCycloFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(expByXCycloFp12BN254_c22_x) + $ => B :MLOAD(expByXCycloFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(expByXCycloFp12BN254_c23_x) + $ => B :MLOAD(expByXCycloFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + ; c = c·a̅ + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(expByXCycloFp12BN254_c11_x) + B :MSTORE(expByXCycloFp12BN254_c11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(expByXCycloFp12BN254_c12_x) + B :MSTORE(expByXCycloFp12BN254_c12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(expByXCycloFp12BN254_c13_x) + B :MSTORE(expByXCycloFp12BN254_c13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(expByXCycloFp12BN254_c21_x) + B :MSTORE(expByXCycloFp12BN254_c21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(expByXCycloFp12BN254_c22_x) + B :MSTORE(expByXCycloFp12BN254_c22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(expByXCycloFp12BN254_c23_x) + B :MSTORE(expByXCycloFp12BN254_c23_y) + :JMP(expByXCycloFp12BN254_loop) + +expByXCycloFp12BN254_end: + $ => RR :MLOAD(expByXCycloFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/unused/expFp12BN254.zkasm b/main/pairings/unused/expFp12BN254.zkasm new file mode 100644 index 00000000..e98f9b8e --- /dev/null +++ b/main/pairings/unused/expFp12BN254.zkasm @@ -0,0 +1,333 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; expFp12BN254: +;; in: e, (a1 + a2·w) ∈ Fp12, where e ∈ [0,p¹²-2] ai ∈ Fp6 +;; out: (a1 + a2·w)^e = (c1 + c2·w) ∈ Fp12 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Comment: We use this algorithm with a very small e (i.e., it fits in 32 bits), but it must be adpated to use it with a bigger e +; Comment: In some cases, we can speed this algorithm up by using pseudobinary encoding instead of binary encoding + +VAR GLOBAL expFp12BN254_e +VAR GLOBAL expFp12BN254_a11_x +VAR GLOBAL expFp12BN254_a11_y +VAR GLOBAL expFp12BN254_a12_x +VAR GLOBAL expFp12BN254_a12_y +VAR GLOBAL expFp12BN254_a13_x +VAR GLOBAL expFp12BN254_a13_y +VAR GLOBAL expFp12BN254_a21_x +VAR GLOBAL expFp12BN254_a21_y +VAR GLOBAL expFp12BN254_a22_x +VAR GLOBAL expFp12BN254_a22_y +VAR GLOBAL expFp12BN254_a23_x +VAR GLOBAL expFp12BN254_a23_y +VAR GLOBAL expFp12BN254_c11_x +VAR GLOBAL expFp12BN254_c11_y +VAR GLOBAL expFp12BN254_c12_x +VAR GLOBAL expFp12BN254_c12_y +VAR GLOBAL expFp12BN254_c13_x +VAR GLOBAL expFp12BN254_c13_y +VAR GLOBAL expFp12BN254_c21_x +VAR GLOBAL expFp12BN254_c21_y +VAR GLOBAL expFp12BN254_c22_x +VAR GLOBAL expFp12BN254_c22_y +VAR GLOBAL expFp12BN254_c23_x +VAR GLOBAL expFp12BN254_c23_y + +VAR GLOBAL expFp12BN254_RR + +expFp12BN254: + RR :MSTORE(expFp12BN254_RR) + + ; Trivial cases: + ; 1] Is a = 0? + 0n => B + $ => A :MLOAD(expFp12BN254_a11_x) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a11_y) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a12_x) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a12_y) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a13_x) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a13_y) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a21_x) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a21_y) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a22_x) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a22_y) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a23_x) + $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ => A :MLOAD(expFp12BN254_a23_y) + $ :EQ, JMPC(expFp12BN254_a_is_zero) + expFp12BN254_a_continue1: + + ; 2] Is a = 1? + 1n => B + $ => A :MLOAD(expFp12BN254_a11_x) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + 0n => B + $ => A :MLOAD(expFp12BN254_a11_y) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a12_x) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a12_y) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a13_x) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a13_y) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a21_x) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a21_y) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a22_x) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a22_y) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a23_x) + $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ => A :MLOAD(expFp12BN254_a23_y) + $ :EQ, JMPC(expFp12BN254_a_is_one) + expFp12BN254_a_continue2: + + ; 3] Is e = 0? + $ => A :MLOAD(expFp12BN254_e) + 0n => B + $ :EQ, JMPC(expFp12BN254_e_is_zero) + + 257 => RCX + + $ => A :MLOAD(expFp12BN254_a11_x) + $ => B :MLOAD(expFp12BN254_a11_y) + A :MSTORE(expFp12BN254_c11_x) + B :MSTORE(expFp12BN254_c11_y) + $ => A :MLOAD(expFp12BN254_a12_x) + $ => B :MLOAD(expFp12BN254_a12_y) + A :MSTORE(expFp12BN254_c12_x) + B :MSTORE(expFp12BN254_c12_y) + $ => A :MLOAD(expFp12BN254_a13_x) + $ => B :MLOAD(expFp12BN254_a13_y) + A :MSTORE(expFp12BN254_c13_x) + B :MSTORE(expFp12BN254_c13_y) + $ => A :MLOAD(expFp12BN254_a21_x) + $ => B :MLOAD(expFp12BN254_a21_y) + A :MSTORE(expFp12BN254_c21_x) + B :MSTORE(expFp12BN254_c21_y) + $ => A :MLOAD(expFp12BN254_a22_x) + $ => B :MLOAD(expFp12BN254_a22_y) + A :MSTORE(expFp12BN254_c22_x) + B :MSTORE(expFp12BN254_c22_y) + $ => A :MLOAD(expFp12BN254_a23_x) + $ => B :MLOAD(expFp12BN254_a23_y) + A :MSTORE(expFp12BN254_c23_x) + B :MSTORE(expFp12BN254_c23_y) + + :JMP(expFp12BN254_find_MSB_e) + +expFp12BN254_a_is_zero: + ; I define 0^0 = 0 for simplicity + 0n :MSTORE(expFp12BN254_c11_x) + 0n :MSTORE(expFp12BN254_c11_y) + 0n :MSTORE(expFp12BN254_c12_x) + 0n :MSTORE(expFp12BN254_c12_y) + 0n :MSTORE(expFp12BN254_c13_x) + 0n :MSTORE(expFp12BN254_c13_y) + 0n :MSTORE(expFp12BN254_c21_x) + 0n :MSTORE(expFp12BN254_c21_y) + 0n :MSTORE(expFp12BN254_c22_x) + 0n :MSTORE(expFp12BN254_c22_y) + 0n :MSTORE(expFp12BN254_c23_x) + 0n :MSTORE(expFp12BN254_c23_y) + + :JMP(expFp12BN254_end) + +expFp12BN254_a_is_one: + ; 1^e = 1 + 1n :MSTORE(expFp12BN254_c11_x) + 0n :MSTORE(expFp12BN254_c11_y) + 0n :MSTORE(expFp12BN254_c12_x) + 0n :MSTORE(expFp12BN254_c12_y) + 0n :MSTORE(expFp12BN254_c13_x) + 0n :MSTORE(expFp12BN254_c13_y) + 0n :MSTORE(expFp12BN254_c21_x) + 0n :MSTORE(expFp12BN254_c21_y) + 0n :MSTORE(expFp12BN254_c22_x) + 0n :MSTORE(expFp12BN254_c22_y) + 0n :MSTORE(expFp12BN254_c23_x) + 0n :MSTORE(expFp12BN254_c23_y) + + :JMP(expFp12BN254_end) + +expFp12BN254_e_is_zero: + ; a^0 = 1 + 1n :MSTORE(expFp12BN254_c11_x) + 0n :MSTORE(expFp12BN254_c11_y) + 0n :MSTORE(expFp12BN254_c12_x) + 0n :MSTORE(expFp12BN254_c12_y) + 0n :MSTORE(expFp12BN254_c13_x) + 0n :MSTORE(expFp12BN254_c13_y) + 0n :MSTORE(expFp12BN254_c21_x) + 0n :MSTORE(expFp12BN254_c21_y) + 0n :MSTORE(expFp12BN254_c22_x) + 0n :MSTORE(expFp12BN254_c22_y) + 0n :MSTORE(expFp12BN254_c23_x) + 0n :MSTORE(expFp12BN254_c23_y) + + :JMP(expFp12BN254_end) + +expFp12BN254_find_MSB_e: + RCX - 1 => RCX + $ => A,B :MLOAD(expFp12BN254_e) + ; E = 2A + $ => E :ADD,MSTORE(expFp12BN254_e), JMPNC(expFp12BN254_find_MSB_e) + + +expFp12BN254_loop: + RCX - 1 => RCX :JMPZ(expFp12BN254_end) + + ; We always square: c = c^2 + $ => A :MLOAD(expFp12BN254_c11_x) + $ => B :MLOAD(expFp12BN254_c11_y) + A :MSTORE(squareFp12BN254_a11_x) + B :MSTORE(squareFp12BN254_a11_y) + $ => A :MLOAD(expFp12BN254_c12_x) + $ => B :MLOAD(expFp12BN254_c12_y) + A :MSTORE(squareFp12BN254_a12_x) + B :MSTORE(squareFp12BN254_a12_y) + $ => A :MLOAD(expFp12BN254_c13_x) + $ => B :MLOAD(expFp12BN254_c13_y) + A :MSTORE(squareFp12BN254_a13_x) + B :MSTORE(squareFp12BN254_a13_y) + $ => A :MLOAD(expFp12BN254_c21_x) + $ => B :MLOAD(expFp12BN254_c21_y) + A :MSTORE(squareFp12BN254_a21_x) + B :MSTORE(squareFp12BN254_a21_y) + $ => A :MLOAD(expFp12BN254_c22_x) + $ => B :MLOAD(expFp12BN254_c22_y) + A :MSTORE(squareFp12BN254_a22_x) + B :MSTORE(squareFp12BN254_a22_y) + $ => A :MLOAD(expFp12BN254_c23_x) + $ => B :MLOAD(expFp12BN254_c23_y) + A :MSTORE(squareFp12BN254_a23_x) + B :MSTORE(squareFp12BN254_a23_y), CALL(squareFp12BN254) + + ; c = c^2 + $ => A :MLOAD(squareFp12BN254_c11_x) + $ => B :MLOAD(squareFp12BN254_c11_y) + A :MSTORE(expFp12BN254_c11_x) + B :MSTORE(expFp12BN254_c11_y) + $ => A :MLOAD(squareFp12BN254_c12_x) + $ => B :MLOAD(squareFp12BN254_c12_y) + A :MSTORE(expFp12BN254_c12_x) + B :MSTORE(expFp12BN254_c12_y) + $ => A :MLOAD(squareFp12BN254_c13_x) + $ => B :MLOAD(squareFp12BN254_c13_y) + A :MSTORE(expFp12BN254_c13_x) + B :MSTORE(expFp12BN254_c13_y) + $ => A :MLOAD(squareFp12BN254_c21_x) + $ => B :MLOAD(squareFp12BN254_c21_y) + A :MSTORE(expFp12BN254_c21_x) + B :MSTORE(expFp12BN254_c21_y) + $ => A :MLOAD(squareFp12BN254_c22_x) + $ => B :MLOAD(squareFp12BN254_c22_y) + A :MSTORE(expFp12BN254_c22_x) + B :MSTORE(expFp12BN254_c22_y) + $ => A :MLOAD(squareFp12BN254_c23_x) + $ => B :MLOAD(squareFp12BN254_c23_y) + A :MSTORE(expFp12BN254_c23_x) + B :MSTORE(expFp12BN254_c23_y) + + ; 2] We check if the MSB b of e is either 1 or 0. If b==1, we should multiply a to c. + ; Then, update the value of e. + $ => A,B :MLOAD(expFp12BN254_e) + ; E = 2A + $ => E :ADD,MSTORE(expFp12BN254_e), JMPNC(expFp12BN254_loop) + +expFp12BN254_multiply: + $ => A :MLOAD(expFp12BN254_a11_x) + $ => B :MLOAD(expFp12BN254_a11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(expFp12BN254_a12_x) + $ => B :MLOAD(expFp12BN254_a12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(expFp12BN254_a13_x) + $ => B :MLOAD(expFp12BN254_a13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(expFp12BN254_a21_x) + $ => B :MLOAD(expFp12BN254_a21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(expFp12BN254_a22_x) + $ => B :MLOAD(expFp12BN254_a22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(expFp12BN254_a23_x) + $ => B :MLOAD(expFp12BN254_a23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(expFp12BN254_c11_x) + $ => B :MLOAD(expFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(expFp12BN254_c12_x) + $ => B :MLOAD(expFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(expFp12BN254_c13_x) + $ => B :MLOAD(expFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(expFp12BN254_c21_x) + $ => B :MLOAD(expFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(expFp12BN254_c22_x) + $ => B :MLOAD(expFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(expFp12BN254_c23_x) + $ => B :MLOAD(expFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + ; c = c·a + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(expFp12BN254_c11_x) + B :MSTORE(expFp12BN254_c11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(expFp12BN254_c12_x) + B :MSTORE(expFp12BN254_c12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(expFp12BN254_c13_x) + B :MSTORE(expFp12BN254_c13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(expFp12BN254_c21_x) + B :MSTORE(expFp12BN254_c21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(expFp12BN254_c22_x) + B :MSTORE(expFp12BN254_c22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(expFp12BN254_c23_x) + B :MSTORE(expFp12BN254_c23_y) + :JMP(expFp12BN254_loop) + +expFp12BN254_end: + $ => RR :MLOAD(expFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/unused/subFp12BN254.zkasm b/main/pairings/unused/subFp12BN254.zkasm new file mode 100644 index 00000000..92c8b830 --- /dev/null +++ b/main/pairings/unused/subFp12BN254.zkasm @@ -0,0 +1,130 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; subFp12BN254: +;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai,bi ∈ Fp6 +;; out: (c1 + c2·w) = (a1-b1) + (a2-b2)·w ∈ Fp12 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL subFp12BN254_a11_x +VAR GLOBAL subFp12BN254_a11_y +VAR GLOBAL subFp12BN254_a12_x +VAR GLOBAL subFp12BN254_a12_y +VAR GLOBAL subFp12BN254_a13_x +VAR GLOBAL subFp12BN254_a13_y +VAR GLOBAL subFp12BN254_a21_x +VAR GLOBAL subFp12BN254_a21_y +VAR GLOBAL subFp12BN254_a22_x +VAR GLOBAL subFp12BN254_a22_y +VAR GLOBAL subFp12BN254_a23_x +VAR GLOBAL subFp12BN254_a23_y +VAR GLOBAL subFp12BN254_b11_x +VAR GLOBAL subFp12BN254_b11_y +VAR GLOBAL subFp12BN254_b12_x +VAR GLOBAL subFp12BN254_b12_y +VAR GLOBAL subFp12BN254_b13_x +VAR GLOBAL subFp12BN254_b13_y +VAR GLOBAL subFp12BN254_b21_x +VAR GLOBAL subFp12BN254_b21_y +VAR GLOBAL subFp12BN254_b22_x +VAR GLOBAL subFp12BN254_b22_y +VAR GLOBAL subFp12BN254_b23_x +VAR GLOBAL subFp12BN254_b23_y +VAR GLOBAL subFp12BN254_c11_x +VAR GLOBAL subFp12BN254_c11_y +VAR GLOBAL subFp12BN254_c12_x +VAR GLOBAL subFp12BN254_c12_y +VAR GLOBAL subFp12BN254_c13_x +VAR GLOBAL subFp12BN254_c13_y +VAR GLOBAL subFp12BN254_c21_x +VAR GLOBAL subFp12BN254_c21_y +VAR GLOBAL subFp12BN254_c22_x +VAR GLOBAL subFp12BN254_c22_y +VAR GLOBAL subFp12BN254_c23_x +VAR GLOBAL subFp12BN254_c23_y + +VAR GLOBAL subFp12BN254_RR + +subFp12BN254: + RR :MSTORE(subFp12BN254_RR) + + ; 1] c1 = a1 - b1 + $ => A :MLOAD(subFp12BN254_a11_x) + $ => B :MLOAD(subFp12BN254_a11_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(subFp12BN254_a12_x) + $ => B :MLOAD(subFp12BN254_a12_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(subFp12BN254_a13_x) + $ => B :MLOAD(subFp12BN254_a13_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + + $ => A :MLOAD(subFp12BN254_b11_x) + $ => B :MLOAD(subFp12BN254_b11_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(subFp12BN254_b12_x) + $ => B :MLOAD(subFp12BN254_b12_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(subFp12BN254_b13_x) + $ => B :MLOAD(subFp12BN254_b13_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(subFp12BN254_c11_x) + B :MSTORE(subFp12BN254_c11_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(subFp12BN254_c12_x) + B :MSTORE(subFp12BN254_c12_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(subFp12BN254_c13_x) + B :MSTORE(subFp12BN254_c13_y) + + ; 2] c2 = a2 - b2 + $ => A :MLOAD(subFp12BN254_a21_x) + $ => B :MLOAD(subFp12BN254_a21_y) + A :MSTORE(subFp6BN254_a1_x) + B :MSTORE(subFp6BN254_a1_y) + $ => A :MLOAD(subFp12BN254_a22_x) + $ => B :MLOAD(subFp12BN254_a22_y) + A :MSTORE(subFp6BN254_a2_x) + B :MSTORE(subFp6BN254_a2_y) + $ => A :MLOAD(subFp12BN254_a23_x) + $ => B :MLOAD(subFp12BN254_a23_y) + A :MSTORE(subFp6BN254_a3_x) + B :MSTORE(subFp6BN254_a3_y) + + $ => A :MLOAD(subFp12BN254_b21_x) + $ => B :MLOAD(subFp12BN254_b21_y) + A :MSTORE(subFp6BN254_b1_x) + B :MSTORE(subFp6BN254_b1_y) + $ => A :MLOAD(subFp12BN254_b22_x) + $ => B :MLOAD(subFp12BN254_b22_y) + A :MSTORE(subFp6BN254_b2_x) + B :MSTORE(subFp6BN254_b2_y) + $ => A :MLOAD(subFp12BN254_b23_x) + $ => B :MLOAD(subFp12BN254_b23_y) + A :MSTORE(subFp6BN254_b3_x) + B :MSTORE(subFp6BN254_b3_y), CALL(subFp6BN254) + $ => A :MLOAD(subFp6BN254_c1_x) + $ => B :MLOAD(subFp6BN254_c1_y) + A :MSTORE(subFp12BN254_c21_x) + B :MSTORE(subFp12BN254_c21_y) + $ => A :MLOAD(subFp6BN254_c2_x) + $ => B :MLOAD(subFp6BN254_c2_y) + A :MSTORE(subFp12BN254_c22_x) + B :MSTORE(subFp12BN254_c22_y) + $ => A :MLOAD(subFp6BN254_c3_x) + $ => B :MLOAD(subFp6BN254_c3_y) + A :MSTORE(subFp12BN254_c23_x) + B :MSTORE(subFp12BN254_c23_y) + + $ => RR :MLOAD(subFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/unused/xPseudoBinDecompBN254.zkasm b/main/pairings/unused/xPseudoBinDecompBN254.zkasm new file mode 100644 index 00000000..933b1886 --- /dev/null +++ b/main/pairings/unused/xPseudoBinDecompBN254.zkasm @@ -0,0 +1,68 @@ +;; +;; parameter of BN254 x = 4965661367192848881, which can be expressed in (little-endian) pseudobinary as: +;; 1000-1000010100001001011001010010001011010100100110010-1001010001 +;; + +xPseudoBinDecompBN254: + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN \ No newline at end of file diff --git a/main/pairings/utilsTests/expCycloFp12BN254.zkasm b/main/pairings/utilsTests/expCycloFp12BN254.zkasm new file mode 100644 index 00000000..fabaa317 --- /dev/null +++ b/main/pairings/utilsTests/expCycloFp12BN254.zkasm @@ -0,0 +1,333 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; expCycloFp12BN254: +;; in: e, (a1 + a2·w) ∈ GΦ6(p²), where e ∈ [0,p¹²-2] ai ∈ Fp6 +;; out: (c1 + c2·w) = (a1 + a2·w)^e ∈ GΦ6(p²) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Comment: We use this algorithm with a very small e (i.e., it fits in 32 bits), but it must be adpated to use it with a bigger e +; Comment: In some cases, we can speed this algorithm up by using pseudobinary encoding instead of binary encoding + +VAR GLOBAL expCycloFp12BN254_e +VAR GLOBAL expCycloFp12BN254_a11_x +VAR GLOBAL expCycloFp12BN254_a11_y +VAR GLOBAL expCycloFp12BN254_a12_x +VAR GLOBAL expCycloFp12BN254_a12_y +VAR GLOBAL expCycloFp12BN254_a13_x +VAR GLOBAL expCycloFp12BN254_a13_y +VAR GLOBAL expCycloFp12BN254_a21_x +VAR GLOBAL expCycloFp12BN254_a21_y +VAR GLOBAL expCycloFp12BN254_a22_x +VAR GLOBAL expCycloFp12BN254_a22_y +VAR GLOBAL expCycloFp12BN254_a23_x +VAR GLOBAL expCycloFp12BN254_a23_y +VAR GLOBAL expCycloFp12BN254_c11_x +VAR GLOBAL expCycloFp12BN254_c11_y +VAR GLOBAL expCycloFp12BN254_c12_x +VAR GLOBAL expCycloFp12BN254_c12_y +VAR GLOBAL expCycloFp12BN254_c13_x +VAR GLOBAL expCycloFp12BN254_c13_y +VAR GLOBAL expCycloFp12BN254_c21_x +VAR GLOBAL expCycloFp12BN254_c21_y +VAR GLOBAL expCycloFp12BN254_c22_x +VAR GLOBAL expCycloFp12BN254_c22_y +VAR GLOBAL expCycloFp12BN254_c23_x +VAR GLOBAL expCycloFp12BN254_c23_y + +VAR GLOBAL expCycloFp12BN254_RR + +expCycloFp12BN254: + RR :MSTORE(expCycloFp12BN254_RR) + + ; Trivial cases: + ; 1] Is a = 0? + 0n => B + $ => A :MLOAD(expCycloFp12BN254_a11_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a11_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a12_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a12_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a13_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a13_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a21_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a21_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a22_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a22_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a23_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ => A :MLOAD(expCycloFp12BN254_a23_y) + $ :EQ, JMPC(expCycloFp12BN254_a_is_zero) + expCycloFp12BN254_a_continue1: + + ; 2] Is a = 1? + 1n => B + $ => A :MLOAD(expCycloFp12BN254_a11_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + 0n => B + $ => A :MLOAD(expCycloFp12BN254_a11_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a12_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a12_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a13_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a13_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a21_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a21_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a22_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a22_y) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a23_x) + $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ => A :MLOAD(expCycloFp12BN254_a23_y) + $ :EQ, JMPC(expCycloFp12BN254_a_is_one) + expCycloFp12BN254_a_continue2: + + ; 3] Check if e = 0 + $ => A :MLOAD(expCycloFp12BN254_e) + 0n => B + $ :EQ, JMPC(expCycloFp12BN254_e_is_zero) + + 257 => RCX + + $ => A :MLOAD(expCycloFp12BN254_a11_x) + $ => B :MLOAD(expCycloFp12BN254_a11_y) + A :MSTORE(expCycloFp12BN254_c11_x) + B :MSTORE(expCycloFp12BN254_c11_y) + $ => A :MLOAD(expCycloFp12BN254_a12_x) + $ => B :MLOAD(expCycloFp12BN254_a12_y) + A :MSTORE(expCycloFp12BN254_c12_x) + B :MSTORE(expCycloFp12BN254_c12_y) + $ => A :MLOAD(expCycloFp12BN254_a13_x) + $ => B :MLOAD(expCycloFp12BN254_a13_y) + A :MSTORE(expCycloFp12BN254_c13_x) + B :MSTORE(expCycloFp12BN254_c13_y) + $ => A :MLOAD(expCycloFp12BN254_a21_x) + $ => B :MLOAD(expCycloFp12BN254_a21_y) + A :MSTORE(expCycloFp12BN254_c21_x) + B :MSTORE(expCycloFp12BN254_c21_y) + $ => A :MLOAD(expCycloFp12BN254_a22_x) + $ => B :MLOAD(expCycloFp12BN254_a22_y) + A :MSTORE(expCycloFp12BN254_c22_x) + B :MSTORE(expCycloFp12BN254_c22_y) + $ => A :MLOAD(expCycloFp12BN254_a23_x) + $ => B :MLOAD(expCycloFp12BN254_a23_y) + A :MSTORE(expCycloFp12BN254_c23_x) + B :MSTORE(expCycloFp12BN254_c23_y) + + :JMP(expCycloFp12BN254_find_MSB_e) + +expCycloFp12BN254_a_is_zero: + ; I define 0^0 = 0 for simplicity + 0n :MSTORE(expCycloFp12BN254_c11_x) + 0n :MSTORE(expCycloFp12BN254_c11_y) + 0n :MSTORE(expCycloFp12BN254_c12_x) + 0n :MSTORE(expCycloFp12BN254_c12_y) + 0n :MSTORE(expCycloFp12BN254_c13_x) + 0n :MSTORE(expCycloFp12BN254_c13_y) + 0n :MSTORE(expCycloFp12BN254_c21_x) + 0n :MSTORE(expCycloFp12BN254_c21_y) + 0n :MSTORE(expCycloFp12BN254_c22_x) + 0n :MSTORE(expCycloFp12BN254_c22_y) + 0n :MSTORE(expCycloFp12BN254_c23_x) + 0n :MSTORE(expCycloFp12BN254_c23_y) + + :JMP(expCycloFp12BN254_end) + +expCycloFp12BN254_a_is_one: + ; c = 1 + 1n :MSTORE(expCycloFp12BN254_c11_x) + 0n :MSTORE(expCycloFp12BN254_c11_y) + 0n :MSTORE(expCycloFp12BN254_c12_x) + 0n :MSTORE(expCycloFp12BN254_c12_y) + 0n :MSTORE(expCycloFp12BN254_c13_x) + 0n :MSTORE(expCycloFp12BN254_c13_y) + 0n :MSTORE(expCycloFp12BN254_c21_x) + 0n :MSTORE(expCycloFp12BN254_c21_y) + 0n :MSTORE(expCycloFp12BN254_c22_x) + 0n :MSTORE(expCycloFp12BN254_c22_y) + 0n :MSTORE(expCycloFp12BN254_c23_x) + 0n :MSTORE(expCycloFp12BN254_c23_y) + + :JMP(expCycloFp12BN254_end) + +expCycloFp12BN254_e_is_zero: + ; c = 1 + 1n :MSTORE(expCycloFp12BN254_c11_x) + 0n :MSTORE(expCycloFp12BN254_c11_y) + 0n :MSTORE(expCycloFp12BN254_c12_x) + 0n :MSTORE(expCycloFp12BN254_c12_y) + 0n :MSTORE(expCycloFp12BN254_c13_x) + 0n :MSTORE(expCycloFp12BN254_c13_y) + 0n :MSTORE(expCycloFp12BN254_c21_x) + 0n :MSTORE(expCycloFp12BN254_c21_y) + 0n :MSTORE(expCycloFp12BN254_c22_x) + 0n :MSTORE(expCycloFp12BN254_c22_y) + 0n :MSTORE(expCycloFp12BN254_c23_x) + 0n :MSTORE(expCycloFp12BN254_c23_y) + + :JMP(expCycloFp12BN254_end) + +expCycloFp12BN254_find_MSB_e: + RCX - 1 => RCX + $ => A,B :MLOAD(expCycloFp12BN254_e) + ; E = 2A + $ => E :ADD,MSTORE(expCycloFp12BN254_e), JMPNC(expCycloFp12BN254_find_MSB_e) + + +expCycloFp12BN254_loop: + RCX - 1 => RCX :JMPZ(expCycloFp12BN254_end) + + ; We always square: c = c^2 + $ => A :MLOAD(expCycloFp12BN254_c11_x) + $ => B :MLOAD(expCycloFp12BN254_c11_y) + A :MSTORE(squareCycloFp12BN254_a11_x) + B :MSTORE(squareCycloFp12BN254_a11_y) + $ => A :MLOAD(expCycloFp12BN254_c12_x) + $ => B :MLOAD(expCycloFp12BN254_c12_y) + A :MSTORE(squareCycloFp12BN254_a12_x) + B :MSTORE(squareCycloFp12BN254_a12_y) + $ => A :MLOAD(expCycloFp12BN254_c13_x) + $ => B :MLOAD(expCycloFp12BN254_c13_y) + A :MSTORE(squareCycloFp12BN254_a13_x) + B :MSTORE(squareCycloFp12BN254_a13_y) + $ => A :MLOAD(expCycloFp12BN254_c21_x) + $ => B :MLOAD(expCycloFp12BN254_c21_y) + A :MSTORE(squareCycloFp12BN254_a21_x) + B :MSTORE(squareCycloFp12BN254_a21_y) + $ => A :MLOAD(expCycloFp12BN254_c22_x) + $ => B :MLOAD(expCycloFp12BN254_c22_y) + A :MSTORE(squareCycloFp12BN254_a22_x) + B :MSTORE(squareCycloFp12BN254_a22_y) + $ => A :MLOAD(expCycloFp12BN254_c23_x) + $ => B :MLOAD(expCycloFp12BN254_c23_y) + A :MSTORE(squareCycloFp12BN254_a23_x) + B :MSTORE(squareCycloFp12BN254_a23_y), CALL(squareCycloFp12BN254) + + ; c = c^2 + $ => A :MLOAD(squareCycloFp12BN254_c11_x) + $ => B :MLOAD(squareCycloFp12BN254_c11_y) + A :MSTORE(expCycloFp12BN254_c11_x) + B :MSTORE(expCycloFp12BN254_c11_y) + $ => A :MLOAD(squareCycloFp12BN254_c12_x) + $ => B :MLOAD(squareCycloFp12BN254_c12_y) + A :MSTORE(expCycloFp12BN254_c12_x) + B :MSTORE(expCycloFp12BN254_c12_y) + $ => A :MLOAD(squareCycloFp12BN254_c13_x) + $ => B :MLOAD(squareCycloFp12BN254_c13_y) + A :MSTORE(expCycloFp12BN254_c13_x) + B :MSTORE(expCycloFp12BN254_c13_y) + $ => A :MLOAD(squareCycloFp12BN254_c21_x) + $ => B :MLOAD(squareCycloFp12BN254_c21_y) + A :MSTORE(expCycloFp12BN254_c21_x) + B :MSTORE(expCycloFp12BN254_c21_y) + $ => A :MLOAD(squareCycloFp12BN254_c22_x) + $ => B :MLOAD(squareCycloFp12BN254_c22_y) + A :MSTORE(expCycloFp12BN254_c22_x) + B :MSTORE(expCycloFp12BN254_c22_y) + $ => A :MLOAD(squareCycloFp12BN254_c23_x) + $ => B :MLOAD(squareCycloFp12BN254_c23_y) + A :MSTORE(expCycloFp12BN254_c23_x) + B :MSTORE(expCycloFp12BN254_c23_y) + + ; 2] We check if the MSB b of e is either 1 or 0. If b==1, we should multiply a to c. + ; Then, update the value of e. + $ => A,B :MLOAD(expCycloFp12BN254_e) + ; E = 2A + $ => E :ADD,MSTORE(expCycloFp12BN254_e), JMPNC(expCycloFp12BN254_loop) + +expCycloFp12BN254_multiply: + $ => A :MLOAD(expCycloFp12BN254_a11_x) + $ => B :MLOAD(expCycloFp12BN254_a11_y) + A :MSTORE(mulFp12BN254_a11_x) + B :MSTORE(mulFp12BN254_a11_y) + $ => A :MLOAD(expCycloFp12BN254_a12_x) + $ => B :MLOAD(expCycloFp12BN254_a12_y) + A :MSTORE(mulFp12BN254_a12_x) + B :MSTORE(mulFp12BN254_a12_y) + $ => A :MLOAD(expCycloFp12BN254_a13_x) + $ => B :MLOAD(expCycloFp12BN254_a13_y) + A :MSTORE(mulFp12BN254_a13_x) + B :MSTORE(mulFp12BN254_a13_y) + $ => A :MLOAD(expCycloFp12BN254_a21_x) + $ => B :MLOAD(expCycloFp12BN254_a21_y) + A :MSTORE(mulFp12BN254_a21_x) + B :MSTORE(mulFp12BN254_a21_y) + $ => A :MLOAD(expCycloFp12BN254_a22_x) + $ => B :MLOAD(expCycloFp12BN254_a22_y) + A :MSTORE(mulFp12BN254_a22_x) + B :MSTORE(mulFp12BN254_a22_y) + $ => A :MLOAD(expCycloFp12BN254_a23_x) + $ => B :MLOAD(expCycloFp12BN254_a23_y) + A :MSTORE(mulFp12BN254_a23_x) + B :MSTORE(mulFp12BN254_a23_y) + $ => A :MLOAD(expCycloFp12BN254_c11_x) + $ => B :MLOAD(expCycloFp12BN254_c11_y) + A :MSTORE(mulFp12BN254_b11_x) + B :MSTORE(mulFp12BN254_b11_y) + $ => A :MLOAD(expCycloFp12BN254_c12_x) + $ => B :MLOAD(expCycloFp12BN254_c12_y) + A :MSTORE(mulFp12BN254_b12_x) + B :MSTORE(mulFp12BN254_b12_y) + $ => A :MLOAD(expCycloFp12BN254_c13_x) + $ => B :MLOAD(expCycloFp12BN254_c13_y) + A :MSTORE(mulFp12BN254_b13_x) + B :MSTORE(mulFp12BN254_b13_y) + $ => A :MLOAD(expCycloFp12BN254_c21_x) + $ => B :MLOAD(expCycloFp12BN254_c21_y) + A :MSTORE(mulFp12BN254_b21_x) + B :MSTORE(mulFp12BN254_b21_y) + $ => A :MLOAD(expCycloFp12BN254_c22_x) + $ => B :MLOAD(expCycloFp12BN254_c22_y) + A :MSTORE(mulFp12BN254_b22_x) + B :MSTORE(mulFp12BN254_b22_y) + $ => A :MLOAD(expCycloFp12BN254_c23_x) + $ => B :MLOAD(expCycloFp12BN254_c23_y) + A :MSTORE(mulFp12BN254_b23_x) + B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + + ; c = c·a + $ => A :MLOAD(mulFp12BN254_c11_x) + $ => B :MLOAD(mulFp12BN254_c11_y) + A :MSTORE(expCycloFp12BN254_c11_x) + B :MSTORE(expCycloFp12BN254_c11_y) + $ => A :MLOAD(mulFp12BN254_c12_x) + $ => B :MLOAD(mulFp12BN254_c12_y) + A :MSTORE(expCycloFp12BN254_c12_x) + B :MSTORE(expCycloFp12BN254_c12_y) + $ => A :MLOAD(mulFp12BN254_c13_x) + $ => B :MLOAD(mulFp12BN254_c13_y) + A :MSTORE(expCycloFp12BN254_c13_x) + B :MSTORE(expCycloFp12BN254_c13_y) + $ => A :MLOAD(mulFp12BN254_c21_x) + $ => B :MLOAD(mulFp12BN254_c21_y) + A :MSTORE(expCycloFp12BN254_c21_x) + B :MSTORE(expCycloFp12BN254_c21_y) + $ => A :MLOAD(mulFp12BN254_c22_x) + $ => B :MLOAD(mulFp12BN254_c22_y) + A :MSTORE(expCycloFp12BN254_c22_x) + B :MSTORE(expCycloFp12BN254_c22_y) + $ => A :MLOAD(mulFp12BN254_c23_x) + $ => B :MLOAD(mulFp12BN254_c23_y) + A :MSTORE(expCycloFp12BN254_c23_x) + B :MSTORE(expCycloFp12BN254_c23_y) + :JMP(expCycloFp12BN254_loop) + +expCycloFp12BN254_end: + $ => RR :MLOAD(expCycloFp12BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/precompiled/end.zkasm b/main/precompiled/end.zkasm index 14383eb7..2393ffa6 100644 --- a/main/precompiled/end.zkasm +++ b/main/precompiled/end.zkasm @@ -6,4 +6,21 @@ preEnd: A - 1 :MSTORE(depth) $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - 1 :MSTORE(SP++), JMP(readCode) \ No newline at end of file + 1 :MSTORE(SP++), JMP(readCode) + +preEndFail: + $ => SR :MLOAD(initSR), CALL(revertTouched) + :CALL(revertBlockInfoTree) + ;remaining gas = 0 + $ => A :MLOAD(originCTX), JMPZ(errorAtFirstContext) + A => CTX + ; Add return data context value to origin context + ; Clear return data context + 0 :MSTORE(retDataCTX) + CTX :MSTORE(currentCTX) + $ => GAS :MLOAD(gasCTX) + $ => SP :MLOAD(lastSP) + $ => PC :MLOAD(lastPC) + 0 :MSTORE(SP++) + $ => A :MLOAD(depth) + A - 1 :MSTORE(depth), JMP(readCode) \ No newline at end of file diff --git a/main/precompiled/identity.zkasm b/main/precompiled/identity.zkasm index e353a665..bffbe04a 100644 --- a/main/precompiled/identity.zkasm +++ b/main/precompiled/identity.zkasm @@ -1,3 +1,12 @@ +/** + * @link [https://www.evm.codes/precompiled#0x04?fork=shanghai] + * @zk-counters + * - dynamic steps: 100 + * - dynamic binary: 1 + * @process-precompiled + * - stack input: [data] + * - stack output: [data] + */ IDENTITY: %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) @@ -87,4 +96,4 @@ IDENTITYreturnFinal: IDENTITYend: $ => CTX :MLOAD(originCTX) - CTX :MSTORE(currentCTX), JMP(preEnd) + CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file diff --git a/main/precompiled/pre-ecAdd.zkasm b/main/precompiled/pre-ecAdd.zkasm new file mode 100644 index 00000000..890e3e56 --- /dev/null +++ b/main/precompiled/pre-ecAdd.zkasm @@ -0,0 +1,92 @@ +/** + * @link [https://www.evm.codes/precompiled#0x06?fork=shanghai] + * @zk-counters + * - dynamic steps: 500 + * - dynamic arith: 50 + * - dynamic binary: 10 + * @process-precompiled + * - stack input: [x1, y1, x2, y2] + * - stack output: [x, y] + */ +funcEcAdd: + + %MAX_CNT_BINARY - CNT_BINARY - 10 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 50 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) + + ; Move balances if value > 0 just before executing the contract CALL + $ => B :MLOAD(txValue) + 0 => A + zkPC+2 => RR + $ :LT, JMPC(moveBalances) + + GAS - %ECADD_GAS => GAS :JMPN(outOfGas) ; gas static = 150 + + ; read data stored in calldata + ; x1 [32 bytes], y1 [32 bytes], x2 [32 bytes], y2 [32 bytes] + 32 :MSTORE(readXFromCalldataLength) + 0 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) ; x1 + A :MSTORE(ecAdd_P1_x) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) ; y1 + A :MSTORE(ecAdd_P1_y) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) ; x2 + A :MSTORE(ecAdd_P2_x) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) ; y2 + A :MSTORE(ecAdd_P2_y),CALL(ecAdd) + + ; check error + B :JMPNZ(preEndFail) + + ; write ecAdd data into memory + 0 => E + $ => A :MLOAD(ecAdd_P3_x) + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + $ => A :MLOAD(ecAdd_P3_y) + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + + ; prepare return data + 0 :MSTORE(retDataOffset) + 64 :MSTORE(retDataLength) + $ => A :MLOAD(originCTX), JMPZ(handleGas) + ; set retDataCTX + $ => B :MLOAD(currentCTX) + A => CTX + B :MSTORE(retDataCTX) + B => CTX + + ; write result ecAdd into previous context memory + $ => C :MLOAD(retCallLength), JMPZ(preEndECADD) + $ => E :MLOAD(retCallOffset) + + $ => CTX :MLOAD(originCTX) + $ => A :MLOAD(ecAdd_P3_x) + A :MSTORE(bytesToStore) + C - 32 :JMPN(continueEcAdd) + C - 32 => C + :CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + $ => A :MLOAD(ecAdd_P3_y) + A :MSTORE(bytesToStore) + C - 32 :JMPN(continueEcAdd) + :CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + :JMP(endECADD) + +continueEcAdd: + :CALL(MSTOREX); in: [bytesToStore, E: offset] out: [E: new offset] + :JMP(endECADD) + +;endECADDFail: +; $ => A :MLOAD(originCTX), JMPZ(handleGas) +; 0 => GAS +; A => CTX +; 0 :MSTORE(retDataCTX) +; CTX :MSTORE(currentCTX), JMP(preEndFail) + +preEndECADD: + $ => CTX :MLOAD(originCTX) + +endECADD: + CTX :MSTORE(currentCTX), JMP(preEnd) diff --git a/main/precompiled/pre-ecMul.zkasm b/main/precompiled/pre-ecMul.zkasm new file mode 100644 index 00000000..8948fa04 --- /dev/null +++ b/main/precompiled/pre-ecMul.zkasm @@ -0,0 +1,89 @@ +/** + * @link [https://www.evm.codes/precompiled#0x07?fork=shanghai] + * @zk-counters + * - dynamic steps: 130000 + * - dynamic arith: 20000 + * - dynamic binary: 4000 + * @process-precompiled + * - stack input: [x1, y1, s] + * - stack output: [x, y] + */ +funcEcMul: + + %MAX_CNT_BINARY - CNT_BINARY - 4000 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 20000 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 130000 :JMPN(outOfCountersStep) + + ; Move balances if value > 0 just before executing the contract CALL + $ => B :MLOAD(txValue) + 0 => A + zkPC+2 => RR + $ :LT, JMPC(moveBalances) + + GAS - %ECMUL_GAS => GAS :JMPN(outOfGas) ; gas static = 6000 + + ; read data stored in calldata + ; x1 [32 bytes], y1 [32 bytes], k [32 bytes] + 32 :MSTORE(readXFromCalldataLength) + 0 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) ; x1 + A :MSTORE(ecMul_P_x) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) ; y1 + A :MSTORE(ecMul_P_y) + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) ; k + A :MSTORE(ecMul_k),CALL(ecMul) + + ; check error + B :JMPNZ(preEndFail) + + ; write ecMul data into memory + 0 => E + $ => A :MLOAD(ecMul_Q_x) + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + $ => A :MLOAD(ecMul_Q_y) + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + + ; prepare return data + 0 :MSTORE(retDataOffset) + 64 :MSTORE(retDataLength) + $ => A :MLOAD(originCTX), JMPZ(handleGas) + ; set retDataCTX + $ => B :MLOAD(currentCTX) + A => CTX + B :MSTORE(retDataCTX) + B => CTX + + ; write result ecMul into previous context memory + $ => C :MLOAD(retCallLength), JMPZ(preEndECMUL) + $ => E :MLOAD(retCallOffset) + + $ => CTX :MLOAD(originCTX) + $ => A :MLOAD(ecMul_Q_x) + A :MSTORE(bytesToStore) + C - 32 :JMPN(continueEcMul) + C - 32 => C + :CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + $ => A :MLOAD(ecMul_Q_y) + A :MSTORE(bytesToStore) + C - 32 :JMPN(continueEcMul) + :CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + :JMP(endECMUL) + +continueEcMul: + :CALL(MSTOREX); in: [bytesToStore, E: offset] out: [E: new offset] + :JMP(endECMUL) + +;endECMULFail: +; $ => A :MLOAD(originCTX), JMPZ(handleGas) +; 0 => GAS +; A => CTX +; 0 :MSTORE(retDataCTX) +; CTX :MSTORE(currentCTX), JMP(preEndFail) + +preEndECMUL: + $ => CTX :MLOAD(originCTX) + +endECMUL: + CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file diff --git a/main/precompiled/pre-ecPairing.zkasm b/main/precompiled/pre-ecPairing.zkasm new file mode 100644 index 00000000..481342f7 --- /dev/null +++ b/main/precompiled/pre-ecPairing.zkasm @@ -0,0 +1,85 @@ +/** + * @link [https://www.evm.codes/precompiled#0x08?fork=shanghai] + * @zk-counters + * - dynamic steps: 50000, 550000, 700000,... + * - dynamic airth: 4000, 43000, 56000,... + * - dynamic binary: 400, 700, 1100,... + * @process-precompiled + * - stack input: [x1, y1, x2, y2, ..., xk, yk] + * - stack output: [success] + */ + +funcEcPairing: + ; Move balances if value > 0 just before executing the contract CALL + $ => B :MLOAD(txValue) + 0 => A + zkPC+2 => RR + $ :LT, JMPC(moveBalances) + + GAS - %ECPAIRING_GAS => GAS :JMPN(outOfGas) ; gas static = 45000 + + 1 => C + $ => B :MLOAD(argsLengthCall),JMPZ(continueInput0) + B :MSTORE(arithA) + 192 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => A :MLOAD(arithRes2), JMPNZ(preEndFail) + $ => A :MLOAD(arithRes1) + A :MSTORE(ecPairing_ninputs) + + GAS - 34000*A => GAS :JMPN(outOfGas) ; gas = 34000 * inputsLength + A - 1 :JMPZ(counters6) + A - 2 => A + + %MAX_CNT_BINARY - CNT_BINARY - 700 - 400*A :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 45000 - 14000*A :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 550000 - 200000*A :JMPN(outOfCountersStep) + :JMP(afterCounts) + + $ => A :MLOAD(retCallLength) + 32 => B + $ :LT,JMPC(preEndFail) + +counters6: + + %MAX_CNT_BINARY - CNT_BINARY - 400 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 4000 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 50000 :JMPN(outOfCountersStep) + +afterCounts: + -32 :MSTORE(readXFromCalldataOffset),CALL(ecPairing) + B :JMPNZ(preEndFail) + $ => C :MLOAD(ecPairing_result) + +continueInput0: + + ; write ecAdd data into memory + 0 => E + C :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + + ; prepare return data + 0 :MSTORE(retDataOffset) + 32 :MSTORE(retDataLength) + $ => A :MLOAD(originCTX), JMPZ(handleGas) + ; set retDataCTX + $ => B :MLOAD(currentCTX) + A => CTX + B :MSTORE(retDataCTX) + B => CTX + + ; write result ecpairing into previous context memory + $ => C :MLOAD(retCallLength) + $ => E :MLOAD(retCallOffset) + + ; ecpairing result is in bytesToStore + C - 32 :JMPN(continueECPAIRING) + 32 => C + +continueECPAIRING: + $ => CTX :MLOAD(originCTX), CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset] + :JMP(endECPAIRING) + +preEndECPAIRING: + $ => CTX :MLOAD(originCTX) + +endECPAIRING: + CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file diff --git a/main/precompiled/pre-ecrecover.zkasm b/main/precompiled/pre-ecrecover.zkasm index 6458f96c..e989fd25 100644 --- a/main/precompiled/pre-ecrecover.zkasm +++ b/main/precompiled/pre-ecrecover.zkasm @@ -1,3 +1,13 @@ +/** + * @link [https://www.evm.codes/precompiled#0x01?fork=shanghai] + * @zk-counters + * - dynamic steps: + * - dynamic arith: + * - dynamic binary: + * @process-precompiled + * - stack input: [hash, v, r, s] + * - stack output: [publicAddress] + */ funcECRECOVER: ; Move balances if value > 0 just before executing the contract CALL $ => B :MLOAD(txValue) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm new file mode 100644 index 00000000..781d0998 --- /dev/null +++ b/main/precompiled/pre-modexp.zkasm @@ -0,0 +1,289 @@ +/** + * @link [https://www.evm.codes/precompiled#0x05?fork=shanghai] + * @zk-counters + * - dynamic steps: + * - dynamic arith: + * - dynamic binary: + * @process-precompiled + * - stack input: [x1, y1, x2, y2] + * - stack output: [x, y] + */ +INCLUDE "../modexp/modexp.zkasm" +INCLUDE "../modexp/modexp_utils.zkasm" + +INCLUDE "../modexp/array_lib/utils/array_trim.zkasm" +INCLUDE "../modexp/array_lib/utils/array_compare.zkasm" + +INCLUDE "../modexp/array_lib/array_add_AGTB.zkasm" +INCLUDE "../modexp/array_lib/array_add_short.zkasm" +INCLUDE "../modexp/array_lib/array_mul_long.zkasm" +INCLUDE "../modexp/array_lib/array_mul_short.zkasm" +INCLUDE "../modexp/array_lib/array_mul.zkasm" +INCLUDE "../modexp/array_lib/array_square.zkasm" +INCLUDE "../modexp/array_lib/array_div_mod_short.zkasm" +INCLUDE "../modexp/array_lib/array_div_mod_long.zkasm" +INCLUDE "../modexp/array_lib/array_div_mod.zkasm" + +VAR GLOBAL multiplication_complexity + +VAR GLOBAL modexp_Bsize +VAR GLOBAL modexp_Esize +VAR GLOBAL modexp_Msize +VAR GLOBAL modexp_Mend +VAR GLOBAL modexp_offset +VAR GLOBAL modexp_returnIndex +VAR GLOBAL expLenBits + +funcModexp: + + %MAX_CNT_BINARY - CNT_BINARY - 20 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) + + ; Move balances if value > 0 just before executing the contract CALL + $ => B :MLOAD(txValue) + 0 => A + zkPC+2 => RR + $ :LT, JMPC(moveBalances) + + ; read data stored in calldata + ; Bsize [32 bytes], Esize [32 bytes], Msize [32 bytes] + ; Bsize [32 bytes] + 32 :MSTORE(readXFromCalldataLength) + 0 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(modexp_Bsize) ;Bsize = base size + ; Esize [32 bytes] + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(modexp_Esize) ;Esize = exp size + ; Msize [32 bytes] + E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + A :MSTORE(modexp_Msize) ;Msize = mod size + ; store offset modexp num values + E + 32 => E + E :MSTORE(modexp_offset) + $ => A :MLOAD(modexp_Bsize) + A :MSTORE(arithA) + 96 :MSTORE(arithB),CALL(addARITH) + $ => A :MLOAD(arithRes1) + $ => B :MLOAD(txCalldataLen) + 0 :MSTORE(expLenBits) + $ :LT,JMPC(setExpBits,setMaxLen) + +setExpBits: + A => E + $ => A,C :MLOAD(modexp_Esize) + 33 => B + ; if Esize <= 32 --> setExpBitsContinue + $ => B :LT,JMPC(setExpBitsContinue) + 32 => C + +setExpBitsContinue: + C :MSTORE(readXFromCalldataLength) + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + 32 - C => D :CALL(SHRarith) + A => B :CALL(getLenBits); A bits length first 32 bytes + A :JMPZ(setMaxLen) + A - 1 :MSTORE(expLenBits) + +setMaxLen: + $ => B :MLOAD(modexp_Msize) + $ => A :MLOAD(modexp_Bsize) + $ :LT, JMPC(calculateGas) + A => B + +; B: max_length = max(Blen, Mlen) +calculateGas: + + %MAX_CNT_BINARY - CNT_BINARY - 10 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 120 :JMPN(outOfCountersStep) + + B :MSTORE(arithA) + 7 :MSTORE(arithB),CALL(addARITH) + $ => B :MLOAD(arithRes1) + B :MSTORE(arithA) + 8 :MSTORE(arithB),CALL(divARITH) + ; C: words = (max_length + 7) / 8 + $ => B :MLOAD(arithRes1) + %MAX_GAS_WORD_MODEXP => A + $ :LT,JMPC(outOfGas) + ; A: multiplication_complexity = words**2 + B :MSTORE(arithA) + B :MSTORE(arithB),CALL(mulARITH) + $ => A :MLOAD(arithRes1) + A :MSTORE(multiplication_complexity),JMPZ(dinamicGas) + + $ => A :MLOAD(modexp_Esize) + 33 => B + ; if Esize <= 32 --> modexp_expLT32 + $ => B :LT,JMPC(modexp_expLT32) + ;elif Esize > 32: iteration_count = (8 * (Esize - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) + A :MSTORE(arithA) + 32 :MSTORE(arithB),CALL(subARITH) + $ => A :MLOAD(arithRes1) + A :MSTORE(arithA) + 8 :MSTORE(arithB),CALL(mulARITH) + ; A = 8 * (Esize - 32) + $ => A :MLOAD(arithRes1) + $ => B :MLOAD(expLenBits) + ; iteration_count = (8 * (Esize - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) + A + B => E :JMP(finalGas) + ; E = iteration_count + +modexp_expLT32: + $ => E :MLOAD(expLenBits) + +finalGas: + E => B + %MAX_GAS_IT_MODEXP => A + $ :LT,JMPC(outOfGas) + 1 => A + $ :LT,JMPC(dinamicGas) + 1 => E + +dinamicGas: + + %MAX_CNT_BINARY - CNT_BINARY - 9 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 3 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 55 :JMPN(outOfCountersStep) + + ; E = calculate_iteration_count = max(iteration_count, 1) + $ => A :MLOAD(multiplication_complexity) + A :MSTORE(arithA) + E :MSTORE(arithB),CALL(mulARITH) + ; A = multiplication_complexity * iteration_count + $ => A :MLOAD(arithRes1) + A :MSTORE(arithA) + 3 :MSTORE(arithB),CALL(divARITH) + ; A = multiplication_complexity * iteration_count / 3 + $ => A :MLOAD(arithRes1) + %TX_GAS_LIMIT => B + $ :LT,JMPNC(outOfGas) + 200 => B + $ :LT,JMPC(callMODEXP) + A => B + +callMODEXP: + ; B = max(200, multiplication_complexity * iteration_count / 3) + GAS - B => GAS :JMPN(outOfGas) + 0 => A + $ => B :MLOAD(modexp_Msize) + $ :EQ,JMPC(save0outMod0) ; if Msize = 0 --> save0outMod0 + $ => B :MLOAD(modexp_Bsize) + $ :EQ,JMPC(save0out) ; if Bsize = 0 --> save0outMod0 + %MAX_SIZE_MODEXP => A + $ => B :MLOAD(modexp_Bsize) + $ :LT,JMPC(endMODEXPFail) ; if Bsize > MAX_SIZE_MODEXP --> endMODEXPFail + $ => B :MLOAD(modexp_Esize) + $ :LT,JMPC(endMODEXPFail) ; if Esize > MAX_SIZE_MODEXP --> endMODEXPFail + $ => B :MLOAD(modexp_Msize) + $ :LT,JMPC(endMODEXPFail) ; if Msize > MAX_SIZE_MODEXP --> endMODEXPFail + $ => E :MLOAD(modexp_offset) + $ => C :MLOAD(modexp_Bsize) + :CALL(modexp_getBase) + $ => C :MLOAD(modexp_Esize) + :CALL(modexp_getExp) + $ => C :MLOAD(modexp_Msize) + E :MSTORE(arithA) + C :MSTORE(arithB),CALL(addARITH) + $ => B :MLOAD(arithRes1) + %MAX_SAFE_INTEGER_MODEXP => A + $ :LT,JMPC(endMODEXPFail) ; if Msize+offset > MAX_SAFE_INTEGER_MODEXP --> endMODEXPFail + :CALL(modexp_getMod) + $ => A :MLOAD(modexp_Elen),JMPZ(modexpExp0) + $ => A :MLOAD(modexp_Mlen),JMPZ(modexpMod0) + $ => A :MLOAD(modexp_Blen),JMPZ(modexpBase0) + :CALL(modexp) + :JMP(finalMODEXP) + +modexpBase0: + $ => A :MLOAD(modexp_Elen) + A :JMPZ(save1out) + 0 :MSTORE(modexp_out),JMP(finalMODEXP) + +modexpExp0: +modexpMod0: + $ => A :MLOAD(modexp_Mlen) + 0 :MSTORE(modexp_out) + A :JMPZ(finalMODEXP) + A - 1 :JMPNZ(save1out) + $ => A :MLOAD(modexp_M) + A - 1 :JMPZ(finalMODEXP) +save1out: + 1 :MSTORE(modexp_out),JMP(finalMODEXP) + +save0out: + $ => B :MLOAD(modexp_Msize) + %MAX_SAFE_INTEGER_MODEXP => A + $ :LT,JMPC(endMODEXPFail) + 0 :MSTORE(modexp_out),JMP(finalMODEXP) + +save0outMod0: + 0 :MSTORE(modexp_out),JMP(endMODEXP) + +finalMODEXP: + + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + + ; write data into memory + 0 => E + $ => C :MLOAD(modexp_Msize) + + ; prepare return data + 0 :MSTORE(retDataOffset) + C :MSTORE(retDataLength) + $ => B :MLOAD(retCallOffset) + $ => A :MLOAD(originCTX),JMPZ(handleGas) + ; set retDataCTX + $ => E :MLOAD(currentCTX) + A => CTX + E :MSTORE(retDataCTX) + + C :MSTORE(arithA) + 32 :MSTORE(arithB),CALL(divARITH) + $ => E :MLOAD(arithRes1) + E :MSTORE(modexp_returnIndex) + $ => A :MLOAD(arithRes2),JMPZ(returnLoop) + A => C + $ => A :MLOAD(modexp_out+E) + 32 - C => D :CALL(SHLarith) + A :MSTORE(bytesToStore) + B => E + :CALL(MSTOREX) ; in: [bytesToStore, E: offset] out: [E: new offset] + E => B + $ => A :MLOAD(modexp_Msize) + A - C => C :JMPZ(endMODEXP) + $ => E :MLOAD(modexp_returnIndex) + +returnLoop: + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + + E - 1 => E :MSTORE(modexp_returnIndex) + $ => A :MLOAD(modexp_out+E) + A :MSTORE(bytesToStore) + B => E + :CALL(MSTORE32) + E => B + $ => E :MLOAD(modexp_returnIndex) + C - 32 => C :JMPZ(endMODEXP, returnLoop) + + +endMODEXPFail: + $ => A :MLOAD(originCTX), JMPZ(handleGas) + A => CTX + 0 :MSTORE(retDataCTX) + 0 => GAS + CTX :MSTORE(currentCTX), JMP(preEndFail) + +preEndMODEXP: + $ => CTX :MLOAD(originCTX) + +endMODEXP: + CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file diff --git a/main/precompiled/revert-precompiled.zkasm b/main/precompiled/revert-precompiled.zkasm index cfcef93d..118a0a2e 100644 --- a/main/precompiled/revert-precompiled.zkasm +++ b/main/precompiled/revert-precompiled.zkasm @@ -5,7 +5,7 @@ revertPrecompiled: ; revert touched accounts $ => SR :MLOAD(initSR), CALL(revertTouched) $${eventLog(onError, revert)} - + :CALL(revertBlockInfoTree) ; check if it is the first context $ => A :MLOAD(originCTX), JMPZ(handleGas) ; first context A => CTX :MSTORE(currentCTX) diff --git a/main/precompiled/selector.zkasm b/main/precompiled/selector.zkasm index a503909d..ae978556 100644 --- a/main/precompiled/selector.zkasm +++ b/main/precompiled/selector.zkasm @@ -1,11 +1,64 @@ INCLUDE "pre-ecrecover.zkasm" INCLUDE "revert-precompiled.zkasm" INCLUDE "identity.zkasm" +INCLUDE "pre-ecAdd.zkasm" +INCLUDE "pre-ecMul.zkasm" +INCLUDE "pre-ecPairing.zkasm" +INCLUDE "pre-modexp.zkasm" +INCLUDE "../pairings/constants.zkasm" +INCLUDE "../pairings/BN254/ecAdd.zkasm" +INCLUDE "../pairings/BN254/ecMul.zkasm" +INCLUDE "../pairings/ecPairing.zkasm" +INCLUDE "../pairings/FRBN254/reduceFrBN254.zkasm" +INCLUDE "../pairings/FPBN254/addFpBN254.zkasm" +INCLUDE "../pairings/FPBN254/subFpBN254.zkasm" +INCLUDE "../pairings/FPBN254/mulFpBN254.zkasm" +INCLUDE "../pairings/FPBN254/squareFpBN254.zkasm" +INCLUDE "../pairings/FPBN254/invFpBN254.zkasm" +INCLUDE "../pairings/FPBN254/reduceFpBN254.zkasm" +INCLUDE "../pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../pairings/FP2BN254/invFp2BN254.zkasm" +INCLUDE "../pairings/FP4BN254/squareFp4BN254.zkasm" +INCLUDE "../pairings/FP6BN254/addFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/subFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/mulFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/sparseMulAFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/sparseMulBFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/sparseMulCFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/squareFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/inverseFp6BN254.zkasm" +INCLUDE "../pairings/FP12BN254/mulFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/sparseMulAFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/sparseMulBFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/squareFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/inverseFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/frobFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/frob2Fp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/frob3Fp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm" +INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm" +INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm" +INCLUDE "../pairings/BN254/addPointBN254.zkasm" +INCLUDE "../pairings/BN254/escalarMulBN254.zkasm" +INCLUDE "../pairings/BN254/lineSamePointsBN254.zkasm" +INCLUDE "../pairings/BN254/lineDiffPointsBN254.zkasm" +INCLUDE "../pairings/halfPairingBN254.zkasm" +INCLUDE "../pairings/millerLoopBN254.zkasm" +INCLUDE "../pairings/loopLengthBN254.zkasm" +INCLUDE "../pairings/finalExpBN254.zkasm" INCLUDE "end.zkasm" /** * Selector precompiled contract to run - * Current precompiled supported: ECRECOVER & IDENTITY + * Current precompiled supported: ECRECOVER, IDENTITY, MODEXP, ECADD, ECMUL, ECPAIRING * @param {A} - Precompiled address * @dev Any call to an unsupported precompiled will result in a revert * - All gas is refunded @@ -16,8 +69,8 @@ selectorPrecompiled: A - 3 :JMPN(revertPrecompiled) ;:JMPN(SHA256) A - 4 :JMPN(revertPrecompiled) ;:JMPN(RIPEMD160) A - 5 :JMPN(IDENTITY) - A - 6 :JMPN(revertPrecompiled) ;:JMPN(MODEXP) - A - 7 :JMPN(revertPrecompiled) ;:JMPN(ECADD) - A - 8 :JMPN(revertPrecompiled) ;:JMPN(ECMUL) - A - 9 :JMPN(revertPrecompiled) ;:JMPN(ECPAIRING) - A - 10 :JMPN(revertPrecompiled) ;:JMPN(BLAKE2F) \ No newline at end of file + A - 6 :JMPN(funcModexp) + A - 7 :JMPN(funcEcAdd) + A - 8 :JMPN(funcEcMul) + A - 9 :JMPN(funcEcPairing) + A - 10 :JMPN(revertPrecompiled) ;:JMPN(BLAKE2F) \ No newline at end of file diff --git a/main/process-change-l2-block.zkasm b/main/process-change-l2-block.zkasm new file mode 100644 index 00000000..e855a6d4 --- /dev/null +++ b/main/process-change-l2-block.zkasm @@ -0,0 +1,111 @@ +processChangeL2Block: + $${eventLog(onProcessTx)} + ; checks zk-counters + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*6 :JMPN(outOfCountersPoseidon) + $ => A :MLOAD(cntKeccakPreProcess) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 2 :JMPN(outOfCountersKeccak) + %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + + ; If it's not first tx, we must consolidate previous block + $ => A :MLOAD(currentTx) + A - 1 :JMPZ(continueProcessChangeL2Block) + :CALL(consolidateBlock) +continueProcessChangeL2Block: + ; Reset tx index, logIndex and cumulative gas used + 0 :MSTORE(txIndex) + 0 :MSTORE(cumulativeGasUsed) + 0 :MSTORE(currentLogIndex) + ; Set block hash (current state root) on storage + ;Update state root mapping + 32 => D + 0 => HASHPOS ; A new hash with position 0 is started + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) + + %ADDRESS_SYSTEM => A + %SMT_KEY_SC_STORAGE => B + $ => C :MLOAD(blockNum) + C :HASHK(E) + %STATE_ROOT_STORAGE_POS :HASHK(E) + HASHPOS :HASHKLEN(E) + $ => C :HASHKDIGEST(E) + SR => D :MSTORE(previousBlockHash) + $ => SR :SSTORE, CALL(initBlockInfoTree) + + ; Read block number, increase it by 1 and write it + ; Get last block number + $ => A :MLOAD(blockNum) + ;Update last block number at system storage + 1 => B + $ => D :ADD, MSTORE(blockNum) + %LAST_BLOCK_STORAGE_POS => C + %ADDRESS_SYSTEM => A + %SMT_KEY_SC_STORAGE => B + $ => SR :SSTORE + + ; Load current timestamp + %TIMESTAMP_STORAGE_POS => C + %ADDRESS_SYSTEM => A + %SMT_KEY_SC_STORAGE => B + $ => A, B :SLOAD, MSTORE(timestamp) ; currentTimestamp => B + ; If is forced, new timestamp = timestampLimit, else timestamp = timestamp + deltaTimestamp + $ => C :MLOAD(timestampLimit) + C :MSTORE(timestamp) + ; If it is a forced tx, no delta timestamp is needed + $ :MLOAD(isForced), JMPNZ(processForcedChangeL2Block) + $ => B :MLOAD(deltaTimestamp) + ; Addition of two values of 8 bytes (currentTimestamp + deltaTimestamp) + $ => B :ADD, MSTORE(timestamp) + + processForcedChangeL2Block: + ; Verify currentTimestamp + deltaTimestamp <= limitTimestamp or Verify currentTimestamp <= limitTimestamp if forced tx + $ => A :MLOAD(timestampLimit) + $ :LT, JMPC(invalidChangeL2Block) + + ; Retrieve newGER from free input + $ => A :MLOAD(currentTx) + ${getNewGERRoot(A)} :MSTORE(newGER) + + ; Verify newGER | indexHistoricalGERTree belong to historicGER + ; $ :MLOAD(indexHistGERTree),JMPNZ(verifyMerkleProof) + + ; Set new timestamp + %TIMESTAMP_STORAGE_POS => C + %ADDRESS_SYSTEM => A + %SMT_KEY_SC_STORAGE => B + $ => D :MLOAD(timestamp) + $ => SR :SSTORE + + ; Set new GER + $ => A :MLOAD(newGER) + ; If it is a forced tx, newGER = historicGER + $ :MLOAD(isForced), JMPZ(setnewGER) + $ => A :MLOAD(historicGER) +setnewGER: + 0 => B + ; Dont set if zero + $ :EQ, JMPC(skipSetHistoricGERRoot) + 0 => HASHPOS + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) + + 32 => D + A :HASHK(E) + %GLOBAL_EXIT_ROOT_STORAGE_POS :HASHK(E) ; Storage position of the global exit root map + HASHPOS :HASHKLEN(E) + $ => C :HASHKDIGEST(E) + + %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A + %SMT_KEY_SC_STORAGE => B + + ; read timestampLimit given the historicGER + ; skip overwrite timestampLimit if it is different than 0 (already set) + ; Since timestampLimit is enforced by the smart contract it is safe to compare only 32 bits in 'op0' with JMPNZ + $ :SLOAD, JMPNZ(skipSetHistoricGERRoot) + $ => D :MLOAD(timestamp) + $ => SR :SSTORE ; Store 'timestamp' in storage position 'keccak256(historicGER, 0)' + + skipSetHistoricGERRoot: + :CALL(setupNewBlockInfoTree) + :JMP(txLoop) \ No newline at end of file diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index 0fa24e22..72f17223 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -26,8 +26,6 @@ processTx: ;; Store init state ;;;;;;;;; - ; Store initial state at the beginning of the transaction - SR :MSTORE(originSR) SR :MSTORE(initSR) CTX :MSTORE(currentCTX) ; Minimum of 100000 steps left to process a tx @@ -35,15 +33,9 @@ processTx: %MAX_CNT_BINARY - CNT_BINARY - 100 :JMPN(outOfCountersBinary) %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) - $ => A :MLOAD(txHash) ; Check the signature - $ => B :MLOAD(txR) - $ => C :MLOAD(txS) - $ => D :MLOAD(txV), CALL(ecrecover_tx) - ; Check result is non-zero -checkAndSaveFrom: 0 => B - A :MSTORE(txSrcAddr) + $ => A :MLOAD(txSrcAddr) A :MSTORE(txSrcOriginAddr) $ :EQ,JMPC(invalidIntrinsicTxSignature) @@ -69,8 +61,10 @@ endCheckChainId: ;; Reset warm/cold information $ => A :MLOAD(txSrcOriginAddr), CALL(initTouchedTree) :CALL(isColdAddress) ; add tx.origin to touched addresses - 0 :MSTORE(depth) ; Initial depth is 0 + 0 :MSTORE(depth) ,CALL(checkpointBlockInfoTree) ; Initial depth is 0 +; Set tx status to success by default + 1 :MSTORE(txStatus) ;; Set gasPrice global var depending on effectivePercentage [0-255] -> txGasPrice = Floor((gasPrice * (effectivePercentage + 1)) / 256) ; gasPrice => A $ => A :MLOAD(txGasPriceRLP) @@ -489,7 +483,7 @@ endDeploy: $ => A :MLOAD(createContractAddress) 0 => C %SMT_KEY_SC_CODE => B - $ => SR :SSTORE + $ => SR :SSTORE, JMP(handleGas) ;;;;;;;;;;;;;;;;;; ;; G - Handle GAS @@ -497,7 +491,9 @@ endDeploy: ;; - Return gas not used to caller ;; - Pay gas to sequencer ;;;;;;;;;;;;;;;;;; - +handleGasFromError: + ; Set tx status to failure + 0 :MSTORE(txStatus) ;; compute maximum gas to refund handleGas: %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) @@ -557,7 +553,7 @@ sendGasSeq: $ => D :MLOAD(arithRes1) $ => A :MLOAD(sequencerAddr) 0 => B,C ; balance key smt - $ => SR :SSTORE, JMP(processTxEnd) + $ => SR :SSTORE, JMP(processTxFinished) ;; handle invalid transaction due to intrinsic checks invalidIntrinsicTxSignature: @@ -583,9 +579,8 @@ invalidIntrinsicBatchGasLimit: invalidIntrinsicTxSenderCode: $${eventLog(onError, intrinsic_invalid_sender_code)} :JMP(handleIntrinsicError) - handleIntrinsicError: - $ => SR :MLOAD(originSR), JMP(processTxFinished) + $ => SR :MLOAD(originSR), JMP(processIntrinsicTxFinished) ;; handle error no more bytecode to read defaultOpCode: diff --git a/main/utils.zkasm b/main/utils.zkasm index d7314dcd..6ecbc7bd 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -839,6 +839,8 @@ outOfCountersPadding: $${eventLog(onError, OOCPA)} :JMP(handleBatchError) outOfCountersPoseidon: $${eventLog(onError, OOCPO)} :JMP(handleBatchError) +invalidChangeL2Block: + $${eventLog(onError, invalid_change_l2_block)} :JMP(handleBatchError) outOfGas: $${eventLog(onError, OOG)} :JMP(handleError) invalidJump: @@ -863,10 +865,9 @@ handleError: %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) ;revert all state changes $ => SR :MLOAD(initSR), CALL(revertTouched) + :CALL(revertBlockInfoTree) ;remaining gas = 0 - $ => A :MLOAD(originCTX) - 0 => B - $ :EQ,JMPC(firstContextInvalid) + $ => A :MLOAD(originCTX), JMPZ(errorAtFirstContext) A => CTX ; Add return data context value to origin context ; Clear return data context @@ -887,7 +888,9 @@ handleBatchError: $ :MLOAD(isLoadingRLP),JMPNZ(appendTxsInit) $${eventLog(onFinishTx)} :JMP(processTxsEnd) -firstContextInvalid: +errorAtFirstContext: + ; Set tx status to failure + 0 :MSTORE(txStatus) ;save Root and jump to send gas to sequencer 0 :MSTORE(gasRefund) 0 => GAS :JMP(sendGasSeq) @@ -1271,41 +1274,6 @@ maskAddress: $ => A :AND $ => B :MLOAD(tmpVarBmask), RETURN -;@info: updates the address system storage with current batch and state root -updateSystemData: - ; check keccak counters - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) - ; checks zk-counters - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - - ; Get last tx count - $ => A :MLOAD(txCount) - ;Update last tx Count at system storage - 1 => B - $ => D :ADD, MSTORE(txCount) - - %LAST_TX_STORAGE_POS => C - %ADDRESS_SYSTEM => A - %SMT_KEY_SC_STORAGE => B - $ => SR :SSTORE - - ;Update state root mapping - D => A - 32 => D - 0 => HASHPOS ; A new hash with position 0 is started - $ => E :MLOAD(lastHashKIdUsed) - E + 1 => E :MSTORE(lastHashKIdUsed) - A :HASHK(E) - %STATE_ROOT_STORAGE_POS :HASHK(E) - HASHPOS :HASHKLEN(E) - $ => C :HASHKDIGEST(E) - %ADDRESS_SYSTEM => A - SR => D - $ => SR :SSTORE, RETURN - VAR GLOBAL tmpVarAmulmod VAR GLOBAL tmpVarBmulmod VAR GLOBAL tmpVarDmulmod @@ -1516,6 +1484,53 @@ failAssert: 1 => A 2 :ASSERT +VAR GLOBAL tmpZkPCVerifyMerkleProof +;@info verifies GER with sibilings +verifyMerkleProof: + ; check zk-counters + $ => A :MLOAD(cntKeccakPreProcess) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + + RR :MSTORE(tmpZkPCVerifyMerkleProof) + $ => C :MLOAD(newGER) + $ => B :MLOAD(indexHistGERTree) + B :MSTORE(arithA) + 0 => D + +verifyMerkleProofLoop: + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %GER_TREE_LEVELS - D :JMPZ(verifyMerkleProofEnd) + $ => B :MLOAD(indexHistGERTree) + ${getSmtProof(B, D)} => A + D => RR + :CALL(@exp_num + RR); out:[B: 2**RR] + B :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) + D => B + 32 => D + 0 => HASHPOS + $ :MLOAD(arithRes2), JMPZ(reverseHashValue) + $ => C :MLOAD(newGER) + A :HASHK(E) + C :HASHK(E), JMP(reverseHashValueEnd) +reverseHashValue: + C :HASHK(E) + A :HASHK(E) +reverseHashValueEnd: + HASHPOS :HASHKLEN(E) + $ => C :HASHKDIGEST(E) + B => D + D + 1 => D :JMP(verifyMerkleProofLoop) + +verifyMerkleProofEnd: + $ => A :MLOAD(historicGER) + C :ASSERT +verifyMerkleProofReturn: + $ => RR :MLOAD(tmpZkPCVerifyMerkleProof) + :RETURN + VAR GLOBAL tmpZkPCreadXFromOffset VAR GLOBAL readXFromCalldataOffset diff --git a/main/vars.zkasm b/main/vars.zkasm index a14069d6..f32cc37b 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -1,16 +1,19 @@ ; Input variables VAR GLOBAL oldStateRoot ; Previous state-tree root VAR GLOBAL oldAccInputHash ; Previous accumulated input hash -VAR GLOBAL globalExitRoot ; Global exit-tree root +VAR GLOBAL historicGER ; Global exit-tree root VAR GLOBAL oldNumBatch ; Previous batch processed VAR GLOBAL sequencerAddr ; Coinbase address which will receive the fees VAR GLOBAL batchHashData ; batchHashData = H_keccak( transactions ) +VAR GLOBAL timestampLimit ; timestampLimit of the batch VAR GLOBAL timestamp ; Current batch timestamp VAR GLOBAL chainID ; Current batch chain id VAR GLOBAL forkID ; Fork identifier +VAR GLOBAL isForced ; Flag to determine if the batch is forced +VAR GLOBAL cumulativeGasUsed ; cumulative gas used in the block ; Output variables -VAR GLOBAL newAccInputHash ; Final accumulated input hash. newAccInputHash = H_keccak( oldAccInputHash | batchHashData | globalExitRoot | timestamp | sequencerAddr ) +VAR GLOBAL newAccInputHash ; Final accumulated input hash. newAccInputHash = H_keccak( oldAccInputHash | batchHashData | historicGER | timestamp | sequencerAddr ) VAR GLOBAL newLocalExitRoot ; Updated local exit tree root VAR GLOBAL newNumBatch ; Current batch processed @@ -37,11 +40,13 @@ VAR GLOBAL txGasPrice ; transaction parameter: 'gasPrice' global var VAR GLOBAL depth ; Current depth execution VAR GLOBAL cntKeccakPreProcess ; Number of keccak counters needed to finish the batch -VAR GLOBAL nextFreeLogIndex ; pointer to the next free slot to store information in LOG opcode VAR GLOBAL originSR ; State root before processing each transaction VAR GLOBAL batchSR ; State root before processing any transaction -VAR GLOBAL txCount ; Current transaction count +VAR GLOBAL blockNum ; Current block number +VAR GLOBAL previousBlockHash ; Previous block hash +VAR GLOBAL currentTx ; Current tx index in batch +VAR GLOBAL blockInfoSR ; block info tree root VAR GLOBAL touchedSR ; touched tree root VAR GLOBAL numTopics ; number of topics depending on LOG opcode call VAR GLOBAL auxSR ; auxiliary variable. Temporary state root @@ -50,6 +55,8 @@ VAR GLOBAL txDataRead ; aux variable to check transaction 'data' left that needs VAR GLOBAL isLoadingRLP ; flag to determine if the function is called from RLP loop VAR GLOBAL globalCalldataMemoryOffset ; Aux variable to store current calldata memory offset at calldata CTX's memory +VAR GLOBAL txIndex ; index of the current tx in the block +VAR CTX l2TxHashPointer ; Pointer to tx's hash hashp VAR CTX txGasLimit ; transaction parameter: 'gas limit' VAR CTX txDestAddr ; transaction parameter: 'to' VAR CTX storageAddr ; address which the storage will be modified @@ -62,7 +69,9 @@ VAR CTX txS ; transaction parameter: ecdsa signature S VAR CTX txR ; transaction parameter: ecdsa signature R VAR CTX txV ; transaction parameter: ecdsa signature V VAR CTX txSrcAddr ; address that sends a transaction 'message.sender' +VAR CTX txStatus ; flag indicating success or failure of current transaction VAR CTX txHash ; signed tx hash +VAR CTX l2TxHash ; L2 tx hash linearPoseidon[nonce, gasPrice, gasLimit, to, value, data, from] VAR CTX txCalldataLen ; calldata length VAR CTX isCreateContract ; flag to determine if a transaction will create a new contract VAR CTX createContractAddress ; address computed of a new contract @@ -94,4 +103,11 @@ VAR CTX salt ; CREATE2 parameter 'salt' used to compute new contract address VAR CTX gasCTX ; remaining gas in the origin CTX when a new context is created VAR CTX dataStarts; hash position where the transaction 'data' starts in the batchHashData VAR CTX isPreEIP155 ; flag to check if the current tx is legacy, previous to Spurious Dragon (EIP-155) -VAR CTX initTouchedSR ; touched root once a new context begins \ No newline at end of file +VAR CTX initTouchedSR ; touched root once a new context begins +VAR CTX initBlockInfoSR ; block info root once a new context begins +VAR CTX initLogIndex ; log index once a new context begins + +VAR CTX deltaTimestamp ; delta timestamp of the current change L2 block tx +VAR CTX newGER ; new GER of the current change L2 block tx +VAR CTX indexHistGERTree ; indexHistGERTree of the current change L2 block tx +VAR CTX isChangeL2BlockTx ; flag to determine if the current tx is a change L2 block tx diff --git a/package.json b/package.json index a6158fe8..ab990c4f 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "test:counters": "node counters/counters-executor.js", "test:calldatacopy": "mkdir -p build && npx zkasm test/opcalldatacopy.zkasm -o build/opcalldatacopy.test.json", "test:mstorex": "mkdir -p build && npx zkasm test/mstorex.zkasm -o build/mstorex.test.json", - "test:zkasm": "node tools/run-tests-zkasm.js ./test", + "test:zkasm": "node tools/run-tests-zkasm.js ./test --helpers ../main/helper.js", "eslint": "npx eslint tools/**.js && npx eslint counters/counters-executor.js", "eslint:fix": "npx eslint tools/**.js --fix && npx eslint counters/counters-executor.js --fix", "test:gen": "node tools/gen-parallel-tests.js", @@ -37,18 +37,18 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#v1.0.0", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/addr-command", "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#fix/ecrecover-alias-diffequals-sqrt", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#feature/update-fork", - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v2.0.0-fork.5", - "mocha": "^9.1.3", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/forkid-6-fix-gas", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/fork-etrog", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-mocha": "^10.1.0" + "eslint-plugin-mocha": "^10.1.0", + "mocha": "^10.2.0" } -} +} \ No newline at end of file diff --git a/test/modexp-utils/README.md b/test/modexp-utils/README.md new file mode 100644 index 00000000..f87bd4fe --- /dev/null +++ b/test/modexp-utils/README.md @@ -0,0 +1,5 @@ +## Notes + +The file `modexp-test-gen.js` automatically geneates a zkasm file, executes it some specified number of times and outputs a json file containing the record of the counters. At this moment, it is hardcoded to work for the operation `array_div_mod(array_mul(a, b),c)`, where `a` and `b` was chosen to be $2^{256} - 3$, while `c` was chosen to be $2^{256} - 1$ to achieve the maximum complexity in the operation. + +The `modexp-test-init.sage` takes the counters in the json file and, for each different counter, interpolates the multivariate polynomial (having as evaluation points the lenght of the inputs in the previous file) that evaluates to the counters. \ No newline at end of file diff --git a/test/modexp-utils/modexp-test-gen.js b/test/modexp-utils/modexp-test-gen.js new file mode 100644 index 00000000..b6126d12 --- /dev/null +++ b/test/modexp-utils/modexp-test-gen.js @@ -0,0 +1,168 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +const filePath = path.join(__dirname, 'tmpTest.zkasm'); + +const fileBefore = +`; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) +`; +const fileAfter = +` +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + \${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/modexp/array_lib/utils/array_trim.zkasm" +INCLUDE "../main/modexp/array_lib/utils/array_compare.zkasm" + +INCLUDE "../main/modexp/array_lib/array_add_AGTB.zkasm" +INCLUDE "../main/modexp/array_lib/array_add_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" +`; + +const counters = []; + +for (let i = 1; i <= 5; i++) { + for (let j = 1; j <= i; j++) { + for (let k = 1; k <= j; k++) { + console.log(`Test (${i},${j},${k}):`); + + // Define the test + let fileTest1 = `\t${i} => C\n\t${j} => D\n\t115792089237316195423570985008687907853269984665640564039457584007913129639933n :MSTORE(array_mul_inA)\n\t115792089237316195423570985008687907853269984665640564039457584007913129639933n :MSTORE(array_mul_inB)\n` + + for (let l = 1; l < j; l++) { + fileTest1 += `\t${l} => E\n\t115792089237316195423570985008687907853269984665640564039457584007913129639933n :MSTORE(array_mul_inA + E)\n` + fileTest1 += `\t115792089237316195423570985008687907853269984665640564039457584007913129639933n :MSTORE(array_mul_inB + E)\n` + } + + for (let l = j; l < i; l++) { + fileTest1 += `\t${l} => E\n\t115792089237316195423570985008687907853269984665640564039457584007913129639933n :MSTORE(array_mul_inA + E)\n` + } + + const fileTest2 = `\t\t:CALL(array_mul)\n\t${i+j} => C\n\t${k} => D\n\t` + + let fileTest3 =`$ => A :MLOAD(array_mul_out)\n\tA :MSTORE(array_div_mod_inA)\n\t115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB)\n\t` + + for (let l = 1; l < k; l++) { + fileTest3 += `${l} => E\n\t$ => A :MLOAD(array_mul_out + E)\n\tA :MSTORE(array_div_mod_inA + E)\n\t115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E)\n\t` + } + + for (let l = k; l < i + j; l++) { + fileTest3 += `${l} => E\n\t$ => A :MLOAD(array_mul_out + E)\n\tA :MSTORE(array_div_mod_inA + E)\n\t` + } + + fileTest3 += `:CALL(array_div_mod)\n`; + + const fileTest = fileTest1 + fileTest2 + fileTest3; + + // Create the file + fs.writeFileSync(filePath, fileBefore + fileTest + fileAfter); + + const output = execSync( + `node node_modules/@0xpolygonhermez/zkevm-proverjs/test/zkasmtest.js ${filePath} -H ./main/modexp/helper.js -N "2**24" -d` + ).toString(); + + // Capture the counters + const pattern = /cntArith: (\d+)n,\n cntBinary: (\d+)n,\n cntKeccakF: (\d+)n,\n cntMemAlign: (\d+)n,\n cntPoseidonG: (\d+)n,\n cntPaddingPG: (\d+)n,\n cntSteps: (\d+)/; + const matches = output.match(pattern); + + if (matches) { + const [,cntArith, cntBinary, , , , , cntSteps] = matches.map(Number); + const testCounters = { + lenR: i, + lenB: j, + lenM: k, + cntArith, + cntBinary, + cntSteps, + }; + console.log(testCounters); + counters.push(testCounters); + } else { + console.log('Something wrong happened with the output'); + } + + // Delete the file + fs.unlinkSync(filePath); + } + } +} + +// Write the counters to a JSON file +fs.writeFileSync(path.join(__dirname, 'modexp-counters.json'), JSON.stringify(counters)); diff --git a/test/modexp-utils/modexp-test-int.sage b/test/modexp-utils/modexp-test-int.sage new file mode 100644 index 00000000..26b5e2e0 --- /dev/null +++ b/test/modexp-utils/modexp-test-int.sage @@ -0,0 +1,37 @@ +import json +import os + +dir_path = os.path.dirname(os.path.realpath(__file__)) + +with open(dir_path + '/modexp-counters.json') as f: + data = json.load(f) + +points = [] +valuesArith = [] +valuesBinary = [] +valuesSteps = [] +for i in range(0, len(data)): + points.append([data[i]['lenR'],data[i]['lenB'],data[i]['lenM']]) + valuesArith.append(data[i]['cntArith']) + valuesBinary.append(data[i]['cntBinary']) + valuesSteps.append(data[i]['cntSteps']) + +R. = PolynomialRing(QQ) + +def findInterpolation(points, values): + for i in range(1, 11): + for j in range(1, i+1): + for k in range(1, j+1): + try: + f = R.interpolation([i,j,k], points, values) + return f + except: + pass + +f1 = findInterpolation(points, valuesArith) +f2 = findInterpolation(points, valuesBinary) +f3 = findInterpolation(points, valuesSteps) +print("f1",f1) +print("f2",f2) +print("f3",f3) +print(f1(3,2,1), f2(3,2,1), f3(3,2,1)) \ No newline at end of file diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm new file mode 100644 index 00000000..d50c53aa --- /dev/null +++ b/test/testArrayArith.zkasm @@ -0,0 +1,987 @@ +; constants needed by executor C++ +INCLUDE "../main/constants.zkasm" + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + ; array_add + ; --------------------------------------------------------------- + ; 1] len(inA) = len(inB) + 3 => C + 3 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + :CALL(array_add) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 3 => E + 1n :MLOAD(array_add_out + E) + 4 :MLOAD(array_add_len_out) + + ; 2] len(inA) > len(inB) + 3 => C + 2 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + :CALL(array_add) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 2 => E + 0n :MLOAD(array_add_out + E) + 3 => E + 1n :MLOAD(array_add_out + E) + 4 :MLOAD(array_add_len_out) + + ; 2] len(inA) > len(inB) + 7 => C + 4 => D + 0n :MSTORE(array_add_inA) + 1 => E + 0n :MSTORE(array_add_inA + E) + 2 => E + 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inA + E) + 3 => E + 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inA + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inA + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inA + E) + 6 => E + 370491411790392985199n :MSTORE(array_add_inA + E) + + 0n :MSTORE(array_add_inB) + 1 => E + 0n :MSTORE(array_add_inB + E) + 2 => E + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inB + E) + 3 => E + 6019321230n :MSTORE(array_add_inB + E) + :CALL(array_add) + 0n :MLOAD(array_add_out) + 1 => E + 0n :MLOAD(array_add_out + E) + 2 => E + 0n :MLOAD(array_add_out + E) + 3 => E + 0n :MLOAD(array_add_out + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + 6 => E + 370491411790392985199n :MLOAD(array_add_out + E) + 7 :MLOAD(array_add_len_out) + + ; 2] len(inA) < len(inB) + 4 => C + 7 => D + 0n :MSTORE(array_add_inA) + 1 => E + 0n :MSTORE(array_add_inA + E) + 2 => E + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inA + E) + 3 => E + 6019321230n :MSTORE(array_add_inA + E) + + 0n :MSTORE(array_add_inB) + 1 => E + 0n :MSTORE(array_add_inB + E) + 2 => E + 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inB + E) + 3 => E + 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inB + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inB + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inB + E) + 6 => E + 370491411790392985199n :MSTORE(array_add_inB + E) + :CALL(array_add) + 0n :MLOAD(array_add_out) + 1 => E + 0n :MLOAD(array_add_out + E) + 2 => E + 0n :MLOAD(array_add_out + E) + 3 => E + 0n :MLOAD(array_add_out + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + 6 => E + 370491411790392985199n :MLOAD(array_add_out + E) + 7 :MLOAD(array_add_len_out) + ; --------------------------------------------------------------- + + ; array_add AGTB + ; --------------------------------------------------------------- + ; 1] [2**256-1,2**256-1,2**256-1] + [2**256-1,2**256-1] + 3 => C + 2 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB + E) + :CALL(array_add_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_AGTB_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_AGTB_out + E) + 2 => E + 0n :MLOAD(array_add_AGTB_out + E) + 3 => E + 1n :MLOAD(array_add_AGTB_out + E) + 4 :MLOAD(array_add_AGTB_len_out) + ; --------------------------------------------------------------- + + ; array_add small + ; --------------------------------------------------------------- + ; 1] [2**256-1,2**256-1,2**256-1] + [2**256-1] + 3 => C + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inB) + :CALL(array_add_short) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_short_out) + 1 => E + 0n :MLOAD(array_add_short_out + E) + 2 => E + 0n :MLOAD(array_add_short_out + E) + 3 => E + 1n :MLOAD(array_add_short_out + E) + 4 :MLOAD(array_add_short_len_out) + ; --------------------------------------------------------------- + + ; array_sub + ; --------------------------------------------------------------- + ; 1] len(inA) > len(inB) and inA_i >= inb_i for all i + 3 => C + 2 => D + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 6n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + + 2n :MSTORE(array_sub_AGTB_inB) + 1 => E + 3n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + ; 0 :MLOAD(array_sub_sign) + 3n :MLOAD(array_sub_AGTB_out) + 1 => E + 3n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 7n :MLOAD(array_sub_AGTB_out + E) + + ; 2] len(inA) > len(inB) and inA_i < inb_i for some i + 3 => C + 2 => D + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 6n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 3n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + ; 0 :MLOAD(array_sub_sign) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 1 => E + 2n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 7n :MLOAD(array_sub_AGTB_out + E) + + ; 3] len(inA) > len(inB) and inA_i < inB_i for all i lower than len(inA) + 3 => C + 2 => D + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 1n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + ; 0 :MLOAD(array_sub_sign) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 6n :MLOAD(array_sub_AGTB_out + E) + + ; 4] len(inB) > len(inA) and inB_i < inA_i for all i lower than len(inB) + 3 => C + 2 => D + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 1n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + :CALL(array_sub_AGTB) + ; 1 :MLOAD(array_sub_sign) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 6n :MLOAD(array_sub_AGTB_out + E) + + ; 5] len(inB) = len(inA) and inB > inA + 3 => C + 3 => D + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + 2 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + + 7n :MSTORE(array_sub_AGTB_inA) + 1 => E + 8n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 8n :MSTORE(array_sub_AGTB_inA + E) + :CALL(array_sub_AGTB) + ; 1 :MLOAD(array_sub_sign) + 1n :MLOAD(array_sub_AGTB_out) + 1 => E + 0n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 0n :MLOAD(array_sub_AGTB_out + E) + ; --------------------------------------------------------------- + + ; array long mul + ; --------------------------------------------------------------- + ; 1] len(inB) = len(inA) and inB > inA + 3 => C + 3 => D + 5n :MSTORE(array_mul_inA) + 1 => E + 6n :MSTORE(array_mul_inA + E) + 2 => E + 7n :MSTORE(array_mul_inA + E) + + 2n :MSTORE(array_mul_inB) + 1 => E + 3n :MSTORE(array_mul_inB + E) + 2 => E + 4n :MSTORE(array_mul_inB + E) + :CALL(array_mul) + 10n :MLOAD(array_mul_out) + 1 => E + 27n :MLOAD(array_mul_out + E) + 2 => E + 52n :MLOAD(array_mul_out + E) + 3 => E + 45n :MLOAD(array_mul_out + E) + 4 => E + 28n :MLOAD(array_mul_out + E) + 5 :MLOAD(array_mul_len_out) + + ; 2] len(inB) != len(inA) + 2 => C + 3 => D + 5n :MSTORE(array_mul_inA) + 1 => E + 6n :MSTORE(array_mul_inA + E) + + 11n :MSTORE(array_mul_inB) + 1 => E + 21n :MSTORE(array_mul_inB + E) + 2 => E + 16n :MSTORE(array_mul_inB + E) + :CALL(array_mul) + 55n :MLOAD(array_mul_out) + 1 => E + 171n :MLOAD(array_mul_out + E) + 2 => E + 206n :MLOAD(array_mul_out + E) + 3 => E + 96n :MLOAD(array_mul_out + E) + 4 :MLOAD(array_mul_len_out) + ; --------------------------------------------------------------- + + ; ; WIP: array karatsuba mul + ; ; --------------------------------------------------------------- + ; ; 1] len(inA) > len(inB) + ; 2 => C + ; 1 => D + ; 2n :MSTORE(array_mul_karatsuba_inA) + ; 1 => E + ; 6n :MSTORE(array_mul_karatsuba_inA + E) + + ; 8n :MSTORE(array_mul_karatsuba_inB) + ; :CALL(array_mul_karatsuba) + ; 16n :MLOAD(array_mul_karatsuba_out) + ; 1 => E + ; 48n :MLOAD(array_mul_karatsuba_out + E) + ; 2 :MLOAD(array_mul_karatsuba_len_out) + + ; ; 2] len(inA) = len(inB) + ; 2 => C + ; 2 => D + ; 10n :MSTORE(array_mul_karatsuba_inA) + ; 1 => E + ; 50n :MSTORE(array_mul_karatsuba_inA + E) + + ; 98n :MSTORE(array_mul_karatsuba_inB) + ; 1 => E + ; 1000n :MSTORE(array_mul_karatsuba_inB + E) + ; :CALL(array_mul_karatsuba) + ; 980n :MLOAD(array_mul_karatsuba_out) + ; 1 => E + ; 14900n :MLOAD(array_mul_karatsuba_out + E) + ; 2 => E + ; 50000n :MLOAD(array_mul_karatsuba_out + E) + ; 3 :MLOAD(array_mul_karatsuba_len_out) + + ; ; 3] + ; 3 => C + ; 3 => D + ; 10n :MSTORE(array_mul_karatsuba_inA) + ; 1 => E + ; 6n :MSTORE(array_mul_karatsuba_inA + E) + ; 2 => E + ; 2n :MSTORE(array_mul_karatsuba_inA + E) + + ; 8n :MSTORE(array_mul_karatsuba_inB) + ; 1 => E + ; 3n :MSTORE(array_mul_karatsuba_inB + E) + ; 2 => E + ; 5n :MSTORE(array_mul_karatsuba_inB + E) + ; :CALL(array_mul_karatsuba) + ; 16n :MLOAD(array_mul_karatsuba_out) + ; 1 => E + ; 54n :MLOAD(array_mul_karatsuba_out + E) + ; 2 => E + ; 40n :MLOAD(array_mul_karatsuba_out + E) + ; 3 => E + ; 24n :MLOAD(array_mul_karatsuba_out + E) + ; 4 => E + ; 6n :MLOAD(array_mul_karatsuba_out + E) + ; 5 :MLOAD(array_mul_karatsuba_len_out) + ; ; --------------------------------------------------------------- + + ; array short mult + ; --------------------------------------------------------------- + ; 1] [a, a, a] * a + 3 => C + 1 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inB) + :CALL(array_mul) + 1n :MLOAD(array_mul_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_mul_out + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_mul_out + E) + 3 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_mul_out + E) + 4 :MLOAD(array_mul_len_out) + + ; 2] [a, 100, a, 6] * 400 + 4 => C + 1 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA) + 1 => E + 100n :MSTORE(array_mul_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) + 3 => E + 6n :MSTORE(array_mul_inA + E) + + 400n :MSTORE(array_mul_inB) + :CALL(array_mul) + 115792089237316195423570985008687907853269984665640564039457584007913129639536n :MLOAD(array_mul_out) + 1 => E + 40399n :MLOAD(array_mul_out + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639536n :MLOAD(array_mul_out + E) + 3 => E + 2799n :MLOAD(array_mul_out + E) + 4 :MLOAD(array_mul_len_out) + ; --------------------------------------------------------------- + + ; array square + ; --------------------------------------------------------------- + ; 1] [4n, 4n, 4n, 3n, 2n, 4n] + 6 => C + 4n :MSTORE(array_square_in) + 1 => E + 4n :MSTORE(array_square_in + E) + 2 => E + 4n :MSTORE(array_square_in + E) + 3 => E + 3n :MSTORE(array_square_in + E) + 4 => E + 2n :MSTORE(array_square_in + E) + 5 => E + 4n :MSTORE(array_square_in + E) + :CALL(array_square) + 16n :MLOAD(array_square_out) + 1 => E + 32n :MLOAD(array_square_out + E) + 2 => E + 48n :MLOAD(array_square_out + E) + 3 => E + 56n :MLOAD(array_square_out + E) + 4 => E + 56n :MLOAD(array_square_out + E) + 5 => E + 72n :MLOAD(array_square_out + E) + 6 => E + 57n :MLOAD(array_square_out + E) + 7 => E + 44n :MLOAD(array_square_out + E) + 8 => E + 28n :MLOAD(array_square_out + E) + 9 => E + 16n :MLOAD(array_square_out + E) + 10 => E + 16n :MLOAD(array_square_out + E) + 11 :MLOAD(array_square_len_out) + + ; 2] [49625181101706940895816136432294817651401421999560241731196107431962769845690n, 16541727033902313631938712144098272550467140666520080577065369143987589948564n, 2n] + 3 => C + 49625181101706940895816136432294817651401421999560241731196107431962769845690n :MSTORE(array_square_in) + 1 => E + 16541727033902313631938712144098272550467140666520080577065369143987589948564n :MSTORE(array_square_in + E) + 2 => E + 2n :MSTORE(array_square_in + E) + :CALL(array_square) + 73256219721567388941442868066720921294925908666017499698432349066230755486500n :MLOAD(array_square_out) + 1 => E + 59077596549651120114066829086065259108811216666143144918090604085669964102021n :MLOAD(array_square_out + E) + 2 => E + 75619323583553433746005541230163531659278357332663225495155973229657554050588n :MLOAD(array_square_out + E) + 3 => E + 68530011997595299332317521739835700566221011332726048104985100739377158358338n :MLOAD(array_square_out + E) + 4 => E + 4n :MLOAD(array_square_out + E) + 5 :MLOAD(array_square_len_out) + + ; 3] [108509871213644914495224788117262720812102234692915980461799068728781566717980n, 97610657482852136417037764955262109743864410230427530868747251158690618238750n, 3n] + 3 => C + 108509871213644914495224788117262720812102234692915980461799068728781566717980n :MSTORE(array_square_in) + 1 => E + 97610657482852136417037764955262109743864410230427530868747251158690618238750n :MSTORE(array_square_in + E) + 2 => E + 3n :MSTORE(array_square_in + E) + :CALL(array_square) + 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MLOAD(array_square_out) + 1 => E + 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MLOAD(array_square_out + E) + 2 => E + 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MLOAD(array_square_out + E) + 3 => E + 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MLOAD(array_square_out + E) + 4 => E + 14n :MLOAD(array_square_out + E) + 5 :MLOAD(array_square_len_out) + + ; 4] [94296684984090328915786319894647341212298256830891608529662243544763352873524n,85801804490443701075961240310880668636621463408258506144468684495763969931231n] + 2 => C + 94296684984090328915786319894647341212298256830891608529662243544763352873524n :MSTORE(array_square_in) + 1 => E + 85801804490443701075961240310880668636621463408258506144468684495763969931231n :MSTORE(array_square_in + E) + :CALL(array_square) + 56476742620324943499420425449441725188859143808665910845865775685761970051728n :MLOAD(array_square_out) + 1 => E + 15939360972613038527243286761436595585964755988147232278935003110685006573864n :MLOAD(array_square_out + E) + 2 => E + 71885101902860809166787972884705167254384530826288829047389464757277834814455n :MLOAD(array_square_out + E) + 3 => E + 63579038104476977130956937454941822659502127575865339775268690127769381598323n :MLOAD(array_square_out + E) + 4 :MLOAD(array_square_len_out) + ; --------------------------------------------------------------- + + ; array short mod div + ; --------------------------------------------------------------- + ; 1] [9n, 8n, 7n, 6n] / 8n + 4 => C + 1 => D + 9n :MSTORE(array_div_mod_inA) + 1 => E + 8n :MSTORE(array_div_mod_inA + E) + 2 => E + 7n :MSTORE(array_div_mod_inA + E) + 3 => E + 6n :MSTORE(array_div_mod_inA + E) + + 8n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 1n :MLOAD(array_div_mod_quo) + 1 => E + 101318078082651670995624611882601919371611236582435493534525386006923988434945n :MLOAD(array_div_mod_quo + E) + 2 => E + 86844066927987146567678238756515930889952488499230423029593188005934847229952n :MLOAD(array_div_mod_quo + E) + 1n :MLOAD(array_div_mod_rem) + 3 :MLOAD(array_div_mod_len_quo) + + ; 2] [a, 7n, a, 12n, a, 20n, a, 80n] / a + 8 => C + 1 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) + 1 => E + 7n :MSTORE(array_div_mod_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 3 => E + 12n :MSTORE(array_div_mod_inA + E) + 4 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 5 => E + 20n :MSTORE(array_div_mod_inA + E) + 6 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 7 => E + 80n :MSTORE(array_div_mod_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 120n :MLOAD(array_div_mod_quo) + 1 => E + 112n :MLOAD(array_div_mod_quo + E) + 2 => E + 113n :MLOAD(array_div_mod_quo + E) + 3 => E + 100n :MLOAD(array_div_mod_quo + E) + 4 => E + 101n :MLOAD(array_div_mod_quo + E) + 5 => E + 80n :MLOAD(array_div_mod_quo + E) + 6 => E + 81n :MLOAD(array_div_mod_quo + E) + 119n :MLOAD(array_div_mod_rem) + 7 :MLOAD(array_div_mod_len_quo) + + ; 3] inA == 0, inB != 0 + 1 => C + 1 => D + 0n :MSTORE(array_div_mod_inA) + + 8n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) + + ; 4] inA != 0, inB == 0 -> error + 2 => C + 1 => D + 0n :MSTORE(array_div_mod_inA) + 1 => E + 30n :MSTORE(array_div_mod_inA + E) + + 0n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 1 => A + B :ASSERT + + ; 5] inA == inB + 1 => C + 1 => D + 10n :MSTORE(array_div_mod_inA) + + 10n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 1n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) + + ; 6] inA < inB + 1 => C + 1 => D + 10n :MSTORE(array_div_mod_inA) + + 11n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 10n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) + + ; 7] [28948022309329048855892746252171976963317496166410141009864396001978282409984n, 1n] / 2 + 2 => C + 1 => D + 28948022309329048855892746252171976963317496166410141009864396001978282409984n :MSTORE(array_div_mod_inA) + 1 => E + 1n :MSTORE(array_div_mod_inA + E) + + 2n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MLOAD(array_div_mod_quo) + 1 :MLOAD(array_div_mod_len_quo) + + ; 8] [72370055773322622139731865630429942408293740416025352524660990004945706024960n] / 2 + 1 => C + 1 => D + 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MSTORE(array_div_mod_inA) + 2n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 36185027886661311069865932815214971204146870208012676262330495002472853012480n :MLOAD(array_div_mod_quo) + 1 :MLOAD(array_div_mod_len_quo) + ; --------------------------------------------------------------- + + ; array long mod div + ; --------------------------------------------------------------- + ; 1] len(inB) = len(inA) and inB > inA + 4 => C + 2 => D + 9n :MSTORE(array_div_mod_inA) + 1 => E + 8n :MSTORE(array_div_mod_inA + E) + 2 => E + 7n :MSTORE(array_div_mod_inA + E) + 3 => E + 6n :MSTORE(array_div_mod_inA + E) + + 8n :MSTORE(array_div_mod_inB) + 1 => E + 1n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 335n :MLOAD(array_div_mod_quo) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639895n :MLOAD(array_div_mod_quo + E) + 2 => E + 5n :MLOAD(array_div_mod_quo + E) + 115792089237316195423570985008687907853269984665640564039457584007913129637265n :MLOAD(array_div_mod_rem) + + ; 2] [a, 7n, a, 12n, a, 20n, a, 80n] / [a, a, a, a, 100n] + 8 => C + 5 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) + 1 => E + 7n :MSTORE(array_div_mod_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 3 => E + 12n :MSTORE(array_div_mod_inA + E) + 4 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 5 => E + 20n :MSTORE(array_div_mod_inA + E) + 6 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 7 => E + 80n :MSTORE(array_div_mod_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 3 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 4 => E + 100n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 87130681010257731209815790699606742543054641926620622445532439451498988639951n :MLOAD(array_div_mod_quo) + 1 => E + 76812574048516684092863920748337523031377118540573443471719387411189897879957n :MLOAD(array_div_mod_quo + E) + 2 => E + 92862962655669424052566829561422975605097710474424610764317468362781816839948n :MLOAD(array_div_mod_quo + E) + 87130681010257731209815790699606742543054641926620622445532439451498988639950n :MLOAD(array_div_mod_rem) + 1 => E + 76812574048516684092863920748337523031377118540573443471719387411189897879965n :MLOAD(array_div_mod_rem + E) + 2 => E + 92862962655669424052566829561422975605097710474424610764317468362781816839947n :MLOAD(array_div_mod_rem + E) + 3 => E + 13n :MLOAD(array_div_mod_rem + E) + 4 => E + 84n :MLOAD(array_div_mod_rem + E) + + ; 3] inA == 0, inB != 0 + 1 => C + 2 => D + 0n :MSTORE(array_div_mod_inA) + + 8n :MSTORE(array_div_mod_inB) + 1 => E + 1n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + + ; 4] inA != 0, inB == 0 -> error + 2 => C + 1 => D + 0n :MSTORE(array_div_mod_inA) + 1 => E + 30n :MSTORE(array_div_mod_inA + E) + + 0n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 1 => A + B :ASSERT + + ; 5] inA == inB + 2 => C + 2 => D + 10n :MSTORE(array_div_mod_inA) + 1 => E + 30n :MSTORE(array_div_mod_inA + E) + + 10n :MSTORE(array_div_mod_inB) + 1 => E + 30n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 1n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + + ; 6] inA < inB + 2 => C + 3 => D + 10n :MSTORE(array_div_mod_inA) + 1 => E + 30n :MSTORE(array_div_mod_inA + E) + + 6n :MSTORE(array_div_mod_inB) + 1 => E + 7n :MSTORE(array_div_mod_inB + E) + 2 => E + 8n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 10n :MLOAD(array_div_mod_rem) + 1 => E + 30n :MSTORE(array_div_mod_rem + E) + + ; 7] [82987931714326364316120253427931880709278140571418487333162713377057429160720n,4257238595720679277571917967782652353394431698489248379634099239588181418140n,15209178211456919413336795740141505754388379695813905932093982440742677791802n,88987534839350135473536361176867192550264928852523682165693061442019881855583n,14n], [4n, 6n, 7n] + 5 => C + 3 => D + 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MSTORE(array_div_mod_inA) + 1 => E + 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MSTORE(array_div_mod_inA + E) + 2 => E + 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MSTORE(array_div_mod_inA + E) + 3 => E + 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MSTORE(array_div_mod_inA + E) + 4 => E + 14n :MSTORE(array_div_mod_inA + E) + + 4n :MSTORE(array_div_mod_inB) + 1 => E + 6n :MSTORE(array_div_mod_inB + E) + 2 => E + 7n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 90526669110436282262084097418054683975846294708417529350769755852355732618090n :MLOAD(array_div_mod_quo) + 1 => E + 12712504977050019353362337310981027507180704121789097452241865920288554550795n :MLOAD(array_div_mod_quo + E) + 2 => E + 2n :MLOAD(array_div_mod_quo + E) + 68257522984529821538496818781776868365702915734670062048456441991373887608168n :MLOAD(array_div_mod_rem) + 1 => E + 104999739448800080833043894267657885589213754954671066702793604491778345346033n :MSTORE(array_div_mod_rem + E) + 2 => E + 4n :MSTORE(array_div_mod_rem + E) + 3 :MLOAD(array_div_mod_len_quo) + 3 :MLOAD(array_div_mod_len_rem) + + ; 8] [0n,0n,0n,0n,87552057494100699607633960453116574392480272162273084008350826812719088235449n,29405388739667337424543497575767709934732594998639086405406332616399343873602n,370491411790392985199n], [0n, 0n, 8238129386n, 23102318237n] + 7 => C + 4 => D + 0n :MSTORE(array_div_mod_inA) + 1 => E + 0n :MSTORE(array_div_mod_inA + E) + 2 => E + 0n :MSTORE(array_div_mod_inA + E) + 3 => E + 0n :MSTORE(array_div_mod_inA + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MSTORE(array_div_mod_inA + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_div_mod_inA + E) + 6 => E + 370491411790392985199n :MSTORE(array_div_mod_inA + E) + + 0n :MSTORE(array_div_mod_inB) + 1 => E + 0n :MSTORE(array_div_mod_inB + E) + 2 => E + 8238129386n :MSTORE(array_div_mod_inB + E) + 3 => E + 23102318237n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 10624890954144362706283399919870985530330343554129711486796784890935496833177n :MLOAD(array_div_mod_quo) + 1 => E + 12699239907746414269759600684072701206520647567004427767570235373004025148518n :MLOAD(array_div_mod_quo + E) + 2 => E + 62973947849727744055941265906651873030488901951864462234513788026171769471385n :MLOAD(array_div_mod_quo + E) + 3 => E + 16036979838n :MLOAD(array_div_mod_quo + E) + 0n :MLOAD(array_div_mod_rem) + 1 => E + 0n :MSTORE(array_div_mod_rem + E) + 2 => E + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_div_mod_rem + E) + 3 => E + 6019321230n :MSTORE(array_div_mod_rem + E) + 4 :MLOAD(array_div_mod_len_quo) + 4 :MLOAD(array_div_mod_len_rem) + + ; 9] [7n], [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] + 1 => C + 2 => D + 7n :MSTORE(array_div_mod_inA) + 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(array_div_mod_inB) + 1 => E + 17n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 7n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) + 1 :MLOAD(array_div_mod_len_rem) + + ; 10] [9,12,16,2,0,2**256-4], [2**256-1,2**256-1] + 6 => C + 2 => D + 9n :MSTORE(array_div_mod_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + 1 => E + 12n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 2 => E + 16n :MSTORE(array_div_mod_inA + E) + 3 => E + 2n :MSTORE(array_div_mod_inA + E) + 4 => E + 0n :MSTORE(array_div_mod_inA + E) + 5 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MSTORE(array_div_mod_inA + E) + :CALL(array_div_mod) + 4 :MLOAD(array_div_mod_len_quo) + 2 :MLOAD(array_div_mod_len_rem) + 17n :MLOAD(array_div_mod_quo) + 26n :MLOAD(array_div_mod_rem) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_div_mod_quo + E) + 10n :MLOAD(array_div_mod_rem + E) + 2 => E + 0n :MLOAD(array_div_mod_quo + E) + 3 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_div_mod_quo + E) + ; --------------------------------------------------------------- + +outOfCountersArith: +outOfCountersBinary: +outOfCountersStep: + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/modexp/array_lib/utils/array_trim.zkasm" +INCLUDE "../main/modexp/array_lib/utils/array_compare.zkasm" + +INCLUDE "../main/modexp/array_lib/array_add_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_add_AGTB.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul.zkasm" +INCLUDE "../main/modexp/array_lib/array_square.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" + +INCLUDE "../main/modexp/array_lib/unused/array_sub_AGTB.zkasm" +INCLUDE "../main/modexp/array_lib/unused/array_add.zkasm" \ No newline at end of file diff --git a/test/testArrayUtils.zkasm b/test/testArrayUtils.zkasm new file mode 100644 index 00000000..6ff5f055 --- /dev/null +++ b/test/testArrayUtils.zkasm @@ -0,0 +1,481 @@ +; constants needed by executor C++ +INCLUDE "../main/constants.zkasm" + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +VAR GLOBAL inA[300] +VAR GLOBAL inB[300] +VAR GLOBAL out[300] + +; Fix better notation for the above + +start: + + STEP => A + 0 :ASSERT + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + +; array_compare +; --------------------------------------------------------------- +; 1] len(inA) > len(inB) should return 2 +array_compare_test_1: + 5n :MSTORE(inA) + 1 => E + 6n :MSTORE(inA + E) + 2 => E + 7n :MSTORE(inA + E) + + 2n :MSTORE(inB) + 1 => E + 3n :MSTORE(inB + E) + + 3 => C + 2 => D + 0 => E,RR +array_compare_test_1_memory_copy_inA_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_compare_inA + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_compare_test_1_memory_copy_inB_loop, array_compare_test_1_memory_copy_inA_loop) + +array_compare_test_1_memory_copy_inB_loop: + $ => A :MLOAD(inB + RR) + A :MSTORE(array_compare_inB + RR) + RR + 1 => RR + RR => A + D => B + $ :EQ, JMPC(array_compare_test_1_compare, array_compare_test_1_memory_copy_inB_loop) + +array_compare_test_1_compare: + :CALL(array_compare) + 2 :MLOAD(array_compare_result) + +; 2] len(inA) < len(inB) should return 0 +array_compare_test_2: + 5n :MSTORE(inA) + 1 => E + 6n :MSTORE(inA + E) + + 2n :MSTORE(inB) + 1 => E + 3n :MSTORE(inB + E) + 2 => E + 4n :MSTORE(inB + E) + + 2 => C + 3 => D + 0 => E,RR +array_compare_test_2_memory_copy_inA_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_compare_inA + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_compare_test_2_memory_copy_inB_loop, array_compare_test_2_memory_copy_inA_loop) + +array_compare_test_2_memory_copy_inB_loop: + $ => A :MLOAD(inB + RR) + A :MSTORE(array_compare_inB + RR) + RR + 1 => RR + RR => A + D => B + $ :EQ, JMPC(array_compare_test_2_compare, array_compare_test_2_memory_copy_inB_loop) + +array_compare_test_2_compare: + :CALL(array_compare) + 0 :MLOAD(array_compare_result) + + + +; 3] len(inA) = len(inB) but inA > inB should return 2 +array_compare_test_3: + 5n :MSTORE(inA) + 1 => E + 6n :MSTORE(inA + E) + 2 => E + 7n :MSTORE(inA + E) + + 5n :MSTORE(inB) + 1 => E + 6n :MSTORE(inB + E) + 2 => E + 6n :MSTORE(inB + E) + + 3 => C + 3 => D + 0 => E,RR +array_compare_test_3_memory_copy_inA_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_compare_inA + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_compare_test_3_memory_copy_inB_loop, array_compare_test_3_memory_copy_inA_loop) + +array_compare_test_3_memory_copy_inB_loop: + $ => A :MLOAD(inB + RR) + A :MSTORE(array_compare_inB + RR) + RR + 1 => RR + RR => A + D => B + $ :EQ, JMPC(array_compare_test_3_compare, array_compare_test_3_memory_copy_inB_loop) + +array_compare_test_3_compare: + :CALL(array_compare) + 2 :MLOAD(array_compare_result) + +; 4] len(inA) = len(inB) but inA < inB should return 0 +array_compare_test_4: + 5n :MSTORE(inA) + 1 => E + 6n :MSTORE(inA + E) + 2 => E + 6n :MSTORE(inA + E) + + 5n :MSTORE(inB) + 1 => E + 6n :MSTORE(inB + E) + 2 => E + 7n :MSTORE(inB + E) + + 3 => C + 3 => D + 0 => E,RR +array_compare_test_4_memory_copy_inA_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_compare_inA + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_compare_test_4_memory_copy_inB_loop, array_compare_test_4_memory_copy_inA_loop) + +array_compare_test_4_memory_copy_inB_loop: + $ => A :MLOAD(inB + RR) + A :MSTORE(array_compare_inB + RR) + RR + 1 => RR + RR => A + D => B + $ :EQ, JMPC(array_compare_test_4_compare, array_compare_test_4_memory_copy_inB_loop) + +array_compare_test_4_compare: + :CALL(array_compare) + 0 :MLOAD(array_compare_result) + +; 5] inA = inB should return 1 +array_compare_test_5: + 5n :MSTORE(inA) + 1 => E + 6n :MSTORE(inA + E) + 2 => E + 6n :MSTORE(inA + E) + + 5n :MSTORE(inB) + 1 => E + 6n :MSTORE(inB + E) + 2 => E + 6n :MSTORE(inB + E) + + 3 => C + 3 => D + 0 => E,RR +array_compare_test_5_memory_copy_inA_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_compare_inA + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_compare_test_5_memory_copy_inB_loop, array_compare_test_5_memory_copy_inA_loop) + +array_compare_test_5_memory_copy_inB_loop: + $ => A :MLOAD(inB + RR) + A :MSTORE(array_compare_inB + RR) + RR + 1 => RR + RR => A + D => B + $ :EQ, JMPC(array_compare_test_5_compare, array_compare_test_5_memory_copy_inB_loop) + +array_compare_test_5_compare: + :CALL(array_compare) + 1 :MLOAD(array_compare_result) +; --------------------------------------------------------------- + +; array unshift +; --------------------------------------------------------------- + 0 => C + 5n => D + 3n :MSTORE(array_unshift_in) + :CALL(array_unshift) + 5 :MLOAD(array_unshift_in) + 1 :MLOAD(array_unshift_len) + +array_unshift_test_1: + 2n :MSTORE(inA) + 1 => E + 1n :MSTORE(inA + E) + 2 => E + 1n :MSTORE(inA + E) + 5n => D + + 3 => C + 0 => E +array_unshift_test_1_memory_copy_in_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_unshift_in + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_unshift_test_1_unshift, array_unshift_test_1_memory_copy_in_loop) + +array_unshift_test_1_unshift: + :CALL(array_unshift) + 4 :MLOAD(array_unshift_len) + 3 => C ; reset the len back to 3 + 0 => E ; reset the loop counter + +array_unshift_test_1_memory_copy_out_loop: + $ => A :MLOAD(array_unshift_in + E) + A :MSTORE(out + E) + E + 1 => E + E => A + C + 1 => B + $ :EQ, JMPC(array_unshift_test_1_dump, array_unshift_test_1_memory_copy_out_loop) + +array_unshift_test_1_dump: + 4 :MLOAD(array_unshift_len) +; --------------------------------------------------------------- + +; array trim +; --------------------------------------------------------------- +; 1] [2,1,0] should return 2 +array_trim_test_1: + 2n :MSTORE(inA) + 1 => E + 1n :MSTORE(inA + E) + 2 => E + 0n :MSTORE(inA + E) + +3 => C +0 => E +array_trim_test_1_memory_copy_in_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_trim_in + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_trim_test_1_trim, array_trim_test_1_memory_copy_in_loop) + +array_trim_test_1_trim: + :CALL(array_trim) + 2 => A + C :ASSERT + +; 2] [2,1,0,2] should return 4 +array_trim_test_2: + 2n :MSTORE(inA) + 1 => E + 1n :MSTORE(inA + E) + 2 => E + 0n :MSTORE(inA + E) + 3 => E + 2n :MSTORE(inA + E) + +4 => C +0 => E +array_trim_test_2_memory_copy_in_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_trim_in + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_trim_test_2_trim, array_trim_test_2_memory_copy_in_loop) + +array_trim_test_2_trim: + :CALL(array_trim) + 4 => A + C :ASSERT + +; 3] [0,0,0,0,0,0] should return 1 +array_trim_test_3: + 0n :MSTORE(inA) + 1 => E + 0n :MSTORE(inA + E) + 2 => E + 0n :MSTORE(inA + E) + 3 => E + 0n :MSTORE(inA + E) + 4 => E + 0n :MSTORE(inA + E) + 5 => E + 0n :MSTORE(inA + E) + +6 => C +0 => E +array_trim_test_3_memory_copy_in_loop: + $ => A :MLOAD(inA + E) + A :MSTORE(array_trim_in + E) + E + 1 => E + E => A + C => B + $ :EQ, JMPC(array_trim_test_3_trim, array_trim_test_3_memory_copy_in_loop) + +array_trim_test_3_trim: + :CALL(array_trim) + 1 => A + C :ASSERT + +; 4] [0] should return 1 +array_trim_test_4: + 1 => C + 0n :MSTORE(array_trim_in) + :CALL(array_trim) + 1 => A + C :ASSERT +; --------------------------------------------------------------- + +; array is zero +; --------------------------------------------------------------- +; 1] [2,1] should return 0 +array_is_zero_test_1: + 2 => C + 2n :MSTORE(array_is_zero_in) + 1 => E + 1n :MSTORE(array_is_zero_in + E) + :CALL(array_is_zero) + 0 :MLOAD(array_is_zero_result) + +; 2] [0] should return 1 +array_is_zero_test_2: + 1 => C + 0n :MSTORE(array_is_zero_in) + :CALL(array_is_zero) + 1 :MLOAD(array_is_zero_result) + +; 3] [5] should return 0 +array_is_zero_test_3: + 1 => C + 5n :MSTORE(array_is_zero_in) + :CALL(array_is_zero) + 0 :MLOAD(array_is_zero_result) +; --------------------------------------------------------------- + +; array is one +; --------------------------------------------------------------- +; 1] [2,1] should return 0 +array_is_one_test_1: + 2 => C + 2n :MSTORE(array_is_one_in) + 1 => E + 1n :MSTORE(array_is_one_in + E) + :CALL(array_is_one) + 0 :MLOAD(array_is_one_result) + +; 2] [1] should return 1 +array_is_one_test_2: + 1 => C + 1n :MSTORE(array_is_one_in) + :CALL(array_is_one) + 1 :MLOAD(array_is_one_result) + +; 3] [5] should return 0 +array_is_one_test_3: + 1 => C + 5n :MSTORE(array_is_one_in) + :CALL(array_is_one) + 0 :MLOAD(array_is_one_result) +; --------------------------------------------------------------- + +; array is odd +; --------------------------------------------------------------- +; 1] [2,1] should return 0 +array_is_odd_test_1: + 2n :MSTORE(array_is_odd_in) + 1 => E + 1n :MSTORE(array_is_odd_in + E) + :CALL(array_is_odd) + 0 :MLOAD(array_is_odd_result) + +; 2] [5] should return 1 +array_is_odd_test_2: + 5n :MSTORE(array_is_odd_in) + :CALL(array_is_odd) + 1 :MLOAD(array_is_odd_result) + +; 2] [3, 2] should return 1 +array_is_odd_test_3: + 3n :MSTORE(array_is_odd_in) + 1 => E + 2n :MSTORE(array_is_odd_in + E) + :CALL(array_is_odd) + 1 :MLOAD(array_is_odd_result) +; --------------------------------------------------------------- + +outOfCountersBinary: +outOfCountersStep: + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/modexp/array_lib/utils/array_compare.zkasm" +INCLUDE "../main/modexp/array_lib/utils/array_trim.zkasm" + +INCLUDE "../main/modexp/array_lib/unused/array_is_zero.zkasm" +INCLUDE "../main/modexp/array_lib/unused/array_is_one.zkasm" +INCLUDE "../main/modexp/array_lib/unused/array_is_odd.zkasm" +INCLUDE "../main/modexp/array_lib/unused/array_unshift.zkasm" \ No newline at end of file diff --git a/test/testCycloFp12ArithBN254.zkasm b/test/testCycloFp12ArithBN254.zkasm new file mode 100644 index 00000000..4de6ae43 --- /dev/null +++ b/test/testCycloFp12ArithBN254.zkasm @@ -0,0 +1,499 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n + +VAR GLOBAL test + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + + ; TODO: Find an example with a2 = 0 + + ; 1] Compression and decompression: It must happen that D(C(a)) = a + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(compressFp12BN254_a0_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(compressFp12BN254_a0_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(compressFp12BN254_a2_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(compressFp12BN254_a2_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(compressFp12BN254_a4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(compressFp12BN254_a4_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(compressFp12BN254_a1_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(compressFp12BN254_a1_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(compressFp12BN254_a3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(compressFp12BN254_a3_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(compressFp12BN254_a5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(compressFp12BN254_a5_y) + :CALL(compressFp12BN254) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MLOAD(compressFp12BN254_Ca2_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MLOAD(compressFp12BN254_Ca2_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MLOAD(compressFp12BN254_Ca3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MLOAD(compressFp12BN254_Ca3_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MLOAD(compressFp12BN254_Ca4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MLOAD(compressFp12BN254_Ca4_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MLOAD(compressFp12BN254_Ca5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MLOAD(compressFp12BN254_Ca5_y) + + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(decompressFp12BN254_Ca2_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(decompressFp12BN254_Ca2_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(decompressFp12BN254_Ca3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(decompressFp12BN254_Ca3_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(decompressFp12BN254_Ca4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(decompressFp12BN254_Ca4_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(decompressFp12BN254_Ca5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(decompressFp12BN254_Ca5_y) + :CALL(decompressFp12BN254) + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MLOAD(decompressFp12BN254_a0_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MLOAD(decompressFp12BN254_a0_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MLOAD(decompressFp12BN254_a2_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MLOAD(decompressFp12BN254_a2_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MLOAD(decompressFp12BN254_a4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MLOAD(decompressFp12BN254_a4_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MLOAD(decompressFp12BN254_a1_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MLOAD(decompressFp12BN254_a1_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MLOAD(decompressFp12BN254_a3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MLOAD(decompressFp12BN254_a3_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MLOAD(decompressFp12BN254_a5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MLOAD(decompressFp12BN254_a5_y) + + ; 2] Squaring + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(squareCycloFp12BN254_a11_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(squareCycloFp12BN254_a11_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(squareCycloFp12BN254_a12_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(squareCycloFp12BN254_a12_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(squareCycloFp12BN254_a13_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(squareCycloFp12BN254_a13_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(squareCycloFp12BN254_a21_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(squareCycloFp12BN254_a21_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(squareCycloFp12BN254_a22_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(squareCycloFp12BN254_a22_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(squareCycloFp12BN254_a23_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(squareCycloFp12BN254_a23_y) + :CALL(squareCycloFp12BN254) + 2098026393950394559493690260865166581266928315924710629633888310320006689795n :MLOAD(squareCycloFp12BN254_c11_x) + 1846888720299666666109042029094532002505741710678796245911331796963733914187n :MLOAD(squareCycloFp12BN254_c11_y) + 6856859212192321831831255712736216614951508355737406292407364405936415355512n :MLOAD(squareCycloFp12BN254_c12_x) + 17209588680055969912485542074372495831925486815137906387799790601911548657525n :MLOAD(squareCycloFp12BN254_c12_y) + 15781046857382959121140505691131389728661226093902862303002526578701400754315n :MLOAD(squareCycloFp12BN254_c13_x) + 8625093555241362381542545391636743832938050376057983419042860774659518282797n :MLOAD(squareCycloFp12BN254_c13_y) + 14351778565182200844681812560787756136192441388960773363087263587389322671562n :MLOAD(squareCycloFp12BN254_c21_x) + 15695337662963643544813486120899631949921737819129690254830667492646284393382n :MLOAD(squareCycloFp12BN254_c21_y) + 5570195873148749154672896518046181211644563497843962677067647498629814883385n :MLOAD(squareCycloFp12BN254_c22_x) + 14991026153829150387150002728101017951749162083560649689008171461754623678203n :MLOAD(squareCycloFp12BN254_c22_y) + 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(squareCycloFp12BN254_c23_x) + 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(squareCycloFp12BN254_c23_y) + + ; 3] Squaring in Compressed Form: It must happen that D(C(a²)) = a² + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(squareCompCycloFp12BN254_Ca2_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(squareCompCycloFp12BN254_Ca2_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(squareCompCycloFp12BN254_Ca3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(squareCompCycloFp12BN254_Ca3_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(squareCompCycloFp12BN254_Ca4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(squareCompCycloFp12BN254_Ca4_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(squareCompCycloFp12BN254_Ca5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(squareCompCycloFp12BN254_Ca5_y) + :CALL(squareCompCycloFp12BN254) + 14351778565182200844681812560787756136192441388960773363087263587389322671562n :MLOAD(squareCompCycloFp12BN254_Cb2_x) + 15695337662963643544813486120899631949921737819129690254830667492646284393382n :MLOAD(squareCompCycloFp12BN254_Cb2_y) + 15781046857382959121140505691131389728661226093902862303002526578701400754315n :MLOAD(squareCompCycloFp12BN254_Cb3_x) + 8625093555241362381542545391636743832938050376057983419042860774659518282797n :MLOAD(squareCompCycloFp12BN254_Cb3_y) + 6856859212192321831831255712736216614951508355737406292407364405936415355512n :MLOAD(squareCompCycloFp12BN254_Cb4_x) + 17209588680055969912485542074372495831925486815137906387799790601911548657525n :MLOAD(squareCompCycloFp12BN254_Cb4_y) + 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(squareCompCycloFp12BN254_Cb5_x) + 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(squareCompCycloFp12BN254_Cb5_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(decompressFp12BN254_Ca2_x) + B :MSTORE(decompressFp12BN254_Ca2_y) + C :MSTORE(decompressFp12BN254_Ca3_x) + D :MSTORE(decompressFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(decompressFp12BN254_Ca4_x) + B :MSTORE(decompressFp12BN254_Ca4_y) + C :MSTORE(decompressFp12BN254_Ca5_x) + D :MSTORE(decompressFp12BN254_Ca5_y) + :CALL(decompressFp12BN254) + 2098026393950394559493690260865166581266928315924710629633888310320006689795n :MLOAD(decompressFp12BN254_a0_x) + 1846888720299666666109042029094532002505741710678796245911331796963733914187n :MLOAD(decompressFp12BN254_a0_y) + 14351778565182200844681812560787756136192441388960773363087263587389322671562n :MLOAD(decompressFp12BN254_a2_x) + 15695337662963643544813486120899631949921737819129690254830667492646284393382n :MLOAD(decompressFp12BN254_a2_y) + 6856859212192321831831255712736216614951508355737406292407364405936415355512n :MLOAD(decompressFp12BN254_a4_x) + 17209588680055969912485542074372495831925486815137906387799790601911548657525n :MLOAD(decompressFp12BN254_a4_y) + 5570195873148749154672896518046181211644563497843962677067647498629814883385n :MLOAD(decompressFp12BN254_a1_x) + 14991026153829150387150002728101017951749162083560649689008171461754623678203n :MLOAD(decompressFp12BN254_a1_y) + 15781046857382959121140505691131389728661226093902862303002526578701400754315n :MLOAD(decompressFp12BN254_a3_x) + 8625093555241362381542545391636743832938050376057983419042860774659518282797n :MLOAD(decompressFp12BN254_a3_y) + 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(decompressFp12BN254_a5_x) + 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(decompressFp12BN254_a5_y) + + ; 4] Exponentiation + 0n :MSTORE(expCycloFp12BN254_e) + 0n :MSTORE(expCycloFp12BN254_a11_x) + 0n :MSTORE(expCycloFp12BN254_a11_y) + 0n :MSTORE(expCycloFp12BN254_a12_x) + 0n :MSTORE(expCycloFp12BN254_a12_y) + 0n :MSTORE(expCycloFp12BN254_a13_x) + 0n :MSTORE(expCycloFp12BN254_a13_y) + 0n :MSTORE(expCycloFp12BN254_a21_x) + 0n :MSTORE(expCycloFp12BN254_a21_y) + 0n :MSTORE(expCycloFp12BN254_a22_x) + 0n :MSTORE(expCycloFp12BN254_a22_y) + 0n :MSTORE(expCycloFp12BN254_a23_x) + 0n :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 0n :MLOAD(expCycloFp12BN254_c11_x) + 0n :MLOAD(expCycloFp12BN254_c11_y) + 0n :MLOAD(expCycloFp12BN254_c12_x) + 0n :MLOAD(expCycloFp12BN254_c12_y) + 0n :MLOAD(expCycloFp12BN254_c13_x) + 0n :MLOAD(expCycloFp12BN254_c13_y) + 0n :MLOAD(expCycloFp12BN254_c21_x) + 0n :MLOAD(expCycloFp12BN254_c21_y) + 0n :MLOAD(expCycloFp12BN254_c22_x) + 0n :MLOAD(expCycloFp12BN254_c22_y) + 0n :MLOAD(expCycloFp12BN254_c23_x) + 0n :MLOAD(expCycloFp12BN254_c23_y) + + 10n :MSTORE(expCycloFp12BN254_e) + 0n :MSTORE(expCycloFp12BN254_a11_x) + 0n :MSTORE(expCycloFp12BN254_a11_y) + 0n :MSTORE(expCycloFp12BN254_a12_x) + 0n :MSTORE(expCycloFp12BN254_a12_y) + 0n :MSTORE(expCycloFp12BN254_a13_x) + 0n :MSTORE(expCycloFp12BN254_a13_y) + 0n :MSTORE(expCycloFp12BN254_a21_x) + 0n :MSTORE(expCycloFp12BN254_a21_y) + 0n :MSTORE(expCycloFp12BN254_a22_x) + 0n :MSTORE(expCycloFp12BN254_a22_y) + 0n :MSTORE(expCycloFp12BN254_a23_x) + 0n :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 0n :MLOAD(expCycloFp12BN254_c11_x) + 0n :MLOAD(expCycloFp12BN254_c11_y) + 0n :MLOAD(expCycloFp12BN254_c12_x) + 0n :MLOAD(expCycloFp12BN254_c12_y) + 0n :MLOAD(expCycloFp12BN254_c13_x) + 0n :MLOAD(expCycloFp12BN254_c13_y) + 0n :MLOAD(expCycloFp12BN254_c21_x) + 0n :MLOAD(expCycloFp12BN254_c21_y) + 0n :MLOAD(expCycloFp12BN254_c22_x) + 0n :MLOAD(expCycloFp12BN254_c22_y) + 0n :MLOAD(expCycloFp12BN254_c23_x) + 0n :MLOAD(expCycloFp12BN254_c23_y) + + 0n :MSTORE(expCycloFp12BN254_e) + 1n :MSTORE(expCycloFp12BN254_a11_x) + 0n :MSTORE(expCycloFp12BN254_a11_y) + 0n :MSTORE(expCycloFp12BN254_a12_x) + 0n :MSTORE(expCycloFp12BN254_a12_y) + 0n :MSTORE(expCycloFp12BN254_a13_x) + 0n :MSTORE(expCycloFp12BN254_a13_y) + 0n :MSTORE(expCycloFp12BN254_a21_x) + 0n :MSTORE(expCycloFp12BN254_a21_y) + 0n :MSTORE(expCycloFp12BN254_a22_x) + 0n :MSTORE(expCycloFp12BN254_a22_y) + 0n :MSTORE(expCycloFp12BN254_a23_x) + 0n :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 1n :MLOAD(expCycloFp12BN254_c11_x) + 0n :MLOAD(expCycloFp12BN254_c11_y) + 0n :MLOAD(expCycloFp12BN254_c12_x) + 0n :MLOAD(expCycloFp12BN254_c12_y) + 0n :MLOAD(expCycloFp12BN254_c13_x) + 0n :MLOAD(expCycloFp12BN254_c13_y) + 0n :MLOAD(expCycloFp12BN254_c21_x) + 0n :MLOAD(expCycloFp12BN254_c21_y) + 0n :MLOAD(expCycloFp12BN254_c22_x) + 0n :MLOAD(expCycloFp12BN254_c22_y) + 0n :MLOAD(expCycloFp12BN254_c23_x) + 0n :MLOAD(expCycloFp12BN254_c23_y) + + 4965661367192848881n :MSTORE(expCycloFp12BN254_e) + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expCycloFp12BN254_a11_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expCycloFp12BN254_a11_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(expCycloFp12BN254_a12_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(expCycloFp12BN254_a12_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(expCycloFp12BN254_a13_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(expCycloFp12BN254_a13_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(expCycloFp12BN254_a21_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(expCycloFp12BN254_a21_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(expCycloFp12BN254_a22_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(expCycloFp12BN254_a22_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(expCycloFp12BN254_a23_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 8622123276929149313920900390800567957350463902034345693686819104151152922572n :MLOAD(expCycloFp12BN254_c11_x) + 8670626622362378075940101766943937502063808822022259182641087586661549444087n :MLOAD(expCycloFp12BN254_c11_y) + 17677799802795013101301829823610804881266875691488004414652375004895811278559n :MLOAD(expCycloFp12BN254_c12_x) + 8272841324134833464040573295664197017808088708485767794513847108589815911499n :MLOAD(expCycloFp12BN254_c12_y) + 9190911511691766859289188288177517604435774623843629661940012957026870785904n :MLOAD(expCycloFp12BN254_c13_x) + 18364099160954539591912436449937202384011431251285107932512938026494677069261n :MLOAD(expCycloFp12BN254_c13_y) + 19407988223605275774004312333801897121509906148567729782984282773586873391901n :MLOAD(expCycloFp12BN254_c21_x) + 15711652497826967457911333154250406880785527028595026050702704710166760791736n :MLOAD(expCycloFp12BN254_c21_y) + 16450402722786864781692733695027245893014266492802042336563706983420459072544n :MLOAD(expCycloFp12BN254_c22_x) + 11669304897933026204553226847848522415487901344170781144466032622467776938641n :MLOAD(expCycloFp12BN254_c22_y) + 14005155248465440637906492674345786073382135452928153479559868247493919227266n :MLOAD(expCycloFp12BN254_c23_x) + 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expCycloFp12BN254_c23_y) + + ; 5] Exponentiation by x + 0n :MSTORE(expByXCycloFp12BN254_a11_x) + 0n :MSTORE(expByXCycloFp12BN254_a11_y) + 0n :MSTORE(expByXCycloFp12BN254_a12_x) + 0n :MSTORE(expByXCycloFp12BN254_a12_y) + 0n :MSTORE(expByXCycloFp12BN254_a13_x) + 0n :MSTORE(expByXCycloFp12BN254_a13_y) + 0n :MSTORE(expByXCycloFp12BN254_a21_x) + 0n :MSTORE(expByXCycloFp12BN254_a21_y) + 0n :MSTORE(expByXCycloFp12BN254_a22_x) + 0n :MSTORE(expByXCycloFp12BN254_a22_y) + 0n :MSTORE(expByXCycloFp12BN254_a23_x) + 0n :MSTORE(expByXCycloFp12BN254_a23_y) + :CALL(expByXCycloFp12BN254) + 0n :MLOAD(expByXCycloFp12BN254_c11_x) + 0n :MLOAD(expByXCycloFp12BN254_c11_y) + 0n :MLOAD(expByXCycloFp12BN254_c12_x) + 0n :MLOAD(expByXCycloFp12BN254_c12_y) + 0n :MLOAD(expByXCycloFp12BN254_c13_x) + 0n :MLOAD(expByXCycloFp12BN254_c13_y) + 0n :MLOAD(expByXCycloFp12BN254_c21_x) + 0n :MLOAD(expByXCycloFp12BN254_c21_y) + 0n :MLOAD(expByXCycloFp12BN254_c22_x) + 0n :MLOAD(expByXCycloFp12BN254_c22_y) + 0n :MLOAD(expByXCycloFp12BN254_c23_x) + 0n :MLOAD(expByXCycloFp12BN254_c23_y) + + 1n :MSTORE(expByXCycloFp12BN254_a11_x) + 0n :MSTORE(expByXCycloFp12BN254_a11_y) + 0n :MSTORE(expByXCycloFp12BN254_a12_x) + 0n :MSTORE(expByXCycloFp12BN254_a12_y) + 0n :MSTORE(expByXCycloFp12BN254_a13_x) + 0n :MSTORE(expByXCycloFp12BN254_a13_y) + 0n :MSTORE(expByXCycloFp12BN254_a21_x) + 0n :MSTORE(expByXCycloFp12BN254_a21_y) + 0n :MSTORE(expByXCycloFp12BN254_a22_x) + 0n :MSTORE(expByXCycloFp12BN254_a22_y) + 0n :MSTORE(expByXCycloFp12BN254_a23_x) + 0n :MSTORE(expByXCycloFp12BN254_a23_y) + :CALL(expByXCycloFp12BN254) + 1n :MLOAD(expByXCycloFp12BN254_c11_x) + 0n :MLOAD(expByXCycloFp12BN254_c11_y) + 0n :MLOAD(expByXCycloFp12BN254_c12_x) + 0n :MLOAD(expByXCycloFp12BN254_c12_y) + 0n :MLOAD(expByXCycloFp12BN254_c13_x) + 0n :MLOAD(expByXCycloFp12BN254_c13_y) + 0n :MLOAD(expByXCycloFp12BN254_c21_x) + 0n :MLOAD(expByXCycloFp12BN254_c21_y) + 0n :MLOAD(expByXCycloFp12BN254_c22_x) + 0n :MLOAD(expByXCycloFp12BN254_c22_y) + 0n :MLOAD(expByXCycloFp12BN254_c23_x) + 0n :MLOAD(expByXCycloFp12BN254_c23_y) + + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expByXCycloFp12BN254_a11_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expByXCycloFp12BN254_a11_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(expByXCycloFp12BN254_a12_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(expByXCycloFp12BN254_a12_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(expByXCycloFp12BN254_a13_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(expByXCycloFp12BN254_a13_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(expByXCycloFp12BN254_a21_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(expByXCycloFp12BN254_a21_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(expByXCycloFp12BN254_a22_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(expByXCycloFp12BN254_a22_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(expByXCycloFp12BN254_a23_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(expByXCycloFp12BN254_a23_y) + :CALL(expByXCycloFp12BN254) + 8622123276929149313920900390800567957350463902034345693686819104151152922572n :MLOAD(expByXCycloFp12BN254_c11_x) + 8670626622362378075940101766943937502063808822022259182641087586661549444087n :MLOAD(expByXCycloFp12BN254_c11_y) + 17677799802795013101301829823610804881266875691488004414652375004895811278559n :MLOAD(expByXCycloFp12BN254_c12_x) + 8272841324134833464040573295664197017808088708485767794513847108589815911499n :MLOAD(expByXCycloFp12BN254_c12_y) + 9190911511691766859289188288177517604435774623843629661940012957026870785904n :MLOAD(expByXCycloFp12BN254_c13_x) + 18364099160954539591912436449937202384011431251285107932512938026494677069261n :MLOAD(expByXCycloFp12BN254_c13_y) + 19407988223605275774004312333801897121509906148567729782984282773586873391901n :MLOAD(expByXCycloFp12BN254_c21_x) + 15711652497826967457911333154250406880785527028595026050702704710166760791736n :MLOAD(expByXCycloFp12BN254_c21_y) + 16450402722786864781692733695027245893014266492802042336563706983420459072544n :MLOAD(expByXCycloFp12BN254_c22_x) + 11669304897933026204553226847848522415487901344170781144466032622467776938641n :MLOAD(expByXCycloFp12BN254_c22_y) + 14005155248465440637906492674345786073382135452928153479559868247493919227266n :MLOAD(expByXCycloFp12BN254_c23_x) + 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expByXCycloFp12BN254_c23_y) + + + ; 6] Exponentiation by x using the compression/decompression technique + 0n :MSTORE(expByXCompCycloFp12BN254_a0_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a0_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_y) + :CALL(expByXCompCycloFp12BN254) + 0n :MLOAD(expByXCompCycloFp12BN254_c0_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c0_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_y) + + 1n :MSTORE(expByXCompCycloFp12BN254_a0_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a0_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_y) + :CALL(expByXCompCycloFp12BN254) + 1n :MLOAD(expByXCompCycloFp12BN254_c0_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c0_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_y) + + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expByXCompCycloFp12BN254_a0_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expByXCompCycloFp12BN254_a0_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(expByXCompCycloFp12BN254_a2_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(expByXCompCycloFp12BN254_a2_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(expByXCompCycloFp12BN254_a4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(expByXCompCycloFp12BN254_a4_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(expByXCompCycloFp12BN254_a1_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(expByXCompCycloFp12BN254_a1_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(expByXCompCycloFp12BN254_a3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(expByXCompCycloFp12BN254_a3_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(expByXCompCycloFp12BN254_a5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(expByXCompCycloFp12BN254_a5_y) + :CALL(expByXCompCycloFp12BN254) + 8622123276929149313920900390800567957350463902034345693686819104151152922572n :MLOAD(expByXCompCycloFp12BN254_c0_x) + 8670626622362378075940101766943937502063808822022259182641087586661549444087n :MLOAD(expByXCompCycloFp12BN254_c0_y) + 19407988223605275774004312333801897121509906148567729782984282773586873391901n :MLOAD(expByXCompCycloFp12BN254_c2_x) + 15711652497826967457911333154250406880785527028595026050702704710166760791736n :MLOAD(expByXCompCycloFp12BN254_c2_y) + 17677799802795013101301829823610804881266875691488004414652375004895811278559n :MLOAD(expByXCompCycloFp12BN254_c4_x) + 8272841324134833464040573295664197017808088708485767794513847108589815911499n :MLOAD(expByXCompCycloFp12BN254_c4_y) + 16450402722786864781692733695027245893014266492802042336563706983420459072544n :MLOAD(expByXCompCycloFp12BN254_c1_x) + 11669304897933026204553226847848522415487901344170781144466032622467776938641n :MLOAD(expByXCompCycloFp12BN254_c1_y) + 9190911511691766859289188288177517604435774623843629661940012957026870785904n :MLOAD(expByXCompCycloFp12BN254_c3_x) + 18364099160954539591912436449937202384011431251285107932512938026494677069261n :MLOAD(expByXCompCycloFp12BN254_c3_y) + 14005155248465440637906492674345786073382135452928153479559868247493919227266n :MLOAD(expByXCompCycloFp12BN254_c5_x) + 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expByXCompCycloFp12BN254_c5_y) + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" + +INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" + +INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/mulFp12BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm" + +INCLUDE "../main/pairings/utilsTests/expCycloFp12BN254.zkasm" + +INCLUDE "../main/pairings/unused/xPseudoBinDecompBN254.zkasm" +INCLUDE "../main/pairings/unused/expByXCycloFp12BN254.zkasm" \ No newline at end of file diff --git a/test/testEcAdd.zkasm b/test/testEcAdd.zkasm new file mode 100644 index 00000000..d5d76ae6 --- /dev/null +++ b/test/testEcAdd.zkasm @@ -0,0 +1,255 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n +CONSTL %BN254_E_B = 3n + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + ; 1] 0 + 0 = 0 + 0n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 0n :MLOAD(ecAdd_P3_x) + 0n :MLOAD(ecAdd_P3_y) + + + ; 2] 0 + P = P + 0n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 2n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 1n :MLOAD(ecAdd_P3_x) + 2n :MLOAD(ecAdd_P3_y) + + ; 3] P + 0 = P + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 1n :MLOAD(ecAdd_P3_x) + 2n :MLOAD(ecAdd_P3_y) + + ; 4] P1 not in range + 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 3n :MSTORE(ecAdd_P2_x) + 3n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 1 => A + 1 :EQ + + 1n :MSTORE(ecAdd_P1_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208585n :MSTORE(ecAdd_P1_y) + 3n :MSTORE(ecAdd_P2_x) + 3n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 2 => A + 1 :EQ + + ; 5] P2 not in range + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 3 => A + 1 :EQ + + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 4 => A + 1 :EQ + + ; 6] P1 not in E + 1n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 5 => A + 1 :EQ + + 1n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 2n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 5 => A + 1 :EQ + + ; 7] P2 not in E + 0n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 6 => A + 1 :EQ + + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 6 => A + 1 :EQ + + ; 8] P + (-P) = 0 + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P1_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P1_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) + 21039565435327757486054843320102702720990930294403178719740356721829973864651n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 0n :MLOAD(ecAdd_P3_x) + 0n :MLOAD(ecAdd_P3_y) + + ; 9] P + Q when P != Q + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) + 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P2_x) + 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 13154776318592227270778558029295227935378730842313609923118896637591559850250n :MLOAD(ecAdd_P3_x) + 11035980320923476543935377623718958678920911311849399323950347759358969041431n :MLOAD(ecAdd_P3_y) + + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P1_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P1_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 20109137777308224484751705964830245061785572657602899297228633767392913518415n :MLOAD(ecAdd_P3_x) + 14499175368639637950478596677291617168262069295802020711454610174461584835979n :MLOAD(ecAdd_P3_y) + + ; 10] P + P + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P2_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 11220622501868821308995844886766009822833441579384302982823096531245924405698n :MLOAD(ecAdd_P3_x) + 2355690023525969090855462437460037724073976772193253577110863269987724684477n :MLOAD(ecAdd_P3_y) + + 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P1_x) + 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P1_y) + 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P2_x) + 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 14301632400969957113316344359548233118734763289927867040319376723985850943059n :MLOAD(ecAdd_P3_x) + 19259402839901377893267670172732143592044261932601111690978918426524987173751n :MLOAD(ecAdd_P3_y) + + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P1_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P1_y) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P2_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 7635241416710394435863784018619353890364763495262225661273147225960091861733n :MLOAD(ecAdd_P3_x) + 21716464559528323959695889215160185865818678200951896286120725092340748527691n :MLOAD(ecAdd_P3_y) + + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P1_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P1_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 4444740815889402603535294170722302758225367627362056425101568584910268024244n :MLOAD(ecAdd_P3_x) + 10537263096529483164618820017164668921386457028564663708352735080900270541420n :MLOAD(ecAdd_P3_y) + + ; 10] Worst case scenario in terms of ARITH calls and therefore in terms of number of steps + ; In this case, we only need to perform a doubling, since the cost of ecAdd is constant + ; on its input and doubling strictly dominates addition in terms of cost. + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P2_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 11220622501868821308995844886766009822833441579384302982823096531245924405698n :MLOAD(ecAdd_P3_x) + 2355690023525969090855462437460037724073976772193253577110863269987724684477n :MLOAD(ecAdd_P3_y) + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + + +INCLUDE "../main/pairings/BN254/ecAdd.zkasm" + +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/subFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/squareFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/invFpBN254.zkasm" \ No newline at end of file diff --git a/test/testEcMul.zkasm b/test/testEcMul.zkasm new file mode 100644 index 00000000..4049a718 --- /dev/null +++ b/test/testEcMul.zkasm @@ -0,0 +1,236 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n +CONSTL %BN254_R = 21888242871839275222246405745257275088548364400416034343698204186575808495617n +CONSTL %BN254_E_B = 3n + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + ; 1] 0·O = O + 0n :MSTORE(ecMul_k) + 0n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) + + ; 2] k·O = O + 5n :MSTORE(ecMul_k) + 0n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) + + ; 3] 0·P = O, where P != O + 0n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) + + ; 4] P not in range + 0n :MSTORE(ecMul_k) + 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 1 => A + 1 :EQ + + 0n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208585n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 2 => A + 1 :EQ + + ; 5] P not in E + 0n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 3 => A + 1 :EQ + + 65n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 3 => A + 1 :EQ + + ; 6] k·P when k != 0 + 1n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 1n :MLOAD(ecMul_Q_x) + 2n :MLOAD(ecMul_Q_y) + + 2n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MLOAD(ecMul_Q_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MLOAD(ecMul_Q_y) + + 65n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 21184532036463169063041779836861514142873086093180850953095098556309204188255n :MLOAD(ecMul_Q_x) + 16870949628445799017882714788639508275834535486794531840392367353784571921174n :MLOAD(ecMul_Q_y) + + 10000000089n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 4768044760451824005417871472283223457728569810854115125480649095031772328870n :MLOAD(ecMul_Q_x) + 21389337952468851259287213083493638952853622949895525580347877121675081015727n :MLOAD(ecMul_Q_y) + + 57n :MSTORE(ecMul_k) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 21092868577100313210583214784627729175513062432513303686654820611840644382013n :MLOAD(ecMul_Q_x) + 10293123368529248350591404721829100625076077203595282162629899903703630633665n :MLOAD(ecMul_Q_y) + + 123456789n :MSTORE(ecMul_k) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 9551410454255481932113938269904288675272239827491596157984458647610565008967n :MLOAD(ecMul_Q_x) + 17781856861347070862134441477208204792978952663354273425763774350233183876915n :MLOAD(ecMul_Q_y) + + 21888242871839275222246405745257275088548364400416034343698204186575808495617n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) + + 21888242871839275222246405745257275088548364400416034343698204186575808495618n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 1n :MLOAD(ecMul_Q_x) + 2n :MLOAD(ecMul_Q_y) + + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 7793429943220682609834519115512946233910458086191548249060013461061457526887n :MLOAD(ecMul_Q_x) + 16460968250425543446028981775631045522280113359306664586749259656855967130574n :MLOAD(ecMul_Q_y) + + 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 15886422571275617715400903250697722692198979607302343556925904858625057687404n :MLOAD(ecMul_Q_x) + 9788557113822741943783365060165103517008620829146475047263378292709661309554n :MLOAD(ecMul_Q_y) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 21415159568991615317144600033915305503576371596506956373206836402282692989778n :MLOAD(ecMul_Q_x) + 8573070896319864868535933562264623076420652926303237982078693068147657243287n :MLOAD(ecMul_Q_y) + + ; 7] Worst case scenario in terms of ARITH calls and therefore in terms of number of steps. + ; In ecMul, this should be the scalar multiplication with scalar with higer Hamming weight + ; that is lower than r, which in this case is 2^253 - 1. + 14474011154664524427946373126085988481658748083205070504932198000989141204991n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 3739418567393436576913511739065691570763034865122368432616000129799288055432n :MLOAD(ecMul_Q_x) + 18298856760603404171434473181920219106007178146585940397845192637485681860518n :MLOAD(ecMul_Q_y) + + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + + +INCLUDE "../main/pairings/BN254/ecMul.zkasm" +INCLUDE "../main/pairings/BN254/ecAdd.zkasm" + +INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" + +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/subFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/squareFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/invFpBN254.zkasm" \ No newline at end of file diff --git a/test/testEcPairing.zkasm b/test/testEcPairing.zkasm new file mode 100644 index 00000000..88c477a7 --- /dev/null +++ b/test/testEcPairing.zkasm @@ -0,0 +1,484 @@ +; constants needed by executor C++ // TODO +CONST %N = 2**19 +;CONST %MAX_CNT_STEPS_LIMIT = %N +;CONST %MAX_CNT_ARITH_LIMIT = %N +;CONST %MAX_CNT_BINARY_LIMIT = %N +;CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +;CONST %MAX_CNT_KECCAK_F_LIMIT = %N +;CONST %MAX_CNT_PADDING_PG_LIMIT = %N +;CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + ; 1] Tests with 6 inputs + ; 1.1] Fails and returns nothing if the input is invalid + ;0n :MSTORE(ecPairing6_P_x) + ;1n :MSTORE(ecPairing6_P_y) + ;4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(ecPairing6_Q_x1) + ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) + ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) + ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;0n :MSTORE(ecPairing6_P_x) + ;0n :MSTORE(ecPairing6_P_y) + ;4351401811647638138392695977895401859084096897123577305203754529537814663108n :MSTORE(ecPairing6_Q_x1) + ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) + ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) + ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;1n :MSTORE(ecPairing6_P_x) + ;2n :MSTORE(ecPairing6_P_y) + ;4351401811647638138392695977895401859084096897123577305203754529537814663108n :MSTORE(ecPairing6_Q_x1) + ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) + ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) + ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;1n :MSTORE(ecPairing6_P_x) + ;1n :MSTORE(ecPairing6_P_y) + ;0n :MSTORE(ecPairing6_Q_x1) + ;0n :MSTORE(ecPairing6_Q_x2) + ;0n :MSTORE(ecPairing6_Q_y1) + ;0n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;; 1.1] Fails if some input is not in range + ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_P_x) + ;1n :MSTORE(ecPairing6_P_y) + ;0n :MSTORE(ecPairing6_Q_x1) + ;0n :MSTORE(ecPairing6_Q_x2) + ;0n :MSTORE(ecPairing6_Q_y1) + ;0n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;1n :MSTORE(ecPairing6_P_x) + ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_P_y) + ;0n :MSTORE(ecPairing6_Q_x1) + ;0n :MSTORE(ecPairing6_Q_x2) + ;0n :MSTORE(ecPairing6_Q_y1) + ;0n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;1n :MSTORE(ecPairing6_P_x) + ;2n :MSTORE(ecPairing6_P_y) + ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_x1) + ;0n :MSTORE(ecPairing6_Q_x2) + ;0n :MSTORE(ecPairing6_Q_y1) + ;0n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;1n :MSTORE(ecPairing6_P_x) + ;2n :MSTORE(ecPairing6_P_y) + ;0n :MSTORE(ecPairing6_Q_x1) + ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_x2) + ;0n :MSTORE(ecPairing6_Q_y1) + ;0n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;1n :MSTORE(ecPairing6_P_x) + ;2n :MSTORE(ecPairing6_P_y) + ;0n :MSTORE(ecPairing6_Q_x1) + ;0n :MSTORE(ecPairing6_Q_x2) + ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_y1) + ;0n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;1n :MSTORE(ecPairing6_P_x) + ;2n :MSTORE(ecPairing6_P_y) + ;0n :MSTORE(ecPairing6_Q_x1) + ;0n :MSTORE(ecPairing6_Q_x2) + ;0n :MSTORE(ecPairing6_Q_y1) + ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 => A + ;B :ASSERT +; + ;; 1.2] Degenerate tests: e(0,Q) = 1 and e(P,0) = 1 therefore the pairing equation is trivally satisfied + ;; and in fact this is the only possibility for the pairing equation to be satisfied with one pair of P,Q + ;0n :MSTORE(ecPairing6_P_x) + ;0n :MSTORE(ecPairing6_P_y) + ;4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(ecPairing6_Q_x1) + ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) + ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) + ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 :MLOAD(ecPairing6_result) +; + ;1n :MSTORE(ecPairing6_P_x) + ;2n :MSTORE(ecPairing6_P_y) + ;0n :MSTORE(ecPairing6_Q_x1) + ;0n :MSTORE(ecPairing6_Q_x2) + ;0n :MSTORE(ecPairing6_Q_y1) + ;0n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 :MLOAD(ecPairing6_result) +; + ;0n :MSTORE(ecPairing6_P_x) + ;0n :MSTORE(ecPairing6_P_y) + ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing6_Q_x1) + ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing6_Q_x2) + ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing6_Q_y1) + ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing6_Q_y2) + ; :CALL(ecPairing6) + ;1 :MLOAD(ecPairing6_result) +; + ;; 2] Tests with 12 inputs +; + ;; Ethereum example + ;20333349487611174579608837001148061570648440167819460274134014152400656275674n :MSTORE(ecPairing12_P1_x) + ;19928268888036365434500215951569291213336085054454884806456691094014419998198n :MSTORE(ecPairing12_P1_y) + ;15548973838770842196102442698708122006189018193868154757846481038796366125273n :MSTORE(ecPairing12_Q1_x1) + ;14335504872549532354210489828671972911333347940534076142795111812609903378108n :MSTORE(ecPairing12_Q1_x2) + ;21654797034782659092642090020723114658730107139270194997413654453096686856286n :MSTORE(ecPairing12_Q1_y1) + ;19822981108166058814837087071162475941148726886187076297764129491697321004944n :MSTORE(ecPairing12_Q1_y2) + ;1n :MSTORE(ecPairing12_P2_x) + ;21888242871839275222246405745257275088696311157297823662689037894645226208581n :MSTORE(ecPairing12_P2_y) + ;4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(ecPairing12_Q2_x1) + ;11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(ecPairing12_Q2_x2) + ;16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(ecPairing12_Q2_y1) + ;19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(ecPairing12_Q2_y2) + ; :CALL(ecPairing12) + ;1 :MLOAD(ecPairing12_result) +; + ;; KZG proof with one poly and one evaluation + ;20593188969319011263398594823255811823444990825298196162496264072013322991388n :MSTORE(ecPairing12_P1_x) + ;20958531318718262179638310844977035402258325676941759254411716094948903283238n :MSTORE(ecPairing12_P1_y) + ;4011274991290276638756079424799286249285264639232842260296401218902340006571n :MSTORE(ecPairing12_Q1_x1) + ;19014538453489502551198430834271851224745298622671277274539119640314913863353n :MSTORE(ecPairing12_Q1_x2) + ;18471742500483808444303896273620229467289887099913869033627754256214290219997n :MSTORE(ecPairing12_Q1_y1) + ;5493217260886730300768636259682920882409386426126823957476482234761131640151n :MSTORE(ecPairing12_Q1_y2) + ;3526892542800189419786189901545486150149308978725362430328886936745555020543n :MSTORE(ecPairing12_P2_x) + ;2119286186166371280112264238015778473404141003919064027522145193839708208181n :MSTORE(ecPairing12_P2_y) + ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing12_Q2_x1) + ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing12_Q2_x2) + ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing12_Q2_y1) + ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing12_Q2_y2) + ; :CALL(ecPairing12) + ;1 :MLOAD(ecPairing12_result) +; + ;; KZG proof with one poly and one evaluation + ;7732322222446307127032679746925673403013840763103947213960757438494804067267n :MSTORE(ecPairing12_P1_x) + ;8619360092012773279112944586645719683585858765189162557863470404130431808723n :MSTORE(ecPairing12_P1_y) + ;4480687189204505779534873101802061566996023148878380905742776654135663383221n :MSTORE(ecPairing12_Q1_x1) + ;7754062701624777074058760614745676120554164137217320298195308357000412149840n :MSTORE(ecPairing12_Q1_x2) + ;16667361185745910936700318129097219900413959552154798924397125501722669434888n :MSTORE(ecPairing12_Q1_y1) + ;18744429014512523574338799100424477374744612401726532054975840530120472566n :MSTORE(ecPairing12_Q1_y2) + ;595801121933130257838893357109567932541713044978712091132608377833002940532n :MSTORE(ecPairing12_P2_x) + ;15681552092527426161541501125159206079106959026991100968107368848241580050483n :MSTORE(ecPairing12_P2_y) + ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing12_Q2_x1) + ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing12_Q2_x2) + ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing12_Q2_y1) + ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing12_Q2_y2) + ; :CALL(ecPairing12) + ;1 :MLOAD(ecPairing12_result) +; + ;; 3] Tests with 18 inputs +; + ;7732322222446307127032679746925673403013840763103947213960757438494804067267n :MSTORE(ecPairing18_P1_x) + ;8619360092012773279112944586645719683585858765189162557863470404130431808723n :MSTORE(ecPairing18_P1_y) + ;4480687189204505779534873101802061566996023148878380905742776654135663383221n :MSTORE(ecPairing18_Q1_x1) + ;7754062701624777074058760614745676120554164137217320298195308357000412149840n :MSTORE(ecPairing18_Q1_x2) + ;16667361185745910936700318129097219900413959552154798924397125501722669434888n :MSTORE(ecPairing18_Q1_y1) + ;18744429014512523574338799100424477374744612401726532054975840530120472566n :MSTORE(ecPairing18_Q1_y2) + ;595801121933130257838893357109567932541713044978712091132608377833002940532n :MSTORE(ecPairing18_P2_x) + ;15681552092527426161541501125159206079106959026991100968107368848241580050483n :MSTORE(ecPairing18_P2_y) + ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing18_Q2_x1) + ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing18_Q2_x2) + ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing18_Q2_y1) + ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing18_Q2_y2) + ;1n :MSTORE(ecPairing18_P3_x) + ;2n :MSTORE(ecPairing18_P3_y) + ;0n :MSTORE(ecPairing18_Q3_x1) + ;0n :MSTORE(ecPairing18_Q3_x2) + ;0n :MSTORE(ecPairing18_Q3_y1) + ;0n :MSTORE(ecPairing18_Q3_y2) + ; :CALL(ecPairing18) + ;1 :MLOAD(ecPairing18_result) +; +; + ;;======================================================================================= + ; Tests generic + + ; 1] 0 inputs should return 1 + 0 :MSTORE(ecPairing_ninputs) + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + + ; 2] 6 inputs should return 1 iff either P or Q is the identity + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 1n :MSTORE(MEM:E) + 2n :MSTORE(MEM:E+1) + 0n :MSTORE(MEM:E+2) + 0n :MSTORE(MEM:E+3) + 0n :MSTORE(MEM:E+4) + 0n :MSTORE(MEM:E+5) + + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E+1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(MEM:E+2) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(MEM:E+3) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(MEM:E+4) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(MEM:E+5) + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E+1) + 11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(MEM:E+2) + 4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(MEM:E+3) + 19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(MEM:E+4) + 16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(MEM:E+5) + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + + ; The following should fail + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E+1) + 1n :MSTORE(MEM:E+2) + 2n :MSTORE(MEM:E+3) + 3n :MSTORE(MEM:E+4) + 3n :MSTORE(MEM:E+5) + :CALL(ecPairing) + 1 => A + 1 :EQ + + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 1n :MSTORE(MEM:E) + 1n :MSTORE(MEM:E+1) + 0n :MSTORE(MEM:E+2) + 0n :MSTORE(MEM:E+3) + 0n :MSTORE(MEM:E+4) + 0n :MSTORE(MEM:E+5) + :CALL(ecPairing) + 1 => A + 1 :EQ + + ; 3] 12 inputs + 2 :MSTORE(ecPairing_ninputs) + 32*6*2 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 20333349487611174579608837001148061570648440167819460274134014152400656275674n :MSTORE(MEM:E) + 19928268888036365434500215951569291213336085054454884806456691094014419998198n :MSTORE(MEM:E+1) + 14335504872549532354210489828671972911333347940534076142795111812609903378108n :MSTORE(MEM:E+2) + 15548973838770842196102442698708122006189018193868154757846481038796366125273n :MSTORE(MEM:E+3) + 19822981108166058814837087071162475941148726886187076297764129491697321004944n :MSTORE(MEM:E+4) + 21654797034782659092642090020723114658730107139270194997413654453096686856286n :MSTORE(MEM:E+5) + 1n :MSTORE(MEM:E+6) + 21888242871839275222246405745257275088696311157297823662689037894645226208581n :MSTORE(MEM:E+7) + 11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(MEM:E+8) + 4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(MEM:E+9) + 19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(MEM:E+10) + 16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(MEM:E+11) + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + + 2 :MSTORE(ecPairing_ninputs) + 32*6*2 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 20593188969319011263398594823255811823444990825298196162496264072013322991388n :MSTORE(MEM:E) + 20958531318718262179638310844977035402258325676941759254411716094948903283238n :MSTORE(MEM:E+1) + 19014538453489502551198430834271851224745298622671277274539119640314913863353n :MSTORE(MEM:E+2) + 4011274991290276638756079424799286249285264639232842260296401218902340006571n :MSTORE(MEM:E+3) + 5493217260886730300768636259682920882409386426126823957476482234761131640151n :MSTORE(MEM:E+4) + 18471742500483808444303896273620229467289887099913869033627754256214290219997n :MSTORE(MEM:E+5) + 3526892542800189419786189901545486150149308978725362430328886936745555020543n :MSTORE(MEM:E+6) + 2119286186166371280112264238015778473404141003919064027522145193839708208181n :MSTORE(MEM:E+7) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E+8) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E+9) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E+10) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E+11) + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + + ; 3] 18 inputs + 3 :MSTORE(ecPairing_ninputs) + 32*6*3 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 20408625067408993290064640368727791004970573998302586029702220794326757674498n :MSTORE(MEM:E) + 16305464745216061320718924810220361252899630638785881184214175311729150579496n :MSTORE(MEM:E+1) + 19366297632879679637284621799459008574776307690134846433263569915955921902826n :MSTORE(MEM:E+2) + 7402184029652592179271650707149396214555402416834379616679103713331638701004n :MSTORE(MEM:E+3) + 13233069919494729038860025360853108843397419493559475327647450442468969143158n :MSTORE(MEM:E+4) + 10493112377715503836766497500954305714610771526749266396762372159550562853087n :MSTORE(MEM:E+5) + 6065896804174124393372571703959114319291624137637105019419069942189555692569n :MSTORE(MEM:E+6) + 1817372094771574002977021734119138264961743925299214620753363200235482672254n :MSTORE(MEM:E+7) + 19366297632879679637284621799459008574776307690134846433263569915955921902826n :MSTORE(MEM:E+8) + 7402184029652592179271650707149396214555402416834379616679103713331638701004n :MSTORE(MEM:E+9) + 13233069919494729038860025360853108843397419493559475327647450442468969143158n :MSTORE(MEM:E+10) + 10493112377715503836766497500954305714610771526749266396762372159550562853087n :MSTORE(MEM:E+11) + 5155695327752856721154364733178772660419613502017586895566245903460009198248n :MSTORE(MEM:E+12) + 17870951736543108265510715325941304521966082260796939666348236029204261385066n :MSTORE(MEM:E+13) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E+14) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E+15) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E+16) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E+17) + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + + ; 3] 24 inputs + 4 :MSTORE(ecPairing_ninputs) + 32*6*4 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + + 0 => E + 1153563745531144946586097928621095258348432585499389732309707300454996283289n :MSTORE(MEM:E) + 7370404687973809887690049462468892748861464831518247317487007737601322454777n :MSTORE(MEM:E+1) + 9376055848676368316410365621777214987372973768688270899357881297879508822452n :MSTORE(MEM:E+2) + 19738309004667351906306506105426292998739264612662465709107894554928292805496n :MSTORE(MEM:E+3) + 285143926121120094170748007008262512509578107228129423236125884572189904421n :MSTORE(MEM:E+4) + 10279962913447536422932523162364510093030414102832227875578519449385249705476n :MSTORE(MEM:E+5) + 8576791937965657966843713337336683588215881223744955532549571901036035091965n :MSTORE(MEM:E+6) + 20999102966105130950411191886633074956452730563320480529699815227954081231322n :MSTORE(MEM:E+7) + 9376055848676368316410365621777214987372973768688270899357881297879508822452n :MSTORE(MEM:E+8) + 19738309004667351906306506105426292998739264612662465709107894554928292805496n :MSTORE(MEM:E+9) + 285143926121120094170748007008262512509578107228129423236125884572189904421n :MSTORE(MEM:E+10) + 10279962913447536422932523162364510093030414102832227875578519449385249705476n :MSTORE(MEM:E+11) + 18556379486610508840908277815073629329531616761731760569700551412487192333649n :MSTORE(MEM:E+12) + 17673868103043290791894327402153901008120365354485186198280340860768344163073n :MSTORE(MEM:E+13) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E+14) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E+15) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E+16) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E+17) + 20364104435611758595377721340560864676183708759135257849771131236782155536356n :MSTORE(MEM:E+18) + 6044194345605039714961350342623860353524318320217972076629496104743557530117n :MSTORE(MEM:E+19) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E+20) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E+21) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E+22) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E+23) + :CALL(ecPairing) + 1 :MLOAD(ecPairing_result) + 0 => A + 1 :EQ + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/main.zkasm" \ No newline at end of file diff --git a/test/testFinalExpBn254.zkasm b/test/testFinalExpBn254.zkasm new file mode 100644 index 00000000..b15120ae --- /dev/null +++ b/test/testFinalExpBn254.zkasm @@ -0,0 +1,136 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + 13640254227245024655838601068231183157721360561601028708811475275217122101072n :MSTORE(finalExpBN254_f11_x) + 19308417300657558492615098636528930118171456086181403615599560648373004008445n :MSTORE(finalExpBN254_f11_y) + 11600807028088028070223911119334614254604789223029238428546002219857166268982n :MSTORE(finalExpBN254_f12_x) + 4879406373235938927297467572708988980645988929154072556290202741257062565094n :MSTORE(finalExpBN254_f12_y) + 4171685090913488783052266386653991584736187693807813444268445186114207424938n :MSTORE(finalExpBN254_f13_x) + 1277573873092817905392452044933753278511826457458184982228668801202320403016n :MSTORE(finalExpBN254_f13_y) + 14431703268682647902296102635071887590346322924866425403256046961671041030534n :MSTORE(finalExpBN254_f21_x) + 11898392435919290118390574221795784387718317590754683868792519816848089304255n :MSTORE(finalExpBN254_f21_y) + 583787015380908422861158991038392109634638768690762169717364137330743074526n :MSTORE(finalExpBN254_f22_x) + 13126870183170761631152540488140870675640427576483291663794972909787720839738n :MSTORE(finalExpBN254_f22_y) + 6457767870676104874999362178075129079810053093666926870765167604207462152679n :MSTORE(finalExpBN254_f23_x) + 12911511138445339632082563502636262379527290965988664015632615336010308825090n :MSTORE(finalExpBN254_f23_y) + :CALL(finalExpBN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(finalExpBN254_f11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(finalExpBN254_f11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(finalExpBN254_f12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(finalExpBN254_f12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(finalExpBN254_f13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(finalExpBN254_f13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(finalExpBN254_f21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(finalExpBN254_f21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(finalExpBN254_f22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(finalExpBN254_f22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(finalExpBN254_f23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(finalExpBN254_f23_y) + + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/constants.zkasm" + +INCLUDE "../main/pairings/finalExpBN254.zkasm" + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" + +INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" + +INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/squareFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/inverseFp6BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/mulFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/inverseFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frobFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frob2Fp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frob3Fp12BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm" \ No newline at end of file diff --git a/test/testFp12ArithBN254.zkasm b/test/testFp12ArithBN254.zkasm new file mode 100644 index 00000000..61cc64a2 --- /dev/null +++ b/test/testFp12ArithBN254.zkasm @@ -0,0 +1,618 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +INCLUDE "../main/pairings/constants.zkasm" + +VAR GLOBAL test + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + + 10n :MSTORE(addFp12BN254_a11_x) + 2n :MSTORE(addFp12BN254_a11_y) + 5n :MSTORE(addFp12BN254_a12_x) + 13n :MSTORE(addFp12BN254_a12_y) + 7n :MSTORE(addFp12BN254_a13_x) + 5n :MSTORE(addFp12BN254_a13_y) + 10n :MSTORE(addFp12BN254_a21_x) + 2n :MSTORE(addFp12BN254_a21_y) + 5n :MSTORE(addFp12BN254_a22_x) + 13n :MSTORE(addFp12BN254_a22_y) + 7n :MSTORE(addFp12BN254_a23_x) + 5n :MSTORE(addFp12BN254_a23_y) + 78n :MSTORE(addFp12BN254_b11_x) + 5n :MSTORE(addFp12BN254_b11_y) + 3n :MSTORE(addFp12BN254_b12_x) + 193n :MSTORE(addFp12BN254_b12_y) + 20n :MSTORE(addFp12BN254_b13_x) + 2n :MSTORE(addFp12BN254_b13_y) + 1n :MSTORE(addFp12BN254_b21_x) + 0n :MSTORE(addFp12BN254_b21_y) + 0n :MSTORE(addFp12BN254_b22_x) + 3n :MSTORE(addFp12BN254_b22_y) + 69n :MSTORE(addFp12BN254_b23_x) + 27n :MSTORE(addFp12BN254_b23_y) + :CALL(addFp12BN254) + 88n :MLOAD(addFp12BN254_c11_x) + 7n :MLOAD(addFp12BN254_c11_y) + 8n :MLOAD(addFp12BN254_c12_x) + 206n :MLOAD(addFp12BN254_c12_y) + 27n :MLOAD(addFp12BN254_c13_x) + 7n :MLOAD(addFp12BN254_c13_y) + 11n :MLOAD(addFp12BN254_c21_x) + 2n :MLOAD(addFp12BN254_c21_y) + 5n :MLOAD(addFp12BN254_c22_x) + 16n :MLOAD(addFp12BN254_c22_y) + 76n :MLOAD(addFp12BN254_c23_x) + 32n :MLOAD(addFp12BN254_c23_y) + + 10n :MSTORE(subFp12BN254_a11_x) + 2n :MSTORE(subFp12BN254_a11_y) + 5n :MSTORE(subFp12BN254_a12_x) + 13n :MSTORE(subFp12BN254_a12_y) + 7n :MSTORE(subFp12BN254_a13_x) + 5n :MSTORE(subFp12BN254_a13_y) + 10n :MSTORE(subFp12BN254_a21_x) + 2n :MSTORE(subFp12BN254_a21_y) + 5n :MSTORE(subFp12BN254_a22_x) + 13n :MSTORE(subFp12BN254_a22_y) + 7n :MSTORE(subFp12BN254_a23_x) + 5n :MSTORE(subFp12BN254_a23_y) + 78n :MSTORE(subFp12BN254_b11_x) + 5n :MSTORE(subFp12BN254_b11_y) + 3n :MSTORE(subFp12BN254_b12_x) + 193n :MSTORE(subFp12BN254_b12_y) + 20n :MSTORE(subFp12BN254_b13_x) + 2n :MSTORE(subFp12BN254_b13_y) + 1n :MSTORE(subFp12BN254_b21_x) + 0n :MSTORE(subFp12BN254_b21_y) + 0n :MSTORE(subFp12BN254_b22_x) + 3n :MSTORE(subFp12BN254_b22_y) + 69n :MSTORE(subFp12BN254_b23_x) + 27n :MSTORE(subFp12BN254_b23_y) + :CALL(subFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226208515n :MLOAD(subFp12BN254_c11_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208580n :MLOAD(subFp12BN254_c11_y) + 2n :MLOAD(subFp12BN254_c12_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208403n :MLOAD(subFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208570n :MLOAD(subFp12BN254_c13_x) + 3n :MLOAD(subFp12BN254_c13_y) + 9n :MLOAD(subFp12BN254_c21_x) + 2n :MLOAD(subFp12BN254_c21_y) + 5n :MLOAD(subFp12BN254_c22_x) + 10n :MLOAD(subFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208521n :MLOAD(subFp12BN254_c23_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208561n :MLOAD(subFp12BN254_c23_y) + + 10n :MSTORE(mulFp12BN254_a11_x) + 2n :MSTORE(mulFp12BN254_a11_y) + 5n :MSTORE(mulFp12BN254_a12_x) + 13n :MSTORE(mulFp12BN254_a12_y) + 7n :MSTORE(mulFp12BN254_a13_x) + 5n :MSTORE(mulFp12BN254_a13_y) + 10n :MSTORE(mulFp12BN254_a21_x) + 2n :MSTORE(mulFp12BN254_a21_y) + 5n :MSTORE(mulFp12BN254_a22_x) + 13n :MSTORE(mulFp12BN254_a22_y) + 7n :MSTORE(mulFp12BN254_a23_x) + 5n :MSTORE(mulFp12BN254_a23_y) + 78n :MSTORE(mulFp12BN254_b11_x) + 5n :MSTORE(mulFp12BN254_b11_y) + 3n :MSTORE(mulFp12BN254_b12_x) + 193n :MSTORE(mulFp12BN254_b12_y) + 20n :MSTORE(mulFp12BN254_b13_x) + 2n :MSTORE(mulFp12BN254_b13_y) + 1n :MSTORE(mulFp12BN254_b21_x) + 0n :MSTORE(mulFp12BN254_b21_y) + 0n :MSTORE(mulFp12BN254_b22_x) + 3n :MSTORE(mulFp12BN254_b22_y) + 69n :MSTORE(mulFp12BN254_b23_x) + 27n :MSTORE(mulFp12BN254_b23_y) + :CALL(mulFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226204895n :MLOAD(mulFp12BN254_c11_x) + 18516n :MLOAD(mulFp12BN254_c11_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208376n :MLOAD(mulFp12BN254_c12_x) + 13589n :MLOAD(mulFp12BN254_c12_y) + 820n :MLOAD(mulFp12BN254_c13_x) + 6686n :MLOAD(mulFp12BN254_c13_y) + 21888242871839275222246405745257275088696311157297823662689037894645226198655n :MLOAD(mulFp12BN254_c21_x) + 23518n :MLOAD(mulFp12BN254_c21_y) + 3622n :MLOAD(mulFp12BN254_c22_x) + 9328n :MLOAD(mulFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207410n :MLOAD(mulFp12BN254_c23_x) + 1917n :MLOAD(mulFp12BN254_c23_y) + + 2n :MSTORE(mulFp12BN254_a11_x) + 4n :MSTORE(mulFp12BN254_a11_y) + 0n :MSTORE(mulFp12BN254_a12_x) + 0n :MSTORE(mulFp12BN254_a12_y) + 0n :MSTORE(mulFp12BN254_a13_x) + 5n :MSTORE(mulFp12BN254_a13_y) + 5n :MSTORE(mulFp12BN254_a21_x) + 10n :MSTORE(mulFp12BN254_a21_y) + 20n :MSTORE(mulFp12BN254_a22_x) + 30n :MSTORE(mulFp12BN254_a22_y) + 7n :MSTORE(mulFp12BN254_a23_x) + 69n :MSTORE(mulFp12BN254_a23_y) + 78n :MSTORE(mulFp12BN254_b11_x) + 14n :MSTORE(mulFp12BN254_b11_y) + 2n :MSTORE(mulFp12BN254_b12_x) + 1n :MSTORE(mulFp12BN254_b12_y) + 2n :MSTORE(mulFp12BN254_b13_x) + 10n :MSTORE(mulFp12BN254_b13_y) + 100n :MSTORE(mulFp12BN254_b21_x) + 99n :MSTORE(mulFp12BN254_b21_y) + 88n :MSTORE(mulFp12BN254_b22_x) + 77n :MSTORE(mulFp12BN254_b22_y) + 20n :MSTORE(mulFp12BN254_b23_x) + 2n :MSTORE(mulFp12BN254_b23_y) + :CALL(mulFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226137236n :MLOAD(mulFp12BN254_c11_x) + 101671n :MLOAD(mulFp12BN254_c11_y) + 21888242871839275222246405745257275088696311157297823662689037894645226161169n :MLOAD(mulFp12BN254_c12_x) + 62447n :MLOAD(mulFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226205801n :MLOAD(mulFp12BN254_c13_x) + 19211n :MLOAD(mulFp12BN254_c13_y) + 21888242871839275222246405745257275088696311157297823662689037894645226201492n :MLOAD(mulFp12BN254_c21_x) + 8353n :MLOAD(mulFp12BN254_c21_y) + 21888242871839275222246405745257275088696311157297823662689037894645226203109n :MLOAD(mulFp12BN254_c22_x) + 5237n :MLOAD(mulFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207620n :MLOAD(mulFp12BN254_c23_x) + 6214n :MLOAD(mulFp12BN254_c23_y) + + 2n :MSTORE(squareFp12BN254_a11_x) + 4n :MSTORE(squareFp12BN254_a11_y) + 0n :MSTORE(squareFp12BN254_a12_x) + 0n :MSTORE(squareFp12BN254_a12_y) + 0n :MSTORE(squareFp12BN254_a13_x) + 5n :MSTORE(squareFp12BN254_a13_y) + 5n :MSTORE(squareFp12BN254_a21_x) + 10n :MSTORE(squareFp12BN254_a21_y) + 20n :MSTORE(squareFp12BN254_a22_x) + 30n :MSTORE(squareFp12BN254_a22_y) + 7n :MSTORE(squareFp12BN254_a23_x) + 69n :MSTORE(squareFp12BN254_a23_y) + :CALL(squareFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226190251n :MLOAD(squareFp12BN254_c11_x) + 16476n :MLOAD(squareFp12BN254_c11_y) + 21888242871839275222246405745257275088696311157297823662689037894645226170363n :MLOAD(squareFp12BN254_c12_x) + 24835n :MLOAD(squareFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226164769n :MLOAD(squareFp12BN254_c13_x) + 4702n :MLOAD(squareFp12BN254_c13_y) + 21888242871839275222246405745257275088696311157297823662689037894645226205623n :MLOAD(squareFp12BN254_c21_x) + 1580n :MLOAD(squareFp12BN254_c21_y) + 21888242871839275222246405745257275088696311157297823662689037894645226202143n :MLOAD(squareFp12BN254_c22_x) + 220n :MLOAD(squareFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207959n :MLOAD(squareFp12BN254_c23_x) + 382n :MLOAD(squareFp12BN254_c23_y) + + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(squareFp12BN254_a11_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(squareFp12BN254_a11_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(squareFp12BN254_a12_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(squareFp12BN254_a12_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(squareFp12BN254_a13_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(squareFp12BN254_a13_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(squareFp12BN254_a21_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(squareFp12BN254_a21_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(squareFp12BN254_a22_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(squareFp12BN254_a22_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(squareFp12BN254_a23_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(squareFp12BN254_a23_y) + :CALL(squareFp12BN254) + 2098026393950394559493690260865166581266928315924710629633888310320006689795n :MLOAD(squareFp12BN254_c11_x) + 1846888720299666666109042029094532002505741710678796245911331796963733914187n :MLOAD(squareFp12BN254_c11_y) + 6856859212192321831831255712736216614951508355737406292407364405936415355512n :MLOAD(squareFp12BN254_c12_x) + 17209588680055969912485542074372495831925486815137906387799790601911548657525n :MLOAD(squareFp12BN254_c12_y) + 15781046857382959121140505691131389728661226093902862303002526578701400754315n :MLOAD(squareFp12BN254_c13_x) + 8625093555241362381542545391636743832938050376057983419042860774659518282797n :MLOAD(squareFp12BN254_c13_y) + 14351778565182200844681812560787756136192441388960773363087263587389322671562n :MLOAD(squareFp12BN254_c21_x) + 15695337662963643544813486120899631949921737819129690254830667492646284393382n :MLOAD(squareFp12BN254_c21_y) + 5570195873148749154672896518046181211644563497843962677067647498629814883385n :MLOAD(squareFp12BN254_c22_x) + 14991026153829150387150002728101017951749162083560649689008171461754623678203n :MLOAD(squareFp12BN254_c22_y) + 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(squareFp12BN254_c23_x) + 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(squareFp12BN254_c23_y) + + 2n :MSTORE(inverseFp12BN254_a11_x) + 4n :MSTORE(inverseFp12BN254_a11_y) + 0n :MSTORE(inverseFp12BN254_a12_x) + 0n :MSTORE(inverseFp12BN254_a12_y) + 0n :MSTORE(inverseFp12BN254_a13_x) + 5n :MSTORE(inverseFp12BN254_a13_y) + 5n :MSTORE(inverseFp12BN254_a21_x) + 10n :MSTORE(inverseFp12BN254_a21_y) + 20n :MSTORE(inverseFp12BN254_a22_x) + 30n :MSTORE(inverseFp12BN254_a22_y) + 7n :MSTORE(inverseFp12BN254_a23_x) + 69n :MSTORE(inverseFp12BN254_a23_y) + :CALL(inverseFp12BN254) + 20888671201298710215559703514044964345994874487104175886056878644554404140739n :MLOAD(inverseFp12BN254_c11_x) + 18341611945458884647361257454040416792770938911765857382502174274013923134382n :MLOAD(inverseFp12BN254_c11_y) + 17212264596994956074343974726440644554067711720592905218425974958919607539075n :MLOAD(inverseFp12BN254_c12_x) + 6732381207586209376886879348286689555260828461769669735069071849456515851212n :MLOAD(inverseFp12BN254_c12_y) + 21368147715739918891454619601590918042420736987188643135495514508402788769683n :MLOAD(inverseFp12BN254_c13_x) + 3663521624002505260290817291830274755837177609996429331224604043807131463817n :MLOAD(inverseFp12BN254_c13_y) + 3032132887036960235387737000759039646563507175772143153015916596005685046007n :MLOAD(inverseFp12BN254_c21_x) + 13055139790251789501688599598738101973446402124156655452735772999414040890403n :MLOAD(inverseFp12BN254_c21_y) + 6517756700633644793630942808183387771630781381170479363578086592172656898770n :MLOAD(inverseFp12BN254_c22_x) + 395650894991045560122132702409515890328368535989210404180801859598882957185n :MLOAD(inverseFp12BN254_c22_y) + 8570196145412438361611057965650768730501569553533068267820731323855389368346n :MLOAD(inverseFp12BN254_c23_x) + 7491118698937156772874143978394611345783939114329232646099076078308797709778n :MLOAD(inverseFp12BN254_c23_y) + + 2n :MSTORE(frobFp12BN254_a11_x) + 4n :MSTORE(frobFp12BN254_a11_y) + 0n :MSTORE(frobFp12BN254_a12_x) + 0n :MSTORE(frobFp12BN254_a12_y) + 0n :MSTORE(frobFp12BN254_a13_x) + 5n :MSTORE(frobFp12BN254_a13_y) + 5n :MSTORE(frobFp12BN254_a21_x) + 10n :MSTORE(frobFp12BN254_a21_y) + 20n :MSTORE(frobFp12BN254_a22_x) + 30n :MSTORE(frobFp12BN254_a22_y) + 7n :MSTORE(frobFp12BN254_a23_x) + 69n :MSTORE(frobFp12BN254_a23_y) + :CALL(frobFp12BN254) + 2n :MLOAD(frobFp12BN254_c11_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208579n :MLOAD(frobFp12BN254_c11_y) + 0n :MLOAD(frobFp12BN254_c12_x) + 0n :MLOAD(frobFp12BN254_c12_y) + 12135813371521139050994037868617609616787958635633452590810720783422678470818n :MLOAD(frobFp12BN254_c13_x) + 8978686149504228545909850167913259590937983131916839958350011601804054476893n :MLOAD(frobFp12BN254_c13_y) + 9584641713043712721593590042581712654775596374742780276939764667903927806313n :MLOAD(frobFp12BN254_c21_x) + 20476170829590101375852353274876318157843683729155685571889366804266103799363n :MLOAD(frobFp12BN254_c21_y) + 8388916578362501695849260316596592932525470900775430933148668612207026983089n :MLOAD(frobFp12BN254_c22_x) + 7358162764234297459542225094137172218712665797959405470620213129713321020023n :MLOAD(frobFp12BN254_c22_y) + 18558562840876269057841639761243305870292532112761084078231157243871160309578n :MLOAD(frobFp12BN254_c23_x) + 11857974535903257516183381046246360366676403947472414230254839754001932999778n :MLOAD(frobFp12BN254_c23_y) + + 2n :MSTORE(frob2Fp12BN254_a11_x) + 4n :MSTORE(frob2Fp12BN254_a11_y) + 0n :MSTORE(frob2Fp12BN254_a12_x) + 0n :MSTORE(frob2Fp12BN254_a12_y) + 0n :MSTORE(frob2Fp12BN254_a13_x) + 5n :MSTORE(frob2Fp12BN254_a13_y) + 5n :MSTORE(frob2Fp12BN254_a21_x) + 10n :MSTORE(frob2Fp12BN254_a21_y) + 20n :MSTORE(frob2Fp12BN254_a22_x) + 30n :MSTORE(frob2Fp12BN254_a22_y) + 7n :MSTORE(frob2Fp12BN254_a23_x) + 69n :MSTORE(frob2Fp12BN254_a23_y) + :CALL(frob2Fp12BN254) + 2n :MLOAD(frob2Fp12BN254_c11_x) + 4n :MLOAD(frob2Fp12BN254_c11_y) + 0n :MLOAD(frob2Fp12BN254_c12_x) + 0n :MLOAD(frob2Fp12BN254_c12_y) + 0n :MLOAD(frob2Fp12BN254_c13_x) + 11019802425740609607093018714128810104871396294401028259830n :MLOAD(frob2Fp12BN254_c13_y) + 21888242871839275211226603319516665481603292443169013557817641600244197948753n :MLOAD(frob2Fp12BN254_c21_x) + 21888242871839275200206800893776055874510273729040203452946245305843169688923n :MLOAD(frob2Fp12BN254_c21_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208563n :MLOAD(frob2Fp12BN254_c22_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208553n :MLOAD(frob2Fp12BN254_c22_y) + 15427723396036853449930226199780334146819954812161439563769n :MLOAD(frob2Fp12BN254_c23_x) + 152073273475220412577883658254977579447225268862734189985723n :MLOAD(frob2Fp12BN254_c23_y) + + 2n :MSTORE(frob3Fp12BN254_a11_x) + 4n :MSTORE(frob3Fp12BN254_a11_y) + 0n :MSTORE(frob3Fp12BN254_a12_x) + 0n :MSTORE(frob3Fp12BN254_a12_y) + 0n :MSTORE(frob3Fp12BN254_a13_x) + 5n :MSTORE(frob3Fp12BN254_a13_y) + 5n :MSTORE(frob3Fp12BN254_a21_x) + 10n :MSTORE(frob3Fp12BN254_a21_y) + 20n :MSTORE(frob3Fp12BN254_a22_x) + 30n :MSTORE(frob3Fp12BN254_a22_y) + 7n :MSTORE(frob3Fp12BN254_a23_x) + 69n :MSTORE(frob3Fp12BN254_a23_y) + :CALL(frob3Fp12BN254) + 2n :MLOAD(frob3Fp12BN254_c11_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208579n :MLOAD(frob3Fp12BN254_c11_y) + 0n :MLOAD(frob3Fp12BN254_c12_x) + 0n :MLOAD(frob3Fp12BN254_c12_y) + 15379773288170639757858258400900114640879698627390973011522457221008541989446n :MLOAD(frob3Fp12BN254_c13_x) + 17154089731429032730858894512983477767751333502592430926476358946503966738576n :MLOAD(frob3Fp12BN254_c13_y) + 17749105629462879953863937671185175801732786780399070592042899283982922600439n :MLOAD(frob3Fp12BN254_c21_x) + 15874459213129437722334522520084447110335778476790487949919376082271117456313n :MLOAD(frob3Fp12BN254_c21_y) + 13499326293476773526397145428660682156170840256522392729540369282438199225494n :MLOAD(frob3Fp12BN254_c22_x) + 14530080107604977762704180651120102869983645359338418192068824764931905188560n :MLOAD(frob3Fp12BN254_c22_y) + 9835836312269481659124129352040423254366959727421963915440501313066399824733n :MLOAD(frob3Fp12BN254_c23_x) + 2627768430169233579625702931774614886811535516639531274999928953109345755919n :MLOAD(frob3Fp12BN254_c23_y) + + ; exp + 0n :MSTORE(expFp12BN254_e) + 0n :MSTORE(expFp12BN254_a11_x) + 0n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 0n :MSTORE(expFp12BN254_a13_y) + 0n :MSTORE(expFp12BN254_a21_x) + 0n :MSTORE(expFp12BN254_a21_y) + 0n :MSTORE(expFp12BN254_a22_x) + 0n :MSTORE(expFp12BN254_a22_y) + 0n :MSTORE(expFp12BN254_a23_x) + 0n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 0n :MLOAD(expFp12BN254_c11_x) + 0n :MLOAD(expFp12BN254_c11_y) + 0n :MLOAD(expFp12BN254_c12_x) + 0n :MLOAD(expFp12BN254_c12_y) + 0n :MLOAD(expFp12BN254_c13_x) + 0n :MLOAD(expFp12BN254_c13_y) + 0n :MLOAD(expFp12BN254_c21_x) + 0n :MLOAD(expFp12BN254_c21_y) + 0n :MLOAD(expFp12BN254_c22_x) + 0n :MLOAD(expFp12BN254_c22_y) + 0n :MLOAD(expFp12BN254_c23_x) + 0n :MLOAD(expFp12BN254_c23_y) + + 10n :MSTORE(expFp12BN254_e) + 0n :MSTORE(expFp12BN254_a11_x) + 0n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 0n :MSTORE(expFp12BN254_a13_y) + 0n :MSTORE(expFp12BN254_a21_x) + 0n :MSTORE(expFp12BN254_a21_y) + 0n :MSTORE(expFp12BN254_a22_x) + 0n :MSTORE(expFp12BN254_a22_y) + 0n :MSTORE(expFp12BN254_a23_x) + 0n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 0n :MLOAD(expFp12BN254_c11_x) + 0n :MLOAD(expFp12BN254_c11_y) + 0n :MLOAD(expFp12BN254_c12_x) + 0n :MLOAD(expFp12BN254_c12_y) + 0n :MLOAD(expFp12BN254_c13_x) + 0n :MLOAD(expFp12BN254_c13_y) + 0n :MLOAD(expFp12BN254_c21_x) + 0n :MLOAD(expFp12BN254_c21_y) + 0n :MLOAD(expFp12BN254_c22_x) + 0n :MLOAD(expFp12BN254_c22_y) + 0n :MLOAD(expFp12BN254_c23_x) + 0n :MLOAD(expFp12BN254_c23_y) + + 0n :MSTORE(expFp12BN254_e) + 1n :MSTORE(expFp12BN254_a11_x) + 0n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 0n :MSTORE(expFp12BN254_a13_y) + 0n :MSTORE(expFp12BN254_a21_x) + 0n :MSTORE(expFp12BN254_a21_y) + 0n :MSTORE(expFp12BN254_a22_x) + 0n :MSTORE(expFp12BN254_a22_y) + 0n :MSTORE(expFp12BN254_a23_x) + 0n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 1n :MLOAD(expFp12BN254_c11_x) + 0n :MLOAD(expFp12BN254_c11_y) + 0n :MLOAD(expFp12BN254_c12_x) + 0n :MLOAD(expFp12BN254_c12_y) + 0n :MLOAD(expFp12BN254_c13_x) + 0n :MLOAD(expFp12BN254_c13_y) + 0n :MLOAD(expFp12BN254_c21_x) + 0n :MLOAD(expFp12BN254_c21_y) + 0n :MLOAD(expFp12BN254_c22_x) + 0n :MLOAD(expFp12BN254_c22_y) + 0n :MLOAD(expFp12BN254_c23_x) + 0n :MLOAD(expFp12BN254_c23_y) + + 167n :MSTORE(expFp12BN254_e) + 2n :MSTORE(expFp12BN254_a11_x) + 4n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 5n :MSTORE(expFp12BN254_a13_y) + 5n :MSTORE(expFp12BN254_a21_x) + 10n :MSTORE(expFp12BN254_a21_y) + 20n :MSTORE(expFp12BN254_a22_x) + 30n :MSTORE(expFp12BN254_a22_y) + 7n :MSTORE(expFp12BN254_a23_x) + 69n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 20586466107674193719139483068538172518814581654122963093910816135984072539339n :MLOAD(expFp12BN254_c11_x) + 5953152173779773418366712639682598574554542297764337418575574775937014969989n :MLOAD(expFp12BN254_c11_y) + 3661221552326322626584296132914038982026189413490444409336642019079026110580n :MLOAD(expFp12BN254_c12_x) + 20307132177350548649365896131720817832905154290927819017533246898384788331797n :MLOAD(expFp12BN254_c12_y) + 6554555865226798697690787889597704881283210849129154679946065129492384662441n :MLOAD(expFp12BN254_c13_x) + 3734827310994017806686109338552434684262950155862064206859738515342034657482n :MLOAD(expFp12BN254_c13_y) + 12833166236118024621207291725677388530384380602869578473315220328428476013127n :MLOAD(expFp12BN254_c21_x) + 4283613850875227600923719261463876211784033209984079537562941239663105744102n :MLOAD(expFp12BN254_c21_y) + 1362526929780209469431909191206089688453294120749489634524494745650488027728n :MLOAD(expFp12BN254_c22_x) + 9956431918991355996517300910757034285810490343731619009685769604165956972299n :MLOAD(expFp12BN254_c22_y) + 4130369998871020954078407548456754295747138847271917082666014536095464174364n :MLOAD(expFp12BN254_c23_x) + 1685641307692274787278258791922218462843126978449545532205987451962723928051n :MLOAD(expFp12BN254_c23_y) + + 123456789n :MSTORE(expFp12BN254_e) + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expFp12BN254_a11_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expFp12BN254_a11_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(expFp12BN254_a12_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(expFp12BN254_a12_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(expFp12BN254_a13_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(expFp12BN254_a13_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(expFp12BN254_a21_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(expFp12BN254_a21_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(expFp12BN254_a22_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(expFp12BN254_a22_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(expFp12BN254_a23_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 9142802627783465593784550980810782727704583580322919181640530262912683835706n :MLOAD(expFp12BN254_c11_x) + 19736874964269248324216922850918903092400740214902232906683421321363422544357n :MLOAD(expFp12BN254_c11_y) + 9476200663504583903004483007751205251215508180544679553549510605575011163386n :MLOAD(expFp12BN254_c12_x) + 14186756296199578735747739817754651119620054607441288968678361496476074454054n :MLOAD(expFp12BN254_c12_y) + 10811240079738065614702763572796448667972493770153862713781508146531351529275n :MLOAD(expFp12BN254_c13_x) + 6916893165906060112199703736125165648798333038384173213301776553630314914213n :MLOAD(expFp12BN254_c13_y) + 11668055882291754411787223452140593554367736493306160926568664665506066150091n :MLOAD(expFp12BN254_c21_x) + 16585699975551858978680527368328456609554018944982648222232641881312088417111n :MLOAD(expFp12BN254_c21_y) + 9954544605243092097823114175115201680862638136567273250934647601724164887142n :MLOAD(expFp12BN254_c22_x) + 18147343955385037719970517295541563914369052645949029345280746768598576659961n :MLOAD(expFp12BN254_c22_y) + 2894810207171007395751896130534905544170418813733418015224386592699923578372n :MLOAD(expFp12BN254_c23_x) + 18124993142426825678658622810384924838784371007656354124172463271771994460493n :MLOAD(expFp12BN254_c23_y) + + 2n :MSTORE(sparseMulAFp12BN254_a11_x) + 4n :MSTORE(sparseMulAFp12BN254_a11_y) + 0n :MSTORE(sparseMulAFp12BN254_a12_x) + 0n :MSTORE(sparseMulAFp12BN254_a12_y) + 0n :MSTORE(sparseMulAFp12BN254_a13_x) + 5n :MSTORE(sparseMulAFp12BN254_a13_y) + 5n :MSTORE(sparseMulAFp12BN254_a21_x) + 10n :MSTORE(sparseMulAFp12BN254_a21_y) + 20n :MSTORE(sparseMulAFp12BN254_a22_x) + 30n :MSTORE(sparseMulAFp12BN254_a22_y) + 7n :MSTORE(sparseMulAFp12BN254_a23_x) + 69n :MSTORE(sparseMulAFp12BN254_a23_y) + 7n :MSTORE(sparseMulAFp12BN254_b12_x) + 6n :MSTORE(sparseMulAFp12BN254_b12_y) + 7n :MSTORE(sparseMulAFp12BN254_b22_x) + 83n :MSTORE(sparseMulAFp12BN254_b22_y) + 2n :MSTORE(sparseMulAFp12BN254_b23_x) + 29n :MSTORE(sparseMulAFp12BN254_b23_y) + :CALL(sparseMulAFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226182573n :MLOAD(sparseMulAFp12BN254_c11_x) + 15970n :MLOAD(sparseMulAFp12BN254_c11_y) + 21888242871839275222246405745257275088696311157297823662689037894645226148297n :MLOAD(sparseMulAFp12BN254_c12_x) + 8868n :MLOAD(sparseMulAFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226189564n :MLOAD(sparseMulAFp12BN254_c13_x) + 1567n :MLOAD(sparseMulAFp12BN254_c13_y) + 21888242871839275222246405745257275088696311157297823662689037894645226201003n :MLOAD(sparseMulAFp12BN254_c21_x) + 4260n :MLOAD(sparseMulAFp12BN254_c21_y) + 21888242871839275222246405745257275088696311157297823662689037894645226206925n :MLOAD(sparseMulAFp12BN254_c22_x) + 239n :MLOAD(sparseMulAFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208431n :MLOAD(sparseMulAFp12BN254_c23_x) + 396n :MLOAD(sparseMulAFp12BN254_c23_y) + + 2n :MSTORE(sparseMulBFp12BN254_a11_x) + 4n :MSTORE(sparseMulBFp12BN254_a11_y) + 0n :MSTORE(sparseMulBFp12BN254_a12_x) + 0n :MSTORE(sparseMulBFp12BN254_a12_y) + 0n :MSTORE(sparseMulBFp12BN254_a13_x) + 5n :MSTORE(sparseMulBFp12BN254_a13_y) + 5n :MSTORE(sparseMulBFp12BN254_a21_x) + 10n :MSTORE(sparseMulBFp12BN254_a21_y) + 20n :MSTORE(sparseMulBFp12BN254_a22_x) + 30n :MSTORE(sparseMulBFp12BN254_a22_y) + 7n :MSTORE(sparseMulBFp12BN254_a23_x) + 69n :MSTORE(sparseMulBFp12BN254_a23_y) + 7n :MSTORE(sparseMulBFp12BN254_b11_x) + 6n :MSTORE(sparseMulBFp12BN254_b11_y) + 7n :MSTORE(sparseMulBFp12BN254_b13_x) + 83n :MSTORE(sparseMulBFp12BN254_b13_y) + 2n :MSTORE(sparseMulBFp12BN254_b22_x) + 29n :MSTORE(sparseMulBFp12BN254_b22_y) + :CALL(sparseMulBFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226200463n :MLOAD(sparseMulBFp12BN254_c11_x) + 4970n :MLOAD(sparseMulBFp12BN254_c11_y) + 21888242871839275222246405745257275088696311157297823662689037894645226186589n :MLOAD(sparseMulBFp12BN254_c12_x) + 982n :MLOAD(sparseMulBFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207955n :MLOAD(sparseMulBFp12BN254_c13_x) + 394n :MLOAD(sparseMulBFp12BN254_c13_y) + 21888242871839275222246405745257275088696311157297823662689037894645226184223n :MLOAD(sparseMulBFp12BN254_c21_x) + 14525n :MLOAD(sparseMulBFp12BN254_c21_y) + 21888242871839275222246405745257275088696311157297823662689037894645226156265n :MLOAD(sparseMulBFp12BN254_c22_x) + 4294n :MLOAD(sparseMulBFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207423n :MLOAD(sparseMulBFp12BN254_c23_x) + 1010n :MLOAD(sparseMulBFp12BN254_c23_y) + + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" + +INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/squareFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/inverseFp6BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/mulFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/squareFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/inverseFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frobFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frob2Fp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frob3Fp12BN254.zkasm" + +INCLUDE "../main/pairings/unused/addFp12BN254.zkasm" +INCLUDE "../main/pairings/unused/subFp12BN254.zkasm" +INCLUDE "../main/pairings/unused/expFp12BN254.zkasm" diff --git a/test/testFp2ArithBN254.zkasm b/test/testFp2ArithBN254.zkasm new file mode 100644 index 00000000..234f6863 --- /dev/null +++ b/test/testFp2ArithBN254.zkasm @@ -0,0 +1,138 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + 1n => A + 2n => B + 3n => C + 4n => D + :CALL(addFp2BN254) + E => A + 4n => B :ASSERT + C => A + 6n => B :ASSERT + + 1n => A + 4n => B + 3n => C + 2n => D + :CALL(subFp2BN254) + E => A + 21888242871839275222246405745257275088696311157297823662689037894645226208581n => B :ASSERT + C => A + 2n => B :ASSERT + + 1n => A + 2n => B + :CALL(invFp2BN254) + C => A + 13132945723103565133347843447154365053217786694378694197613422736787135725150n => B :ASSERT + D => A + 17510594297471420177797124596205820070957048925838258930151230315716180966866n => B :ASSERT + + 1n => A + 4n => B + :CALL(invFp2BN254) + C => A + 5150174793373947111116801351825241197340308507599487920632714798740053225549n => B :ASSERT + D => A + 1287543698343486777779200337956310299335077126899871980158178699685013306387n => B :ASSERT + + 1n => A + 4n => B + :CALL(squareFp2BN254) + E => A + 21888242871839275222246405745257275088696311157297823662689037894645226208568n => B :ASSERT + C => A + 8n => B :ASSERT + + 3n => A + 6n => C + 4n => D + :CALL(escalarMulFp2BN254) + E => A + 18n => B :ASSERT + C => A + 12n => B :ASSERT + + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" \ No newline at end of file diff --git a/test/testFp4ArithBN254.zkasm b/test/testFp4ArithBN254.zkasm new file mode 100644 index 00000000..0bfa89fb --- /dev/null +++ b/test/testFp4ArithBN254.zkasm @@ -0,0 +1,128 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n + +VAR GLOBAL test + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + + 10n :MSTORE(squareFp4BN254_a1_x) + 2n :MSTORE(squareFp4BN254_a1_y) + 5n :MSTORE(squareFp4BN254_a2_x) + 13n :MSTORE(squareFp4BN254_a2_y) + :CALL(squareFp4BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226207253n :MLOAD(squareFp4BN254_c1_x) + 1066n :MLOAD(squareFp4BN254_c1_y) + 48n :MLOAD(squareFp4BN254_c2_x) + 280n :MLOAD(squareFp4BN254_c2_y) + + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(squareFp4BN254_a1_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(squareFp4BN254_a1_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(squareFp4BN254_a2_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(squareFp4BN254_a2_y) + :CALL(squareFp4BN254) + 15642230407184709854191402253941510745542675973646512616778035989040585383674n :MLOAD(squareFp4BN254_c1_x) + 10571263136441780241186417424383296989551244467442137323566769601209939419494n :MLOAD(squareFp4BN254_c1_y) + 6170062994267544397251278503016502296650869661919757709986684938219961904903n :MLOAD(squareFp4BN254_c2_x) + 12649805430863841208195335781539094665986469361747095927044787835518047599036n :MLOAD(squareFp4BN254_c2_y) + + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(squareFp4BN254_a1_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(squareFp4BN254_a1_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(squareFp4BN254_a2_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(squareFp4BN254_a2_y) + :CALL(squareFp4BN254) + 16581870619415451126551726594735526085487022283882461718257601048476775174962n :MLOAD(squareFp4BN254_c1_x) + 17425425191459276292844278407733970229852884109311293307835712217611024800631n :MLOAD(squareFp4BN254_c1_y) + 8575705441614264531578658232489896441903287755517533490443707322133595575350n :MLOAD(squareFp4BN254_c2_x) + 1420704269848014824822507372800732975177532865526459851528139384475759777251n :MLOAD(squareFp4BN254_c2_y) + + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(squareFp4BN254_a1_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(squareFp4BN254_a1_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(squareFp4BN254_a2_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(squareFp4BN254_a2_y) + :CALL(squareFp4BN254) + 21619634434169277903921567747458615807087054226321025796441846170083311843089n :MLOAD(squareFp4BN254_c1_x) + 11114801799445547818360302932473536671091998531326283968259951405183921806320n :MLOAD(squareFp4BN254_c1_y) + 13146343736154811194795223124891192023354979304499035796722737687445144937601n :MLOAD(squareFp4BN254_c2_x) + 4599958258989867272310306821691486925189277480266178822728743054647870795549n :MLOAD(squareFp4BN254_c2_y) + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" + +INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" \ No newline at end of file diff --git a/test/testFp6ArithBN254.zkasm b/test/testFp6ArithBN254.zkasm new file mode 100644 index 00000000..bbd985ce --- /dev/null +++ b/test/testFp6ArithBN254.zkasm @@ -0,0 +1,238 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n + +VAR GLOBAL test + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + + 10n :MSTORE(addFp6BN254_a1_x) + 2n :MSTORE(addFp6BN254_a1_y) + 5n :MSTORE(addFp6BN254_a2_x) + 13n :MSTORE(addFp6BN254_a2_y) + 7n :MSTORE(addFp6BN254_a3_x) + 5n :MSTORE(addFp6BN254_a3_y) + 9n :MSTORE(addFp6BN254_b1_x) + 1n :MSTORE(addFp6BN254_b1_y) + 1n :MSTORE(addFp6BN254_b2_x) + 2n :MSTORE(addFp6BN254_b2_y) + 14n :MSTORE(addFp6BN254_b3_x) + 3n :MSTORE(addFp6BN254_b3_y) + :CALL(addFp6BN254) + 19n :MLOAD(addFp6BN254_c1_x) + 3n :MLOAD(addFp6BN254_c1_y) + 6n :MLOAD(addFp6BN254_c2_x) + 15n :MLOAD(addFp6BN254_c2_y) + 21n :MLOAD(addFp6BN254_c3_x) + 8n :MLOAD(addFp6BN254_c3_y) + + + 10n :MSTORE(subFp6BN254_a1_x) + 2n :MSTORE(subFp6BN254_a1_y) + 5n :MSTORE(subFp6BN254_a2_x) + 13n :MSTORE(subFp6BN254_a2_y) + 7n :MSTORE(subFp6BN254_a3_x) + 5n :MSTORE(subFp6BN254_a3_y) + 9n :MSTORE(subFp6BN254_b1_x) + 1n :MSTORE(subFp6BN254_b1_y) + 1n :MSTORE(subFp6BN254_b2_x) + 2n :MSTORE(subFp6BN254_b2_y) + 14n :MSTORE(subFp6BN254_b3_x) + 3n :MSTORE(subFp6BN254_b3_y) + :CALL(subFp6BN254) + 1n :MLOAD(subFp6BN254_c1_x) + 1n :MLOAD(subFp6BN254_c1_y) + 4n :MLOAD(subFp6BN254_c2_x) + 11n :MLOAD(subFp6BN254_c2_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208576n :MLOAD(subFp6BN254_c3_x) + 2n :MLOAD(subFp6BN254_c3_y) + + 10n :MSTORE(mulFp6BN254_a1_x) + 2n :MSTORE(mulFp6BN254_a1_y) + 5n :MSTORE(mulFp6BN254_a2_x) + 13n :MSTORE(mulFp6BN254_a2_y) + 7n :MSTORE(mulFp6BN254_a3_x) + 5n :MSTORE(mulFp6BN254_a3_y) + 9n :MSTORE(mulFp6BN254_b1_x) + 1n :MSTORE(mulFp6BN254_b1_y) + 1n :MSTORE(mulFp6BN254_b2_x) + 2n :MSTORE(mulFp6BN254_b2_y) + 14n :MSTORE(mulFp6BN254_b3_x) + 2n :MSTORE(mulFp6BN254_b3_y) + :CALL(mulFp6BN254) + 246n :MLOAD(mulFp6BN254_c1_x) + 1968n :MLOAD(mulFp6BN254_c1_y) + 746n :MLOAD(mulFp6BN254_c2_x) + 988n :MLOAD(mulFp6BN254_c2_y) + 173n :MLOAD(mulFp6BN254_c3_x) + 123n :MLOAD(mulFp6BN254_c3_y) + + 10n :MSTORE(squareFp6BN254_a1_x) + 2n :MSTORE(squareFp6BN254_a1_y) + 5n :MSTORE(squareFp6BN254_a2_x) + 13n :MSTORE(squareFp6BN254_a2_y) + 7n :MSTORE(squareFp6BN254_a3_x) + 5n :MSTORE(squareFp6BN254_a3_y) + :CALL(squareFp6BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226207907n :MLOAD(squareFp6BN254_c1_x) + 2068n :MLOAD(squareFp6BN254_c1_y) + 194n :MLOAD(squareFp6BN254_c2_x) + 934n :MLOAD(squareFp6BN254_c2_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208559n :MLOAD(squareFp6BN254_c3_x) + 258n :MLOAD(squareFp6BN254_c3_y) + + 10n :MSTORE(inverseFp6BN254_a1_x) + 2n :MSTORE(inverseFp6BN254_a1_y) + 5n :MSTORE(inverseFp6BN254_a2_x) + 13n :MSTORE(inverseFp6BN254_a2_y) + 7n :MSTORE(inverseFp6BN254_a3_x) + 5n :MSTORE(inverseFp6BN254_a3_y) + :CALL(inverseFp6BN254) + 5783650677754332851980206846879135451516056759867773021970105892178521520613n :MLOAD(inverseFp6BN254_c1_x) + 18013759458838322471361728283975517938597408816356047328991338914305007310576n :MLOAD(inverseFp6BN254_c1_y) + 18110874882414180653560035658613063208901925857749522062575191314371766555250n :MLOAD(inverseFp6BN254_c2_x) + 17807280852945820517699726487578389146070561376290295053174148308721316478672n :MLOAD(inverseFp6BN254_c2_y) + 14149695447230733832672344969363233706238986964811686150151922078523920094032n :MLOAD(inverseFp6BN254_c3_x) + 8319081930844559069109603696113388970848243877139140810016204850690606105497n :MLOAD(inverseFp6BN254_c3_y) + + 10n :MSTORE(sparseMulAFp6BN254_a1_x) + 2n :MSTORE(sparseMulAFp6BN254_a1_y) + 5n :MSTORE(sparseMulAFp6BN254_a2_x) + 13n :MSTORE(sparseMulAFp6BN254_a2_y) + 7n :MSTORE(sparseMulAFp6BN254_a3_x) + 5n :MSTORE(sparseMulAFp6BN254_a3_y) + 5n :MSTORE(sparseMulAFp6BN254_b2_x) + 78n :MSTORE(sparseMulAFp6BN254_b2_y) + :CALL(sparseMulAFp6BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226204817n :MLOAD(sparseMulAFp6BN254_c1_x) + 4784n :MLOAD(sparseMulAFp6BN254_c1_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208477n :MLOAD(sparseMulAFp6BN254_c2_x) + 790n :MLOAD(sparseMulAFp6BN254_c2_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207594n :MLOAD(sparseMulAFp6BN254_c3_x) + 455n :MLOAD(sparseMulAFp6BN254_c3_y) + + 10n :MSTORE(sparseMulBFp6BN254_a1_x) + 2n :MSTORE(sparseMulBFp6BN254_a1_y) + 5n :MSTORE(sparseMulBFp6BN254_a2_x) + 13n :MSTORE(sparseMulBFp6BN254_a2_y) + 7n :MSTORE(sparseMulBFp6BN254_a3_x) + 5n :MSTORE(sparseMulBFp6BN254_a3_y) + 3n :MSTORE(sparseMulBFp6BN254_b2_x) + 100n :MSTORE(sparseMulBFp6BN254_b2_y) + 17n :MSTORE(sparseMulBFp6BN254_b3_x) + 8n :MSTORE(sparseMulBFp6BN254_b3_y) + :CALL(sparseMulBFp6BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226203125n :MLOAD(sparseMulBFp6BN254_c1_x) + 8286n :MLOAD(sparseMulBFp6BN254_c1_y) + 400n :MLOAD(sparseMulBFp6BN254_c2_x) + 2354n :MLOAD(sparseMulBFp6BN254_c2_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207452n:MLOAD(sparseMulBFp6BN254_c3_x) + 653n :MLOAD(sparseMulBFp6BN254_c3_y) + + 10n :MSTORE(sparseMulCFp6BN254_a1_x) + 2n :MSTORE(sparseMulCFp6BN254_a1_y) + 5n :MSTORE(sparseMulCFp6BN254_a2_x) + 13n :MSTORE(sparseMulCFp6BN254_a2_y) + 7n :MSTORE(sparseMulCFp6BN254_a3_x) + 5n :MSTORE(sparseMulCFp6BN254_a3_y) + 3n :MSTORE(sparseMulCFp6BN254_b1_x) + 100n :MSTORE(sparseMulCFp6BN254_b1_y) + 17n :MSTORE(sparseMulCFp6BN254_b3_x) + 8n :MSTORE(sparseMulCFp6BN254_b3_y) + :CALL(sparseMulCFp6BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226207981n :MLOAD(sparseMulCFp6BN254_c1_x) + 3336n :MLOAD(sparseMulCFp6BN254_c1_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207868n :MLOAD(sparseMulCFp6BN254_c2_x) + 1887n :MLOAD(sparseMulCFp6BN254_c2_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208258n :MLOAD(sparseMulCFp6BN254_c3_x) + 829n :MLOAD(sparseMulCFp6BN254_c3_y) + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" + +INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/squareFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/inverseFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm" \ No newline at end of file diff --git a/test/testFpArithBN254.zkasm b/test/testFpArithBN254.zkasm new file mode 100644 index 00000000..0a8857e3 --- /dev/null +++ b/test/testFpArithBN254.zkasm @@ -0,0 +1,145 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + + 1n => A + 3n => C + :CALL(addFpBN254) + C => A + 4n => B :ASSERT + + 2n => A + 3n => C + :CALL(subFpBN254) + C => A + 21888242871839275222246405745257275088696311157297823662689037894645226208582n => B :ASSERT + + ${const.BN254_P - 2} => A + :CALL(squareFpBN254) + B => A + 4n => B :ASSERT + + 0n => A + :CALL(invFpBN254) + B => A + 0n => B :ASSERT + + %BN254_P + %BN254_P => A + :CALL(invFpBN254) + 0n => B :ASSERT + + %BN254_P + %BN254_P + %BN254_P => A + :CALL(invFpBN254) + 0n => B :ASSERT + + %BN254_P + %BN254_P + %BN254_P + %BN254_P => A + :CALL(invFpBN254) + 0n => B :ASSERT + + %BN254_P + %BN254_P + %BN254_P + %BN254_P + %BN254_P => A + :CALL(invFpBN254) + 0n => B :ASSERT + + 0n => A + :CALL(reduceFpBN254) + 0n => B :ASSERT + + %BN254_P => A + :CALL(reduceFpBN254) + 0n => B :ASSERT + + %BN254_P + 1n => A + :CALL(reduceFpBN254) + 1n => B :ASSERT + + %BN254_P + 21888242871839275222246405745257275088696311157297823662689037894645226208582n => A + :CALL(reduceFpBN254) + 21888242871839275222246405745257275088696311157297823662689037894645226208582n => B :ASSERT + + 43776485743678550444492811490514550177392622314595647325378075789290452417166n => A + :CALL(reduceFpBN254) + 0n => B :ASSERT + + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/subFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/squareFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/invFpBN254.zkasm" \ No newline at end of file diff --git a/test/testFrArithBN254.zkasm b/test/testFrArithBN254.zkasm new file mode 100644 index 00000000..e06aebb6 --- /dev/null +++ b/test/testFrArithBN254.zkasm @@ -0,0 +1,113 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +INCLUDE "../main/pairings/constants.zkasm" + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + + 3n => B + :CALL(reduceFrBN254) + C => A + 3n => B :ASSERT + + %BN254_R => B + :CALL(reduceFrBN254) + C => A + 0n => B :ASSERT + + 21888242871839275222246405745257275088548364400416034343698204186575808495618n => B + :CALL(reduceFrBN254) + C => A + 1n => B :ASSERT + + %BN254_P => B + :CALL(reduceFrBN254) + C => A + %BN254_SIX_TIMES_X_SQ => B :ASSERT + + 21888242871839275222246405745257275088696311157297823662689037894645226208584n => B + :CALL(reduceFrBN254) + C => A + 147946756881789318990833708069417712967n => B :ASSERT + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n => B + :CALL(reduceFrBN254) + C => A + 6350874878119819312338956282401532410528162663560392320966563075034087161850n => B :ASSERT + + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + + +INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" \ No newline at end of file diff --git a/test/testHalfPairingBN254.zkasm b/test/testHalfPairingBN254.zkasm new file mode 100644 index 00000000..b3971e4b --- /dev/null +++ b/test/testHalfPairingBN254.zkasm @@ -0,0 +1,132 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(halfPairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(halfPairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(halfPairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(halfPairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(halfPairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + 13640254227245024655838601068231183157721360561601028708811475275217122101072n :MLOAD(halfPairingBN254_f11_x) + 19308417300657558492615098636528930118171456086181403615599560648373004008445n :MLOAD(halfPairingBN254_f11_y) + 11600807028088028070223911119334614254604789223029238428546002219857166268982n :MLOAD(halfPairingBN254_f12_x) + 4879406373235938927297467572708988980645988929154072556290202741257062565094n :MLOAD(halfPairingBN254_f12_y) + 4171685090913488783052266386653991584736187693807813444268445186114207424938n :MLOAD(halfPairingBN254_f13_x) + 1277573873092817905392452044933753278511826457458184982228668801202320403016n :MLOAD(halfPairingBN254_f13_y) + 14431703268682647902296102635071887590346322924866425403256046961671041030534n :MLOAD(halfPairingBN254_f21_x) + 11898392435919290118390574221795784387718317590754683868792519816848089304255n :MLOAD(halfPairingBN254_f21_y) + 583787015380908422861158991038392109634638768690762169717364137330743074526n :MLOAD(halfPairingBN254_f22_x) + 13126870183170761631152540488140870675640427576483291663794972909787720839738n :MLOAD(halfPairingBN254_f22_y) + 6457767870676104874999362178075129079810053093666926870765167604207462152679n :MLOAD(halfPairingBN254_f23_x) + 12911511138445339632082563502636262379527290965988664015632615336010308825090n :MLOAD(halfPairingBN254_f23_y) + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/constants.zkasm" + +INCLUDE "../main/pairings/halfPairingBN254.zkasm" + +INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" + +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" + +INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/squareFp12BN254.zkasm" + +INCLUDE "../main/pairings/BN254/addPointBN254.zkasm" +INCLUDE "../main/pairings/BN254/escalarMulBN254.zkasm" +INCLUDE "../main/pairings/BN254/lineSamePointsBN254.zkasm" +INCLUDE "../main/pairings/BN254/lineDiffPointsBN254.zkasm" + +INCLUDE "../main/pairings/millerLoopBN254.zkasm" +INCLUDE "../main/pairings/loopLengthBN254.zkasm" \ No newline at end of file diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm new file mode 100644 index 00000000..99d6efdd --- /dev/null +++ b/test/testModExp.zkasm @@ -0,0 +1,452 @@ +; constants needed by executor C++ +INCLUDE "../main/constants.zkasm" + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + ; EDGE CASES + ; --------------------------------------------------------------------------------------------- + ; 1] B == 0, E != 0, M != 0 should return 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 3n :MSTORE(modexp_E) + 4n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 1 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 2 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 0n :MSTORE(modexp_E) + 1 => E + 1n :MSTORE(modexp_E + E) + 0n :MSTORE(modexp_M) + 1 => E + 1n :MSTORE(modexp_M + E) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 2] B != 0, E == 0, M != 0 should return 1 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 2n :MSTORE(modexp_B) + 0n :MSTORE(modexp_E) + 4n :MSTORE(modexp_M) + :CALL(modexp) + + 1n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 2 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 2 :MSTORE(modexp_Mlen) + + 2n :MSTORE(modexp_B) + 1 => E + 4n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + 1 => E + 1n :MSTORE(modexp_M + E) + :CALL(modexp) + + 1n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 3] B != 0, E != 0, M == 0 should return 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 2n :MSTORE(modexp_B) + 1n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 2 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 2n :MSTORE(modexp_B) + 1 => E + 4n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_E) + 1 => E + 4n :MSTORE(modexp_E + E) + 0n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 4] B != 0, E != 0, M == 1 should return 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 2n :MSTORE(modexp_B) + 1n :MSTORE(modexp_E) + 1n :MSTORE(modexp_M) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 2 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 2n :MSTORE(modexp_B) + 1 => E + 4n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_E) + 1 => E + 4n :MSTORE(modexp_E + E) + 1n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 5] B == 0, E == 0, M != 0 should return 0^0 = 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 0n :MSTORE(modexp_E) + 4n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 2 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 0n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + 1 => E + 1n :MSTORE(modexp_M + E) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 6] B == 0, E != 0, M == 0 should return 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 4n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 1 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 0n :MSTORE(modexp_E) + 1 => E + 1n :MSTORE(modexp_E + E) + 0n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 7] B != 0, E == 0, M == 0 should return 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 1n :MSTORE(modexp_B) + 0n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 2 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 1 => E + 1n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 8] B == 0, E == 0, M == 0 should return 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 0n :MSTORE(modexp_B) + 0n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + :CALL(modexp) + + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + ; --------------------------------------------------------------------------------------------- + + ; 256 BITS EXPONENT TESTS + ; --------------------------------------------------------------------------------------------- + ; 1] B = [100n, 2831023n, 0n, 73916234139162n], E = [115792089237316195423570985008687907853269984665640564039457584007913129639935n], M = [0n, 0n, 8238129386n, 23102318237n] + ; Hamming weight of E is 256 + 4 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 4 :MSTORE(modexp_Mlen) + + 100n :MSTORE(modexp_B) + 1 => E + 2831023n :MSTORE(modexp_B + E) + 2 => E + 0n :MSTORE(modexp_B + E) + 3 => E + 73916234139162n :MSTORE(modexp_B + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + 1 => E + 0n :MSTORE(modexp_M + E) + 2 => E + 8238129386n :MSTORE(modexp_M + E) + 3 => E + 23102318237n :MSTORE(modexp_M + E) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 => E + 0n :MLOAD(modexp_out + E) + 2 => E + 25636070175539943947777314844209202718110211581133019863886488575898865601868n :MLOAD(modexp_out + E) + 3 => E + 4679155145n :MLOAD(modexp_out + E) + 4 :MLOAD(modexp_outlen) + + ; 2] B = [100n, 2831023n, 0n, 73916234139162n, 100n, 2831023n, 0n, 73916234139162n,100n, 2831023n, 0n, 73916234139162n], E = [903741926349715234612309461283471234n], M = [0n, 0n, 8238129386n, 23102318237n, 1892397612351n, 7246598123051n, 8238129386n, 1264591241237897123126n] + ; Hamming weight of E is 120 + 12 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 8 :MSTORE(modexp_Mlen) + + 100n :MSTORE(modexp_B) + 1 => E + 2831023n :MSTORE(modexp_B + E) + 2 => E + 0n :MSTORE(modexp_B + E) + 3 => E + 73916234139162n :MSTORE(modexp_B + E) + 4 => E + 100n :MSTORE(modexp_B + E) + 5 => E + 2831023n :MSTORE(modexp_B + E) + 6 => E + 0n :MSTORE(modexp_B + E) + 7 => E + 73916234139162n :MSTORE(modexp_B + E) + 8 => E + 100n :MSTORE(modexp_B + E) + 9 => E + 2831023n :MSTORE(modexp_B + E) + 10 => E + 0n :MSTORE(modexp_B + E) + 11 => E + 73916234139162n :MSTORE(modexp_B + E) + 903741926349715234612309461283471234n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + 1 => E + 0n :MSTORE(modexp_M + E) + 2 => E + 8238129386n :MSTORE(modexp_M + E) + 3 => E + 23102318237n :MSTORE(modexp_M + E) + 4 => E + 1892397612351n :MSTORE(modexp_M + E) + 5 => E + 7246598123051n :MSTORE(modexp_M + E) + 6 => E + 8238129386n :MSTORE(modexp_M + E) + 7 => E + 1264591241237897123126n :MSTORE(modexp_M + E) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 => E + 0n :MLOAD(modexp_out + E) + 2 => E + 14984469305990977542353827078899382678368215018946198341845725551977623627446n :MLOAD(modexp_out + E) + 3 => E + 68986200907052834988812862957862042564780541926701277492865197684364096948359n :MLOAD(modexp_out + E) + 4 => E + 19960171666179366961875030436152164148711578520678689062449823687317995303656n :MLOAD(modexp_out + E) + 5 => E + 10163909190618518832451417682132582498490814809943760852308996448668923869413n :MLOAD(modexp_out + E) + 6 => E + 29735535392706191114764336807325502135962613879333248096358552087717155148899n :MLOAD(modexp_out + E) + 7 => E + 511131288598502431475n :MLOAD(modexp_out + E) + 8 :MLOAD(modexp_outlen) + ; --------------------------------------------------------------------------------------------- + + ; 512 BITS EXPONENT TESTS + ; --------------------------------------------------------------------------------------------- + ; 1] B = [2n, 1n, 1n, 1n], E = [3n, 5n], M = [4n, 6n, 7n] + ; Hamming weight of E is 4 + 4 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 3 :MSTORE(modexp_Mlen) + + 2n :MSTORE(modexp_B) + 1 => E + 1n :MSTORE(modexp_B + E) + 2 => E + 1n :MSTORE(modexp_B + E) + 3 => E + 1n :MSTORE(modexp_B + E) + 3n :MSTORE(modexp_E) + 1 => E + 5n :MSTORE(modexp_E + E) + 4n :MSTORE(modexp_M) + 1 => E + 6n :MSTORE(modexp_M + E) + 2 => E + 7n :MSTORE(modexp_M + E) + :CALL(modexp) + 16799222018138169590613227618843456355247327644003751420511040302320945803948n :MLOAD(modexp_out) + 1 => E + 67226185770814561827024093064262870237432709513661454124124794094744315370418n :MLOAD(modexp_out + E) + 2 => E + 1n :MLOAD(modexp_out + E) + 3 :MLOAD(modexp_outlen) + + ; 2] B = [7n], E = [110n], M = [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] + ; Hamming weight of E is 5 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 2 :MSTORE(modexp_Mlen) + + 7n :MSTORE(modexp_B) + 110n :MSTORE(modexp_E) + 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(modexp_M) + 1 => E + 17n :MSTORE(modexp_M + E) + :CALL(modexp) + 81730215206688390341255830729934766338330049967253209305087427132484271882414n :MLOAD(modexp_out) + 1 => E + 13n :MLOAD(modexp_out + E) + 2 :MLOAD(modexp_outlen) + ; --------------------------------------------------------------------------------------------- + + ; 768 BITS EXPONENT TESTS + ; --------------------------------------------------------------------------------------------- + ; --------------------------------------------------------------------------------------------- + + ; 1024 BITS EXPONENT TESTS + ; --------------------------------------------------------------------------------------------- + ; --------------------------------------------------------------------------------------------- + +outOfCountersArith: +outOfCountersBinary: +outOfCountersStep: + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/modexp/array_lib/utils/array_trim.zkasm" +INCLUDE "../main/modexp/array_lib/utils/array_compare.zkasm" + +INCLUDE "../main/modexp/array_lib/array_add_AGTB.zkasm" +INCLUDE "../main/modexp/array_lib/array_add_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_mul.zkasm" +INCLUDE "../main/modexp/array_lib/array_square.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" + +INCLUDE "../main/modexp/modexp.zkasm" \ No newline at end of file diff --git a/test/testPairingBN254.zkasm b/test/testPairingBN254.zkasm new file mode 100644 index 00000000..10e78a38 --- /dev/null +++ b/test/testPairingBN254.zkasm @@ -0,0 +1,442 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + ; Generators P,Q + + ; 1] Degenerate tests: e(0,Q) = 1 and e(P,0) = 1 + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 1n :MLOAD(pairingBN254_f11_x) + 0n :MLOAD(pairingBN254_f11_y) + 0n :MLOAD(pairingBN254_f12_x) + 0n :MLOAD(pairingBN254_f12_y) + 0n :MLOAD(pairingBN254_f13_x) + 0n :MLOAD(pairingBN254_f13_y) + 0n :MLOAD(pairingBN254_f21_x) + 0n :MLOAD(pairingBN254_f21_y) + 0n :MLOAD(pairingBN254_f22_x) + 0n :MLOAD(pairingBN254_f22_y) + 0n :MLOAD(pairingBN254_f23_x) + 0n :MLOAD(pairingBN254_f23_y) + + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) + 0n :MSTORE(pairingBN254_Q_x1) + 0n :MSTORE(pairingBN254_Q_x2) + 0n :MSTORE(pairingBN254_Q_y1) + 0n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 1n :MLOAD(pairingBN254_f11_x) + 0n :MLOAD(pairingBN254_f11_y) + 0n :MLOAD(pairingBN254_f12_x) + 0n :MLOAD(pairingBN254_f12_y) + 0n :MLOAD(pairingBN254_f13_x) + 0n :MLOAD(pairingBN254_f13_y) + 0n :MLOAD(pairingBN254_f21_x) + 0n :MLOAD(pairingBN254_f21_y) + 0n :MLOAD(pairingBN254_f22_x) + 0n :MLOAD(pairingBN254_f22_y) + 0n :MLOAD(pairingBN254_f23_x) + 0n :MLOAD(pairingBN254_f23_y) + + ; 2] P not in range + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 1 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 2 => A + 1 :EQ + + ; 3] Q not in range + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 3 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 4 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 5 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 6 => A + 1 :EQ + + ; 4] P not in G1 + 1n :MSTORE(pairingBN254_P_x) + 1n :MSTORE(pairingBN254_P_y) + 0n :MSTORE(pairingBN254_Q_x1) + 0n :MSTORE(pairingBN254_Q_x2) + 0n :MSTORE(pairingBN254_Q_y1) + 0n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 7 => A + 1 :EQ + + ; 5] Q not in G2 + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 13952973379259391431794065814946995996741015657664522404741834284791195202656n :MSTORE(pairingBN254_Q_x1) + 10904417650644905372723866879625669404817699819926286815323845522270190436451n :MSTORE(pairingBN254_Q_x2) + 12292403207927938194042684085166933223459250332097452603928615449631462314854n :MSTORE(pairingBN254_Q_y1) + 3535501093699632689489376651381121898720279562088698464643486166587401099479n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 8 => A + 1 :EQ + + ; 6] Bilinearity test: e(2P,12Q) = e(P,12Q)² = e(2P,Q)¹² = e(P,Q)²⁴ = e(12P,2Q) + ; e(2P,12Q) + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(pairingBN254_f11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(pairingBN254_f11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(pairingBN254_f12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(pairingBN254_f12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(pairingBN254_f13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(pairingBN254_f13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(pairingBN254_f21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(pairingBN254_f21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(pairingBN254_f22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(pairingBN254_f22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(pairingBN254_f23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(pairingBN254_f23_y) + + ; e(P,12Q) + 1n :MSTORE(pairingBN254_P_x) + 2n :MSTORE(pairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 2n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + + ; e(2P,Q) + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(pairingBN254_Q_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 12n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + + ; e(P,Q) + 1n :MSTORE(pairingBN254_P_x) + 2n :MSTORE(pairingBN254_P_y) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(pairingBN254_Q_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 24n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + + ; e(12P,2Q) + 17108685722251241369314020928988529881027530433467445791267465866135602972753n :MSTORE(pairingBN254_P_x) + 20666112440056908034039013737427066139426903072479162670940363761207457724060n :MSTORE(pairingBN254_P_y) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(pairingBN254_Q_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(pairingBN254_Q_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(pairingBN254_Q_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + +INCLUDE "../main/pairings/constants.zkasm" + +INCLUDE "../main/pairings/pairingBN254.zkasm" + +INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" + +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" + +INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" + +INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/squareFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/inverseFp6BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/mulFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/squareFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/inverseFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frobFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frob2Fp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/frob3Fp12BN254.zkasm" + +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm" +INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm" + +INCLUDE "../main/pairings/BN254/addPointBN254.zkasm" +INCLUDE "../main/pairings/BN254/escalarMulBN254.zkasm" +INCLUDE "../main/pairings/BN254/lineSamePointsBN254.zkasm" +INCLUDE "../main/pairings/BN254/lineDiffPointsBN254.zkasm" + +INCLUDE "../main/pairings/millerLoopBN254.zkasm" +INCLUDE "../main/pairings/loopLengthBN254.zkasm" +INCLUDE "../main/pairings/finalExpBN254.zkasm" + +INCLUDE "../main/pairings/utilsTests/expCycloFp12BN254.zkasm" \ No newline at end of file diff --git a/test/testPointArithBN254.zkasm b/test/testPointArithBN254.zkasm new file mode 100644 index 00000000..1f7a2637 --- /dev/null +++ b/test/testPointArithBN254.zkasm @@ -0,0 +1,266 @@ +; constants needed by executor C++ +CONST %N = 2**19 +CONST %MAX_CNT_STEPS_LIMIT = %N +CONST %MAX_CNT_ARITH_LIMIT = %N +CONST %MAX_CNT_BINARY_LIMIT = %N +CONST %MAX_CNT_MEM_ALIGN_LIMIT = %N +CONST %MAX_CNT_KECCAK_F_LIMIT = %N +CONST %MAX_CNT_PADDING_PG_LIMIT = %N +CONST %MAX_CNT_POSEIDON_G_LIMIT = %N + +INCLUDE "../main/pairings/constants.zkasm" + +VAR GLOBAL lastHashKId +VAR GLOBAL lastHashPId + +VAR GLOBAL initial_A +VAR GLOBAL initial_B +VAR GLOBAL initial_C +VAR GLOBAL initial_D +VAR GLOBAL initial_E +VAR GLOBAL initial_CTX +VAR GLOBAL initial_SP +VAR GLOBAL initial_PC +VAR GLOBAL initial_GAS +VAR GLOBAL initial_SR +VAR GLOBAL initial_RR +VAR GLOBAL initial_HASHPOS +VAR GLOBAL initial_RCX + +start: + + STEP => A + 0 :ASSERT + + + A :MSTORE(initial_A) + B :MSTORE(initial_B) + C :MSTORE(initial_C) + D :MSTORE(initial_D) + E :MSTORE(initial_E) + CTX :MSTORE(initial_CTX) + SP :MSTORE(initial_SP) + PC :MSTORE(initial_PC) + GAS :MSTORE(initial_GAS) + SR :MSTORE(initial_SR) + RR :MSTORE(initial_RR) + HASHPOS :MSTORE(initial_HASHPOS) + RCX :MSTORE(initial_RCX) + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, RR, HASHPOS, RCX + + -1 :MSTORE(lastHashKId) + -1 :MSTORE(lastHashPId) + + + ; 1] Point addition + ; 0 + 0 = 0 + 0n :MSTORE(addPointBN254_P1_x1) + 0n :MSTORE(addPointBN254_P1_x2) + 0n :MSTORE(addPointBN254_P1_y1) + 0n :MSTORE(addPointBN254_P1_y2) + 0n :MSTORE(addPointBN254_P2_x1) + 0n :MSTORE(addPointBN254_P2_x2) + 0n :MSTORE(addPointBN254_P2_y1) + 0n :MSTORE(addPointBN254_P2_y2) + :CALL(addPointBN254) + 0n :MLOAD(addPointBN254_P3_x1) + 0n :MLOAD(addPointBN254_P3_x2) + 0n :MLOAD(addPointBN254_P3_y1) + 0n :MLOAD(addPointBN254_P3_y2) + + ; 0 + P2 = P2 + 0n :MSTORE(addPointBN254_P1_x1) + 0n :MSTORE(addPointBN254_P1_x2) + 0n :MSTORE(addPointBN254_P1_y1) + 0n :MSTORE(addPointBN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P2_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P2_y2) + :CALL(addPointBN254) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MLOAD(addPointBN254_P3_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MLOAD(addPointBN254_P3_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MLOAD(addPointBN254_P3_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MLOAD(addPointBN254_P3_y2) + + ; P1 + 0 = P1 + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(addPointBN254_P1_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(addPointBN254_P1_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(addPointBN254_P1_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(addPointBN254_P1_y2) + 0n :MSTORE(addPointBN254_P2_x1) + 0n :MSTORE(addPointBN254_P2_x2) + 0n :MSTORE(addPointBN254_P2_y1) + 0n :MSTORE(addPointBN254_P2_y2) + :CALL(addPointBN254) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MLOAD(addPointBN254_P3_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MLOAD(addPointBN254_P3_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MLOAD(addPointBN254_P3_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MLOAD(addPointBN254_P3_y2) + + ; P1 + (-P1) = 0 + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P1_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P1_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P1_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) + 13392588948715843804641432497768002650278120570034223513918757245338268106653n :MSTORE(addPointBN254_P2_y1) + 17805874995975841540914202342111839520379459829704422454583296818431106115052n :MSTORE(addPointBN254_P2_y2) + :CALL(addPointBN254) + 0n :MLOAD(addPointBN254_P3_x1) + 0n :MLOAD(addPointBN254_P3_x2) + 0n :MLOAD(addPointBN254_P3_y1) + 0n :MLOAD(addPointBN254_P3_y2) + + ; P1 + P1 = 2·P1 + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P1_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P1_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P1_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P2_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P2_y2) + :CALL(addPointBN254) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MLOAD(addPointBN254_P3_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MLOAD(addPointBN254_P3_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MLOAD(addPointBN254_P3_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MLOAD(addPointBN254_P3_y2) + + ; P1 + P2 = P3 + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(addPointBN254_P1_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(addPointBN254_P1_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(addPointBN254_P1_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(addPointBN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P2_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P2_y2) + :CALL(addPointBN254) + 2725019753478801796453339367788033689375851816420509565303521482350756874229n :MLOAD(addPointBN254_P3_x1) + 7273165102799931111715871471550377909735733521218303035754523677688038059653n :MLOAD(addPointBN254_P3_x2) + 2512659008974376214222774206987427162027254181373325676825515531566330959255n :MLOAD(addPointBN254_P3_y1) + 957874124722006818841961785324909313781880061366718538693995380805373202866n :MLOAD(addPointBN254_P3_y2) + + ; 2] Escalar multiplication + 0n :MSTORE(escalarMulBN254_k) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(escalarMulBN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(escalarMulBN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) + :CALL(escalarMulBN254) + 0n :MLOAD(escalarMulBN254_Q_x1) + 0n :MLOAD(escalarMulBN254_Q_x2) + 0n :MLOAD(escalarMulBN254_Q_y1) + 0n :MLOAD(escalarMulBN254_Q_y2) + + %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k) + 0n :MSTORE(escalarMulBN254_P_x1) + 0n :MSTORE(escalarMulBN254_P_x2) + 0n :MSTORE(escalarMulBN254_P_y1) + 0n :MSTORE(escalarMulBN254_P_y2) + :CALL(escalarMulBN254) + 0n :MLOAD(escalarMulBN254_Q_x1) + 0n :MLOAD(escalarMulBN254_Q_x2) + 0n :MLOAD(escalarMulBN254_Q_y1) + 0n :MLOAD(escalarMulBN254_Q_y2) + + %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(escalarMulBN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(escalarMulBN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) + :CALL(escalarMulBN254) + 13824868563399673693405984206252027284526901521624614945388441201916943098448n :MLOAD(escalarMulBN254_Q_x1) + 6070174842523651825461006324987645339257276059765462992338211551285097849152n :MLOAD(escalarMulBN254_Q_x2) + 4224873494559498571787136390356590572898009346319218613936276445484292886657n :MLOAD(escalarMulBN254_Q_y1) + 14979195929948718632567968180703131754953567972706796447883440492471033097811n :MLOAD(escalarMulBN254_Q_y2) + + %BN254_R :MSTORE(escalarMulBN254_k) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(escalarMulBN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(escalarMulBN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) + :CALL(escalarMulBN254) + 0n :MLOAD(escalarMulBN254_Q_x1) + 0n :MLOAD(escalarMulBN254_Q_x2) + 0n :MLOAD(escalarMulBN254_Q_y1) + 0n :MLOAD(escalarMulBN254_Q_y2) + + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(lineSamePointsBN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(lineSamePointsBN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(lineSamePointsBN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(lineSamePointsBN254_P_y2) + 1n :MSTORE(lineSamePointsBN254_Q_x) + 2n :MSTORE(lineSamePointsBN254_Q_y) + :CALL(lineSamePointsBN254) + 5866721355212621053956121605984270769408822799517647453365718615957338215267n :MLOAD(lineSamePointsBN254_l11_x) + 10805765471263851218954508755716868212208493914051915959293621483915454724277n :MLOAD(lineSamePointsBN254_l11_y) + 441787448737107494458538247410558220237964585327985295018200621859384744906n :MLOAD(lineSamePointsBN254_l13_x) + 16376088161625424614405301418083801678984212103591999741784373000936238959085n :MLOAD(lineSamePointsBN254_l13_y) + 12094372820654450448173487244699814664976451191756576932392084702582606199137n :MLOAD(lineSamePointsBN254_l22_x) + 16329471503453734725328813612581742273267405310373604832422964304856480374124n :MLOAD(lineSamePointsBN254_l22_y) + + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(lineDiffPointsBN254_P1_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(lineDiffPointsBN254_P1_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(lineDiffPointsBN254_P1_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(lineDiffPointsBN254_P1_y2) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(lineDiffPointsBN254_P2_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(lineDiffPointsBN254_P2_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(lineDiffPointsBN254_P2_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(lineDiffPointsBN254_P2_y2) + 1n :MSTORE(lineDiffPointsBN254_Q_x) + 2n :MSTORE(lineDiffPointsBN254_Q_y) + :CALL(lineDiffPointsBN254) + 14345297355255362181497444452150170632573334682972773847873355690178269903256n :MLOAD(lineDiffPointsBN254_l12_x) + 6048094043816276132918639274747177880187336235946285989629387201109000140142n :MLOAD(lineDiffPointsBN254_l12_y) + 6355424306145694606947493475832538496819777935726521244993642728797005357180n :MLOAD(lineDiffPointsBN254_l22_x) + 14495749000319008587101889994427132655409931118529976780236175098644084667216n :MLOAD(lineDiffPointsBN254_l22_y) + 4617834131706974237889373560251879390068389218389281828469153443366136187126n :MLOAD(lineDiffPointsBN254_l23_x) + 18535807517613687025007129469892030737201813557688282181535107728189048279364n :MLOAD(lineDiffPointsBN254_l23_y) + + +end: + + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) + +; label finalizeExecution needed by executor C++ +finalizeExecution: + ${beforeLast()} : JMPN(finalizeExecution) + + : JMP(start) +opINVALID: +; label checkAndSaveFrom needed by executor C++ +checkAndSaveFrom: + :JMP(opINVALID) + + +INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/subFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" + +INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" + +INCLUDE "../main/pairings/BN254/addPointBN254.zkasm" +INCLUDE "../main/pairings/BN254/escalarMulBN254.zkasm" +INCLUDE "../main/pairings/BN254/lineSamePointsBN254.zkasm" +INCLUDE "../main/pairings/BN254/lineDiffPointsBN254.zkasm" \ No newline at end of file diff --git a/tools/gen-parallel-tests.js b/tools/gen-parallel-tests.js index edcb8672..3d03aaef 100644 --- a/tools/gen-parallel-tests.js +++ b/tools/gen-parallel-tests.js @@ -10,7 +10,7 @@ const buildPoseidon = require('@0xpolygonhermez/zkevm-commonjs').getPoseidon; const folderPaths = [ '../node_modules/@0xpolygonhermez/zkevm-testvectors/inputs-executor', - '../node_modules/@0xpolygonhermez/zkevm-testvectors/tools/ethereum-tests/GeneralStateTests', + '../node_modules/@0xpolygonhermez/zkevm-testvectors/inputs-executor/ethereum-tests/GeneralStateTests', ]; const fileCachePil = path.join(__dirname, '../node_modules/@0xpolygonhermez/zkevm-proverjs/cache-main-pil.json'); @@ -41,12 +41,13 @@ async function main() { const inputsPath = path.join(__dirname, folder); fs.readdirSync(inputsPath).forEach((file) => { const filePath = path.join(inputsPath, file); - if (file.endsWith('.json')) { + // Remove json lists that are generated with gen inputs script and are not inputs + if (file.endsWith('.json') && !file.includes('testsOOC-list.json') && !file.includes('tests30M-list.json')) { inputs.push(filePath); - } else if (fs.statSync(filePath).isDirectory()) { + } else if (fs.statSync(filePath).isDirectory() && !filePath.includes('tests-OOC')) { fs.readdirSync(filePath).forEach((subFile) => { const subFilePath = path.join(filePath, subFile); - if (subFile.endsWith('.json')) { + if (subFile.endsWith('.json') && !subFile.includes('testsOOC-list.json') && !subFile.includes('tests30M-list.json')) { inputs.push(subFilePath); } }); diff --git a/tools/get-not-used-labels.js b/tools/get-not-used-labels.js new file mode 100644 index 00000000..f582e0b4 --- /dev/null +++ b/tools/get-not-used-labels.js @@ -0,0 +1,31 @@ +const fs = require('fs'); +const rom = require('../build/rom.json'); + +async function main() { + const labelsAddr = Object.values(rom.labels); + const { program } = rom; + for (let i = 0; i < program.length; i++) { + const { jmpAddr, elseAddr } = program[i]; + if (jmpAddr) { + const indexJmp = labelsAddr.indexOf(jmpAddr); + if (indexJmp !== -1) { + labelsAddr.splice(indexJmp, 1); + } + } + if (elseAddr) { + const indexElse = labelsAddr.indexOf(elseAddr); + if (indexElse !== -1) { + labelsAddr.splice(indexElse, 1); + } + } + } + const filteredLabels = []; + for (let j = 0; j < labelsAddr.length; j++) { + filteredLabels.push(Object.keys(rom.labels).find((key) => rom.labels[key] === labelsAddr[j])); + } + console.log(filteredLabels); + await fs.writeFileSync('no-used-labels.json', JSON.stringify(filteredLabels, null, 2)); + // await fs.writeFileSync('no-used-labelsAddr-Addr.json', JSON.stringify(labelsAddr, null, 2)); +} + +main(); diff --git a/tools/parallel-tests-sample/sample.test.js b/tools/parallel-tests-sample/sample.test.js index b3b2b992..24ae4fd6 100644 --- a/tools/parallel-tests-sample/sample.test.js +++ b/tools/parallel-tests-sample/sample.test.js @@ -1,3 +1,6 @@ +/* eslint-disable global-require */ +/* eslint-disable import/no-dynamic-require */ +/* eslint-disable no-use-before-define */ /* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/extensions */ /* eslint-disable import/no-unresolved */ @@ -9,6 +12,7 @@ const { newCommitPolsArray } = require('pilcom'); const smMain = require('@0xpolygonhermez/zkevm-proverjs/src/sm/sm_main/sm_main'); let rom = require('../../build/rom.json'); + let stepsN = 2 ** 23; let counters = false; @@ -19,6 +23,8 @@ const checkerDir = path.join(__dirname, 'checker.txt'); const inputPath = '%%INPUT_PATH%%'; const nameFile = path.basename(inputPath); const input = JSON.parse(fs.readFileSync(inputPath, 'utf8')); +const stepRetries = 3; +let currentTries = 0; it(`${nameFile}`, async () => { if (fs.existsSync(checkerDir)) { @@ -27,26 +33,40 @@ it(`${nameFile}`, async () => { const pil = JSON.parse(fs.readFileSync(fileCachePil)); const cmPols = newCommitPolsArray(pil); if (input.gasLimit) { - rom = require(`../../build/rom-${input.gasLimit}.test.json`) + rom = require(`../../build/rom-${input.gasLimit}.test.json`); } if (input.stepsN) { - stepsN = input.stepsN + stepsN = input.stepsN; counters = true; } + await runTest(cmPols, stepsN); + + expect(true).to.be.equal(true); +}); + +async function runTest(cmPols, steps) { try { const config = { debug: true, debugInfo: { inputName: path.basename(inputPath), }, - stepsN: stepsN, + stepsN: steps, counters, assertOutputs: true, }; + await smMain.execute(cmPols.Main, input, rom, config); } catch (err) { - fs.writeFileSync(checkerDir, `Failed test ${inputPath}`); + // If fails for ooc, retry increasing stepsN up to three times + if (err.toString().includes('OOC') && currentTries < stepRetries) { + currentTries += 1; + counters = true; + await runTest(cmPols, steps * 2); + + return; + } + fs.writeFileSync(checkerDir, `Failed test ${inputPath} - ${err}}`); throw err; } - expect(true).to.be.equal(true); -}); +} diff --git a/tools/run-tests-zkasm.js b/tools/run-tests-zkasm.js index 0dd374de..888871d7 100644 --- a/tools/run-tests-zkasm.js +++ b/tools/run-tests-zkasm.js @@ -21,20 +21,19 @@ async function main() { // Get all zkasm files const pathZkasm = path.join(process.cwd(), process.argv[2]); const files = await getTestFiles(pathZkasm); - + let wasFailed = false; // Run all zkasm files // eslint-disable-next-line no-restricted-syntax console.log(chalk.yellow('--> Start running zkasm files')); for (const file of files) { - if (file.includes('ignore')) - continue; + if (file.includes('ignore')) { continue; } if (await runTest(file, cmPols) == 1) { wasFailed = true; } } if (wasFailed) { - process.exit(1); + process.exit(1); } } @@ -47,7 +46,6 @@ async function runTest(pathTest, cmPols) { allowOverwriteLabels: true, }; - const config = { debug: true, stepsN: 8388608, @@ -73,6 +71,7 @@ async function runTest(pathTest, cmPols) { console.log(e); failed = true; } + return failed; } From 380d906f69fc35542323d766e657772732950f43 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 18 Oct 2023 17:43:36 +0200 Subject: [PATCH 005/121] add l1InfoTree --- main/block-info.zkasm | 14 +++- main/constants.zkasm | 27 ++++--- main/load-change-l2-block.zkasm | 33 +++++---- main/load-tx-rlp.zkasm | 19 +++-- main/main.zkasm | 36 ++++++--- main/process-change-l2-block.zkasm | 114 +++++++++++++++++++---------- main/process-tx.zkasm | 3 +- main/{ => tables}/2-exp.zkasm | 0 main/utils.zkasm | 93 ++++++++++++++++------- main/vars.zkasm | 11 ++- package.json | 2 +- 11 files changed, 240 insertions(+), 112 deletions(-) rename main/{ => tables}/2-exp.zkasm (100%) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index 618e9489..a6892a66 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -72,13 +72,22 @@ setupNewBlockInfoTree: $ => D :MLOAD(timestamp) $ => SR :SSTORE - ; Insert block timestamp + ; Insert block new ger ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) ; value: GER %INDEX_BLOCK_HEADER_PARAM_GER => A %SMT_KEY_BLOCK_HEADER_PARAM => B 0 => C - $ => D :MLOAD(newGER) + $ => D :MLOAD(gerL1InfoTree) + $ => SR :SSTORE + + ; Insert block new blockHashL1 + ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: blockHashL1 + %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH_L1 => A + %SMT_KEY_BLOCK_HEADER_PARAM => B + 0 => C + $ => D :MLOAD(blockchashL1InfoTree) $ => SR :SSTORE ; Restore current SR @@ -144,6 +153,7 @@ consolidateBlock: SR :MSTORE(blockInfoSR) $ => SR :MLOAD(tmpBlockInfoSR) +finalConsolidateBlockInfoTree: ; Store block Info Root in storage %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B diff --git a/main/constants.zkasm b/main/constants.zkasm index ddd831f6..0d343d67 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -6,8 +6,8 @@ CONST %BATCH_DIFFICULTY = 0 CONST %TX_GAS_LIMIT = 30000000 CONST %BLOCK_GAS_LIMIT = 2**32-1 CONST %MAX_MEM_EXPANSION_BYTES = 0x3fffe0 -CONST %FORK_ID = 6 -CONST %GER_TREE_LEVELS = 32 +CONST %FORK_ID = 7 +CONST %L1INFO_TREE_LEVELS = 32 CONST %CALLDATA_RESERVED_CTX = 1 ; GER manager storage positions constants @@ -43,13 +43,14 @@ CONST %SMT_KEY_BLOCK_HEADER_CUMULATIVE_GAS_USED = 10 CONST %SMT_KEY_BLOCK_HEADER_LOGS = 11 ; SMT block header data leaf keys -CONST %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH = 0; -CONST %INDEX_BLOCK_HEADER_PARAM_COINBASE = 1; -CONST %INDEX_BLOCK_HEADER_PARAM_NUMBER = 2; -CONST %INDEX_BLOCK_HEADER_PARAM_GAS_LIMIT = 3; -CONST %INDEX_BLOCK_HEADER_PARAM_TIMESTAMP = 4; -CONST %INDEX_BLOCK_HEADER_PARAM_GER = 5; -CONST %INDEX_BLOCK_HEADER_PARAM_GAS_USED = 6; +CONST %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH = 0 +CONST %INDEX_BLOCK_HEADER_PARAM_COINBASE = 1 +CONST %INDEX_BLOCK_HEADER_PARAM_NUMBER = 2 +CONST %INDEX_BLOCK_HEADER_PARAM_GAS_LIMIT = 3 +CONST %INDEX_BLOCK_HEADER_PARAM_TIMESTAMP = 4 +CONST %INDEX_BLOCK_HEADER_PARAM_GER = 5 +CONST %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH_L1 = 6 +CONST %INDEX_BLOCK_HEADER_PARAM_GAS_USED = 7 ; GAS CONST %BASE_TX_GAS = 21000 @@ -129,4 +130,10 @@ CONST %BYTECODE_STARTS_EF = 0xEF CONST %MAX_SIZE_MODEXP = 2147483647 CONSTL %MAX_SAFE_INTEGER_MODEXP = 0x1fffffffffffffn CONST %MAX_GAS_WORD_MODEXP = 9487 -CONSTL %MAX_GAS_IT_MODEXP = 90000000; %TX_GAS_LIMIT*3 \ No newline at end of file +CONSTL %MAX_GAS_IT_MODEXP = 90000000 ; %TX_GAS_LIMIT*3 + +; CONSTANTS TX CHANGEL2BLOCK +CONST %CHANGE_L2_BLOCK_TX_TYPE = 0x0b +CONST %DELTA_TIMESTAMP_BYTES = 4 +CONST %INDEX_L1INFOTREE_BYTES = 4 +CONST %TYPE_BYTES = 1 diff --git a/main/load-change-l2-block.zkasm b/main/load-change-l2-block.zkasm index 16e25b33..cb14cb23 100644 --- a/main/load-change-l2-block.zkasm +++ b/main/load-change-l2-block.zkasm @@ -1,28 +1,35 @@ +;;;;;;;;;;;;;;;;;; +;; ChangeL2BlockTx: +;; - fields: [type | deltaTimestamp | indexL1InfoTree ] +;; - bytes: [ 1 | 4 | 4 ] +;;;;;;;;;;;;;;;;;; + decodeChangeL2BlockTx: - ; No changeL2BlockTx to allowed at forced batches - $ :MLOAD(isForced), JMPNZ(invalidTxRLP) + ; No changeL2BlockTx allowed at forced batches + $ :MLOAD(isForced), JMPNZ(invalidDecodeChangeL2Block) - ; decode "txType" / 1 byte - 1 => D :CALL(getTxData) + ; decode txType / 1 byte + %TYPE_BYTES => D :CALL(getTxData) C + D => C :CALL(addBatchHashData) - ; Decode deltaTimestamp / 8 bytes - 8 => D :CALL(getTxData) + ; Decode deltaTimestamp / 4 bytes + %DELTA_TIMESTAMP_BYTES => D :CALL(getTxData) C + D => C :CALL(addBatchHashData) A :MSTORE(deltaTimestamp) - ; Decode indexHistGERTree / 4 bytes - 4 => D :CALL(getTxData) + ; Decode indexL1InfoTree / 4 bytes + %INDEX_L1INFOTREE_BYTES => D :CALL(getTxData) C + D => C :CALL(addBatchHashData) - A :MSTORE(indexHistGERTree) + A :MSTORE(indexL1InfoTree) 1 :MSTORE(isChangeL2BlockTx), JMP(finishLoadChangeL2BlockTx) getTxData: ${getTxs(p,D)} => A $${p = p + D} :RETURN + finishLoadChangeL2BlockTx: ;; update bytes parsed - $ => A :MLOAD(batchL2DataParsed) - A + C :MSTORE(batchL2DataParsed) + $ => A :MLOAD(batchL2DataParsed) + A + C :MSTORE(batchL2DataParsed) ;; increase number of transaction to process - $ => A :MLOAD(pendingTxs) - A + 1 :MSTORE(pendingTxs), JMP(txLoopRLP) \ No newline at end of file + $ => A :MLOAD(pendingTxs) + A + 1 :MSTORE(pendingTxs), JMP(txLoopRLP) \ No newline at end of file diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 75f3e77e..7051aeb8 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -29,11 +29,11 @@ loadTx_rlp: ; Check its a change L2 block transaction 1 => D ${getTxs(p,D)} => A - A - 0x0b :JMPZ(decodeChangeL2BlockTx) - ; First transaction must be a change L2 block transaction if is NOT a forced batch + A - %CHANGE_L2_BLOCK_TX_TYPE :JMPZ(decodeChangeL2BlockTx) + ; First transaction must be a change L2 block transaction if it is NOT a forced batch $ => A :MLOAD(pendingTxs), JMPNZ(loadTx_rlp_continue) - ; If is not forced and is not a change L2 block transaction, we discard the entire batch - $ :MLOAD(isForced), JMPZ(invalidTxRLP) + ; If it is not forced and it is not a change L2 block transaction, we discard the entire batch + $ :MLOAD(isForced), JMPZ(invalidNotFirstTxChangeL2Block) loadTx_rlp_continue: ; We get a new hashId @@ -338,6 +338,7 @@ effectivePercentageTx: 1 => D :CALL(getTxBytes) A :MSTORE(effectivePercentageRLP) C + D => C :CALL(addBatchHashData) + ;;;;;;;;; ;; D - Finish RLP parsing ;;;;;;;;; @@ -351,11 +352,13 @@ finishLoadRLP: ;; compute signature $ => A :HASHKDIGEST(E) A :MSTORE(txHash) + ;; Compute L2txHash ;; Get source address from tx signature $ => B :MLOAD(txR) $ => C :MLOAD(txS) $ => D :MLOAD(txV), CALL(ecrecover_tx) +checkAndSaveFrom: A :MSTORE(txSrcAddr) 20 => D $ => E :MLOAD(l2TxHashPointer) @@ -369,7 +372,13 @@ finishLoadRLP: ;; E - Handler error RLP fields ;;;;;;;;; invalidTxRLP: - $${eventLog(onError, invalidRLP)} :JMP(appendTxsInit) + $${eventLog(onError, invalidRLP)} :JMP(appendTxsInit) + +invalidDecodeChangeL2Block: + $${eventLog(onError, invalidDecodeChangeL2Block)} :JMP(appendTxsInit) + +invalidNotFirstTxChangeL2Block: + $${eventLog(onError, invalidNotFirstTxChangeL2Block)} :JMP(appendTxsInit) appendTxsInit: ;; Append all missing 'batchL2Data' to 'batchDataHash' bytes diff --git a/main/main.zkasm b/main/main.zkasm index aa7e0acf..c441bd3d 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -24,24 +24,30 @@ start: ; main zkROM entry point SP :MSTORE(oldNumBatch) GAS :MSTORE(chainID) ; assumed to be less than 32 bits - ${getHistoricGERRoot()} :MSTORE(historicGER) + ${getL1InfoRoot()} :MSTORE(l1InfoRoot) ${getSequencerAddr()} :MSTORE(sequencerAddr) ${getTimestampLimit()} :MSTORE(timestampLimit) ${getTxsLen()} :MSTORE(batchL2DataLength) ; less than 300.000 bytes. Enforced by the smart contract - ${getIsForced()} :MSTORE(isForced) + ${getForcedBlockHashL1()} => A :MSTORE(forcedBlockHashL1) - B => SR ;set initial state root + ;set initial state root + B => SR SR :MSTORE(batchSR) ; Increase batch number SP + 1 :MSTORE(newNumBatch) + ; compute isForced flag + 0 => B + $ :EQ, JMPC(computeKeccaks) + 1 :MSTORE(isForced) ;;;;;;;;;;;;;;;;;; ;; B - Compute keccaks needed to finish the batch ;;;;;;;;;;;;;;;;;; +computeKeccaks: $${eventLog(onStartBatch, C)} ; Compute necessary keccak counters to finish batch - $ => A :MLOAD(batchL2DataLength) + $ => A :MLOAD(batchL2DataLength) ; Divide the total data length + 1 by 136 to obtain the keccak counter increment. ; 136 is the value used by the prover to increment keccak counters A + 1 :MSTORE(arithA) @@ -80,20 +86,22 @@ endCheckRLP: 0 :MSTORE(isLoadingRLP) ;;;;;;;;;;;;;;;;;; -;; D - Load blockNum variable -;; - Loop processing transactions -;; - Load transaction data and interpret it +;; D - Load blockNum variable +;; - Loop processing transactions +;; - Load transaction data and interpret it ;;;;;;;;;;;;;;;;;; setBlockNum: %LAST_BLOCK_STORAGE_POS => C %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B - $ :SLOAD,MSTORE(blockNum) - ; If forced batch, process a forced changeL2BlockTx + $ :SLOAD,MSTORE(blockNum) + ; If forced batch ==> process a forced changeL2BlockTx $ :MLOAD(isForced), JMPZ(txLoop, handleForcedBatch) + handleForcedBatch: 1 :MSTORE(currentTx), JMP(processChangeL2Block) + txLoop: $ => A :MLOAD(pendingTxs) A - 1 :MSTORE(pendingTxs), JMPN(processTxsEnd) @@ -105,6 +113,7 @@ txLoop: ; Store initial state at the beginning of the transaction SR :MSTORE(originSR) $ => A :MLOAD(isChangeL2BlockTx) + ; TODO: could be done with JMPN in one step maybe A - 1 :JMPZ(processChangeL2Block, processTx) processTxFinished: @@ -165,7 +174,7 @@ processTxsEnd: $ => A :MLOAD(batchHashData) A :HASHK(0) - $ => A :MLOAD(historicGER) + $ => A :MLOAD(l1InfoRoot) A :HASHK(0) 8 => D @@ -176,8 +185,11 @@ processTxsEnd: $ => A :MLOAD(sequencerAddr) A :HASHK(0) - $ => A :MLOAD(isForced) - A :HASHK1(0) + 32 => D + $ => A :MLOAD(forcedBlockHashL1) + A :HASHK(0) + + ; finish accInputHash HASHPOS :HASHKLEN(0) $ => C :HASHKDIGEST(0) diff --git a/main/process-change-l2-block.zkasm b/main/process-change-l2-block.zkasm index e855a6d4..9659aad8 100644 --- a/main/process-change-l2-block.zkasm +++ b/main/process-change-l2-block.zkasm @@ -1,23 +1,25 @@ processChangeL2Block: $${eventLog(onProcessTx)} + ; checks zk-counters - %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*6 :JMPN(outOfCountersPoseidon) - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 2 :JMPN(outOfCountersKeccak) - %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*6 :JMPN(outOfCountersPoseidon) + $ => A :MLOAD(cntKeccakPreProcess) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 2 :JMPN(outOfCountersKeccak) + %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - ; If it's not first tx, we must consolidate previous block + ; If it is not the first transaction, we must consolidate previous block $ => A :MLOAD(currentTx) A - 1 :JMPZ(continueProcessChangeL2Block) :CALL(consolidateBlock) + continueProcessChangeL2Block: ; Reset tx index, logIndex and cumulative gas used 0 :MSTORE(txIndex) 0 :MSTORE(cumulativeGasUsed) 0 :MSTORE(currentLogIndex) - ; Set block hash (current state root) on storage - ;Update state root mapping + ;; Set block hash (current state root) on storage + ; Update state root mapping 32 => D 0 => HASHPOS ; A new hash with position 0 is started $ => E :MLOAD(lastHashKIdUsed) @@ -36,7 +38,8 @@ continueProcessChangeL2Block: ; Read block number, increase it by 1 and write it ; Get last block number $ => A :MLOAD(blockNum) - ;Update last block number at system storage + + ; Update last block number at system storage 1 => B $ => D :ADD, MSTORE(blockNum) %LAST_BLOCK_STORAGE_POS => C @@ -48,28 +51,54 @@ continueProcessChangeL2Block: %TIMESTAMP_STORAGE_POS => C %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B - $ => A, B :SLOAD, MSTORE(timestamp) ; currentTimestamp => B - ; If is forced, new timestamp = timestampLimit, else timestamp = timestamp + deltaTimestamp - $ => C :MLOAD(timestampLimit) - C :MSTORE(timestamp) - ; If it is a forced tx, no delta timestamp is needed - $ :MLOAD(isForced), JMPNZ(processForcedChangeL2Block) + $ => A :SLOAD ; currentTimestamp => A + + $ => B :MLOAD(timestampLimit) ; timestampLimit => B + + ; If it is NOT a forced tx ==> verify Timestamp & L1InfoRoot + $ :MLOAD(isForced), JMPZ(verifyTimestampAndL1InfoRoot) + + ; forced batch + ; - update timestamp only if currentTimestamp < limitTimestamp + ; - set blockHash to default + $ => C :MLOAD(forcedBlockHashL1) + C :MSTORE(blockchashL1InfoTree) + A :MSTORE(timestamp) + $ :LT, JMPNC(initSetGERL1InfoTree) + +newForcedTimestamp: + B :MSTORE(timestamp), JMP(setNewTimestamp) + +verifyTimestampAndL1InfoRoot: $ => B :MLOAD(deltaTimestamp) - ; Addition of two values of 8 bytes (currentTimestamp + deltaTimestamp) + ; Addition of two values of 8 bytes [B: currentTimestamp(A) + deltaTimestamp(B)] $ => B :ADD, MSTORE(timestamp) - processForcedChangeL2Block: - ; Verify currentTimestamp + deltaTimestamp <= limitTimestamp or Verify currentTimestamp <= limitTimestamp if forced tx + ; Verify (currentTimestamp + deltaTimestamp) <= limitTimestamp $ => A :MLOAD(timestampLimit) $ :LT, JMPC(invalidChangeL2Block) - ; Retrieve newGER from free input - $ => A :MLOAD(currentTx) - ${getNewGERRoot(A)} :MSTORE(newGER) + ; Set new timestamp + %TIMESTAMP_STORAGE_POS => C + %ADDRESS_SYSTEM => A + %SMT_KEY_SC_STORAGE => B + $ => D :MLOAD(timestamp) + $ => SR :SSTORE + + ; check indexL1InfoTree != 0 to verify data L1InfoTree + $ :MLOAD(indexL1InfoTree), JMPZ(skipSetGERL1InfoTree) + + ${getL1InfoGER(mem.indexL1InfoTree)} => A :MSTORE(gerL1InfoTree) + ${getL1InfoBlockHash(mem.indexL1InfoTree)} => B :MSTORE(blockchashL1InfoTree) + ${getL1InfoTimestamp(mem.indexL1InfoTree)} => C :MSTORE(timestampL1InfoTree) + :CALL(verifyMerkleProof) - ; Verify newGER | indexHistoricalGERTree belong to historicGER - ; $ :MLOAD(indexHistGERTree),JMPNZ(verifyMerkleProof) + ; Verify (currentTimestamp + deltaTimestamp) >= l1InfoRoot.timestamp + $ => A :MLOAD(timestamp) + $ => B :MLOAD(timestampL1InfoTree) + $ :LT, JMPC(invalidChangeL2Block, initSetGERL1InfoTree) +setNewTimestamp: ;make an utils function ; Set new timestamp %TIMESTAMP_STORAGE_POS => C %ADDRESS_SYSTEM => A @@ -77,15 +106,18 @@ continueProcessChangeL2Block: $ => D :MLOAD(timestamp) $ => SR :SSTORE +initSetGERL1InfoTree: ; Set new GER - $ => A :MLOAD(newGER) - ; If it is a forced tx, newGER = historicGER - $ :MLOAD(isForced), JMPZ(setnewGER) - $ => A :MLOAD(historicGER) -setnewGER: + $ => A :MLOAD(gerL1InfoTree) + ; If it is a forced tx ==> gerL1InfoTree = l1InfoRoot + $ :MLOAD(isForced), JMPZ(setGERL1InfoTree) + $ => A :MLOAD(l1InfoRoot) + A :MSTORE(gerL1InfoTree) + +setGERL1InfoTree: 0 => B - ; Dont set if zero - $ :EQ, JMPC(skipSetHistoricGERRoot) + ; Do not set if zero + $ :EQ, JMPC(skipSetGERL1InfoTree) 0 => HASHPOS $ => E :MLOAD(lastHashKIdUsed) E + 1 => E :MSTORE(lastHashKIdUsed) @@ -96,16 +128,20 @@ setnewGER: HASHPOS :HASHKLEN(E) $ => C :HASHKDIGEST(E) + ; read blockchashL1InfoTree given the l1InfoRoot + ; skip overwrite blockHashL1 if it is different than 0 (already set) %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A %SMT_KEY_SC_STORAGE => B + $ => A :SLOAD + 0 => B + $ :EQ, JMPNC(skipSetGERL1InfoTree) - ; read timestampLimit given the historicGER - ; skip overwrite timestampLimit if it is different than 0 (already set) - ; Since timestampLimit is enforced by the smart contract it is safe to compare only 32 bits in 'op0' with JMPNZ - $ :SLOAD, JMPNZ(skipSetHistoricGERRoot) - $ => D :MLOAD(timestamp) - $ => SR :SSTORE ; Store 'timestamp' in storage position 'keccak256(historicGER, 0)' + ; write blockhashL1 + %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A + %SMT_KEY_SC_STORAGE => B + $ => D :MLOAD(blockchashL1InfoTree) + $ => SR :SSTORE ; Store 'blockchashL1InfoTree' in storage position 'keccak256(gerL1InfoTree, 0)' - skipSetHistoricGERRoot: - :CALL(setupNewBlockInfoTree) - :JMP(txLoop) \ No newline at end of file +skipSetGERL1InfoTree: + :CALL(setupNewBlockInfoTree) + :JMP(txLoop) \ No newline at end of file diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index 72f17223..c61f6fe4 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -2,7 +2,7 @@ INCLUDE "map-opcodes.zkasm" INCLUDE "precompiled/selector.zkasm" INCLUDE "ecrecover/ecrecover.zkasm" INCLUDE "touched.zkasm" -INCLUDE "2-exp.zkasm" +INCLUDE "tables/2-exp.zkasm" ; Blocks process txs ; A - Verify ecdsa signature @@ -28,6 +28,7 @@ processTx: SR :MSTORE(initSR) CTX :MSTORE(currentCTX) + ; Minimum of 100000 steps left to process a tx %MAX_CNT_STEPS - STEP - 100000 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 100 :JMPN(outOfCountersBinary) diff --git a/main/2-exp.zkasm b/main/tables/2-exp.zkasm similarity index 100% rename from main/2-exp.zkasm rename to main/tables/2-exp.zkasm diff --git a/main/utils.zkasm b/main/utils.zkasm index 6ecbc7bd..e9a81870 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -1485,53 +1485,96 @@ failAssert: 2 :ASSERT VAR GLOBAL tmpZkPCVerifyMerkleProof -;@info verifies GER with sibilings +;@info verifies L1Info data with sibilings +;@in A: ger +;@in B: blockhashL1 +;@in C: timestamp verifyMerkleProof: ; check zk-counters - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - - RR :MSTORE(tmpZkPCVerifyMerkleProof) - $ => C :MLOAD(newGER) - $ => B :MLOAD(indexHistGERTree) - B :MSTORE(arithA) + $ => E :MLOAD(cntKeccakPreProcess) + + ; 1 keccak for the leaf and 32 for the L1InfoTree + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - E - 33 :JMPN(outOfCountersKeccak) + %MAX_CNT_BINARY - CNT_BINARY - 32 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 * 32 :JMPN(outOfCountersStep) + + RR :MSTORE(tmpZkPCVerifyMerkleProof) + + ;;;;;;;;;;;;;;;;;;;;; + ;; compute leaf value + ;;;;;;;;;;;;;;;;;;;;; + + ; new keccak address + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) + + ; add gerL1InfoTree (32 bytes) + 0 => HASHPOS + 32 => D + A :HASHK(E) + + ; add blockHashL1 (32 bytes) + B :HASHK(E) + + ; add timestamp (8 bytes) + 8 => D + C :HASHK(E) + + ; compute l1InfoTree Leaf value + HASHPOS :HASHKLEN(E) + $ => C :HASHKDIGEST(E) ; initial value + + ; initialization registers for smt verify 0 => D verifyMerkleProofLoop: - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %GER_TREE_LEVELS - D :JMPZ(verifyMerkleProofEnd) - $ => B :MLOAD(indexHistGERTree) - ${getSmtProof(B, D)} => A + %L1INFO_TREE_LEVELS - D :JMPZ(verifyMerkleProofEnd) + + ; get left/right branch + $ => A :MLOAD(indexL1InfoTree) D => RR - :CALL(@exp_num + RR); out:[B: 2**RR] - B :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + :CALL(@exp_num + RR); out:[B: 2**RR] + ; A: index, B: SMTLevel (index maximum value is 4 bytes, SMTLevel maximum value is is 2**32) + $ => B :AND + + + ; get leaf value + ${getSmtProof(mem.indexL1InfoTree, D)} => A + + ; prepare new hash $ => E :MLOAD(lastHashKIdUsed) E + 1 => E :MSTORE(lastHashKIdUsed) - D => B - 32 => D 0 => HASHPOS - $ :MLOAD(arithRes2), JMPZ(reverseHashValue) - $ => C :MLOAD(newGER) + + ; decide left/right branch + B :JMPZ(hashLeft) + + ;hashRight: + D => B ; save D in B for the next loop + 32 => D A :HASHK(E) - C :HASHK(E), JMP(reverseHashValueEnd) -reverseHashValue: + C :HASHK(E), JMP(hashBranchEnd) + +hashLeft: + D => B ; save D in B for the next loop + 32 => D C :HASHK(E) A :HASHK(E) -reverseHashValueEnd: + +hashBranchEnd: HASHPOS :HASHKLEN(E) $ => C :HASHKDIGEST(E) - B => D + B => D ; recover loop iteration D + 1 => D :JMP(verifyMerkleProofLoop) verifyMerkleProofEnd: - $ => A :MLOAD(historicGER) + $ => A :MLOAD(l1InfoRoot) C :ASSERT + verifyMerkleProofReturn: $ => RR :MLOAD(tmpZkPCVerifyMerkleProof) :RETURN - VAR GLOBAL tmpZkPCreadXFromOffset VAR GLOBAL readXFromCalldataOffset VAR GLOBAL readXFromCalldataLength diff --git a/main/vars.zkasm b/main/vars.zkasm index f32cc37b..b22c667e 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -1,7 +1,7 @@ ; Input variables VAR GLOBAL oldStateRoot ; Previous state-tree root VAR GLOBAL oldAccInputHash ; Previous accumulated input hash -VAR GLOBAL historicGER ; Global exit-tree root +VAR GLOBAL l1InfoRoot ; Global exit-tree root VAR GLOBAL oldNumBatch ; Previous batch processed VAR GLOBAL sequencerAddr ; Coinbase address which will receive the fees VAR GLOBAL batchHashData ; batchHashData = H_keccak( transactions ) @@ -9,11 +9,12 @@ VAR GLOBAL timestampLimit ; timestampLimit of the batch VAR GLOBAL timestamp ; Current batch timestamp VAR GLOBAL chainID ; Current batch chain id VAR GLOBAL forkID ; Fork identifier +VAR GLOBAL forcedBlockHashL1 ; blockHash ¡L1 when a forced transaction ahs been done VAR GLOBAL isForced ; Flag to determine if the batch is forced VAR GLOBAL cumulativeGasUsed ; cumulative gas used in the block ; Output variables -VAR GLOBAL newAccInputHash ; Final accumulated input hash. newAccInputHash = H_keccak( oldAccInputHash | batchHashData | historicGER | timestamp | sequencerAddr ) +VAR GLOBAL newAccInputHash ; Final accumulated input hash. newAccInputHash = H_keccak( oldAccInputHash | batchHashData | l1InfoRoot | timestamp | sequencerAddr ) VAR GLOBAL newLocalExitRoot ; Updated local exit tree root VAR GLOBAL newNumBatch ; Current batch processed @@ -108,6 +109,8 @@ VAR CTX initBlockInfoSR ; block info root once a new context begins VAR CTX initLogIndex ; log index once a new context begins VAR CTX deltaTimestamp ; delta timestamp of the current change L2 block tx -VAR CTX newGER ; new GER of the current change L2 block tx -VAR CTX indexHistGERTree ; indexHistGERTree of the current change L2 block tx +VAR CTX indexL1InfoTree ; indexL1InfoTree of the current change L2 block tx +VAR CTX gerL1InfoTree ; new GER of the current change L2 block tx +VAR CTX blockchashL1InfoTree ; new BlockchashL1 of the current change L2 block tx +VAR CTX timestampL1InfoTree ; new timestamp of the current change L2 block tx VAR CTX isChangeL2BlockTx ; flag to determine if the current tx is a change L2 block tx diff --git a/package.json b/package.json index ab990c4f..2219bb8f 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/forkid-6-fix-gas", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", From 6f8d1378005e3043fa02e030808e209bee0b9a4c Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 3 Nov 2023 12:12:36 +0100 Subject: [PATCH 006/121] update package.json to l1-info-tree branches --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 2219bb8f..7c942b05 100644 --- a/package.json +++ b/package.json @@ -37,13 +37,13 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/addr-command", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/l1-info-tree", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/l1-info-tree", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From f3ecf36548193bfe2f51f2a92674faa1eb6fac5a Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 8 Nov 2023 16:36:48 +0100 Subject: [PATCH 007/121] add label to skip first changeL2Block transaction --- main/load-tx-rlp.zkasm | 5 +++-- main/main.zkasm | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 7051aeb8..3d6a6afb 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -26,12 +26,13 @@ loadTx_rlp: ; Pointer to next RLP bytes to read 0 => C - ; Check its a change L2 block transaction + ; Check it is a change L2 block transaction 1 => D ${getTxs(p,D)} => A A - %CHANGE_L2_BLOCK_TX_TYPE :JMPZ(decodeChangeL2BlockTx) +checkFirstTxType: ; First transaction must be a change L2 block transaction if it is NOT a forced batch - $ => A :MLOAD(pendingTxs), JMPNZ(loadTx_rlp_continue) + $ :MLOAD(pendingTxs), JMPNZ(loadTx_rlp_continue) ; If it is not forced and it is not a change L2 block transaction, we discard the entire batch $ :MLOAD(isForced), JMPZ(invalidNotFirstTxChangeL2Block) diff --git a/main/main.zkasm b/main/main.zkasm index c441bd3d..75111025 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -113,7 +113,6 @@ txLoop: ; Store initial state at the beginning of the transaction SR :MSTORE(originSR) $ => A :MLOAD(isChangeL2BlockTx) - ; TODO: could be done with JMPN in one step maybe A - 1 :JMPZ(processChangeL2Block, processTx) processTxFinished: From 993e876d276be1f7232efa7ff0d8fc0b65f7f893 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 10 Nov 2023 17:40:59 +0100 Subject: [PATCH 008/121] fix comment --- main/block-info.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index a6892a66..ba6b125e 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -56,7 +56,7 @@ setupNewBlockInfoTree: ; Insert block gas limit ; key: H([blockHeaderParams[0:4], blockHeaderParams[4:8], blockHeaderParams[8:12], blockHeaderParams[12:16], blockHeaderParams[16:20], 0, SMT_KEY_BLOCK_HEADER_PARAM, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) - ; value: blockNum + ; value: block gas limit %INDEX_BLOCK_HEADER_PARAM_GAS_LIMIT => A %SMT_KEY_BLOCK_HEADER_PARAM => B 0 => C From 891dfe7b772b2d6d7c55be99897a5270029c1808 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Fri, 20 Oct 2023 13:11:06 +0200 Subject: [PATCH 009/121] add pre-sha2 --- main/precompiled/pre-sha2-256.zkasm | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 main/precompiled/pre-sha2-256.zkasm diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm new file mode 100644 index 00000000..0f661879 --- /dev/null +++ b/main/precompiled/pre-sha2-256.zkasm @@ -0,0 +1,70 @@ +/** + * @link [https://www.evm.codes/precompiled#0x02?fork=shanghai] + * @zk-counters + * - dynamic steps: + * - dynamic binary: + * @process-precompiled + * - stack input: [data] + * - stack output: [hash] + */ +funcSHA2256: + ;%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + ;%MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + + ; Move balances if value > 0 just before executing the contract CALL + $ => B :MLOAD(txValue) + 0 => A + zkPC+2 => RR + $ :LT, JMPC(moveBalances) + + GAS - %SHA2_256_GAS => GAS :JMPN(outOfGas) + $ => C :MLOAD(txCalldataLen) + ;(C+31)/32 => A + C + 31 => A + A :MSTORE(arithA) + 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => A :MLOAD(arithRes1) + + GAS - %SHA2_256_WORD_GAS*A => GAS :JMPN(outOfGas) + 0 :MSTORE(retDataOffset) + 32 :MSTORE(retDataLength) + 32 :MSTORE(readXFromCalldataLength) + 0 => E + +SHA2256dataLoop: + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + ; Copy from calldata to hashS (TODO) + C :JMPZ(SHA2256dataReturn) + C - 32 :JMPN(SHA2256dataFinal) + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + E + 32 => E + + ; TODO + ${mockSHA256(A,32)} + ;A :HASHS(E) + + C - 32 => C :JMP(SHA2256dataLoop) + +SHA2256dataFinal: + C :MSTORE(readXFromCalldataLength) + E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] + $ => A :MLOAD(readXFromCalldataResult) + ; TODO + ${mockSHA256(A,C)} + ;A :HASHS(E) + +SHA2256dataReturn: + ; handle CTX + $ => A :MLOAD(originCTX), JMPZ(handleGas) + ; set retDataCTX + $ => B :MLOAD(currentCTX) + A => CTX + B :MSTORE(retDataCTX) + ; Copy from memory current CTX to memory origin CTX + 0 => E + ; TODO + ${mockSHA256(0,0)} => A + + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file From bc4e8d2cb84624df06f43ea4de6a3df1a2fd1bd1 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Thu, 9 Nov 2023 00:31:55 +0100 Subject: [PATCH 010/121] update pre-sha256 --- main/constants.zkasm | 2 + main/precompiled/pre-sha2-256.zkasm | 70 +++++++++++++++++++---------- main/precompiled/selector.zkasm | 3 +- package.json | 4 +- test/testSHA256.zkasm | 27 +++++++++++ 5 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 test/testSHA256.zkasm diff --git a/main/constants.zkasm b/main/constants.zkasm index 0d343d67..7ebd2870 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -71,6 +71,8 @@ CONST %IDENTITY_WORD_GAS = 3 ; Per-work price for a data copy operation CONST %ECADD_GAS = 150; ecAdd gas price CONST %ECMUL_GAS = 6000; ecMul gas price CONST %ECPAIRING_GAS = 45000; ecPairing gas price +CONST %SHA2_256_GAS = 60 ; sha256 static gas +CONST %SHA2_256_WORD_GAS = 12 ; sha256 word gas CONST %KECCAK_GAS = 30 ; Once per KECCAK256 operation. CONST %KECCAK_WORD_GAS = 6 ; Once per word of the KECCAK256 operation's data. CONST %LOG_GAS = 375 ; Per LOG* operation. diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 0f661879..2c4660f3 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -7,6 +7,12 @@ * - stack input: [data] * - stack output: [hash] */ +VAR GLOBAL sha256DataOffset +VAR GLOBAL sha256DataId +VAR GLOBAL sha256HashPos +VAR GLOBAL sha256Hash +VAR GLOBAL tmpZkSHA256 + funcSHA2256: ;%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) ;%MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) @@ -29,42 +35,58 @@ funcSHA2256: 0 :MSTORE(retDataOffset) 32 :MSTORE(retDataLength) 32 :MSTORE(readXFromCalldataLength) + + $ => E :MLOAD(sha256DataId) + 0 => E :MSTORE(sha256DataOffset) + 0 => HASHPOS + :CALL(SHA2256data) + +SHA2256dataReturn: + E + 1 :MSTORE(sha256DataId) + ; handle CTX + $ => A :MLOAD(originCTX), JMPZ(handleGas) + ; set retDataCTX + $ => B :MLOAD(currentCTX) + A => CTX + B :MSTORE(retDataCTX) + ; Copy from memory current CTX to memory origin CTX + $ => A :MLOAD(sha256Hash) 0 => E + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + CTX :MSTORE(currentCTX), JMP(preEnd) + +SHA2256data: + RR :MSTORE(tmpZkSHA256) SHA2256dataLoop: - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - ; Copy from calldata to hashS (TODO) - C :JMPZ(SHA2256dataReturn) + ; Copy from calldata to hashS + C :JMPZ(SHA2256) C - 32 :JMPN(SHA2256dataFinal) + $ => E :MLOAD(sha256DataOffset) E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] $ => A :MLOAD(readXFromCalldataResult) - E + 32 => E + E + 32 => E :MSTORE(sha256DataOffset) - ; TODO - ${mockSHA256(A,32)} - ;A :HASHS(E) + $ => E :MLOAD(sha256DataId) + 32 => D + A :HASHS(E) C - 32 => C :JMP(SHA2256dataLoop) SHA2256dataFinal: + $ => E :MLOAD(sha256DataOffset) C :MSTORE(readXFromCalldataLength) E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] $ => A :MLOAD(readXFromCalldataResult) - ; TODO - ${mockSHA256(A,C)} - ;A :HASHS(E) - -SHA2256dataReturn: - ; handle CTX - $ => A :MLOAD(originCTX), JMPZ(handleGas) - ; set retDataCTX - $ => B :MLOAD(currentCTX) - A => CTX - B :MSTORE(retDataCTX) - ; Copy from memory current CTX to memory origin CTX - 0 => E - ; TODO - ${mockSHA256(0,0)} => A + 32 - C => D + zkPC+1 => RR :JMP(SHRarith) + $ => E :MLOAD(sha256DataId) + C => D + A :HASHS(E) - A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] - CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file +SHA2256: + HASHPOS :HASHSLEN(E) + $ => A :HASHSDIGEST(E) + A :MSTORE(sha256Hash) + $ => RR :MLOAD(tmpZkSHA256) + :RETURN \ No newline at end of file diff --git a/main/precompiled/selector.zkasm b/main/precompiled/selector.zkasm index ae978556..a2c9e0df 100644 --- a/main/precompiled/selector.zkasm +++ b/main/precompiled/selector.zkasm @@ -5,6 +5,7 @@ INCLUDE "pre-ecAdd.zkasm" INCLUDE "pre-ecMul.zkasm" INCLUDE "pre-ecPairing.zkasm" INCLUDE "pre-modexp.zkasm" +INCLUDE "pre-sha2-256.zkasm" INCLUDE "../pairings/constants.zkasm" INCLUDE "../pairings/BN254/ecAdd.zkasm" INCLUDE "../pairings/BN254/ecMul.zkasm" @@ -66,7 +67,7 @@ INCLUDE "end.zkasm" */ selectorPrecompiled: A - 2 :JMPN(funcECRECOVER) - A - 3 :JMPN(revertPrecompiled) ;:JMPN(SHA256) + A - 3 :JMPN(funcSHA2256) ;:JMPN(SHA256) A - 4 :JMPN(revertPrecompiled) ;:JMPN(RIPEMD160) A - 5 :JMPN(IDENTITY) A - 6 :JMPN(funcModexp) diff --git a/package.json b/package.json index 7c942b05..4584cedd 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,12 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/sha256", "yargs": "^17.5.1" }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/l1-info-tree", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/l1-info-tree", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256-l1-info-tree", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree", "chai": "^4.3.6", "chalk": "^3.0.0", diff --git a/test/testSHA256.zkasm b/test/testSHA256.zkasm new file mode 100644 index 00000000..c64c4cc2 --- /dev/null +++ b/test/testSHA256.zkasm @@ -0,0 +1,27 @@ + +start: + STEP => A + 0 :ASSERT ; Ensure it is the beginning of the execution + 1 => C :MSTORE(txCalldataLen) + 1 :MSTORE(originCTX) + 1 :MSTORE(calldataCTX) + 1 => CTX + 0 => E + 0xFF00000000000000000000000000000000000000000000000000000000000000n :MSTORE(MEM:E) + + 2 :MSTORE(currentCTX) + 2 => CTX + + $ => E :MLOAD(sha256DataId) + 0 => E :MSTORE(sha256DataOffset) + 0 => HASHPOS + RR :MSTORE(tmpZkSHA256) + :CALL(SHA2256data) + $ => E :MLOAD(sha256Hash) + + 0xa8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89n => A + E :ASSERT + + :JMP(finalizeExecution) + +INCLUDE "../main/main.zkasm" From b9cbc23f4ab793428659c0fdaa9bcbae5012cd3e Mon Sep 17 00:00:00 2001 From: laisolizq Date: Thu, 9 Nov 2023 13:35:18 +0100 Subject: [PATCH 011/121] fix return & add comments --- main/precompiled/pre-sha2-256.zkasm | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 2c4660f3..658f8126 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -23,40 +23,56 @@ funcSHA2256: zkPC+2 => RR $ :LT, JMPC(moveBalances) + ; GAS - staticGas GAS - %SHA2_256_GAS => GAS :JMPN(outOfGas) + $ => C :MLOAD(txCalldataLen) - ;(C+31)/32 => A + ;words => A === (C+31)/32 => A C + 31 => A A :MSTORE(arithA) 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => A :MLOAD(arithRes1) + ; GAS - dinamicGas GAS - %SHA2_256_WORD_GAS*A => GAS :JMPN(outOfGas) + + ; prepare retData 0 :MSTORE(retDataOffset) 32 :MSTORE(retDataLength) 32 :MSTORE(readXFromCalldataLength) - - $ => E :MLOAD(sha256DataId) - 0 => E :MSTORE(sha256DataOffset) 0 => HASHPOS :CALL(SHA2256data) + ; get & update sha256Data ID + $ => E :MLOAD(sha256DataId) + E + 1 :MSTORE(sha256DataId) + + ; copy sha256 to retData (hash 32 bytes) + 0 => E + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] SHA2256dataReturn: - E + 1 :MSTORE(sha256DataId) ; handle CTX $ => A :MLOAD(originCTX), JMPZ(handleGas) ; set retDataCTX $ => B :MLOAD(currentCTX) A => CTX B :MSTORE(retDataCTX) + B => CTX ; Copy from memory current CTX to memory origin CTX - $ => A :MLOAD(sha256Hash) 0 => E - A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + $ => C :MLOAD(retCallLength) + ; MLOAD memory current CTX + :CALL(MLOADX) + $ => E :MLOAD(retCallOffset) + $ => CTX :MLOAD(originCTX) + ; MSTORE memory origint CTX + A :MSTORE(bytesToStore), CALL(MSTOREX) + ; set currentCTX CTX :MSTORE(currentCTX), JMP(preEnd) SHA2256data: RR :MSTORE(tmpZkSHA256) + 0 => E :MSTORE(sha256DataOffset) SHA2256dataLoop: ; Copy from calldata to hashS @@ -85,6 +101,7 @@ SHA2256dataFinal: A :HASHS(E) SHA2256: + $ => E :MLOAD(sha256DataId) HASHPOS :HASHSLEN(E) $ => A :HASHSDIGEST(E) A :MSTORE(sha256Hash) From ca5c7b1dae502c05fa0568d847cb83ca7d307033 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Fri, 10 Nov 2023 09:22:12 +0100 Subject: [PATCH 012/121] update cnt sha256 --- main/constants.zkasm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main/constants.zkasm b/main/constants.zkasm index 7ebd2870..dfbb2a84 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -110,6 +110,7 @@ CONST %MAX_CNT_MEM_ALIGN_LIMIT = %TOTAL_STEPS_LIMIT / 32 CONST %MAX_CNT_KECCAK_F_LIMIT = (%TOTAL_STEPS_LIMIT / 155286) * 44 CONST %MAX_CNT_PADDING_PG_LIMIT = (%TOTAL_STEPS_LIMIT / 56) CONST %MAX_CNT_POSEIDON_G_LIMIT = (%TOTAL_STEPS_LIMIT / 30) +CONST %MAX_CNT_SHA256_F_LIMIT = 1925 CONST %SAFE_RANGE = 20 ; safe guard counters to not take into account (%RANGE = 1 / SAFE_RANGE) @@ -121,6 +122,7 @@ CONST %MAX_CNT_KECCAK_F = %MAX_CNT_KECCAK_F_LIMIT - (%MAX_CNT_KECCAK_F_LIMIT / % CONST %MAX_CNT_PADDING_PG = %MAX_CNT_PADDING_PG_LIMIT - (%MAX_CNT_PADDING_PG_LIMIT / %SAFE_RANGE) CONST %MAX_CNT_POSEIDON_G = %MAX_CNT_POSEIDON_G_LIMIT - (%MAX_CNT_POSEIDON_G_LIMIT / %SAFE_RANGE) CONST %MAX_CNT_POSEIDON_SLOAD_SSTORE = 257 +CONST %MAX_CNT_SHA256_F = %MAX_CNT_SHA256_F_LIMIT - (%MAX_CNT_SHA256_F_LIMIT / %SAFE_RANGE) CONST %MIN_CNT_KECCAK_BATCH = 1 ; minimum necessary keccaks to compute global hash From 9025d8ca1ae29440ba1776a73dfd4fd637165d92 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Fri, 17 Nov 2023 11:30:53 +0100 Subject: [PATCH 013/121] update main PR --- .github/workflows/main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 874a589b..ad2c002b 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -6,7 +6,7 @@ name: Test executor inputs on: workflow_dispatch: pull_request: - branches: [main, develop, develop-etrog, feature/fork-etrog] + branches: [main, develop, develop-etrog, feature/fork-etrog, feature/l1-info-tree] jobs: build: From 894b2eba4bba10636a28d85e285d8fd7ca19b3ae Mon Sep 17 00:00:00 2001 From: laisolizq Date: Fri, 17 Nov 2023 12:28:17 +0100 Subject: [PATCH 014/121] fix --- counters/endIncludes.zkasm | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/counters/endIncludes.zkasm b/counters/endIncludes.zkasm index 5027bb08..c7e4d263 100644 --- a/counters/endIncludes.zkasm +++ b/counters/endIncludes.zkasm @@ -1,5 +1,5 @@ INCLUDE "../main/load-tx-rlp-utils.zkasm" -INCLUDE "../main/2-exp.zkasm" +INCLUDE "../main/tables/2-exp.zkasm" INCLUDE "../main/vars.zkasm" INCLUDE "../main/utils.zkasm" INCLUDE "../main/opcodes/calldata-returndata-code.zkasm" diff --git a/package.json b/package.json index 4584cedd..1a3ef8f2 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/l1-info-tree", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256-l1-info-tree", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree-merge", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 67757a6d768822e6c680592e27a52ef68f306903 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Mon, 6 Nov 2023 17:51:06 +0100 Subject: [PATCH 015/121] fix modexp --- main/modexp/modexp_utils.zkasm | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/main/modexp/modexp_utils.zkasm b/main/modexp/modexp_utils.zkasm index 50343d96..7de5a0dc 100644 --- a/main/modexp/modexp_utils.zkasm +++ b/main/modexp/modexp_utils.zkasm @@ -45,12 +45,6 @@ modexp_getBaseMloadX: modexp_getBaseMstore: E :MSTORE(tmpVarEmodexp) - A => E - $ => B :MLOAD(modExpArrayIndex) - $ => A :ADD - 0 => B - $ :EQ,JMPC(modexp_getBaseFinal) - E => A $ => E :MLOAD(modExpArrayIndex) A :MSTORE(modexp_B+E) E + 1 => B :MSTORE(modExpArrayIndex) @@ -110,12 +104,6 @@ modexp_getExpMloadX: modexp_getExpMstore: E :MSTORE(tmpVarEmodexp) - A => E - $ => B :MLOAD(modExpArrayIndex) - $ => A :ADD - 0 => B - $ :EQ,JMPC(modexp_getExpFinal) - E => A $ => E :MLOAD(modExpArrayIndex) A :MSTORE(modexp_E+E) E + 1 => B :MSTORE(modExpArrayIndex) @@ -176,12 +164,6 @@ modexp_getModMloadX: modexp_getModMstore: E :MSTORE(tmpVarEmodexp) - A => E - $ => B :MLOAD(modExpArrayIndex) - $ => A :ADD - 0 => B - $ :EQ,JMPC(modexp_getModFinal) - E => A $ => E :MLOAD(modExpArrayIndex) A :MSTORE(modexp_M+E) E + 1 => B :MSTORE(modExpArrayIndex) From 6a4e8b8bdf1093e594b3196db6cab6f18ac5b1de Mon Sep 17 00:00:00 2001 From: laisolizq Date: Mon, 6 Nov 2023 18:22:06 +0100 Subject: [PATCH 016/121] add edge cases --- main/precompiled/pre-modexp.zkasm | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 781d0998..40908eed 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -164,10 +164,10 @@ dinamicGas: %TX_GAS_LIMIT => B $ :LT,JMPNC(outOfGas) 200 => B - $ :LT,JMPC(callMODEXP) + $ :LT,JMPC(lastChecks) A => B -callMODEXP: +lastChecks: ; B = max(200, multiplication_complexity * iteration_count / 3) GAS - B => GAS :JMPN(outOfGas) 0 => A @@ -194,9 +194,22 @@ callMODEXP: %MAX_SAFE_INTEGER_MODEXP => A $ :LT,JMPC(endMODEXPFail) ; if Msize+offset > MAX_SAFE_INTEGER_MODEXP --> endMODEXPFail :CALL(modexp_getMod) - $ => A :MLOAD(modexp_Elen),JMPZ(modexpExp0) + 1 => B $ => A :MLOAD(modexp_Mlen),JMPZ(modexpMod0) + $ :EQ,JMPNC(checkBaseLen) + $ => A :MLOAD(modexp_M) + $ :EQ,JMPC(save1out) + +checkBaseLen: $ => A :MLOAD(modexp_Blen),JMPZ(modexpBase0) + $ :EQ,JMPNC(checkExpLen) + $ => A :MLOAD(modexp_B) + $ :EQ,JMPC(save1out) + +checkExpLen: + $ => A :MLOAD(modexp_Elen),JMPZ(modexpExp0) + +callMODEXP: :CALL(modexp) :JMP(finalMODEXP) From 04c258cc523fc70bf100e201d24bc8d6a53f167f Mon Sep 17 00:00:00 2001 From: laisolizq Date: Tue, 7 Nov 2023 11:19:55 +0100 Subject: [PATCH 017/121] fix package proverjs --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1a3ef8f2..38d64cf7 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/l1-info-tree", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256-l1-info-tree", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree-merge", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/forkid-6-fix-gas", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 6815c6b84daacdc3bf88d2f198061005bda9a249 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Tue, 7 Nov 2023 17:57:42 +0100 Subject: [PATCH 018/121] fix edge cases & comments --- main/modexp/modexp_utils.zkasm | 47 ++++++++++++++++++++--- main/precompiled/pre-modexp.zkasm | 62 +++++++++++++++++-------------- tools/run-tests-zkasm.js | 1 + 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/main/modexp/modexp_utils.zkasm b/main/modexp/modexp_utils.zkasm index 7de5a0dc..39d5b019 100644 --- a/main/modexp/modexp_utils.zkasm +++ b/main/modexp/modexp_utils.zkasm @@ -15,20 +15,25 @@ modexp_getBase: B :MSTORE(tmpVarBmodexp) C :MSTORE(tmpVarCmodexp) D :MSTORE(tmpVarDmodexp) + ; offset init E :MSTORE(offsetInitModexp) - E + C => E ;E = offset final + ;E = offset final + E + C => E 0 :MSTORE(modExpArrayIndex) 0 :MSTORE(modexp_Blen) 32 :MSTORE(readXFromCalldataLength) modexp_getBaseLoop: + %MAX_CNT_BINARY - CNT_BINARY - 6 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - + ; C length to read C => A 0 => B + ; if C (length) == 0 --> modexp_saveBaseLen $ :EQ,JMPC(modexp_saveBaseLen) 32 => B + ; if C (length) < 32 --> modexp_getBaseMloadX $ :LT,JMPC(modexp_getBaseMloadX) E - 32 => E E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] @@ -44,24 +49,32 @@ modexp_getBaseMloadX: 0 => C modexp_getBaseMstore: + ; mstore base at index E E :MSTORE(tmpVarEmodexp) $ => E :MLOAD(modExpArrayIndex) A :MSTORE(modexp_B+E) + ; update modExpArrayIndex + 1 E + 1 => B :MSTORE(modExpArrayIndex) modexp_getBaseFinal: $ => E :MLOAD(tmpVarEmodexp),JMP(modexp_getBaseLoop) modexp_saveBaseLen: + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + ; if modExpArrayIndex == 0 --> modexp_getReturn $ => A :MLOAD(modExpArrayIndex) 0 => B $ :EQ,JMPC(modexp_getReturn) + ; update modExpArrayIndex = modExpArrayIndex - 1 A - 1 => E :MSTORE(modExpArrayIndex) + ; get value of the last index $ => A :MLOAD(modexp_B + E) + ; if last value == 0 --> modexp_saveBaseLen $ :EQ,JMPC(modexp_saveBaseLen) + ; else Blen == modExpArrayIndex + 1 E + 1 :MSTORE(modexp_Blen),JMP(modexp_getReturn) modexp_getExp: @@ -73,8 +86,10 @@ modexp_getExp: B :MSTORE(tmpVarBmodexp) C :MSTORE(tmpVarCmodexp) D :MSTORE(tmpVarDmodexp) + ; offset init E :MSTORE(offsetInitModexp) - E + C => E ;E = offset final + ;E = offset final + E + C => E 0 :MSTORE(modExpArrayIndex) 0 :MSTORE(modexp_Elen) 32 :MSTORE(readXFromCalldataLength) @@ -83,11 +98,13 @@ modexp_getExpLoop: %MAX_CNT_BINARY - CNT_BINARY - 6 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - + ; C length to read C => A 0 => B + ; if C (length) == 0 --> modexp_saveExpLen $ :EQ,JMPC(modexp_saveExpLen) 32 => B + ; if C (length) < 32 --> modexp_getExpMloadX $ :LT,JMPC(modexp_getExpMloadX) E - 32 => E E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] @@ -103,9 +120,11 @@ modexp_getExpMloadX: 0 => C modexp_getExpMstore: + ; mstore exp at index E E :MSTORE(tmpVarEmodexp) $ => E :MLOAD(modExpArrayIndex) A :MSTORE(modexp_E+E) + ; update modExpArrayIndex + 1 E + 1 => B :MSTORE(modExpArrayIndex) modexp_getExpFinal: @@ -116,12 +135,17 @@ modexp_saveExpLen: %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + ; if modExpArrayIndex == 0 --> modexp_getReturn $ => A :MLOAD(modExpArrayIndex) 0 => B $ :EQ,JMPC(modexp_getReturn) + ; update modExpArrayIndex = modExpArrayIndex - 1 A - 1 => E :MSTORE(modExpArrayIndex) + ; get value of the last index $ => A :MLOAD(modexp_E + E) + ; if last value == 0 --> modexp_saveExpLen $ :EQ,JMPC(modexp_saveExpLen) + ; else Elen == modExpArrayIndex + 1 E + 1 :MSTORE(modexp_Elen),JMP(modexp_getReturn) modexp_getMod: @@ -133,8 +157,10 @@ modexp_getMod: B :MSTORE(tmpVarBmodexp) C :MSTORE(tmpVarCmodexp) D :MSTORE(tmpVarDmodexp) + ; offset init E :MSTORE(offsetInitModexp) - E + C => E ;E = offset final + ;E = offset final + E + C => E 0 :MSTORE(modExpArrayIndex) 0 :MSTORE(modexp_Mlen) 32 :MSTORE(readXFromCalldataLength) @@ -143,11 +169,13 @@ modexp_getModLoop: %MAX_CNT_BINARY - CNT_BINARY - 6 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - + ; C length to read C => A 0 => B + ; if C (length) == 0 --> modexp_saveModLen $ :EQ,JMPC(modexp_saveModLen) 32 => B + ; if C (length) < 32 --> modexp_getModMloadX $ :LT,JMPC(modexp_getModMloadX) E - 32 => E E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] @@ -163,9 +191,11 @@ modexp_getModMloadX: 0 => C modexp_getModMstore: + ; mstore mod at index E E :MSTORE(tmpVarEmodexp) $ => E :MLOAD(modExpArrayIndex) A :MSTORE(modexp_M+E) + ; update modExpArrayIndex + 1 E + 1 => B :MSTORE(modExpArrayIndex) modexp_getModFinal: @@ -176,12 +206,17 @@ modexp_saveModLen: %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + ; if modExpArrayIndex == 0 --> modexp_getReturn $ => A :MLOAD(modExpArrayIndex) 0 => B $ :EQ,JMPC(modexp_getReturn) + ; update modExpArrayIndex = modExpArrayIndex - 1 A - 1 => E :MSTORE(modExpArrayIndex) + ; get value of the last index $ => A :MLOAD(modexp_M + E) + ; if last value == 0 --> modexp_saveModLen $ :EQ,JMPC(modexp_saveModLen) + ; else Mlen == modExpArrayIndex + 1 E + 1 :MSTORE(modexp_Mlen),JMP(modexp_getReturn) modexp_getReturn: diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 40908eed..2d17c6c5 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -64,32 +64,41 @@ funcModexp: ; store offset modexp num values E + 32 => E E :MSTORE(modexp_offset) + ; get exp offset = 96 bytes (Bsize | Esize | Msize) + Bsize $ => A :MLOAD(modexp_Bsize) A :MSTORE(arithA) 96 :MSTORE(arithB),CALL(addARITH) $ => A :MLOAD(arithRes1) $ => B :MLOAD(txCalldataLen) + ; expLenBits = bit length of first 32 bytes of exp 0 :MSTORE(expLenBits) + ; if 96 + Bsize (exp offset) < txCalldataLen --> setExpBits, else --> expLenBits = 0 $ :LT,JMPC(setExpBits,setMaxLen) setExpBits: + ; E exp offset A => E $ => A,C :MLOAD(modexp_Esize) 33 => B + ; A, C = Esize ; if Esize <= 32 --> setExpBitsContinue $ => B :LT,JMPC(setExpBitsContinue) 32 => C setExpBitsContinue: + ; read a length of bytes (C) from exp offset (E) C :MSTORE(readXFromCalldataLength) E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] $ => A :MLOAD(readXFromCalldataResult) + ; A = first 32 bytes of exp 32 - C => D :CALL(SHRarith) A => B :CALL(getLenBits); A bits length first 32 bytes + ; A = bit length of first 32 bytes of exp A :JMPZ(setMaxLen) A - 1 :MSTORE(expLenBits) setMaxLen: + ; set B with max length (max(Blen, Mlen)) $ => B :MLOAD(modexp_Msize) $ => A :MLOAD(modexp_Bsize) $ :LT, JMPC(calculateGas) @@ -107,7 +116,7 @@ calculateGas: $ => B :MLOAD(arithRes1) B :MSTORE(arithA) 8 :MSTORE(arithB),CALL(divARITH) - ; C: words = (max_length + 7) / 8 + ; B: words = (max_length + 7) / 8 $ => B :MLOAD(arithRes1) %MAX_GAS_WORD_MODEXP => A $ :LT,JMPC(outOfGas) @@ -174,7 +183,7 @@ lastChecks: $ => B :MLOAD(modexp_Msize) $ :EQ,JMPC(save0outMod0) ; if Msize = 0 --> save0outMod0 $ => B :MLOAD(modexp_Bsize) - $ :EQ,JMPC(save0out) ; if Bsize = 0 --> save0outMod0 + $ :EQ,JMPC(save0out) ; if Bsize = 0 --> save0out %MAX_SIZE_MODEXP => A $ => B :MLOAD(modexp_Bsize) $ :LT,JMPC(endMODEXPFail) ; if Bsize > MAX_SIZE_MODEXP --> endMODEXPFail @@ -184,48 +193,46 @@ lastChecks: $ :LT,JMPC(endMODEXPFail) ; if Msize > MAX_SIZE_MODEXP --> endMODEXPFail $ => E :MLOAD(modexp_offset) $ => C :MLOAD(modexp_Bsize) + ; get base value :CALL(modexp_getBase) $ => C :MLOAD(modexp_Esize) + ; get exp value :CALL(modexp_getExp) $ => C :MLOAD(modexp_Msize) + ; if Msize+offset > MAX_SAFE_INTEGER_MODEXP --> endMODEXPFail E :MSTORE(arithA) C :MSTORE(arithB),CALL(addARITH) $ => B :MLOAD(arithRes1) %MAX_SAFE_INTEGER_MODEXP => A - $ :LT,JMPC(endMODEXPFail) ; if Msize+offset > MAX_SAFE_INTEGER_MODEXP --> endMODEXPFail + $ :LT,JMPC(endMODEXPFail) + ; get mod value :CALL(modexp_getMod) 1 => B - $ => A :MLOAD(modexp_Mlen),JMPZ(modexpMod0) - $ :EQ,JMPNC(checkBaseLen) + ; if mod == 0 --> return 0 + $ => A :MLOAD(modexp_Mlen),JMPZ(save0out) + ; if Mlen != 1 --> checkBaseLen + $ :EQ,JMPNC(checkExpLen) + ; if Mlen == 1 && mod == 1 --> return 0 $ => A :MLOAD(modexp_M) - $ :EQ,JMPC(save1out) + $ :EQ,JMPC(save0out) + +checkExpLen: + ; if exp == 0 --> return 1 + $ => A :MLOAD(modexp_Elen),JMPZ(save1out) checkBaseLen: - $ => A :MLOAD(modexp_Blen),JMPZ(modexpBase0) - $ :EQ,JMPNC(checkExpLen) + ; if base == 0 --> return 0 + $ => A :MLOAD(modexp_Blen),JMPZ(save0out) + ; if Blen != 1 --> checkExpLen + $ :EQ,JMPNC(callMODEXP) + ; if Blen == 1 && base == 1 --> return 1 $ => A :MLOAD(modexp_B) $ :EQ,JMPC(save1out) -checkExpLen: - $ => A :MLOAD(modexp_Elen),JMPZ(modexpExp0) - callMODEXP: :CALL(modexp) :JMP(finalMODEXP) -modexpBase0: - $ => A :MLOAD(modexp_Elen) - A :JMPZ(save1out) - 0 :MSTORE(modexp_out),JMP(finalMODEXP) - -modexpExp0: -modexpMod0: - $ => A :MLOAD(modexp_Mlen) - 0 :MSTORE(modexp_out) - A :JMPZ(finalMODEXP) - A - 1 :JMPNZ(save1out) - $ => A :MLOAD(modexp_M) - A - 1 :JMPZ(finalMODEXP) save1out: 1 :MSTORE(modexp_out),JMP(finalMODEXP) @@ -236,7 +243,7 @@ save0out: 0 :MSTORE(modexp_out),JMP(finalMODEXP) save0outMod0: - 0 :MSTORE(modexp_out),JMP(endMODEXP) + 0 :MSTORE(modexp_out),JMP(preEndMODEXP) finalMODEXP: @@ -296,7 +303,8 @@ endMODEXPFail: CTX :MSTORE(currentCTX), JMP(preEndFail) preEndMODEXP: - $ => CTX :MLOAD(originCTX) + $ => A :MLOAD(originCTX), JMPZ(handleGas) + A => CTX endMODEXP: - CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file + CTX :MSTORE(currentCTX),JMP(preEnd) \ No newline at end of file diff --git a/tools/run-tests-zkasm.js b/tools/run-tests-zkasm.js index 888871d7..95e8db08 100644 --- a/tools/run-tests-zkasm.js +++ b/tools/run-tests-zkasm.js @@ -54,6 +54,7 @@ async function runTest(pathTest, cmPols) { let failed = false; // execute zkasm tests try { + console.log(chalk.blue(' --> start'), pathTest); const rom = await zkasm.compile(pathTest, null, configZkasm); const result = await smMain.execute(cmPols.Main, emptyInput, rom, config); console.log(chalk.green(' --> pass'), pathTest); From 4ece98cf0b86a2aeadea62e335a6606589988a0c Mon Sep 17 00:00:00 2001 From: laisolizq Date: Thu, 9 Nov 2023 00:31:55 +0100 Subject: [PATCH 019/121] update pre-sha256 --- main/precompiled/pre-sha2-256.zkasm | 24 ++++++------------------ package.json | 4 ++-- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 658f8126..2fccea2c 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -40,39 +40,28 @@ funcSHA2256: 0 :MSTORE(retDataOffset) 32 :MSTORE(retDataLength) 32 :MSTORE(readXFromCalldataLength) + + $ => E :MLOAD(sha256DataId) + 0 => E :MSTORE(sha256DataOffset) 0 => HASHPOS :CALL(SHA2256data) - ; get & update sha256Data ID - $ => E :MLOAD(sha256DataId) - E + 1 :MSTORE(sha256DataId) - - ; copy sha256 to retData (hash 32 bytes) - 0 => E - A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] SHA2256dataReturn: + E + 1 :MSTORE(sha256DataId) ; handle CTX $ => A :MLOAD(originCTX), JMPZ(handleGas) ; set retDataCTX $ => B :MLOAD(currentCTX) A => CTX B :MSTORE(retDataCTX) - B => CTX ; Copy from memory current CTX to memory origin CTX + $ => A :MLOAD(sha256Hash) 0 => E - $ => C :MLOAD(retCallLength) - ; MLOAD memory current CTX - :CALL(MLOADX) - $ => E :MLOAD(retCallOffset) - $ => CTX :MLOAD(originCTX) - ; MSTORE memory origint CTX - A :MSTORE(bytesToStore), CALL(MSTOREX) - ; set currentCTX + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] CTX :MSTORE(currentCTX), JMP(preEnd) SHA2256data: RR :MSTORE(tmpZkSHA256) - 0 => E :MSTORE(sha256DataOffset) SHA2256dataLoop: ; Copy from calldata to hashS @@ -101,7 +90,6 @@ SHA2256dataFinal: A :HASHS(E) SHA2256: - $ => E :MLOAD(sha256DataId) HASHPOS :HASHSLEN(E) $ => A :HASHSDIGEST(E) A :MSTORE(sha256Hash) diff --git a/package.json b/package.json index 38d64cf7..b0ec114e 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/forkid-6-fix-gas", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/sha256", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 7ba53dab56698d00376dea22eeef38fc6de1218c Mon Sep 17 00:00:00 2001 From: laisolizq Date: Fri, 10 Nov 2023 19:14:59 +0100 Subject: [PATCH 020/121] update counters --- main/precompiled/pre-ecAdd.zkasm | 5 ++--- main/precompiled/pre-sha2-256.zkasm | 22 ++++++++++++++++++---- main/utils.zkasm | 2 ++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/main/precompiled/pre-ecAdd.zkasm b/main/precompiled/pre-ecAdd.zkasm index 890e3e56..b064a899 100644 --- a/main/precompiled/pre-ecAdd.zkasm +++ b/main/precompiled/pre-ecAdd.zkasm @@ -9,10 +9,9 @@ * - stack output: [x, y] */ funcEcAdd: - - %MAX_CNT_BINARY - CNT_BINARY - 10 :JMPN(outOfCountersBinary) %MAX_CNT_ARITH - CNT_ARITH - 50 :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 50 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 800 :JMPN(outOfCountersStep) ; Move balances if value > 0 just before executing the contract CALL $ => B :MLOAD(txValue) diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 2fccea2c..6c6fddcc 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -14,8 +14,9 @@ VAR GLOBAL sha256Hash VAR GLOBAL tmpZkSHA256 funcSHA2256: - ;%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - ;%MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) ; Move balances if value > 0 just before executing the contract CALL $ => B :MLOAD(txValue) @@ -47,7 +48,10 @@ funcSHA2256: :CALL(SHA2256data) SHA2256dataReturn: - E + 1 :MSTORE(sha256DataId) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + ; handle CTX $ => A :MLOAD(originCTX), JMPZ(handleGas) ; set retDataCTX @@ -64,6 +68,9 @@ SHA2256data: RR :MSTORE(tmpZkSHA256) SHA2256dataLoop: + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + ; Copy from calldata to hashS C :JMPZ(SHA2256) C - 32 :JMPN(SHA2256dataFinal) @@ -75,10 +82,13 @@ SHA2256dataLoop: $ => E :MLOAD(sha256DataId) 32 => D A :HASHS(E) - C - 32 => C :JMP(SHA2256dataLoop) SHA2256dataFinal: + %MAX_CNT_STEPS - STEP - 300 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 15 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 10 :JMPN(outOfCountersArith) + $ => E :MLOAD(sha256DataOffset) C :MSTORE(readXFromCalldataLength) E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] @@ -90,6 +100,10 @@ SHA2256dataFinal: A :HASHS(E) SHA2256: + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_SHA256_F - 1 :JMPN(outOfCountersSha256) + + $ => E :MLOAD(sha256DataId) HASHPOS :HASHSLEN(E) $ => A :HASHSDIGEST(E) A :MSTORE(sha256Hash) diff --git a/main/utils.zkasm b/main/utils.zkasm index e9a81870..1739457c 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -839,6 +839,8 @@ outOfCountersPadding: $${eventLog(onError, OOCPA)} :JMP(handleBatchError) outOfCountersPoseidon: $${eventLog(onError, OOCPO)} :JMP(handleBatchError) +outOfCountersSha256: + $${eventLog(onError, OOCSH)} :JMP(handleBatchError) invalidChangeL2Block: $${eventLog(onError, invalid_change_l2_block)} :JMP(handleBatchError) outOfGas: From 6c3652d2d24a96f4d4a700646ba74dec403d5988 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Tue, 21 Nov 2023 11:57:34 +0100 Subject: [PATCH 021/121] fix merge --- main/precompiled/pre-sha2-256.zkasm | 22 +++++++++++++++++----- package.json | 6 +++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 6c6fddcc..1f878c1d 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -41,11 +41,15 @@ funcSHA2256: 0 :MSTORE(retDataOffset) 32 :MSTORE(retDataLength) 32 :MSTORE(readXFromCalldataLength) - - $ => E :MLOAD(sha256DataId) - 0 => E :MSTORE(sha256DataOffset) 0 => HASHPOS :CALL(SHA2256data) + ; get & update sha256Data ID + $ => E :MLOAD(sha256DataId) + E + 1 :MSTORE(sha256DataId) + + ; copy sha256 to retData (hash 32 bytes) + 0 => E + A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] SHA2256dataReturn: %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) @@ -58,14 +62,22 @@ SHA2256dataReturn: $ => B :MLOAD(currentCTX) A => CTX B :MSTORE(retDataCTX) + B => CTX ; Copy from memory current CTX to memory origin CTX - $ => A :MLOAD(sha256Hash) 0 => E - A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] + $ => C :MLOAD(retCallLength) + ; MLOAD memory current CTX + :CALL(MLOADX) + $ => E :MLOAD(retCallOffset) + $ => CTX :MLOAD(originCTX) + ; MSTORE memory origint CTX + A :MSTORE(bytesToStore), CALL(MSTOREX) + ; set currentCTX CTX :MSTORE(currentCTX), JMP(preEnd) SHA2256data: RR :MSTORE(tmpZkSHA256) + 0 => E :MSTORE(sha256DataOffset) SHA2256dataLoop: %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) diff --git a/package.json b/package.json index b0ec114e..1a3ef8f2 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/forkid-6-fix-gas", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/sha256", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/l1-info-tree", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256-l1-info-tree", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree-merge", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 346f404831a3c3a2331f1580103c997524fe1f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 22 Nov 2023 12:38:17 +0100 Subject: [PATCH 022/121] The input length was found to be 1818 --- main/modexp/array_lib/array_add_AGTB.zkasm | 10 +- main/modexp/array_lib/array_add_short.zkasm | 8 +- main/modexp/array_lib/array_div_mod.zkasm | 12 +- .../modexp/array_lib/array_div_mod_long.zkasm | 12 +- .../array_lib/array_div_mod_short.zkasm | 8 +- main/modexp/array_lib/array_mul.zkasm | 10 +- main/modexp/array_lib/array_mul_long.zkasm | 10 +- main/modexp/array_lib/array_mul_short.zkasm | 6 +- main/modexp/array_lib/array_square.zkasm | 6 +- main/modexp/array_lib/unused/array_add.zkasm | 10 +- .../array_lib/unused/array_is_one.zkasm | 2 +- .../array_lib/unused/array_is_zero.zkasm | 2 +- .../array_lib/unused/array_sub_AGTB.zkasm | 10 +- .../array_lib/unused/array_unshift.zkasm | 4 +- .../array_lib/utils/array_compare.zkasm | 8 +- main/modexp/array_lib/utils/array_trim.zkasm | 4 +- main/modexp/modexp.zkasm | 88 +-- test/testArrayArith.zkasm | 7 +- test/testModExp.zkasm | 544 ++++++++++-------- 19 files changed, 397 insertions(+), 364 deletions(-) diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index 2eda6c1f..2425bb48 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -4,8 +4,8 @@ ;; ;; array_add_AGTB: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -38,9 +38,9 @@ ; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead if possible. -VAR GLOBAL array_add_AGTB_inA[839] -VAR GLOBAL array_add_AGTB_inB[839] -VAR GLOBAL array_add_AGTB_out[840] +VAR GLOBAL array_add_AGTB_inA[1818] +VAR GLOBAL array_add_AGTB_inB[1818] +VAR GLOBAL array_add_AGTB_out[1819] VAR GLOBAL array_add_AGTB_len_inA VAR GLOBAL array_add_AGTB_len_inB VAR GLOBAL array_add_AGTB_len_out diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index f2466d70..6861f880 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -2,7 +2,7 @@ ;; ;; array_add_short: ;; in: -;; · C ∈ [1, 839], the len of inA +;; · C ∈ [1, 1818], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -27,10 +27,10 @@ ; return result; ; } -VAR GLOBAL array_add_short_inA[839] -VAR GLOBAL array_add_short_len_inA +VAR GLOBAL array_add_short_inA[1818] VAR GLOBAL array_add_short_inB -VAR GLOBAL array_add_short_out[840] +VAR GLOBAL array_add_short_out[1819] +VAR GLOBAL array_add_short_len_inA VAR GLOBAL array_add_short_len_out VAR GLOBAL array_add_short_carry diff --git a/main/modexp/array_lib/array_div_mod.zkasm b/main/modexp/array_lib/array_div_mod.zkasm index cc7a7775..9781699c 100644 --- a/main/modexp/array_lib/array_div_mod.zkasm +++ b/main/modexp/array_lib/array_div_mod.zkasm @@ -4,8 +4,8 @@ ;; ;; array_div_mod: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -35,10 +35,10 @@ ; return array_div_mod_long(a, b, B); ; } -VAR GLOBAL array_div_mod_inA[839] -VAR GLOBAL array_div_mod_inB[839] -VAR GLOBAL array_div_mod_quo[839] -VAR GLOBAL array_div_mod_rem[839] +VAR GLOBAL array_div_mod_inA[1818] +VAR GLOBAL array_div_mod_inB[1818] +VAR GLOBAL array_div_mod_quo[1818] +VAR GLOBAL array_div_mod_rem[1818] VAR GLOBAL array_div_mod_len_inA VAR GLOBAL array_div_mod_len_inB diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm index f3e897ab..bd43c142 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -4,8 +4,8 @@ ;; ;; array_div_mod_long: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -33,10 +33,10 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_long_inA[839] -VAR GLOBAL array_div_mod_long_inB[839] -VAR GLOBAL array_div_mod_long_quo[838] -VAR GLOBAL array_div_mod_long_rem[839] +VAR GLOBAL array_div_mod_long_inA[1818] +VAR GLOBAL array_div_mod_long_inB[1818] +VAR GLOBAL array_div_mod_long_quo[1818] +VAR GLOBAL array_div_mod_long_rem[1818] VAR GLOBAL array_div_mod_long_len_inA VAR GLOBAL array_div_mod_long_len_inB diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm index 9b4be528..2e678c7b 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -4,12 +4,12 @@ ;; ;; array_div_mod_short: ;; in: -;; · C ∈ [1, 839], the len of inA +;; · C ∈ [1, 1818], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; ;; output: -;; · [quo,rem] = [inA / inB[0], inA % inB[0]], with len(quo) <= C - 1, len(rem) = 1 +;; · [quo,rem] = [inA / inB[0], inA % inB[0]], with len(quo) <= C, len(rem) = 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_div_mod_short(a: bigint[], b: bigint, B: bigint): bigint[] { @@ -32,9 +32,9 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_short_inA[839] +VAR GLOBAL array_div_mod_short_inA[1818] VAR GLOBAL array_div_mod_short_inB -VAR GLOBAL array_div_mod_short_quo[838] +VAR GLOBAL array_div_mod_short_quo[1818] VAR GLOBAL array_div_mod_short_rem VAR GLOBAL array_div_mod_short_len_inA diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm index 1831bc4a..160cb253 100644 --- a/main/modexp/array_lib/array_mul.zkasm +++ b/main/modexp/array_lib/array_mul.zkasm @@ -3,8 +3,8 @@ ;; ;; array_mul: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -19,9 +19,9 @@ ; return array_mul_long(a, b, B); ; } -VAR GLOBAL array_mul_inA[839] -VAR GLOBAL array_mul_inB[839] -VAR GLOBAL array_mul_out[1678] +VAR GLOBAL array_mul_inA[1818] +VAR GLOBAL array_mul_inB[1818] +VAR GLOBAL array_mul_out[3636] VAR GLOBAL array_mul_len_inA VAR GLOBAL array_mul_len_inB VAR GLOBAL array_mul_len_out diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index 8842a02f..56a04fed 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -4,8 +4,8 @@ ;; ;; array_mul_long: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -36,9 +36,9 @@ ; return result; ; } -VAR GLOBAL array_mul_long_inA[839] -VAR GLOBAL array_mul_long_inB[839] -VAR GLOBAL array_mul_long_out[1678] +VAR GLOBAL array_mul_long_inA[1818] +VAR GLOBAL array_mul_long_inB[1818] +VAR GLOBAL array_mul_long_out[3636] VAR GLOBAL array_mul_long_len_inA VAR GLOBAL array_mul_long_len_inB VAR GLOBAL array_mul_long_len_out diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index debafbb3..219f78c1 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -3,7 +3,7 @@ ;; ;; array_mul_short: ;; in: -;; · C ∈ [1, 839], the len of inA +;; · C ∈ [1, 1818], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -32,9 +32,9 @@ ; return result; ; } -VAR GLOBAL array_mul_short_inA[839] +VAR GLOBAL array_mul_short_inA[1818] VAR GLOBAL array_mul_short_inB -VAR GLOBAL array_mul_short_out[840] +VAR GLOBAL array_mul_short_out[1819] VAR GLOBAL array_mul_short_len_inA VAR GLOBAL array_mul_short_len_out diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index f52aba25..5d8bf6c9 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -3,7 +3,7 @@ ;; ;; array_square: ;; in: -;; · C ∈ [1, 839], the len of in +;; · C ∈ [1, 1818], the len of in ;; · in ∈ [0, 2²⁵ ⁶- 1]^C, the input array ;; ;; output: @@ -33,8 +33,8 @@ ; return result; ; } -VAR GLOBAL array_square_in[839] -VAR GLOBAL array_square_out[1678] +VAR GLOBAL array_square_in[1818] +VAR GLOBAL array_square_out[3636] VAR GLOBAL array_square_len_in VAR GLOBAL array_square_len_out diff --git a/main/modexp/array_lib/unused/array_add.zkasm b/main/modexp/array_lib/unused/array_add.zkasm index 3a50bbba..4f5277bf 100644 --- a/main/modexp/array_lib/unused/array_add.zkasm +++ b/main/modexp/array_lib/unused/array_add.zkasm @@ -2,8 +2,8 @@ ;; ;; array_add: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -11,9 +11,9 @@ ;; · out = inA + inB, with len(out) <= C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_add_inA[839] -VAR GLOBAL array_add_inB[839] -VAR GLOBAL array_add_out[840] +VAR GLOBAL array_add_inA[1818] +VAR GLOBAL array_add_inB[1818] +VAR GLOBAL array_add_out[1819] VAR GLOBAL array_add_len_inA VAR GLOBAL array_add_len_inB VAR GLOBAL array_add_len_out diff --git a/main/modexp/array_lib/unused/array_is_one.zkasm b/main/modexp/array_lib/unused/array_is_one.zkasm index 9d37d24f..ab3b5b39 100644 --- a/main/modexp/array_lib/unused/array_is_one.zkasm +++ b/main/modexp/array_lib/unused/array_is_one.zkasm @@ -3,7 +3,7 @@ ;; ;; array_is_one: ;; in: -;; · C ∈ [1, 839], the len of in +;; · C ∈ [1, 1818], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; output: ;; · 1, if in = 1 diff --git a/main/modexp/array_lib/unused/array_is_zero.zkasm b/main/modexp/array_lib/unused/array_is_zero.zkasm index ca532aeb..3990c2cf 100644 --- a/main/modexp/array_lib/unused/array_is_zero.zkasm +++ b/main/modexp/array_lib/unused/array_is_zero.zkasm @@ -3,7 +3,7 @@ ;; ;; array_is_zero: ;; in: -;; · C ∈ [1, 839], the len of in +;; · C ∈ [1, 1818], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; output: ;; · 1, if in = 0 diff --git a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm index 062af851..bcc72761 100644 --- a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +++ b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm @@ -3,8 +3,8 @@ ;; ;; array_sub_AGTB: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -12,9 +12,9 @@ ;; · out = inA - inB, with len(out) <= C ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_sub_AGTB_inA[839] -VAR GLOBAL array_sub_AGTB_inB[839] -VAR GLOBAL array_sub_AGTB_out[839] +VAR GLOBAL array_sub_AGTB_inA[1818] +VAR GLOBAL array_sub_AGTB_inB[1818] +VAR GLOBAL array_sub_AGTB_out[1818] VAR GLOBAL array_sub_AGTB_len_inA VAR GLOBAL array_sub_AGTB_len_inB diff --git a/main/modexp/array_lib/unused/array_unshift.zkasm b/main/modexp/array_lib/unused/array_unshift.zkasm index a9cbb23a..3fd3e76b 100644 --- a/main/modexp/array_lib/unused/array_unshift.zkasm +++ b/main/modexp/array_lib/unused/array_unshift.zkasm @@ -2,7 +2,7 @@ ;; ;; array_unshift: ;; in: -;; · C ∈ [1, 839], the len of in = [in[0], in[1], ..., in[C - 1]] +;; · C ∈ [1, 1818], the len of in = [in[0], in[1], ..., in[C - 1]] ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; · D ∈ [0, 2²⁵⁶ - 1], the element to unshift ;; @@ -11,7 +11,7 @@ ;; · len = C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_unshift_in[839] +VAR GLOBAL array_unshift_in[1818] VAR GLOBAL array_unshift_len VAR GLOBAL array_unshift_RR diff --git a/main/modexp/array_lib/utils/array_compare.zkasm b/main/modexp/array_lib/utils/array_compare.zkasm index ea2cd5a2..7e2db778 100644 --- a/main/modexp/array_lib/utils/array_compare.zkasm +++ b/main/modexp/array_lib/utils/array_compare.zkasm @@ -3,8 +3,8 @@ ;; ;; array_compare: ;; in: -;; · C ∈ [1, 839], the len of inA -;; · D ∈ [1, 839], the len of inB +;; · C ∈ [1, 1818], the len of inA +;; · D ∈ [1, 1818], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -37,8 +37,8 @@ ; · inA < inB and lenA = lenB. ; ---------------------------------- -VAR GLOBAL array_compare_inA[839] -VAR GLOBAL array_compare_inB[839] +VAR GLOBAL array_compare_inA[1818] +VAR GLOBAL array_compare_inB[1818] VAR GLOBAL array_compare_result diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm index 547fe78b..8dd46382 100644 --- a/main/modexp/array_lib/utils/array_trim.zkasm +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -2,7 +2,7 @@ ;; ;; array_trim: ;; in: -;; · C ∈ [1, 839], the len of in +;; · C ∈ [1, 3636], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; ;; output: @@ -18,7 +18,7 @@ ; a.length = i + 1; ; } -VAR GLOBAL array_trim_in[839] +VAR GLOBAL array_trim_in[3636] VAR GLOBAL array_trim_RR diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 86971bfc..3112b0c7 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -5,9 +5,9 @@ ;; modexp: ;; ---------------------------------------- ;; input: -;; · Blen ∈ [1, 839], the len of B -;; · Elen ∈ [1, 839], the len of E -;; · Mlen ∈ [1, 839], the len of M +;; · Blen ∈ [1, 1818], the len of B +;; · Elen ∈ [1, 1818], the len of E +;; · Mlen ∈ [1, 1818], the len of M ;; · B ∈ [0, 2²⁵⁶ - 1]^Blen, the base represented in little-endian ;; · E ∈ [0, 2²⁵⁶ - 1]^Elen, the exponent represented in little-endian ;; · M ∈ [0, 2²⁵⁶ - 1]^Mlen, the modulus represented in little-endian @@ -51,11 +51,11 @@ VAR GLOBAL modexp_Blen VAR GLOBAL modexp_Elen VAR GLOBAL modexp_Mlen -VAR GLOBAL modexp_B[839] -VAR GLOBAL modexp_E[839] -VAR GLOBAL modexp_M[839] +VAR GLOBAL modexp_B[1818] +VAR GLOBAL modexp_E[1818] +VAR GLOBAL modexp_M[1818] -VAR GLOBAL modexp_out[839] +VAR GLOBAL modexp_out[1818] VAR GLOBAL modexp_outlen VAR GLOBAL modexp_RR @@ -67,56 +67,8 @@ modexp: RR :MSTORE(modexp_RR) - ; Edge cases - ; 1] Is M = 0? - $ => A :MLOAD(modexp_Mlen) - 1 => B - $ :EQ, JMPNC(modexp_M_continue1) - $ => A :MLOAD(modexp_M) - 0 => B - $ :EQ, JMPC(modexp_M_is_zero) - modexp_M_continue1: - ; From here, M > 0 - - ; 2] Is M = 1? - $ => A :MLOAD(modexp_Mlen) - 1 => B - $ :EQ, JMPNC(modexp_M_continue2) - $ => A :MLOAD(modexp_M) - 1 => B - $ :EQ, JMPC(modexp_M_is_one) - modexp_M_continue2: - ; From here, M > 1 - - ; 3] Is B = 0? - $ => A :MLOAD(modexp_Blen) - 1 => B - $ :EQ, JMPNC(modexp_B_continue1) - $ => A :MLOAD(modexp_B) - 0 => B - $ :EQ, JMPC(modexp_B_is_zero) - modexp_B_continue1: - ; From here, B > 0 - - ; 4] Is B = 1? - $ => A :MLOAD(modexp_Blen) - 1 => B - $ :EQ, JMPNC(modexp_B_continue2) - $ => A :MLOAD(modexp_B) - 1 => B - $ :EQ, JMPC(modexp_B_is_one) - modexp_B_continue2: - ; From here, B > 1 - - ; 5] Is E = 0? - $ => A :MLOAD(modexp_Elen) - 1 => B - $ :EQ, JMPNC(modexp_E_continue1) - $ => A :MLOAD(modexp_E) - 0 => B - $ :EQ, JMPC(modexp_E_is_zero) - modexp_E_continue1: - ; From here, E > 0 + ; I do not need to cover edge cases here since they are covered in the pre-modexp file + ; Therefore, I can assume that M > 1, B > 1, E > 0 1 :MSTORE(modexp_out) 1 :MSTORE(modexp_outlen) @@ -162,30 +114,10 @@ modexp_rem_from_divmod1: ; ------------------- ; Begin of edge cases -modexp_M_is_zero: - ; (B^E) % 0 = 0 - 1 :MSTORE(modexp_outlen) - 0 :MSTORE(modexp_out), JMP(modexp_end) - -modexp_M_is_one: - ; (B^E) % 1 = 0 - 1 :MSTORE(modexp_outlen) - 0 :MSTORE(modexp_out), JMP(modexp_end) - modexp_B_is_zero: - ; (0^E) % M = 0. I define 0^0 = 0 for simplicity + ; (0^E) % M = 0. 1 :MSTORE(modexp_outlen) 0 :MSTORE(modexp_out), JMP(modexp_end) - -modexp_B_is_one: - ; (1^E) % M = 1 - 1 :MSTORE(modexp_outlen) - 1 :MSTORE(modexp_out), JMP(modexp_end) - -modexp_E_is_zero: - ; (B^0) % M = 1 - 1 :MSTORE(modexp_outlen) - 1 :MSTORE(modexp_out), JMP(modexp_end) ; End of edge cases ; Begin of branching diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index d50c53aa..7ff129b1 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -940,9 +940,14 @@ start: 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_div_mod_quo + E) ; --------------------------------------------------------------- -outOfCountersArith: + :JMP(end) + outOfCountersBinary: + ${dump(CNT_BINARY)} :JMP(end) outOfCountersStep: + ${dump(STEP)} :JMP(end) +outOfCountersArith: + ${dump(CNT_ARITH)} :JMP(end) end: diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index 99d6efdd..61acf4c2 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -41,220 +41,221 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; EDGE CASES - ; --------------------------------------------------------------------------------------------- - ; 1] B == 0, E != 0, M != 0 should return 0 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 3n :MSTORE(modexp_E) - 4n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - 1 :MSTORE(modexp_Blen) - 2 :MSTORE(modexp_Elen) - 2 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 0n :MSTORE(modexp_E) - 1 => E - 1n :MSTORE(modexp_E + E) - 0n :MSTORE(modexp_M) - 1 => E - 1n :MSTORE(modexp_M + E) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 2] B != 0, E == 0, M != 0 should return 1 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 2n :MSTORE(modexp_B) - 0n :MSTORE(modexp_E) - 4n :MSTORE(modexp_M) - :CALL(modexp) - - 1n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - 2 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 2 :MSTORE(modexp_Mlen) - - 2n :MSTORE(modexp_B) - 1 => E - 4n :MSTORE(modexp_B + E) - 0n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) - 1 => E - 1n :MSTORE(modexp_M + E) - :CALL(modexp) - - 1n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 3] B != 0, E != 0, M == 0 should return 0 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 2n :MSTORE(modexp_B) - 1n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) - :CALL(modexp) - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - 2 :MSTORE(modexp_Blen) - 2 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 2n :MSTORE(modexp_B) - 1 => E - 4n :MSTORE(modexp_B + E) - 0n :MSTORE(modexp_E) - 1 => E - 4n :MSTORE(modexp_E + E) - 0n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 4] B != 0, E != 0, M == 1 should return 0 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 2n :MSTORE(modexp_B) - 1n :MSTORE(modexp_E) - 1n :MSTORE(modexp_M) - :CALL(modexp) - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - 2 :MSTORE(modexp_Blen) - 2 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 2n :MSTORE(modexp_B) - 1 => E - 4n :MSTORE(modexp_B + E) - 0n :MSTORE(modexp_E) - 1 => E - 4n :MSTORE(modexp_E + E) - 1n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 5] B == 0, E == 0, M != 0 should return 0^0 = 0 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 0n :MSTORE(modexp_E) - 4n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 2 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 0n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) - 1 => E - 1n :MSTORE(modexp_M + E) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 6] B == 0, E != 0, M == 0 should return 0 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 4n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - 1 :MSTORE(modexp_Blen) - 2 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 0n :MSTORE(modexp_E) - 1 => E - 1n :MSTORE(modexp_E + E) - 0n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 7] B != 0, E == 0, M == 0 should return 0 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 1n :MSTORE(modexp_B) - 0n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - 2 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 1 => E - 1n :MSTORE(modexp_B + E) - 0n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 8] B == 0, E == 0, M == 0 should return 0 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 0n :MSTORE(modexp_B) - 0n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) - :CALL(modexp) - - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - ; --------------------------------------------------------------------------------------------- + ; ; UPDATE: Edge cases are not handled by the modexp function directly + ; ; EDGE CASES TESTS + ; ; --------------------------------------------------------------------------------------------- + ; ; 1] B == 0, E != 0, M != 0 should return 0 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 3n :MSTORE(modexp_E) + ; 4n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; 1 :MSTORE(modexp_Blen) + ; 2 :MSTORE(modexp_Elen) + ; 2 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 0n :MSTORE(modexp_E) + ; 1 => E + ; 1n :MSTORE(modexp_E + E) + ; 0n :MSTORE(modexp_M) + ; 1 => E + ; 1n :MSTORE(modexp_M + E) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; ; 2] B != 0, E == 0, M != 0 should return 1 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 2n :MSTORE(modexp_B) + ; 0n :MSTORE(modexp_E) + ; 4n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 1n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; 2 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 2 :MSTORE(modexp_Mlen) + + ; 2n :MSTORE(modexp_B) + ; 1 => E + ; 4n :MSTORE(modexp_B + E) + ; 0n :MSTORE(modexp_E) + ; 0n :MSTORE(modexp_M) + ; 1 => E + ; 1n :MSTORE(modexp_M + E) + ; :CALL(modexp) + + ; 1n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; ; 3] B != 0, E != 0, M == 0 should return 0 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 2n :MSTORE(modexp_B) + ; 1n :MSTORE(modexp_E) + ; 0n :MSTORE(modexp_M) + ; :CALL(modexp) + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; 2 :MSTORE(modexp_Blen) + ; 2 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 2n :MSTORE(modexp_B) + ; 1 => E + ; 4n :MSTORE(modexp_B + E) + ; 0n :MSTORE(modexp_E) + ; 1 => E + ; 4n :MSTORE(modexp_E + E) + ; 0n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; ; 4] B != 0, E != 0, M == 1 should return 0 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 2n :MSTORE(modexp_B) + ; 1n :MSTORE(modexp_E) + ; 1n :MSTORE(modexp_M) + ; :CALL(modexp) + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; 2 :MSTORE(modexp_Blen) + ; 2 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 2n :MSTORE(modexp_B) + ; 1 => E + ; 4n :MSTORE(modexp_B + E) + ; 0n :MSTORE(modexp_E) + ; 1 => E + ; 4n :MSTORE(modexp_E + E) + ; 1n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; ; 5] B == 0, E == 0, M != 0 should return 0^0 = 0 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 0n :MSTORE(modexp_E) + ; 4n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 2 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 0n :MSTORE(modexp_E) + ; 0n :MSTORE(modexp_M) + ; 1 => E + ; 1n :MSTORE(modexp_M + E) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; ; 6] B == 0, E != 0, M == 0 should return 0 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 4n :MSTORE(modexp_E) + ; 0n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; 1 :MSTORE(modexp_Blen) + ; 2 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 0n :MSTORE(modexp_E) + ; 1 => E + ; 1n :MSTORE(modexp_E + E) + ; 0n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; ; 7] B != 0, E == 0, M == 0 should return 0 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 1n :MSTORE(modexp_B) + ; 0n :MSTORE(modexp_E) + ; 0n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; 2 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 1 => E + ; 1n :MSTORE(modexp_B + E) + ; 0n :MSTORE(modexp_E) + ; 0n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + + ; ; 8] B == 0, E == 0, M == 0 should return 0 + ; 1 :MSTORE(modexp_Blen) + ; 1 :MSTORE(modexp_Elen) + ; 1 :MSTORE(modexp_Mlen) + + ; 0n :MSTORE(modexp_B) + ; 0n :MSTORE(modexp_E) + ; 0n :MSTORE(modexp_M) + ; :CALL(modexp) + + ; 0n :MLOAD(modexp_out) + ; 1 :MLOAD(modexp_outlen) + ; ; --------------------------------------------------------------------------------------------- ; 256 BITS EXPONENT TESTS ; --------------------------------------------------------------------------------------------- - ; 1] B = [100n, 2831023n, 0n, 73916234139162n], E = [115792089237316195423570985008687907853269984665640564039457584007913129639935n], M = [0n, 0n, 8238129386n, 23102318237n] + ; 1] B = [100n, 2831023n, 0n, 73916234139162n], E = [2n**256n - 1n], M = [0n, 0n, 8238129386n, 23102318237n] ; Hamming weight of E is 256 4 :MSTORE(modexp_Blen) 1 :MSTORE(modexp_Elen) @@ -347,6 +348,23 @@ start: 7 => E 511131288598502431475n :MLOAD(modexp_out + E) 8 :MLOAD(modexp_outlen) + + ; 3] B = [7n], E = [110n], M = [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] + ; Hamming weight of E is 5 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 2 :MSTORE(modexp_Mlen) + + 7n :MSTORE(modexp_B) + 110n :MSTORE(modexp_E) + 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(modexp_M) + 1 => E + 17n :MSTORE(modexp_M + E) + :CALL(modexp) + 81730215206688390341255830729934766338330049967253209305087427132484271882414n :MLOAD(modexp_out) + 1 => E + 13n :MLOAD(modexp_out + E) + 2 :MLOAD(modexp_outlen) ; --------------------------------------------------------------------------------------------- ; 512 BITS EXPONENT TESTS @@ -380,22 +398,34 @@ start: 1n :MLOAD(modexp_out + E) 3 :MLOAD(modexp_outlen) - ; 2] B = [7n], E = [110n], M = [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] - ; Hamming weight of E is 5 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 2 :MSTORE(modexp_Mlen) + ; 2] B = [2n, 1n, 1n, 1n], E = [2n**256n - 1n, 2n**256n - 1n], M = [4n, 6n, 7n] + ; Hamming weight of E is 512 + 4 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 3 :MSTORE(modexp_Mlen) - 7n :MSTORE(modexp_B) - 110n :MSTORE(modexp_E) - 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(modexp_M) + 2n :MSTORE(modexp_B) 1 => E - 17n :MSTORE(modexp_M + E) + 1n :MSTORE(modexp_B + E) + 2 => E + 1n :MSTORE(modexp_B + E) + 3 => E + 1n :MSTORE(modexp_B + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E + E) + 4n :MSTORE(modexp_M) + 1 => E + 6n :MSTORE(modexp_M + E) + 2 => E + 7n :MSTORE(modexp_M + E) :CALL(modexp) - 81730215206688390341255830729934766338330049967253209305087427132484271882414n :MLOAD(modexp_out) + 111873638420780286093512129901489267041413036926649390648147612881355784341812n :MLOAD(modexp_out) 1 => E - 13n :MLOAD(modexp_out + E) - 2 :MLOAD(modexp_outlen) + 11181991619082508729788448443921623930160246165837402400671610626538926623319n :MLOAD(modexp_out + E) + 2 => E + 2n :MLOAD(modexp_out + E) + 3 :MLOAD(modexp_outlen) ; --------------------------------------------------------------------------------------------- ; 768 BITS EXPONENT TESTS @@ -406,9 +436,75 @@ start: ; --------------------------------------------------------------------------------------------- ; --------------------------------------------------------------------------------------------- -outOfCountersArith: + ; SINGLETON TESTS TO ENSURE THE MAXIMUM INPUT LENGTH WE CAN ACHIEVE IN EACH OF BASE, EXPONENT + ; AND MODULUS WITHOUT OVERFLOWING EITHER THE ARITH, BINARY OF STEPS COUNTERS + ; --------------------------------------------------------------------------------------------- + ; 1] B = [2n:1818n], E = [1n], M = [2n] + ; Hamming weight of E is 1 + 1818 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 1818 => E +singleton_test1_copy_in_loop: + E - 1 => E + 2 :MSTORE(modexp_B + E) + E :JMPZ(singleton_test1_modexp, singleton_test1_copy_in_loop) + +singleton_test1_modexp: + 1n :MSTORE(modexp_E) + 2n :MSTORE(modexp_M) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 2] B = [2n], E = [1n], M = [2n:1818] + ; Hamming weight of E is 1 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1818 :MSTORE(modexp_Mlen) + + 1818 => E +singleton_test2_copy_in_loop: + E - 1 => E + 1 :MSTORE(modexp_M + E) + E :JMPZ(singleton_test2_modexp, singleton_test2_copy_in_loop) + +singleton_test2_modexp: + 2n :MSTORE(modexp_B) + 1n :MSTORE(modexp_E) + :CALL(modexp) + 2n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 3] B = [2n], E = [1n:1818], M = [2n] + ; Hamming weight of E is 1818 + 1 :MSTORE(modexp_Blen) + 1818 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + + 1818 => E +singleton_test3_copy_in_loop: + E - 1 => E + 1 :MSTORE(modexp_E + E) + E :JMPZ(singleton_test3_modexp, singleton_test3_copy_in_loop) + +singleton_test3_modexp: + 2n :MSTORE(modexp_B) + 2n :MSTORE(modexp_M) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + ; --------------------------------------------------------------------------------------------- + + :JMP(end) + outOfCountersBinary: + ${dump(CNT_BINARY)} :JMP(end) outOfCountersStep: + ${dump(STEP)} :JMP(end) +outOfCountersArith: + ${dump(CNT_ARITH)} :JMP(end) end: From f8578b38646a2a56b960883481284a73ba135996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 22 Nov 2023 15:58:03 +0100 Subject: [PATCH 023/121] Fixing some counters --- main/modexp/modexp.zkasm | 3 +-- test/testModExp.zkasm | 54 ++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 3112b0c7..7f6e364b 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -62,8 +62,7 @@ VAR GLOBAL modexp_RR modexp: - %MAX_CNT_BINARY - CNT_BINARY - 10 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 42 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 8 :JMPN(outOfCountersStep) RR :MSTORE(modexp_RR) diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index 61acf4c2..5f3fe323 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -398,34 +398,34 @@ start: 1n :MLOAD(modexp_out + E) 3 :MLOAD(modexp_outlen) - ; 2] B = [2n, 1n, 1n, 1n], E = [2n**256n - 1n, 2n**256n - 1n], M = [4n, 6n, 7n] - ; Hamming weight of E is 512 - 4 :MSTORE(modexp_Blen) - 2 :MSTORE(modexp_Elen) - 3 :MSTORE(modexp_Mlen) + ; ; 2] B = [2n, 1n, 1n, 1n], E = [2n**256n - 1n, 2n**256n - 1n], M = [4n, 6n, 7n] + ; ; Hamming weight of E is 512 + ; 4 :MSTORE(modexp_Blen) + ; 2 :MSTORE(modexp_Elen) + ; 3 :MSTORE(modexp_Mlen) - 2n :MSTORE(modexp_B) - 1 => E - 1n :MSTORE(modexp_B + E) - 2 => E - 1n :MSTORE(modexp_B + E) - 3 => E - 1n :MSTORE(modexp_B + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E + E) - 4n :MSTORE(modexp_M) - 1 => E - 6n :MSTORE(modexp_M + E) - 2 => E - 7n :MSTORE(modexp_M + E) - :CALL(modexp) - 111873638420780286093512129901489267041413036926649390648147612881355784341812n :MLOAD(modexp_out) - 1 => E - 11181991619082508729788448443921623930160246165837402400671610626538926623319n :MLOAD(modexp_out + E) - 2 => E - 2n :MLOAD(modexp_out + E) - 3 :MLOAD(modexp_outlen) + ; 2n :MSTORE(modexp_B) + ; 1 => E + ; 1n :MSTORE(modexp_B + E) + ; 2 => E + ; 1n :MSTORE(modexp_B + E) + ; 3 => E + ; 1n :MSTORE(modexp_B + E) + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E + E) + ; 4n :MSTORE(modexp_M) + ; 1 => E + ; 6n :MSTORE(modexp_M + E) + ; 2 => E + ; 7n :MSTORE(modexp_M + E) + ; :CALL(modexp) + ; 111873638420780286093512129901489267041413036926649390648147612881355784341812n :MLOAD(modexp_out) + ; 1 => E + ; 11181991619082508729788448443921623930160246165837402400671610626538926623319n :MLOAD(modexp_out + E) + ; 2 => E + ; 2n :MLOAD(modexp_out + E) + ; 3 :MLOAD(modexp_outlen) ; --------------------------------------------------------------------------------------------- ; 768 BITS EXPONENT TESTS From 30c5b72402c0c04e966a288ea9767754c97c4067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 22 Nov 2023 19:08:39 +0100 Subject: [PATCH 024/121] Modexp input length restricted to 16 --- main/modexp/array_lib/array_add_AGTB.zkasm | 10 +- main/modexp/array_lib/array_add_short.zkasm | 6 +- main/modexp/array_lib/array_div_mod.zkasm | 12 +- .../modexp/array_lib/array_div_mod_long.zkasm | 12 +- .../array_lib/array_div_mod_short.zkasm | 6 +- main/modexp/array_lib/array_mul.zkasm | 10 +- main/modexp/array_lib/array_mul_long.zkasm | 10 +- main/modexp/array_lib/array_mul_short.zkasm | 6 +- main/modexp/array_lib/array_square.zkasm | 6 +- main/modexp/array_lib/unused/array_add.zkasm | 10 +- .../array_lib/unused/array_is_one.zkasm | 2 +- .../array_lib/unused/array_is_zero.zkasm | 2 +- .../array_lib/unused/array_sub_AGTB.zkasm | 10 +- .../array_lib/unused/array_unshift.zkasm | 4 +- .../array_lib/utils/array_compare.zkasm | 8 +- main/modexp/array_lib/utils/array_trim.zkasm | 2 +- main/modexp/modexp.zkasm | 17 +- test/testModExp.zkasm | 174 +++++++++--------- 18 files changed, 155 insertions(+), 152 deletions(-) diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index 2425bb48..69c87aa8 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -4,8 +4,8 @@ ;; ;; array_add_AGTB: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -38,9 +38,9 @@ ; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead if possible. -VAR GLOBAL array_add_AGTB_inA[1818] -VAR GLOBAL array_add_AGTB_inB[1818] -VAR GLOBAL array_add_AGTB_out[1819] +VAR GLOBAL array_add_AGTB_inA[16] +VAR GLOBAL array_add_AGTB_inB[16] +VAR GLOBAL array_add_AGTB_out[17] VAR GLOBAL array_add_AGTB_len_inA VAR GLOBAL array_add_AGTB_len_inB VAR GLOBAL array_add_AGTB_len_out diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index 6861f880..a4c77521 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -2,7 +2,7 @@ ;; ;; array_add_short: ;; in: -;; · C ∈ [1, 1818], the len of inA +;; · C ∈ [1, 16], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -27,9 +27,9 @@ ; return result; ; } -VAR GLOBAL array_add_short_inA[1818] +VAR GLOBAL array_add_short_inA[16] VAR GLOBAL array_add_short_inB -VAR GLOBAL array_add_short_out[1819] +VAR GLOBAL array_add_short_out[17] VAR GLOBAL array_add_short_len_inA VAR GLOBAL array_add_short_len_out diff --git a/main/modexp/array_lib/array_div_mod.zkasm b/main/modexp/array_lib/array_div_mod.zkasm index 9781699c..7c7ecbba 100644 --- a/main/modexp/array_lib/array_div_mod.zkasm +++ b/main/modexp/array_lib/array_div_mod.zkasm @@ -4,8 +4,8 @@ ;; ;; array_div_mod: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -35,10 +35,10 @@ ; return array_div_mod_long(a, b, B); ; } -VAR GLOBAL array_div_mod_inA[1818] -VAR GLOBAL array_div_mod_inB[1818] -VAR GLOBAL array_div_mod_quo[1818] -VAR GLOBAL array_div_mod_rem[1818] +VAR GLOBAL array_div_mod_inA[16] +VAR GLOBAL array_div_mod_inB[16] +VAR GLOBAL array_div_mod_quo[16] +VAR GLOBAL array_div_mod_rem[16] VAR GLOBAL array_div_mod_len_inA VAR GLOBAL array_div_mod_len_inB diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm index bd43c142..ddeaa367 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -4,8 +4,8 @@ ;; ;; array_div_mod_long: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -33,10 +33,10 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_long_inA[1818] -VAR GLOBAL array_div_mod_long_inB[1818] -VAR GLOBAL array_div_mod_long_quo[1818] -VAR GLOBAL array_div_mod_long_rem[1818] +VAR GLOBAL array_div_mod_long_inA[16] +VAR GLOBAL array_div_mod_long_inB[16] +VAR GLOBAL array_div_mod_long_quo[16] +VAR GLOBAL array_div_mod_long_rem[16] VAR GLOBAL array_div_mod_long_len_inA VAR GLOBAL array_div_mod_long_len_inB diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm index 2e678c7b..506f5c98 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -4,7 +4,7 @@ ;; ;; array_div_mod_short: ;; in: -;; · C ∈ [1, 1818], the len of inA +;; · C ∈ [1, 16], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -32,9 +32,9 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_short_inA[1818] +VAR GLOBAL array_div_mod_short_inA[16] VAR GLOBAL array_div_mod_short_inB -VAR GLOBAL array_div_mod_short_quo[1818] +VAR GLOBAL array_div_mod_short_quo[16] VAR GLOBAL array_div_mod_short_rem VAR GLOBAL array_div_mod_short_len_inA diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm index 160cb253..dba11ee6 100644 --- a/main/modexp/array_lib/array_mul.zkasm +++ b/main/modexp/array_lib/array_mul.zkasm @@ -3,8 +3,8 @@ ;; ;; array_mul: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -19,9 +19,9 @@ ; return array_mul_long(a, b, B); ; } -VAR GLOBAL array_mul_inA[1818] -VAR GLOBAL array_mul_inB[1818] -VAR GLOBAL array_mul_out[3636] +VAR GLOBAL array_mul_inA[16] +VAR GLOBAL array_mul_inB[16] +VAR GLOBAL array_mul_out[32] VAR GLOBAL array_mul_len_inA VAR GLOBAL array_mul_len_inB VAR GLOBAL array_mul_len_out diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index 56a04fed..81be1e4f 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -4,8 +4,8 @@ ;; ;; array_mul_long: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -36,9 +36,9 @@ ; return result; ; } -VAR GLOBAL array_mul_long_inA[1818] -VAR GLOBAL array_mul_long_inB[1818] -VAR GLOBAL array_mul_long_out[3636] +VAR GLOBAL array_mul_long_inA[16] +VAR GLOBAL array_mul_long_inB[16] +VAR GLOBAL array_mul_long_out[32] VAR GLOBAL array_mul_long_len_inA VAR GLOBAL array_mul_long_len_inB VAR GLOBAL array_mul_long_len_out diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index 219f78c1..3d919d96 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -3,7 +3,7 @@ ;; ;; array_mul_short: ;; in: -;; · C ∈ [1, 1818], the len of inA +;; · C ∈ [1, 16], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -32,9 +32,9 @@ ; return result; ; } -VAR GLOBAL array_mul_short_inA[1818] +VAR GLOBAL array_mul_short_inA[16] VAR GLOBAL array_mul_short_inB -VAR GLOBAL array_mul_short_out[1819] +VAR GLOBAL array_mul_short_out[17] VAR GLOBAL array_mul_short_len_inA VAR GLOBAL array_mul_short_len_out diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 5d8bf6c9..3d0bcdb9 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -3,7 +3,7 @@ ;; ;; array_square: ;; in: -;; · C ∈ [1, 1818], the len of in +;; · C ∈ [1, 16], the len of in ;; · in ∈ [0, 2²⁵ ⁶- 1]^C, the input array ;; ;; output: @@ -33,8 +33,8 @@ ; return result; ; } -VAR GLOBAL array_square_in[1818] -VAR GLOBAL array_square_out[3636] +VAR GLOBAL array_square_in[16] +VAR GLOBAL array_square_out[32] VAR GLOBAL array_square_len_in VAR GLOBAL array_square_len_out diff --git a/main/modexp/array_lib/unused/array_add.zkasm b/main/modexp/array_lib/unused/array_add.zkasm index 4f5277bf..5c945951 100644 --- a/main/modexp/array_lib/unused/array_add.zkasm +++ b/main/modexp/array_lib/unused/array_add.zkasm @@ -2,8 +2,8 @@ ;; ;; array_add: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -11,9 +11,9 @@ ;; · out = inA + inB, with len(out) <= C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_add_inA[1818] -VAR GLOBAL array_add_inB[1818] -VAR GLOBAL array_add_out[1819] +VAR GLOBAL array_add_inA[16] +VAR GLOBAL array_add_inB[16] +VAR GLOBAL array_add_out[17] VAR GLOBAL array_add_len_inA VAR GLOBAL array_add_len_inB VAR GLOBAL array_add_len_out diff --git a/main/modexp/array_lib/unused/array_is_one.zkasm b/main/modexp/array_lib/unused/array_is_one.zkasm index ab3b5b39..a32c006b 100644 --- a/main/modexp/array_lib/unused/array_is_one.zkasm +++ b/main/modexp/array_lib/unused/array_is_one.zkasm @@ -3,7 +3,7 @@ ;; ;; array_is_one: ;; in: -;; · C ∈ [1, 1818], the len of in +;; · C ∈ [1, 16], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; output: ;; · 1, if in = 1 diff --git a/main/modexp/array_lib/unused/array_is_zero.zkasm b/main/modexp/array_lib/unused/array_is_zero.zkasm index 3990c2cf..526b7577 100644 --- a/main/modexp/array_lib/unused/array_is_zero.zkasm +++ b/main/modexp/array_lib/unused/array_is_zero.zkasm @@ -3,7 +3,7 @@ ;; ;; array_is_zero: ;; in: -;; · C ∈ [1, 1818], the len of in +;; · C ∈ [1, 16], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; output: ;; · 1, if in = 0 diff --git a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm index bcc72761..06d388a2 100644 --- a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +++ b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm @@ -3,8 +3,8 @@ ;; ;; array_sub_AGTB: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -12,9 +12,9 @@ ;; · out = inA - inB, with len(out) <= C ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_sub_AGTB_inA[1818] -VAR GLOBAL array_sub_AGTB_inB[1818] -VAR GLOBAL array_sub_AGTB_out[1818] +VAR GLOBAL array_sub_AGTB_inA[16] +VAR GLOBAL array_sub_AGTB_inB[16] +VAR GLOBAL array_sub_AGTB_out[16] VAR GLOBAL array_sub_AGTB_len_inA VAR GLOBAL array_sub_AGTB_len_inB diff --git a/main/modexp/array_lib/unused/array_unshift.zkasm b/main/modexp/array_lib/unused/array_unshift.zkasm index 3fd3e76b..2911d94f 100644 --- a/main/modexp/array_lib/unused/array_unshift.zkasm +++ b/main/modexp/array_lib/unused/array_unshift.zkasm @@ -2,7 +2,7 @@ ;; ;; array_unshift: ;; in: -;; · C ∈ [1, 1818], the len of in = [in[0], in[1], ..., in[C - 1]] +;; · C ∈ [1, 16], the len of in = [in[0], in[1], ..., in[C - 1]] ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; · D ∈ [0, 2²⁵⁶ - 1], the element to unshift ;; @@ -11,7 +11,7 @@ ;; · len = C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_unshift_in[1818] +VAR GLOBAL array_unshift_in[16] VAR GLOBAL array_unshift_len VAR GLOBAL array_unshift_RR diff --git a/main/modexp/array_lib/utils/array_compare.zkasm b/main/modexp/array_lib/utils/array_compare.zkasm index 7e2db778..7a0d1fc9 100644 --- a/main/modexp/array_lib/utils/array_compare.zkasm +++ b/main/modexp/array_lib/utils/array_compare.zkasm @@ -3,8 +3,8 @@ ;; ;; array_compare: ;; in: -;; · C ∈ [1, 1818], the len of inA -;; · D ∈ [1, 1818], the len of inB +;; · C ∈ [1, 16], the len of inA +;; · D ∈ [1, 16], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -37,8 +37,8 @@ ; · inA < inB and lenA = lenB. ; ---------------------------------- -VAR GLOBAL array_compare_inA[1818] -VAR GLOBAL array_compare_inB[1818] +VAR GLOBAL array_compare_inA[16] +VAR GLOBAL array_compare_inB[16] VAR GLOBAL array_compare_result diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm index 8dd46382..dd5e89c3 100644 --- a/main/modexp/array_lib/utils/array_trim.zkasm +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -18,7 +18,7 @@ ; a.length = i + 1; ; } -VAR GLOBAL array_trim_in[3636] +VAR GLOBAL array_trim_in[32] VAR GLOBAL array_trim_RR diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 7f6e364b..447243aa 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -5,9 +5,9 @@ ;; modexp: ;; ---------------------------------------- ;; input: -;; · Blen ∈ [1, 1818], the len of B -;; · Elen ∈ [1, 1818], the len of E -;; · Mlen ∈ [1, 1818], the len of M +;; · Blen ∈ [1, 16], the len of B +;; · Elen ∈ [1, 16], the len of E +;; · Mlen ∈ [1, 16], the len of M ;; · B ∈ [0, 2²⁵⁶ - 1]^Blen, the base represented in little-endian ;; · E ∈ [0, 2²⁵⁶ - 1]^Elen, the exponent represented in little-endian ;; · M ∈ [0, 2²⁵⁶ - 1]^Mlen, the modulus represented in little-endian @@ -48,14 +48,17 @@ ;; cost(total) = cost(pre_loop) + nTimesEIsOdd·cost(iteration1) + nTimesEIsEven·cost(iteration2) ;; ------------ +;; NOTE: After a few discussions, we decided to set the maximum input length to 16. +;; See https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43 for more details. + VAR GLOBAL modexp_Blen VAR GLOBAL modexp_Elen VAR GLOBAL modexp_Mlen -VAR GLOBAL modexp_B[1818] -VAR GLOBAL modexp_E[1818] -VAR GLOBAL modexp_M[1818] +VAR GLOBAL modexp_B[16] +VAR GLOBAL modexp_E[16] +VAR GLOBAL modexp_M[16] -VAR GLOBAL modexp_out[1818] +VAR GLOBAL modexp_out[16] VAR GLOBAL modexp_outlen VAR GLOBAL modexp_RR diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index 5f3fe323..8b0117b5 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -398,34 +398,34 @@ start: 1n :MLOAD(modexp_out + E) 3 :MLOAD(modexp_outlen) - ; ; 2] B = [2n, 1n, 1n, 1n], E = [2n**256n - 1n, 2n**256n - 1n], M = [4n, 6n, 7n] - ; ; Hamming weight of E is 512 - ; 4 :MSTORE(modexp_Blen) - ; 2 :MSTORE(modexp_Elen) - ; 3 :MSTORE(modexp_Mlen) + ; 2] B = [2n, 1n, 1n, 1n], E = [2n**256n - 1n, 2n**256n - 1n], M = [4n, 6n, 7n] + ; Hamming weight of E is 512 + 4 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 3 :MSTORE(modexp_Mlen) - ; 2n :MSTORE(modexp_B) - ; 1 => E - ; 1n :MSTORE(modexp_B + E) - ; 2 => E - ; 1n :MSTORE(modexp_B + E) - ; 3 => E - ; 1n :MSTORE(modexp_B + E) - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E + E) - ; 4n :MSTORE(modexp_M) - ; 1 => E - ; 6n :MSTORE(modexp_M + E) - ; 2 => E - ; 7n :MSTORE(modexp_M + E) - ; :CALL(modexp) - ; 111873638420780286093512129901489267041413036926649390648147612881355784341812n :MLOAD(modexp_out) - ; 1 => E - ; 11181991619082508729788448443921623930160246165837402400671610626538926623319n :MLOAD(modexp_out + E) - ; 2 => E - ; 2n :MLOAD(modexp_out + E) - ; 3 :MLOAD(modexp_outlen) + 2n :MSTORE(modexp_B) + 1 => E + 1n :MSTORE(modexp_B + E) + 2 => E + 1n :MSTORE(modexp_B + E) + 3 => E + 1n :MSTORE(modexp_B + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E + E) + 4n :MSTORE(modexp_M) + 1 => E + 6n :MSTORE(modexp_M + E) + 2 => E + 7n :MSTORE(modexp_M + E) + :CALL(modexp) + 111873638420780286093512129901489267041413036926649390648147612881355784341812n :MLOAD(modexp_out) + 1 => E + 11181991619082508729788448443921623930160246165837402400671610626538926623319n :MLOAD(modexp_out + E) + 2 => E + 2n :MLOAD(modexp_out + E) + 3 :MLOAD(modexp_outlen) ; --------------------------------------------------------------------------------------------- ; 768 BITS EXPONENT TESTS @@ -436,66 +436,66 @@ start: ; --------------------------------------------------------------------------------------------- ; --------------------------------------------------------------------------------------------- - ; SINGLETON TESTS TO ENSURE THE MAXIMUM INPUT LENGTH WE CAN ACHIEVE IN EACH OF BASE, EXPONENT - ; AND MODULUS WITHOUT OVERFLOWING EITHER THE ARITH, BINARY OF STEPS COUNTERS - ; --------------------------------------------------------------------------------------------- - ; 1] B = [2n:1818n], E = [1n], M = [2n] - ; Hamming weight of E is 1 - 1818 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 1818 => E -singleton_test1_copy_in_loop: - E - 1 => E - 2 :MSTORE(modexp_B + E) - E :JMPZ(singleton_test1_modexp, singleton_test1_copy_in_loop) - -singleton_test1_modexp: - 1n :MSTORE(modexp_E) - 2n :MSTORE(modexp_M) - :CALL(modexp) - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 2] B = [2n], E = [1n], M = [2n:1818] - ; Hamming weight of E is 1 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 1818 :MSTORE(modexp_Mlen) - - 1818 => E -singleton_test2_copy_in_loop: - E - 1 => E - 1 :MSTORE(modexp_M + E) - E :JMPZ(singleton_test2_modexp, singleton_test2_copy_in_loop) - -singleton_test2_modexp: - 2n :MSTORE(modexp_B) - 1n :MSTORE(modexp_E) - :CALL(modexp) - 2n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - - ; 3] B = [2n], E = [1n:1818], M = [2n] - ; Hamming weight of E is 1818 - 1 :MSTORE(modexp_Blen) - 1818 :MSTORE(modexp_Elen) - 1 :MSTORE(modexp_Mlen) - - 1818 => E -singleton_test3_copy_in_loop: - E - 1 => E - 1 :MSTORE(modexp_E + E) - E :JMPZ(singleton_test3_modexp, singleton_test3_copy_in_loop) - -singleton_test3_modexp: - 2n :MSTORE(modexp_B) - 2n :MSTORE(modexp_M) - :CALL(modexp) - 0n :MLOAD(modexp_out) - 1 :MLOAD(modexp_outlen) - ; --------------------------------------------------------------------------------------------- +; ; SINGLETON TESTS TO ENSURE THE MAXIMUM INPUT LENGTH WE CAN ACHIEVE IN EACH OF BASE, EXPONENT +; ; AND MODULUS WITHOUT OVERFLOWING EITHER THE ARITH, BINARY OF STEPS COUNTERS +; ; --------------------------------------------------------------------------------------------- +; ; 1] B = [2n:1818n], E = [1n], M = [2n] +; ; Hamming weight of E is 1 +; 1818 :MSTORE(modexp_Blen) +; 1 :MSTORE(modexp_Elen) +; 1 :MSTORE(modexp_Mlen) + +; 1818 => E +; singleton_test1_copy_in_loop: +; E - 1 => E +; 2 :MSTORE(modexp_B + E) +; E :JMPZ(singleton_test1_modexp, singleton_test1_copy_in_loop) + +; singleton_test1_modexp: +; 1n :MSTORE(modexp_E) +; 2n :MSTORE(modexp_M) +; :CALL(modexp) +; 0n :MLOAD(modexp_out) +; 1 :MLOAD(modexp_outlen) + +; ; 2] B = [2n], E = [1n], M = [2n:1818] +; ; Hamming weight of E is 1 +; 1 :MSTORE(modexp_Blen) +; 1 :MSTORE(modexp_Elen) +; 1818 :MSTORE(modexp_Mlen) + +; 1818 => E +; singleton_test2_copy_in_loop: +; E - 1 => E +; 1 :MSTORE(modexp_M + E) +; E :JMPZ(singleton_test2_modexp, singleton_test2_copy_in_loop) + +; singleton_test2_modexp: +; 2n :MSTORE(modexp_B) +; 1n :MSTORE(modexp_E) +; :CALL(modexp) +; 2n :MLOAD(modexp_out) +; 1 :MLOAD(modexp_outlen) + +; ; 3] B = [2n], E = [1n:1818], M = [2n] +; ; Hamming weight of E is 1818 +; 1 :MSTORE(modexp_Blen) +; 1818 :MSTORE(modexp_Elen) +; 1 :MSTORE(modexp_Mlen) + +; 1818 => E +; singleton_test3_copy_in_loop: +; E - 1 => E +; 1 :MSTORE(modexp_E + E) +; E :JMPZ(singleton_test3_modexp, singleton_test3_copy_in_loop) + +; singleton_test3_modexp: +; 2n :MSTORE(modexp_B) +; 2n :MSTORE(modexp_M) +; :CALL(modexp) +; 0n :MLOAD(modexp_out) +; 1 :MLOAD(modexp_outlen) +; ; --------------------------------------------------------------------------------------------- :JMP(end) From 46251949eddf093d0a52d8d8f73dccb7fcce64c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Thu, 23 Nov 2023 09:10:59 +0100 Subject: [PATCH 025/121] Modexp input length finally restricted to 32 --- main/modexp/array_lib/array_add_AGTB.zkasm | 10 +++++----- main/modexp/array_lib/array_add_short.zkasm | 6 +++--- main/modexp/array_lib/array_div_mod.zkasm | 12 +++++------ .../modexp/array_lib/array_div_mod_long.zkasm | 12 +++++------ .../array_lib/array_div_mod_short.zkasm | 6 +++--- main/modexp/array_lib/array_mul.zkasm | 10 +++++----- main/modexp/array_lib/array_mul_long.zkasm | 10 +++++----- main/modexp/array_lib/array_mul_short.zkasm | 6 +++--- main/modexp/array_lib/array_square.zkasm | 6 +++--- main/modexp/array_lib/unused/array_add.zkasm | 10 +++++----- .../array_lib/unused/array_is_one.zkasm | 2 +- .../array_lib/unused/array_is_zero.zkasm | 2 +- .../array_lib/unused/array_sub_AGTB.zkasm | 10 +++++----- .../array_lib/unused/array_unshift.zkasm | 4 ++-- .../array_lib/utils/array_compare.zkasm | 8 ++++---- main/modexp/array_lib/utils/array_trim.zkasm | 2 +- main/modexp/modexp.zkasm | 20 +++++++++---------- 17 files changed, 68 insertions(+), 68 deletions(-) diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index 69c87aa8..ef901202 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -4,8 +4,8 @@ ;; ;; array_add_AGTB: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -38,9 +38,9 @@ ; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead if possible. -VAR GLOBAL array_add_AGTB_inA[16] -VAR GLOBAL array_add_AGTB_inB[16] -VAR GLOBAL array_add_AGTB_out[17] +VAR GLOBAL array_add_AGTB_inA[32] +VAR GLOBAL array_add_AGTB_inB[32] +VAR GLOBAL array_add_AGTB_out[33] VAR GLOBAL array_add_AGTB_len_inA VAR GLOBAL array_add_AGTB_len_inB VAR GLOBAL array_add_AGTB_len_out diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index a4c77521..64a62cc0 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -2,7 +2,7 @@ ;; ;; array_add_short: ;; in: -;; · C ∈ [1, 16], the len of inA +;; · C ∈ [1, 32], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -27,9 +27,9 @@ ; return result; ; } -VAR GLOBAL array_add_short_inA[16] +VAR GLOBAL array_add_short_inA[32] VAR GLOBAL array_add_short_inB -VAR GLOBAL array_add_short_out[17] +VAR GLOBAL array_add_short_out[33] VAR GLOBAL array_add_short_len_inA VAR GLOBAL array_add_short_len_out diff --git a/main/modexp/array_lib/array_div_mod.zkasm b/main/modexp/array_lib/array_div_mod.zkasm index 7c7ecbba..eed9441d 100644 --- a/main/modexp/array_lib/array_div_mod.zkasm +++ b/main/modexp/array_lib/array_div_mod.zkasm @@ -4,8 +4,8 @@ ;; ;; array_div_mod: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -35,10 +35,10 @@ ; return array_div_mod_long(a, b, B); ; } -VAR GLOBAL array_div_mod_inA[16] -VAR GLOBAL array_div_mod_inB[16] -VAR GLOBAL array_div_mod_quo[16] -VAR GLOBAL array_div_mod_rem[16] +VAR GLOBAL array_div_mod_inA[32] +VAR GLOBAL array_div_mod_inB[32] +VAR GLOBAL array_div_mod_quo[32] +VAR GLOBAL array_div_mod_rem[32] VAR GLOBAL array_div_mod_len_inA VAR GLOBAL array_div_mod_len_inB diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm index ddeaa367..9eff1cac 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -4,8 +4,8 @@ ;; ;; array_div_mod_long: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -33,10 +33,10 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_long_inA[16] -VAR GLOBAL array_div_mod_long_inB[16] -VAR GLOBAL array_div_mod_long_quo[16] -VAR GLOBAL array_div_mod_long_rem[16] +VAR GLOBAL array_div_mod_long_inA[32] +VAR GLOBAL array_div_mod_long_inB[32] +VAR GLOBAL array_div_mod_long_quo[32] +VAR GLOBAL array_div_mod_long_rem[32] VAR GLOBAL array_div_mod_long_len_inA VAR GLOBAL array_div_mod_long_len_inB diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm index 506f5c98..80ba7728 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -4,7 +4,7 @@ ;; ;; array_div_mod_short: ;; in: -;; · C ∈ [1, 16], the len of inA +;; · C ∈ [1, 32], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -32,9 +32,9 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_short_inA[16] +VAR GLOBAL array_div_mod_short_inA[32] VAR GLOBAL array_div_mod_short_inB -VAR GLOBAL array_div_mod_short_quo[16] +VAR GLOBAL array_div_mod_short_quo[32] VAR GLOBAL array_div_mod_short_rem VAR GLOBAL array_div_mod_short_len_inA diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm index dba11ee6..55e39431 100644 --- a/main/modexp/array_lib/array_mul.zkasm +++ b/main/modexp/array_lib/array_mul.zkasm @@ -3,8 +3,8 @@ ;; ;; array_mul: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -19,9 +19,9 @@ ; return array_mul_long(a, b, B); ; } -VAR GLOBAL array_mul_inA[16] -VAR GLOBAL array_mul_inB[16] -VAR GLOBAL array_mul_out[32] +VAR GLOBAL array_mul_inA[32] +VAR GLOBAL array_mul_inB[32] +VAR GLOBAL array_mul_out[64] VAR GLOBAL array_mul_len_inA VAR GLOBAL array_mul_len_inB VAR GLOBAL array_mul_len_out diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index 81be1e4f..98ab6599 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -4,8 +4,8 @@ ;; ;; array_mul_long: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -36,9 +36,9 @@ ; return result; ; } -VAR GLOBAL array_mul_long_inA[16] -VAR GLOBAL array_mul_long_inB[16] -VAR GLOBAL array_mul_long_out[32] +VAR GLOBAL array_mul_long_inA[32] +VAR GLOBAL array_mul_long_inB[32] +VAR GLOBAL array_mul_long_out[64] VAR GLOBAL array_mul_long_len_inA VAR GLOBAL array_mul_long_len_inB VAR GLOBAL array_mul_long_len_out diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index 3d919d96..de19921f 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -3,7 +3,7 @@ ;; ;; array_mul_short: ;; in: -;; · C ∈ [1, 16], the len of inA +;; · C ∈ [1, 32], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; @@ -32,9 +32,9 @@ ; return result; ; } -VAR GLOBAL array_mul_short_inA[16] +VAR GLOBAL array_mul_short_inA[32] VAR GLOBAL array_mul_short_inB -VAR GLOBAL array_mul_short_out[17] +VAR GLOBAL array_mul_short_out[33] VAR GLOBAL array_mul_short_len_inA VAR GLOBAL array_mul_short_len_out diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 3d0bcdb9..665dc7a4 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -3,7 +3,7 @@ ;; ;; array_square: ;; in: -;; · C ∈ [1, 16], the len of in +;; · C ∈ [1, 32], the len of in ;; · in ∈ [0, 2²⁵ ⁶- 1]^C, the input array ;; ;; output: @@ -33,8 +33,8 @@ ; return result; ; } -VAR GLOBAL array_square_in[16] -VAR GLOBAL array_square_out[32] +VAR GLOBAL array_square_in[32] +VAR GLOBAL array_square_out[64] VAR GLOBAL array_square_len_in VAR GLOBAL array_square_len_out diff --git a/main/modexp/array_lib/unused/array_add.zkasm b/main/modexp/array_lib/unused/array_add.zkasm index 5c945951..40561db4 100644 --- a/main/modexp/array_lib/unused/array_add.zkasm +++ b/main/modexp/array_lib/unused/array_add.zkasm @@ -2,8 +2,8 @@ ;; ;; array_add: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -11,9 +11,9 @@ ;; · out = inA + inB, with len(out) <= C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_add_inA[16] -VAR GLOBAL array_add_inB[16] -VAR GLOBAL array_add_out[17] +VAR GLOBAL array_add_inA[32] +VAR GLOBAL array_add_inB[32] +VAR GLOBAL array_add_out[33] VAR GLOBAL array_add_len_inA VAR GLOBAL array_add_len_inB VAR GLOBAL array_add_len_out diff --git a/main/modexp/array_lib/unused/array_is_one.zkasm b/main/modexp/array_lib/unused/array_is_one.zkasm index a32c006b..d22ae89a 100644 --- a/main/modexp/array_lib/unused/array_is_one.zkasm +++ b/main/modexp/array_lib/unused/array_is_one.zkasm @@ -3,7 +3,7 @@ ;; ;; array_is_one: ;; in: -;; · C ∈ [1, 16], the len of in +;; · C ∈ [1, 32], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; output: ;; · 1, if in = 1 diff --git a/main/modexp/array_lib/unused/array_is_zero.zkasm b/main/modexp/array_lib/unused/array_is_zero.zkasm index 526b7577..5c6e3ee9 100644 --- a/main/modexp/array_lib/unused/array_is_zero.zkasm +++ b/main/modexp/array_lib/unused/array_is_zero.zkasm @@ -3,7 +3,7 @@ ;; ;; array_is_zero: ;; in: -;; · C ∈ [1, 16], the len of in +;; · C ∈ [1, 32], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; output: ;; · 1, if in = 0 diff --git a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm index 06d388a2..241414a8 100644 --- a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +++ b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm @@ -3,8 +3,8 @@ ;; ;; array_sub_AGTB: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -12,9 +12,9 @@ ;; · out = inA - inB, with len(out) <= C ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_sub_AGTB_inA[16] -VAR GLOBAL array_sub_AGTB_inB[16] -VAR GLOBAL array_sub_AGTB_out[16] +VAR GLOBAL array_sub_AGTB_inA[32] +VAR GLOBAL array_sub_AGTB_inB[32] +VAR GLOBAL array_sub_AGTB_out[32] VAR GLOBAL array_sub_AGTB_len_inA VAR GLOBAL array_sub_AGTB_len_inB diff --git a/main/modexp/array_lib/unused/array_unshift.zkasm b/main/modexp/array_lib/unused/array_unshift.zkasm index 2911d94f..0209f475 100644 --- a/main/modexp/array_lib/unused/array_unshift.zkasm +++ b/main/modexp/array_lib/unused/array_unshift.zkasm @@ -2,7 +2,7 @@ ;; ;; array_unshift: ;; in: -;; · C ∈ [1, 16], the len of in = [in[0], in[1], ..., in[C - 1]] +;; · C ∈ [1, 32], the len of in = [in[0], in[1], ..., in[C - 1]] ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; · D ∈ [0, 2²⁵⁶ - 1], the element to unshift ;; @@ -11,7 +11,7 @@ ;; · len = C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_unshift_in[16] +VAR GLOBAL array_unshift_in[32] VAR GLOBAL array_unshift_len VAR GLOBAL array_unshift_RR diff --git a/main/modexp/array_lib/utils/array_compare.zkasm b/main/modexp/array_lib/utils/array_compare.zkasm index 7a0d1fc9..f94a0631 100644 --- a/main/modexp/array_lib/utils/array_compare.zkasm +++ b/main/modexp/array_lib/utils/array_compare.zkasm @@ -3,8 +3,8 @@ ;; ;; array_compare: ;; in: -;; · C ∈ [1, 16], the len of inA -;; · D ∈ [1, 16], the len of inB +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; @@ -37,8 +37,8 @@ ; · inA < inB and lenA = lenB. ; ---------------------------------- -VAR GLOBAL array_compare_inA[16] -VAR GLOBAL array_compare_inB[16] +VAR GLOBAL array_compare_inA[32] +VAR GLOBAL array_compare_inB[32] VAR GLOBAL array_compare_result diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm index dd5e89c3..5f6e30b6 100644 --- a/main/modexp/array_lib/utils/array_trim.zkasm +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -18,7 +18,7 @@ ; a.length = i + 1; ; } -VAR GLOBAL array_trim_in[32] +VAR GLOBAL array_trim_in[64] VAR GLOBAL array_trim_RR diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 447243aa..f3c345b2 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -1,3 +1,6 @@ +;; NOTE: After a few discussions, we decided to set the maximum input length to 32. +;; See https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43 for more details. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PRE: B, E, M have been trimmed. ;; POST: out is trimmed @@ -5,9 +8,9 @@ ;; modexp: ;; ---------------------------------------- ;; input: -;; · Blen ∈ [1, 16], the len of B -;; · Elen ∈ [1, 16], the len of E -;; · Mlen ∈ [1, 16], the len of M +;; · Blen ∈ [1, 32], the len of B +;; · Elen ∈ [1, 32], the len of E +;; · Mlen ∈ [1, 32], the len of M ;; · B ∈ [0, 2²⁵⁶ - 1]^Blen, the base represented in little-endian ;; · E ∈ [0, 2²⁵⁶ - 1]^Elen, the exponent represented in little-endian ;; · M ∈ [0, 2²⁵⁶ - 1]^Mlen, the modulus represented in little-endian @@ -48,17 +51,14 @@ ;; cost(total) = cost(pre_loop) + nTimesEIsOdd·cost(iteration1) + nTimesEIsEven·cost(iteration2) ;; ------------ -;; NOTE: After a few discussions, we decided to set the maximum input length to 16. -;; See https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43 for more details. - VAR GLOBAL modexp_Blen VAR GLOBAL modexp_Elen VAR GLOBAL modexp_Mlen -VAR GLOBAL modexp_B[16] -VAR GLOBAL modexp_E[16] -VAR GLOBAL modexp_M[16] +VAR GLOBAL modexp_B[32] +VAR GLOBAL modexp_E[32] +VAR GLOBAL modexp_M[32] -VAR GLOBAL modexp_out[16] +VAR GLOBAL modexp_out[32] VAR GLOBAL modexp_outlen VAR GLOBAL modexp_RR From 5c19a21c5c31bdf81b14fae027ef3a1662ef4487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Thu, 23 Nov 2023 16:02:29 +0100 Subject: [PATCH 026/121] Minor optimizations to pre-modexp, adding the new limit of 1024 bytes of input length --- main/constants.zkasm | 3 +- main/modexp/modexp.zkasm | 3 - main/precompiled/pre-modexp.zkasm | 109 ++++++++++++++---------------- 3 files changed, 53 insertions(+), 62 deletions(-) diff --git a/main/constants.zkasm b/main/constants.zkasm index dfbb2a84..07ecf6a4 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -131,8 +131,7 @@ CONSTL %MAX_NONCE = 0xffffffffffffffffn CONSTL %MAX_UINT_256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn CONST %CODE_SIZE_LIMIT = 0x6000 CONST %BYTECODE_STARTS_EF = 0xEF -CONST %MAX_SIZE_MODEXP = 2147483647 -CONSTL %MAX_SAFE_INTEGER_MODEXP = 0x1fffffffffffffn +CONST %MAX_SIZE_MODEXP = 1024 CONST %MAX_GAS_WORD_MODEXP = 9487 CONSTL %MAX_GAS_IT_MODEXP = 90000000 ; %TX_GAS_LIMIT*3 diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index f3c345b2..5a538acb 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -1,6 +1,3 @@ -;; NOTE: After a few discussions, we decided to set the maximum input length to 32. -;; See https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43 for more details. - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PRE: B, E, M have been trimmed. ;; POST: out is trimmed diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 2d17c6c5..d5c47c7a 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -7,6 +7,8 @@ * @process-precompiled * - stack input: [x1, y1, x2, y2] * - stack output: [x, y] + * @note After a few discussions, we decided to set the maximum input length of the base, modulus and exponent to 32. + * See [https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43] for more details. */ INCLUDE "../modexp/modexp.zkasm" INCLUDE "../modexp/modexp_utils.zkasm" @@ -37,13 +39,13 @@ VAR GLOBAL expLenBits funcModexp: %MAX_CNT_BINARY - CNT_BINARY - 20 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) + %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) ; Move balances if value > 0 just before executing the contract CALL $ => B :MLOAD(txValue) 0 => A - zkPC+2 => RR + zkPC + 2 => RR $ :LT, JMPC(moveBalances) ; read data stored in calldata @@ -67,13 +69,13 @@ funcModexp: ; get exp offset = 96 bytes (Bsize | Esize | Msize) + Bsize $ => A :MLOAD(modexp_Bsize) A :MSTORE(arithA) - 96 :MSTORE(arithB),CALL(addARITH) + 96 :MSTORE(arithB), CALL(addARITH) $ => A :MLOAD(arithRes1) $ => B :MLOAD(txCalldataLen) ; expLenBits = bit length of first 32 bytes of exp 0 :MSTORE(expLenBits) ; if 96 + Bsize (exp offset) < txCalldataLen --> setExpBits, else --> expLenBits = 0 - $ :LT,JMPC(setExpBits,setMaxLen) + $ :LT, JMPC(setExpBits, setMaxLen) setExpBits: ; E exp offset @@ -82,7 +84,7 @@ setExpBits: 33 => B ; A, C = Esize ; if Esize <= 32 --> setExpBitsContinue - $ => B :LT,JMPC(setExpBitsContinue) + $ => B :LT, JMPC(setExpBitsContinue) 32 => C setExpBitsContinue: @@ -108,34 +110,34 @@ setMaxLen: calculateGas: %MAX_CNT_BINARY - CNT_BINARY - 10 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) + %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) %MAX_CNT_STEPS - STEP - 120 :JMPN(outOfCountersStep) B :MSTORE(arithA) - 7 :MSTORE(arithB),CALL(addARITH) + 7 :MSTORE(arithB), CALL(addARITH) $ => B :MLOAD(arithRes1) B :MSTORE(arithA) - 8 :MSTORE(arithB),CALL(divARITH) + 8 :MSTORE(arithB), CALL(divARITH) ; B: words = (max_length + 7) / 8 $ => B :MLOAD(arithRes1) %MAX_GAS_WORD_MODEXP => A - $ :LT,JMPC(outOfGas) + $ :LT, JMPC(outOfGas) ; A: multiplication_complexity = words**2 B :MSTORE(arithA) - B :MSTORE(arithB),CALL(mulARITH) + B :MSTORE(arithB), CALL(mulARITH) $ => A :MLOAD(arithRes1) - A :MSTORE(multiplication_complexity),JMPZ(dinamicGas) + A :MSTORE(multiplication_complexity), JMPZ(dynamicGas) $ => A :MLOAD(modexp_Esize) 33 => B ; if Esize <= 32 --> modexp_expLT32 - $ => B :LT,JMPC(modexp_expLT32) + $ => B :LT, JMPC(modexp_expLT32) ;elif Esize > 32: iteration_count = (8 * (Esize - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) A :MSTORE(arithA) - 32 :MSTORE(arithB),CALL(subARITH) + 32 :MSTORE(arithB), CALL(subARITH) $ => A :MLOAD(arithRes1) A :MSTORE(arithA) - 8 :MSTORE(arithB),CALL(mulARITH) + 8 :MSTORE(arithB), CALL(mulARITH) ; A = 8 * (Esize - 32) $ => A :MLOAD(arithRes1) $ => B :MLOAD(expLenBits) @@ -149,12 +151,12 @@ modexp_expLT32: finalGas: E => B %MAX_GAS_IT_MODEXP => A - $ :LT,JMPC(outOfGas) + $ :LT, JMPC(outOfGas) 1 => A - $ :LT,JMPC(dinamicGas) + $ :LT, JMPC(dynamicGas) 1 => E -dinamicGas: +dynamicGas: %MAX_CNT_BINARY - CNT_BINARY - 9 :JMPN(outOfCountersBinary) %MAX_CNT_ARITH - CNT_ARITH - 3 :JMPN(outOfCountersArith) @@ -163,17 +165,17 @@ dinamicGas: ; E = calculate_iteration_count = max(iteration_count, 1) $ => A :MLOAD(multiplication_complexity) A :MSTORE(arithA) - E :MSTORE(arithB),CALL(mulARITH) + E :MSTORE(arithB), CALL(mulARITH) ; A = multiplication_complexity * iteration_count $ => A :MLOAD(arithRes1) A :MSTORE(arithA) - 3 :MSTORE(arithB),CALL(divARITH) + 3 :MSTORE(arithB), CALL(divARITH) ; A = multiplication_complexity * iteration_count / 3 $ => A :MLOAD(arithRes1) %TX_GAS_LIMIT => B - $ :LT,JMPNC(outOfGas) + $ :LT, JMPNC(outOfGas) 200 => B - $ :LT,JMPC(lastChecks) + $ :LT, JMPC(lastChecks) A => B lastChecks: @@ -181,74 +183,67 @@ lastChecks: GAS - B => GAS :JMPN(outOfGas) 0 => A $ => B :MLOAD(modexp_Msize) - $ :EQ,JMPC(save0outMod0) ; if Msize = 0 --> save0outMod0 + $ :EQ, JMPC(save0outMod0) ; if Msize = 0 --> save0outMod0 + ; M > 0 from here $ => B :MLOAD(modexp_Bsize) - $ :EQ,JMPC(save0out) ; if Bsize = 0 --> save0out + $ :EQ, JMPC(save0out) ; if Bsize = 0 --> save0out + ; B > 0 from here %MAX_SIZE_MODEXP => A $ => B :MLOAD(modexp_Bsize) - $ :LT,JMPC(endMODEXPFail) ; if Bsize > MAX_SIZE_MODEXP --> endMODEXPFail + $ :LT, JMPC(endMODEXPFail) ; if Bsize > MAX_SIZE_MODEXP --> endMODEXPFail $ => B :MLOAD(modexp_Esize) - $ :LT,JMPC(endMODEXPFail) ; if Esize > MAX_SIZE_MODEXP --> endMODEXPFail + $ :LT, JMPC(endMODEXPFail) ; if Esize > MAX_SIZE_MODEXP --> endMODEXPFail $ => B :MLOAD(modexp_Msize) - $ :LT,JMPC(endMODEXPFail) ; if Msize > MAX_SIZE_MODEXP --> endMODEXPFail - $ => E :MLOAD(modexp_offset) - $ => C :MLOAD(modexp_Bsize) + $ :LT, JMPC(endMODEXPFail) ; if Msize > MAX_SIZE_MODEXP --> endMODEXPFail + ; get base value + $ => C :MLOAD(modexp_Bsize) :CALL(modexp_getBase) - $ => C :MLOAD(modexp_Esize) ; get exp value + $ => C :MLOAD(modexp_Esize) :CALL(modexp_getExp) - $ => C :MLOAD(modexp_Msize) - ; if Msize+offset > MAX_SAFE_INTEGER_MODEXP --> endMODEXPFail - E :MSTORE(arithA) - C :MSTORE(arithB),CALL(addARITH) - $ => B :MLOAD(arithRes1) - %MAX_SAFE_INTEGER_MODEXP => A - $ :LT,JMPC(endMODEXPFail) ; get mod value + $ => C :MLOAD(modexp_Msize) :CALL(modexp_getMod) 1 => B ; if mod == 0 --> return 0 - $ => A :MLOAD(modexp_Mlen),JMPZ(save0out) + $ => A :MLOAD(modexp_Mlen), JMPZ(save0out) ; if Mlen != 1 --> checkBaseLen - $ :EQ,JMPNC(checkExpLen) + $ :EQ, JMPNC(checkExpLen) ; if Mlen == 1 && mod == 1 --> return 0 $ => A :MLOAD(modexp_M) - $ :EQ,JMPC(save0out) + $ :EQ, JMPC(save0out) checkExpLen: ; if exp == 0 --> return 1 - $ => A :MLOAD(modexp_Elen),JMPZ(save1out) + $ => A :MLOAD(modexp_Elen), JMPZ(save1out) checkBaseLen: ; if base == 0 --> return 0 - $ => A :MLOAD(modexp_Blen),JMPZ(save0out) + $ => A :MLOAD(modexp_Blen), JMPZ(save0out) ; if Blen != 1 --> checkExpLen - $ :EQ,JMPNC(callMODEXP) + $ :EQ, JMPNC(callMODEXP) ; if Blen == 1 && base == 1 --> return 1 $ => A :MLOAD(modexp_B) - $ :EQ,JMPC(save1out) + $ :EQ, JMPC(save1out) callMODEXP: :CALL(modexp) :JMP(finalMODEXP) save1out: - 1 :MSTORE(modexp_out),JMP(finalMODEXP) + 1 :MSTORE(modexp_out), JMP(finalMODEXP) save0out: - $ => B :MLOAD(modexp_Msize) - %MAX_SAFE_INTEGER_MODEXP => A - $ :LT,JMPC(endMODEXPFail) - 0 :MSTORE(modexp_out),JMP(finalMODEXP) + 0 :MSTORE(modexp_out), JMP(finalMODEXP) save0outMod0: - 0 :MSTORE(modexp_out),JMP(preEndMODEXP) + 0 :MSTORE(modexp_out), JMP(preEndMODEXP) finalMODEXP: - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) ; write data into memory @@ -259,17 +254,17 @@ finalMODEXP: 0 :MSTORE(retDataOffset) C :MSTORE(retDataLength) $ => B :MLOAD(retCallOffset) - $ => A :MLOAD(originCTX),JMPZ(handleGas) + $ => A :MLOAD(originCTX), JMPZ(handleGas) ; set retDataCTX $ => E :MLOAD(currentCTX) A => CTX E :MSTORE(retDataCTX) C :MSTORE(arithA) - 32 :MSTORE(arithB),CALL(divARITH) + 32 :MSTORE(arithB), CALL(divARITH) $ => E :MLOAD(arithRes1) E :MSTORE(modexp_returnIndex) - $ => A :MLOAD(arithRes2),JMPZ(returnLoop) + $ => A :MLOAD(arithRes2), JMPZ(returnLoop) A => C $ => A :MLOAD(modexp_out+E) 32 - C => D :CALL(SHLarith) @@ -282,8 +277,8 @@ finalMODEXP: $ => E :MLOAD(modexp_returnIndex) returnLoop: - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) E - 1 => E :MSTORE(modexp_returnIndex) $ => A :MLOAD(modexp_out+E) @@ -307,4 +302,4 @@ preEndMODEXP: A => CTX endMODEXP: - CTX :MSTORE(currentCTX),JMP(preEnd) \ No newline at end of file + CTX :MSTORE(currentCTX), JMP(preEnd) \ No newline at end of file From 9422c6a4353cce492fbb5dc3e1be5d8450580b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Thu, 23 Nov 2023 17:24:11 +0100 Subject: [PATCH 027/121] Minor bug found by Laia --- main/precompiled/pre-modexp.zkasm | 1 + main/precompiled/pre-sha2-256.zkasm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index d5c47c7a..d0e42eef 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -197,6 +197,7 @@ lastChecks: $ :LT, JMPC(endMODEXPFail) ; if Msize > MAX_SIZE_MODEXP --> endMODEXPFail ; get base value + $ => E :MLOAD(modexp_offset) ; This is used in modexp_getBase, modexp_getExp and modexp_getMod $ => C :MLOAD(modexp_Bsize) :CALL(modexp_getBase) ; get exp value diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 1f878c1d..e6c1f666 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -34,7 +34,7 @@ funcSHA2256: 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => A :MLOAD(arithRes1) - ; GAS - dinamicGas + ; GAS - dynamicGas GAS - %SHA2_256_WORD_GAS*A => GAS :JMPN(outOfGas) ; prepare retData From f4d7534ddb2089c1073fb82a8754c241de4be8ed Mon Sep 17 00:00:00 2001 From: laisolizq Date: Thu, 23 Nov 2023 18:42:34 +0100 Subject: [PATCH 028/121] fix premodexp save0out --- main/precompiled/pre-modexp.zkasm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index d0e42eef..7844c9fd 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -195,7 +195,6 @@ lastChecks: $ :LT, JMPC(endMODEXPFail) ; if Esize > MAX_SIZE_MODEXP --> endMODEXPFail $ => B :MLOAD(modexp_Msize) $ :LT, JMPC(endMODEXPFail) ; if Msize > MAX_SIZE_MODEXP --> endMODEXPFail - ; get base value $ => E :MLOAD(modexp_offset) ; This is used in modexp_getBase, modexp_getExp and modexp_getMod $ => C :MLOAD(modexp_Bsize) @@ -236,6 +235,9 @@ save1out: 1 :MSTORE(modexp_out), JMP(finalMODEXP) save0out: + $ => B :MLOAD(modexp_Msize) + %MAX_SIZE_MODEXP => A + $ :LT,JMPC(endMODEXPFail) 0 :MSTORE(modexp_out), JMP(finalMODEXP) save0outMod0: From ec1a2bdf510e47eaec334a749657d8e1ba86fea8 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Thu, 23 Nov 2023 15:18:44 +0100 Subject: [PATCH 029/121] fix sha counters --- main/constants.zkasm | 4 ++-- main/precompiled/pre-sha2-256.zkasm | 14 ++++++++++++-- package.json | 6 +++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/main/constants.zkasm b/main/constants.zkasm index dfbb2a84..a668e9e2 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -110,7 +110,7 @@ CONST %MAX_CNT_MEM_ALIGN_LIMIT = %TOTAL_STEPS_LIMIT / 32 CONST %MAX_CNT_KECCAK_F_LIMIT = (%TOTAL_STEPS_LIMIT / 155286) * 44 CONST %MAX_CNT_PADDING_PG_LIMIT = (%TOTAL_STEPS_LIMIT / 56) CONST %MAX_CNT_POSEIDON_G_LIMIT = (%TOTAL_STEPS_LIMIT / 30) -CONST %MAX_CNT_SHA256_F_LIMIT = 1925 +CONST %MAX_CNT_SHA256_F_LIMIT = (%TOTAL_STEPS_LIMIT / 31487) * 7 CONST %SAFE_RANGE = 20 ; safe guard counters to not take into account (%RANGE = 1 / SAFE_RANGE) @@ -121,8 +121,8 @@ CONST %MAX_CNT_MEM_ALIGN = %MAX_CNT_MEM_ALIGN_LIMIT - (%MAX_CNT_MEM_ALIGN_LIMIT CONST %MAX_CNT_KECCAK_F = %MAX_CNT_KECCAK_F_LIMIT - (%MAX_CNT_KECCAK_F_LIMIT / %SAFE_RANGE) CONST %MAX_CNT_PADDING_PG = %MAX_CNT_PADDING_PG_LIMIT - (%MAX_CNT_PADDING_PG_LIMIT / %SAFE_RANGE) CONST %MAX_CNT_POSEIDON_G = %MAX_CNT_POSEIDON_G_LIMIT - (%MAX_CNT_POSEIDON_G_LIMIT / %SAFE_RANGE) -CONST %MAX_CNT_POSEIDON_SLOAD_SSTORE = 257 CONST %MAX_CNT_SHA256_F = %MAX_CNT_SHA256_F_LIMIT - (%MAX_CNT_SHA256_F_LIMIT / %SAFE_RANGE) +CONST %MAX_CNT_POSEIDON_SLOAD_SSTORE = 518 CONST %MIN_CNT_KECCAK_BATCH = 1 ; minimum necessary keccaks to compute global hash diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 1f878c1d..308d498e 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -28,15 +28,26 @@ funcSHA2256: GAS - %SHA2_256_GAS => GAS :JMPN(outOfGas) $ => C :MLOAD(txCalldataLen) + ;words => A === (C+31)/32 => A C + 31 => A A :MSTORE(arithA) 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => A :MLOAD(arithRes1) - ; GAS - dinamicGas + ; GAS - dynamicGas GAS - %SHA2_256_WORD_GAS*A => GAS :JMPN(outOfGas) + ; Compute necessary sha256 counters to finish the full hash + ; Divide the total data length + 1 by 64 to obtain the sha256 counter increment + ; 64 is the value used by the prover to increment sha256 counters + C + 1 :MSTORE(arithA) + 64 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => A :MLOAD(arithRes1) + + ; check enough sha256 counters left + %MAX_CNT_SHA256_F - CNT_SHA256_F - A :JMPN(outOfCountersSha256) + ; prepare retData 0 :MSTORE(retDataOffset) 32 :MSTORE(retDataLength) @@ -113,7 +124,6 @@ SHA2256dataFinal: SHA2256: %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_SHA256_F - 1 :JMPN(outOfCountersSha256) $ => E :MLOAD(sha256DataId) HASHPOS :HASHSLEN(E) diff --git a/package.json b/package.json index 1a3ef8f2..627c85a3 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/l1-info-tree", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256-l1-info-tree", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree-merge", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fix-sha256", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 5dc4c52a96db4301707a3a831c41d159a177d1af Mon Sep 17 00:00:00 2001 From: Ignasi Date: Fri, 24 Nov 2023 12:10:00 +0100 Subject: [PATCH 030/121] Fix sha256 counters and typo --- main/precompiled/pre-sha2-256.zkasm | 32 +++++++++++------------------ main/precompiled/selector.zkasm | 2 +- test/testSHA256.zkasm | 2 +- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 308d498e..d5eb6578 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -13,10 +13,9 @@ VAR GLOBAL sha256HashPos VAR GLOBAL sha256Hash VAR GLOBAL tmpZkSHA256 -funcSHA2256: +funcSHA256: %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; Move balances if value > 0 just before executing the contract CALL $ => B :MLOAD(txValue) @@ -53,7 +52,7 @@ funcSHA2256: 32 :MSTORE(retDataLength) 32 :MSTORE(readXFromCalldataLength) 0 => HASHPOS - :CALL(SHA2256data) + :CALL(SHA256data) ; get & update sha256Data ID $ => E :MLOAD(sha256DataId) E + 1 :MSTORE(sha256DataId) @@ -62,11 +61,7 @@ funcSHA2256: 0 => E A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] -SHA2256dataReturn: - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) - +SHA256dataReturn: ; handle CTX $ => A :MLOAD(originCTX), JMPZ(handleGas) ; set retDataCTX @@ -86,17 +81,16 @@ SHA2256dataReturn: ; set currentCTX CTX :MSTORE(currentCTX), JMP(preEnd) -SHA2256data: +SHA256data: RR :MSTORE(tmpZkSHA256) 0 => E :MSTORE(sha256DataOffset) -SHA2256dataLoop: - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) +SHA256dataLoop: + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) ; Copy from calldata to hashS - C :JMPZ(SHA2256) - C - 32 :JMPN(SHA2256dataFinal) + C :JMPZ(computeSHA256) + C - 32 :JMPN(SHA256dataFinal) $ => E :MLOAD(sha256DataOffset) E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] $ => A :MLOAD(readXFromCalldataResult) @@ -105,12 +99,10 @@ SHA2256dataLoop: $ => E :MLOAD(sha256DataId) 32 => D A :HASHS(E) - C - 32 => C :JMP(SHA2256dataLoop) + C - 32 => C :JMP(SHA256dataLoop) -SHA2256dataFinal: +SHA256dataFinal: %MAX_CNT_STEPS - STEP - 300 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 15 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 10 :JMPN(outOfCountersArith) $ => E :MLOAD(sha256DataOffset) C :MSTORE(readXFromCalldataLength) @@ -122,7 +114,7 @@ SHA2256dataFinal: C => D A :HASHS(E) -SHA2256: +computeSHA256: %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) $ => E :MLOAD(sha256DataId) diff --git a/main/precompiled/selector.zkasm b/main/precompiled/selector.zkasm index a2c9e0df..3aedd8d9 100644 --- a/main/precompiled/selector.zkasm +++ b/main/precompiled/selector.zkasm @@ -67,7 +67,7 @@ INCLUDE "end.zkasm" */ selectorPrecompiled: A - 2 :JMPN(funcECRECOVER) - A - 3 :JMPN(funcSHA2256) ;:JMPN(SHA256) + A - 3 :JMPN(funcSHA256) ;:JMPN(SHA256) A - 4 :JMPN(revertPrecompiled) ;:JMPN(RIPEMD160) A - 5 :JMPN(IDENTITY) A - 6 :JMPN(funcModexp) diff --git a/test/testSHA256.zkasm b/test/testSHA256.zkasm index c64c4cc2..d1b025f1 100644 --- a/test/testSHA256.zkasm +++ b/test/testSHA256.zkasm @@ -16,7 +16,7 @@ start: 0 => E :MSTORE(sha256DataOffset) 0 => HASHPOS RR :MSTORE(tmpZkSHA256) - :CALL(SHA2256data) + :CALL(SHA256data) $ => E :MLOAD(sha256Hash) 0xa8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89n => A From b46718a6e92c3ed967a8ec3d8c579632a9aa7b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Fri, 24 Nov 2023 17:47:45 +0100 Subject: [PATCH 031/121] Fixing the number of inputs of BN254_ADDFP2 and BN254_SUBFP2 --- main/pairings/FP2BN254/addFp2BN254.zkasm | 4 ++-- main/pairings/FP2BN254/subFp2BN254.zkasm | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/main/pairings/FP2BN254/addFp2BN254.zkasm b/main/pairings/FP2BN254/addFp2BN254.zkasm index 36f61df4..e769eb5c 100644 --- a/main/pairings/FP2BN254/addFp2BN254.zkasm +++ b/main/pairings/FP2BN254/addFp2BN254.zkasm @@ -12,7 +12,7 @@ addFp2BN254: ; Compute and check the mul ; A + C = [E] + (q0·BN254_P) ; B + D = [OP] + (q1·BN254_P) - ${ARITH_BN254_ADDFP2_X(A,B,C,D)} => E - ${ARITH_BN254_ADDFP2_Y(A,B,C,D)} :MSTORE(addFp2BN254_i), ARITH_BN254_ADDFP2 + ${ARITH_BN254_ADDFP2(A,C)} => E + ${ARITH_BN254_ADDFP2(B,D)} :MSTORE(addFp2BN254_i), ARITH_BN254_ADDFP2 $ => C :MLOAD(addFp2BN254_i), RETURN diff --git a/main/pairings/FP2BN254/subFp2BN254.zkasm b/main/pairings/FP2BN254/subFp2BN254.zkasm index 852a318b..7542647b 100644 --- a/main/pairings/FP2BN254/subFp2BN254.zkasm +++ b/main/pairings/FP2BN254/subFp2BN254.zkasm @@ -12,7 +12,7 @@ subFp2BN254: ; Compute and check the mul ; A - C = [E] + (q0·BN254_P) ; B - D = [OP] + (q1·BN254_P) - ${ARITH_BN254_SUBFP2_X(A,B,C,D)} => E - ${ARITH_BN254_SUBFP2_Y(A,B,C,D)} :MSTORE(subFp2BN254_i), ARITH_BN254_SUBFP2 + ${ARITH_BN254_SUBFP2(A,C)} => E + ${ARITH_BN254_SUBFP2(B,D)} :MSTORE(subFp2BN254_i), ARITH_BN254_SUBFP2 $ => C :MLOAD(subFp2BN254_i), RETURN diff --git a/package.json b/package.json index 1a3ef8f2..3563fc50 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/l1-info-tree", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/sha256-l1-info-tree", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/l1-info-tree-merge", "chai": "^4.3.6", "chalk": "^3.0.0", From 63193c2c08af7f2dc98119265eb4d6a634160d16 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Fri, 24 Nov 2023 17:25:15 +0100 Subject: [PATCH 032/121] update sample parallel tests --- package.json | 4 ++-- tools/parallel-tests-sample/sample.test.js | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 627c85a3..5c6ff9f1 100644 --- a/package.json +++ b/package.json @@ -37,13 +37,13 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/sha256", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", "yargs": "^17.5.1" }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fix-sha256", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/wip-gha", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", diff --git a/tools/parallel-tests-sample/sample.test.js b/tools/parallel-tests-sample/sample.test.js index 24ae4fd6..c9e87c4b 100644 --- a/tools/parallel-tests-sample/sample.test.js +++ b/tools/parallel-tests-sample/sample.test.js @@ -23,8 +23,6 @@ const checkerDir = path.join(__dirname, 'checker.txt'); const inputPath = '%%INPUT_PATH%%'; const nameFile = path.basename(inputPath); const input = JSON.parse(fs.readFileSync(inputPath, 'utf8')); -const stepRetries = 3; -let currentTries = 0; it(`${nameFile}`, async () => { if (fs.existsSync(checkerDir)) { @@ -59,10 +57,8 @@ async function runTest(cmPols, steps) { await smMain.execute(cmPols.Main, input, rom, config); } catch (err) { // If fails for ooc, retry increasing stepsN up to three times - if (err.toString().includes('OOC') && currentTries < stepRetries) { - currentTries += 1; - counters = true; - await runTest(cmPols, steps * 2); + if (inputPath.includes('invalid-batch')) { + expect(input.oldStateRoot).to.be.equal(input.newStateRoot); return; } From 134fb3e4bd17a4384f0adbff289ee174389aa3b9 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 24 Nov 2023 18:15:27 +0100 Subject: [PATCH 033/121] LT4 sanity check on initial and final root --- main/constants.zkasm | 1 + main/main.zkasm | 13 ++++++++++++- package.json | 2 +- test/lt4-test.zkasm | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 test/lt4-test.zkasm diff --git a/main/constants.zkasm b/main/constants.zkasm index b61d2118..26726832 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -9,6 +9,7 @@ CONST %MAX_MEM_EXPANSION_BYTES = 0x3fffe0 CONST %FORK_ID = 7 CONST %L1INFO_TREE_LEVELS = 32 CONST %CALLDATA_RESERVED_CTX = 1 +CONSTL %FOUR_GOLDILOCKS = 0xffffffff00000001ffffffff00000001ffffffff00000001ffffffff00000001n ; GER manager storage positions constants CONST %GLOBAL_EXIT_ROOT_STORAGE_POS = 0 diff --git a/main/main.zkasm b/main/main.zkasm index 75111025..41e4b4b2 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -20,6 +20,12 @@ start: ; main zkROM entry point CTX - %FORK_ID :JMPNZ(failAssert) B :MSTORE(oldStateRoot) + + ; safety check that the input root is indeed inside the range limit of 4 goldilocks fields elements + B => A + %FOUR_GOLDILOCKS => B + 1 :LT4 + C :MSTORE(oldAccInputHash) SP :MSTORE(oldNumBatch) GAS :MSTORE(chainID) ; assumed to be less than 32 bits @@ -31,7 +37,7 @@ start: ; main zkROM entry point ${getForcedBlockHashL1()} => A :MSTORE(forcedBlockHashL1) ;set initial state root - B => SR + $ => SR :MLOAD(oldStateRoot) SR :MSTORE(batchSR) ; Increase batch number SP + 1 :MSTORE(newNumBatch) @@ -198,6 +204,11 @@ processTxsEnd: ;;;;;;;;;;;;;;;;;; ;; F - Finalize execution ;;;;;;;;;;;;;;;;;; + ; safety check that the output root is indeed inside the range limit of 4 goldilocks fields elements + SR => A + %FOUR_GOLDILOCKS => B + 1 :LT4 + ; Set output registers $ => D :MLOAD(newAccInputHash) $ => E :MLOAD(newLocalExitRoot) diff --git a/package.json b/package.json index 4e8885cf..98cd8c60 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/sha256", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", "yargs": "^17.5.1" }, "devDependencies": { diff --git a/test/lt4-test.zkasm b/test/lt4-test.zkasm new file mode 100644 index 00000000..b6d915d1 --- /dev/null +++ b/test/lt4-test.zkasm @@ -0,0 +1,38 @@ +start: + CONSTL %FOUR_GL = 0xffffffff00000001ffffffff00000001ffffffff00000001ffffffff00000001n + ; less than 4 goldilocks + 0 => A + %FOUR_GL => B + 1 :LT4 + + ; equal than 4 goldilocks + %FOUR_GL => A + %FOUR_GL => B + 0 :LT4 + + ; equal than 4 goldilocks (just 3 elements) + %FOUR_GL => A + 1 => B + $ => A :SUB + %FOUR_GL => B + 0 :LT4 + + ; less than 4 goldilocks (just 1 unit in all elements) + %FOUR_GL => A + 0x1000000000000000100000000000000010000000000000001n => B + $ => A :SUB + %FOUR_GL => B + 1 :LT4 + + ; more than 4 goldilocks (just 1 unit in all elements) + %FOUR_GL => A + 0x1000000000000000100000000000000010000000000000001n => B + $ => A :ADD + %FOUR_GL => B + 0 :LT4 + + + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, HASHPOS, RR ; Set all registers to 0 + :JMP(finalizeExecution) + +INCLUDE "../main/main.zkasm" \ No newline at end of file From 9bef8d0d95cbe881be229395473478b8d9b46315 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Mon, 27 Nov 2023 11:07:57 +0100 Subject: [PATCH 034/121] Bug fixing issues 37 and 38 --- main/load-tx-rlp.zkasm | 2 +- main/main.zkasm | 1 + main/precompiled/pre-ecAdd.zkasm | 7 ------- main/precompiled/pre-modexp.zkasm | 16 ++++------------ main/utils.zkasm | 2 +- 5 files changed, 7 insertions(+), 21 deletions(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 3d6a6afb..fd7c5d52 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -406,4 +406,4 @@ finalAppendTxs: C + D => C endAppendTxs: - HASHPOS :MSTORE(batchHashPos),JMP(processTxsEnd) + HASHPOS :MSTORE(batchHashPos),JMP(finalizeBatch) diff --git a/main/main.zkasm b/main/main.zkasm index 75111025..792f89b6 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -131,6 +131,7 @@ processIntrinsicTxFinished: processTxsEnd: ; Write values at storage at the end of block processing :CALL(consolidateBlock) +finalizeBatch: ;;;;;;;;;;;;;;;;;; ;; E - Batch asserts & computations: diff --git a/main/precompiled/pre-ecAdd.zkasm b/main/precompiled/pre-ecAdd.zkasm index b064a899..522944d1 100644 --- a/main/precompiled/pre-ecAdd.zkasm +++ b/main/precompiled/pre-ecAdd.zkasm @@ -77,13 +77,6 @@ continueEcAdd: :CALL(MSTOREX); in: [bytesToStore, E: offset] out: [E: new offset] :JMP(endECADD) -;endECADDFail: -; $ => A :MLOAD(originCTX), JMPZ(handleGas) -; 0 => GAS -; A => CTX -; 0 :MSTORE(retDataCTX) -; CTX :MSTORE(currentCTX), JMP(preEndFail) - preEndECADD: $ => CTX :MLOAD(originCTX) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 7844c9fd..371413f4 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -190,11 +190,11 @@ lastChecks: ; B > 0 from here %MAX_SIZE_MODEXP => A $ => B :MLOAD(modexp_Bsize) - $ :LT, JMPC(endMODEXPFail) ; if Bsize > MAX_SIZE_MODEXP --> endMODEXPFail + $ :LT, JMPC(preEndFail) ; if Bsize > MAX_SIZE_MODEXP --> preEndFail $ => B :MLOAD(modexp_Esize) - $ :LT, JMPC(endMODEXPFail) ; if Esize > MAX_SIZE_MODEXP --> endMODEXPFail + $ :LT, JMPC(preEndFail) ; if Esize > MAX_SIZE_MODEXP --> preEndFail $ => B :MLOAD(modexp_Msize) - $ :LT, JMPC(endMODEXPFail) ; if Msize > MAX_SIZE_MODEXP --> endMODEXPFail + $ :LT, JMPC(preEndFail) ; if Msize > MAX_SIZE_MODEXP --> preEndFail ; get base value $ => E :MLOAD(modexp_offset) ; This is used in modexp_getBase, modexp_getExp and modexp_getMod $ => C :MLOAD(modexp_Bsize) @@ -237,7 +237,7 @@ save1out: save0out: $ => B :MLOAD(modexp_Msize) %MAX_SIZE_MODEXP => A - $ :LT,JMPC(endMODEXPFail) + $ :LT,JMPC(preEndFail) 0 :MSTORE(modexp_out), JMP(finalMODEXP) save0outMod0: @@ -292,14 +292,6 @@ returnLoop: $ => E :MLOAD(modexp_returnIndex) C - 32 => C :JMPZ(endMODEXP, returnLoop) - -endMODEXPFail: - $ => A :MLOAD(originCTX), JMPZ(handleGas) - A => CTX - 0 :MSTORE(retDataCTX) - 0 => GAS - CTX :MSTORE(currentCTX), JMP(preEndFail) - preEndMODEXP: $ => A :MLOAD(originCTX), JMPZ(handleGas) A => CTX diff --git a/main/utils.zkasm b/main/utils.zkasm index 1739457c..17a93e2a 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -888,7 +888,7 @@ handleBatchError: ; if batch error is triggered while parsing the RLP, it jumps to 'appendTxsInit' ; to fill the missing bytes to complete 'batchDataHash' $ :MLOAD(isLoadingRLP),JMPNZ(appendTxsInit) - $${eventLog(onFinishTx)} :JMP(processTxsEnd) + $${eventLog(onFinishTx)} :JMP(finalizeBatch) errorAtFirstContext: ; Set tx status to failure From 615d22f27c176181edbe7d1e6dbceaee289aebb2 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Mon, 27 Nov 2023 14:35:55 +0100 Subject: [PATCH 035/121] PR review --- main/main.zkasm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main/main.zkasm b/main/main.zkasm index 41e4b4b2..94f53697 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -19,10 +19,9 @@ start: ; main zkROM entry point CTX :MSTORE(forkID) CTX - %FORK_ID :JMPNZ(failAssert) - B :MSTORE(oldStateRoot) + B => A :MSTORE(oldStateRoot) ; safety check that the input root is indeed inside the range limit of 4 goldilocks fields elements - B => A %FOUR_GOLDILOCKS => B 1 :LT4 From 6bbe7d9334ad6cbddfb256914019652cec996af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 27 Nov 2023 19:21:33 +0100 Subject: [PATCH 036/121] Adding constants as array input size --- main/modexp/README.md | 2 +- main/modexp/array_lib/array_add_AGTB.zkasm | 12 +++++----- main/modexp/array_lib/array_add_short.zkasm | 10 ++++----- main/modexp/array_lib/array_div_mod.zkasm | 18 +++++++-------- .../modexp/array_lib/array_div_mod_long.zkasm | 22 +++++++++---------- .../array_lib/array_div_mod_short.zkasm | 16 +++++++------- main/modexp/array_lib/array_mul.zkasm | 12 +++++----- main/modexp/array_lib/array_mul_long.zkasm | 16 +++++++------- main/modexp/array_lib/array_mul_short.zkasm | 10 ++++----- main/modexp/array_lib/array_square.zkasm | 22 +++++++++---------- main/modexp/array_lib/unused/array_add.zkasm | 12 +++++----- .../array_lib/unused/array_is_odd.zkasm | 4 ++-- .../array_lib/unused/array_is_one.zkasm | 4 ++-- .../array_lib/unused/array_is_zero.zkasm | 4 ++-- .../array_lib/unused/array_sub_AGTB.zkasm | 14 ++++++------ .../array_lib/unused/array_unshift.zkasm | 6 ++--- .../array_lib/utils/array_compare.zkasm | 8 +++---- main/modexp/array_lib/utils/array_trim.zkasm | 6 ++--- main/modexp/constants.zkasm | 5 +++++ main/modexp/modexp.zkasm | 12 +++++----- package.json | 2 +- test/testModExp.zkasm | 6 +++-- 22 files changed, 115 insertions(+), 108 deletions(-) create mode 100644 main/modexp/constants.zkasm diff --git a/main/modexp/README.md b/main/modexp/README.md index 2941e553..737e93d1 100644 --- a/main/modexp/README.md +++ b/main/modexp/README.md @@ -1,6 +1,6 @@ ## Notes - We work with unbounded and unsigned integers represented in (little-endian) chunks of $256$ bits. -- The maximum input array lengths for the ModExp are justified [here](https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43), in particular: +- The maximum input array lengths for the ModExp are justified [here](https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43), in particular: $$\text{BLen} \leq 75.894, \quad \text{MLen} \leq 75.894, \quad \text{ELen} \leq 720M + 32.$$ - This is important because it allows us to use the `JMPZ` instruction against the registers holding these values, instead of a binary `EQ` instruction, which is more costly. Here, remember that `JMPZ` only takes into account the first $32$ bits of the registers it is used for (i.e., you can safely use it as long as the register is between $0$ and $2^{32}$). \ No newline at end of file diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index ef901202..3982aa5f 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -3,15 +3,15 @@ ;; ;; ;; array_add_AGTB: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · out = inA + inB, with len(out) <= C + 1 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_add_AGTB(a: bigint[], b: bigint[], B: bigint): bigint[] { ; const alen = a.length; @@ -38,9 +38,9 @@ ; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead if possible. -VAR GLOBAL array_add_AGTB_inA[32] -VAR GLOBAL array_add_AGTB_inB[32] -VAR GLOBAL array_add_AGTB_out[33] +VAR GLOBAL array_add_AGTB_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_add_AGTB_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_add_AGTB_out[%ARRAY_MAX_LEN_PLUS_ONE] VAR GLOBAL array_add_AGTB_len_inA VAR GLOBAL array_add_AGTB_len_inB VAR GLOBAL array_add_AGTB_len_out diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index 64a62cc0..04d2bd42 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -1,14 +1,14 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; array_add_short: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; -;; output: +;; output: ;; · out = inA + inB, with len(out) <= C + 1 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_add_short(a: bigint[], b: bigint, B: bigint): bigint[] { ; const alen = a.length; @@ -27,9 +27,9 @@ ; return result; ; } -VAR GLOBAL array_add_short_inA[32] +VAR GLOBAL array_add_short_inA[%ARRAY_MAX_LEN] VAR GLOBAL array_add_short_inB -VAR GLOBAL array_add_short_out[33] +VAR GLOBAL array_add_short_out[%ARRAY_MAX_LEN_PLUS_ONE] VAR GLOBAL array_add_short_len_inA VAR GLOBAL array_add_short_len_out diff --git a/main/modexp/array_lib/array_div_mod.zkasm b/main/modexp/array_lib/array_div_mod.zkasm index eed9441d..d2fe0399 100644 --- a/main/modexp/array_lib/array_div_mod.zkasm +++ b/main/modexp/array_lib/array_div_mod.zkasm @@ -3,15 +3,15 @@ ;; POST: If div_mod_long, then the remainer is trimmed; if div_mod_short, then the quotient (and naturally the remainder) is trimmed ;; ;; array_div_mod: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_div_mod(a: bigint[], b: bigint[], B: bigint): bigint[] { ; if (a === [0n]) { @@ -21,7 +21,7 @@ ; return [0n, 0n]; ; } else if (b === [0n]) { ; throw new Error("Division by zero"); -; } +; } ; ; if (a === b) { ; return [1n, 0n]; @@ -35,10 +35,10 @@ ; return array_div_mod_long(a, b, B); ; } -VAR GLOBAL array_div_mod_inA[32] -VAR GLOBAL array_div_mod_inB[32] -VAR GLOBAL array_div_mod_quo[32] -VAR GLOBAL array_div_mod_rem[32] +VAR GLOBAL array_div_mod_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_mod_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_mod_quo[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_mod_rem[%ARRAY_MAX_LEN] VAR GLOBAL array_div_mod_len_inA VAR GLOBAL array_div_mod_len_inB @@ -100,7 +100,7 @@ array_div_mod_compare: %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_prep_inALTinB) - 1 => B + 1 => B $ :EQ, JMPC(array_div_mod_same_input) ; From here, inA > inB diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm index 9eff1cac..89aec571 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -3,15 +3,15 @@ ;; POST: The remainder is trimmed. ;; ;; array_div_mod_long: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_div_mod_long(a: bigint[], b: bigint[], B: bigint): bigint[] { ; if (a === [0n]) { @@ -21,7 +21,7 @@ ; return [0n, 0n]; ; } else if (b === [0n]) { ; throw new Error("Division by zero"); -; } +; } ; ; if (a === b) { ; return [1n, 0n]; @@ -33,10 +33,10 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_long_inA[32] -VAR GLOBAL array_div_mod_long_inB[32] -VAR GLOBAL array_div_mod_long_quo[32] -VAR GLOBAL array_div_mod_long_rem[32] +VAR GLOBAL array_div_mod_long_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_mod_long_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_mod_long_quo[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_mod_long_rem[%ARRAY_MAX_LEN] VAR GLOBAL array_div_mod_long_len_inA VAR GLOBAL array_div_mod_long_len_inB @@ -98,10 +98,10 @@ array_div_mod_long_compare1: %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_long_prep_inALTinB) - 1 => B + 1 => B $ :EQ, JMPC(array_div_mod_long_same_input) ; From here, inA > inB - + $${MPdiv(addr.array_div_mod_long_inA,mem.array_div_mod_long_len_inA,addr.array_div_mod_long_inB,mem.array_div_mod_long_len_inB)} :JMP(array_div_mod_long_prepare_trim_rem) @@ -151,7 +151,7 @@ array_div_mod_long_inALTinB: C - 1 => C :JMPNZ(array_div_mod_long_inALTinB) array_div_mod_long_inALTinB_before_end: - 0 :MSTORE(array_div_mod_long_quo) + 0 :MSTORE(array_div_mod_long_quo) 0 => B :JMP(array_div_mod_long_end) ; End of edge cases diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm index 80ba7728..cf09c6c0 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -3,14 +3,14 @@ ;; POST: The quotient is trimmed. ;; ;; array_div_mod_short: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; -;; output: +;; output: ;; · [quo,rem] = [inA / inB[0], inA % inB[0]], with len(quo) <= C, len(rem) = 1 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_div_mod_short(a: bigint[], b: bigint, B: bigint): bigint[] { ; if (a === [0n]) { @@ -20,7 +20,7 @@ ; return [0n, 0n]; ; } else if (b === 0n) { ; throw new Error("Division by zero"); -; } +; } ; ; if (a === b) { ; return [1n, 0n]; @@ -32,9 +32,9 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_short_inA[32] +VAR GLOBAL array_div_mod_short_inA[%ARRAY_MAX_LEN] VAR GLOBAL array_div_mod_short_inB -VAR GLOBAL array_div_mod_short_quo[32] +VAR GLOBAL array_div_mod_short_quo[%ARRAY_MAX_LEN] VAR GLOBAL array_div_mod_short_rem VAR GLOBAL array_div_mod_short_len_inA @@ -54,7 +54,7 @@ array_div_mod_short: RR :MSTORE(array_div_mod_short_RR) C :MSTORE(array_div_mod_short_len_inA) C :MSTORE(array_div_mod_short_len_quo) - + ; Let's cover the edge cases ; 1] Is inA == 0? C => A @@ -90,7 +90,7 @@ array_div_mod_short_compare_inA_inB: %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_short_inALTinB) - 1 => B + 1 => B $ :EQ, JMPC(array_div_mod_short_same_input) ; From here, it is known that inA > inB diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm index 55e39431..df12797a 100644 --- a/main/modexp/array_lib/array_mul.zkasm +++ b/main/modexp/array_lib/array_mul.zkasm @@ -2,15 +2,15 @@ ;; POST: out is trimmed ;; ;; array_mul: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · out = inA·inB, with len(out) <= C + D -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_mul(a: bigint[], b: bigint[], B: bigint): bigint[] { ; if (b.length === 1) { @@ -19,9 +19,9 @@ ; return array_mul_long(a, b, B); ; } -VAR GLOBAL array_mul_inA[32] -VAR GLOBAL array_mul_inB[32] -VAR GLOBAL array_mul_out[64] +VAR GLOBAL array_mul_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_mul_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_mul_out[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_mul_len_inA VAR GLOBAL array_mul_len_inB VAR GLOBAL array_mul_len_out diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index 98ab6599..bb5f6c30 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -3,15 +3,15 @@ ;; POST: out is trimmed ;; ;; array_mul_long: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · out = inA·inB, with len(out) <= C + D -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_mul_long(a: bigint[], b: bigint[], B: bigint): bigint[] { ; const alen = a.length; @@ -36,9 +36,9 @@ ; return result; ; } -VAR GLOBAL array_mul_long_inA[32] -VAR GLOBAL array_mul_long_inB[32] -VAR GLOBAL array_mul_long_out[64] +VAR GLOBAL array_mul_long_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_mul_long_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_mul_long_out[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_mul_long_len_inA VAR GLOBAL array_mul_long_len_inB VAR GLOBAL array_mul_long_len_out @@ -52,7 +52,7 @@ array_mul_long: %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) C => A - D => B + D => B 0 => C,D ${A*B} => E :ARITH A => C @@ -119,7 +119,7 @@ array_mul_long_loopZero2inB: ; out[i + j] = product - carry·B C :MSTORE(array_mul_long_out + E) - + ; out[i + j + 1] += carry E + 1 => E $ => A :MLOAD(array_mul_long_out + E) diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index de19921f..c06a7a8f 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -2,14 +2,14 @@ ;; POST: out is trimmed ;; ;; array_mul_short: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1], the second input ;; -;; output: +;; output: ;; · out = inA·inB, with len(out) <= C + 1 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_mul_short(a: bigint[], b: bigint, B: bigint): bigint[] { ; const alen = a.length; @@ -32,9 +32,9 @@ ; return result; ; } -VAR GLOBAL array_mul_short_inA[32] +VAR GLOBAL array_mul_short_inA[%ARRAY_MAX_LEN] VAR GLOBAL array_mul_short_inB -VAR GLOBAL array_mul_short_out[33] +VAR GLOBAL array_mul_short_out[%ARRAY_MAX_LEN_PLUS_ONE] VAR GLOBAL array_mul_short_len_inA VAR GLOBAL array_mul_short_len_out diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 665dc7a4..9162d44e 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -2,13 +2,13 @@ ;; POST: out is trimmed ;; ;; array_square: -;; in: +;; in: ;; · C ∈ [1, 32], the len of in ;; · in ∈ [0, 2²⁵ ⁶- 1]^C, the input array ;; -;; output: +;; output: ;; · out = in², with len(out) <= 2·C -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function array_square(a: bigint[], B: bigint): bigint[] { ; let len = a.length; @@ -33,8 +33,8 @@ ; return result; ; } -VAR GLOBAL array_square_in[32] -VAR GLOBAL array_square_out[64] +VAR GLOBAL array_square_in[%ARRAY_MAX_LEN] +VAR GLOBAL array_square_out[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_square_len_in VAR GLOBAL array_square_len_out @@ -72,7 +72,7 @@ array_square: $ => A :MLOAD(array_square_in) A => B 0 => C - $${var _arraySquare_a02 = A*B} + $${var _arraySquare_a02 = A*B} ${_arraySquare_a02 >> 256} => D ${_arraySquare_a02} => E :ARITH D :MSTORE(array_square_carry_high) @@ -167,7 +167,7 @@ array_square_loop_index_check: $ => A :MLOAD(array_square_in + RR) A => B 0 => C - $${var _arraySquare_aiai = A*B} + $${var _arraySquare_aiai = A*B} ${_arraySquare_aiai >> 256} => D ${_arraySquare_aiai} => E :ARITH D :MSTORE(array_square_carry_high) @@ -181,12 +181,12 @@ array_square_loop_index_check: array_square_loopZero2inA: RCX => E ; product = 2·(a_i·a_j) + out[i + j] + carry - + ; 1] a_i·a_j: This number cannot be GT (base - 2)·base + 1, two chunks $ => A :MLOAD(array_square_in + E) $ => B :MLOAD(array_square_in + RR) 0 => C - $${var _arraySquare_aiaj = A*B} + $${var _arraySquare_aiaj = A*B} ${_arraySquare_aiaj >> 256} => D ${_arraySquare_aiaj} => E :ARITH D :MSTORE(array_square_aiaj_high) @@ -196,14 +196,14 @@ array_square_loopZero2inA: $ => C :ADD, JMPC(array_square_add_carry_1) return_array_square_add_carry_1: $ => A :MLOAD(array_square_aiaj_high) - D => B + D => B $ => D :ADD, JMPC(array_square_add_carry_carry_1) return_array_square_add_carry_carry_1: ; The result is stored as array_square_highest_carry·base² + D·base + C - ; 3] 2·a_i·a_j + out[i + j]: + ; 3] 2·a_i·a_j + out[i + j]: ; a) j != len: This number cannot be GT base² + (base - 3)·base + 1, as out[i + j] < B ; b) j == len: This number cannot be GT base² + (base - 3)·base + base - 1, as out[i + j] <= B + (B - 3) ; In both cases, three chunks diff --git a/main/modexp/array_lib/unused/array_add.zkasm b/main/modexp/array_lib/unused/array_add.zkasm index 40561db4..1ef8df4e 100644 --- a/main/modexp/array_lib/unused/array_add.zkasm +++ b/main/modexp/array_lib/unused/array_add.zkasm @@ -1,19 +1,19 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; array_add: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · out = inA + inB, with len(out) <= C + 1 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_add_inA[32] -VAR GLOBAL array_add_inB[32] -VAR GLOBAL array_add_out[33] +VAR GLOBAL array_add_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_add_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_add_out[%ARRAY_MAX_LEN_PLUS_ONE] VAR GLOBAL array_add_len_inA VAR GLOBAL array_add_len_inB VAR GLOBAL array_add_len_out diff --git a/main/modexp/array_lib/unused/array_is_odd.zkasm b/main/modexp/array_lib/unused/array_is_odd.zkasm index 51c6e502..d28a60be 100644 --- a/main/modexp/array_lib/unused/array_is_odd.zkasm +++ b/main/modexp/array_lib/unused/array_is_odd.zkasm @@ -2,9 +2,9 @@ ;; PRE: The input arrays have been trimmed. ;; ;; array_is_odd: -;; in: +;; in: ;; · in ∈ [0, 2²⁵⁶ - 1]*, the input array -;; output: +;; output: ;; · 1, if in is an odd number ;; · 0, otherwise ;; diff --git a/main/modexp/array_lib/unused/array_is_one.zkasm b/main/modexp/array_lib/unused/array_is_one.zkasm index d22ae89a..81f96e99 100644 --- a/main/modexp/array_lib/unused/array_is_one.zkasm +++ b/main/modexp/array_lib/unused/array_is_one.zkasm @@ -2,10 +2,10 @@ ;; PRE: The input arrays have been trimmed. ;; ;; array_is_one: -;; in: +;; in: ;; · C ∈ [1, 32], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array -;; output: +;; output: ;; · 1, if in = 1 ;; · 0, otherwise ;; diff --git a/main/modexp/array_lib/unused/array_is_zero.zkasm b/main/modexp/array_lib/unused/array_is_zero.zkasm index 5c6e3ee9..fca7224d 100644 --- a/main/modexp/array_lib/unused/array_is_zero.zkasm +++ b/main/modexp/array_lib/unused/array_is_zero.zkasm @@ -2,10 +2,10 @@ ;; PRE: The input arrays have been trimmed. ;; ;; array_is_zero: -;; in: +;; in: ;; · C ∈ [1, 32], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array -;; output: +;; output: ;; · 1, if in = 0 ;; · 0, otherwise ;; diff --git a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm index 241414a8..6f292c82 100644 --- a/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +++ b/main/modexp/array_lib/unused/array_sub_AGTB.zkasm @@ -2,19 +2,19 @@ ;; PRE: inA >= inB ;; ;; array_sub_AGTB: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · out = inA - inB, with len(out) <= C -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_sub_AGTB_inA[32] -VAR GLOBAL array_sub_AGTB_inB[32] -VAR GLOBAL array_sub_AGTB_out[32] +VAR GLOBAL array_sub_AGTB_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_sub_AGTB_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_sub_AGTB_out[%ARRAY_MAX_LEN] VAR GLOBAL array_sub_AGTB_len_inA VAR GLOBAL array_sub_AGTB_len_inB @@ -37,7 +37,7 @@ array_sub_AGTB_add_carry: array_sub_AGTB_sub_carry: D => A - 1 => B + 1 => B $ :SUB, JMPC(array_sub_AGTB_set_carry_to_1, array_sub_AGTB_set_carry_tp_0) array_sub_AGTB_set_carry_to_1: diff --git a/main/modexp/array_lib/unused/array_unshift.zkasm b/main/modexp/array_lib/unused/array_unshift.zkasm index 0209f475..a42033c2 100644 --- a/main/modexp/array_lib/unused/array_unshift.zkasm +++ b/main/modexp/array_lib/unused/array_unshift.zkasm @@ -1,17 +1,17 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; array_unshift: -;; in: +;; in: ;; · C ∈ [1, 32], the len of in = [in[0], in[1], ..., in[C - 1]] ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; · D ∈ [0, 2²⁵⁶ - 1], the element to unshift ;; -;; output: +;; output: ;; · in = [D, in[0], in[1], ..., in[C - 1]] ;; · len = C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL array_unshift_in[32] +VAR GLOBAL array_unshift_in[%ARRAY_MAX_LEN] VAR GLOBAL array_unshift_len VAR GLOBAL array_unshift_RR diff --git a/main/modexp/array_lib/utils/array_compare.zkasm b/main/modexp/array_lib/utils/array_compare.zkasm index f94a0631..292626d0 100644 --- a/main/modexp/array_lib/utils/array_compare.zkasm +++ b/main/modexp/array_lib/utils/array_compare.zkasm @@ -2,13 +2,13 @@ ;; PRE: The input arrays have been trimmed. ;; ;; array_compare: -;; in: +;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array ;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array ;; -;; output: +;; output: ;; · 2, if inA > inB ;; · 1, if inA = inB ;; · 0, if inA < inB @@ -37,8 +37,8 @@ ; · inA < inB and lenA = lenB. ; ---------------------------------- -VAR GLOBAL array_compare_inA[32] -VAR GLOBAL array_compare_inB[32] +VAR GLOBAL array_compare_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_compare_inB[%ARRAY_MAX_LEN] VAR GLOBAL array_compare_result diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm index 5f6e30b6..0c4bdf48 100644 --- a/main/modexp/array_lib/utils/array_trim.zkasm +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -1,11 +1,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; array_trim: -;; in: +;; in: ;; · C ∈ [1, 3636], the len of in ;; · in ∈ [0, 2²⁵⁶ - 1]^C, the input array ;; -;; output: +;; output: ;; · C, the new length of in ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -18,7 +18,7 @@ ; a.length = i + 1; ; } -VAR GLOBAL array_trim_in[64] +VAR GLOBAL array_trim_in[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_trim_RR diff --git a/main/modexp/constants.zkasm b/main/modexp/constants.zkasm new file mode 100644 index 00000000..37c22310 --- /dev/null +++ b/main/modexp/constants.zkasm @@ -0,0 +1,5 @@ +; See the discussion [https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43] for more details. +CONST %ARRAY_MAX_LEN = 32 +CONST %ARRAY_MAX_LEN_PLUS_ONE = 33 +CONST %ARRAY_MAX_LEN_DOUBLED = 64 +CONST %MODEXP_MAX_LEN = 32 \ No newline at end of file diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 5a538acb..cb71c30d 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -4,7 +4,7 @@ ;; ;; modexp: ;; ---------------------------------------- -;; input: +;; input: ;; · Blen ∈ [1, 32], the len of B ;; · Elen ∈ [1, 32], the len of E ;; · Mlen ∈ [1, 32], the len of M @@ -12,7 +12,7 @@ ;; · E ∈ [0, 2²⁵⁶ - 1]^Elen, the exponent represented in little-endian ;; · M ∈ [0, 2²⁵⁶ - 1]^Mlen, the modulus represented in little-endian ;; -;; output: +;; output: ;; · B^E (mod M) ∈ [0, 2²⁵⁶ - 1]^Mlen ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -51,11 +51,11 @@ VAR GLOBAL modexp_Blen VAR GLOBAL modexp_Elen VAR GLOBAL modexp_Mlen -VAR GLOBAL modexp_B[32] -VAR GLOBAL modexp_E[32] -VAR GLOBAL modexp_M[32] +VAR GLOBAL modexp_B[%MODEXP_MAX_LEN] +VAR GLOBAL modexp_E[%MODEXP_MAX_LEN] +VAR GLOBAL modexp_M[%MODEXP_MAX_LEN] -VAR GLOBAL modexp_out[32] +VAR GLOBAL modexp_out[%MODEXP_MAX_LEN] VAR GLOBAL modexp_outlen VAR GLOBAL modexp_RR diff --git a/package.json b/package.json index 4e8885cf..98cd8c60 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/sha256", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", "yargs": "^17.5.1" }, "devDependencies": { diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index 8b0117b5..a12774e3 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -366,7 +366,7 @@ start: 13n :MLOAD(modexp_out + E) 2 :MLOAD(modexp_outlen) ; --------------------------------------------------------------------------------------------- - + ; 512 BITS EXPONENT TESTS ; --------------------------------------------------------------------------------------------- ; 1] B = [2n, 1n, 1n, 1n], E = [3n, 5n], M = [4n, 6n, 7n] @@ -436,7 +436,7 @@ start: ; --------------------------------------------------------------------------------------------- ; --------------------------------------------------------------------------------------------- -; ; SINGLETON TESTS TO ENSURE THE MAXIMUM INPUT LENGTH WE CAN ACHIEVE IN EACH OF BASE, EXPONENT +; ; SINGLETON TESTS TO ENSURE THE MAXIMUM INPUT LENGTH WE CAN ACHIEVE IN EACH OF BASE, EXPONENT ; ; AND MODULUS WITHOUT OVERFLOWING EITHER THE ARITH, BINARY OF STEPS COUNTERS ; ; --------------------------------------------------------------------------------------------- ; ; 1] B = [2n:1818n], E = [1n], M = [2n] @@ -532,6 +532,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/modexp/constants.zkasm" + INCLUDE "../main/modexp/array_lib/utils/array_trim.zkasm" INCLUDE "../main/modexp/array_lib/utils/array_compare.zkasm" From 87d26d94c4ecd2824642f11643a4030246c1ef58 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Tue, 28 Nov 2023 16:48:02 +0100 Subject: [PATCH 037/121] add label writeBlockInfoRoot --- main/block-info.zkasm | 1 + main/process-change-l2-block.zkasm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index ba6b125e..b1c61a32 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -158,6 +158,7 @@ finalConsolidateBlockInfoTree: %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B %BLOCK_INFO_ROOT_STORAGE_POS => C +writeBlockInfoRoot: $ => D :MLOAD(blockInfoSR) $ => SR :SSTORE, RETURN diff --git a/main/process-change-l2-block.zkasm b/main/process-change-l2-block.zkasm index 9659aad8..e8cd6cf9 100644 --- a/main/process-change-l2-block.zkasm +++ b/main/process-change-l2-block.zkasm @@ -98,7 +98,7 @@ verifyTimestampAndL1InfoRoot: $ => B :MLOAD(timestampL1InfoTree) $ :LT, JMPC(invalidChangeL2Block, initSetGERL1InfoTree) -setNewTimestamp: ;make an utils function +setNewTimestamp: ; Set new timestamp %TIMESTAMP_STORAGE_POS => C %ADDRESS_SYSTEM => A From 4b1be37b5f1bd51e2d34f09f0987c45834f47f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 28 Nov 2023 17:05:16 +0100 Subject: [PATCH 038/121] Added constraints for the free iinputs --- main/modexp/README.md | 6 - main/modexp/array_lib/array_div_mod.zkasm | 2 +- .../modexp/array_lib/array_div_mod_long.zkasm | 111 ++++++++++++------ .../array_lib/array_div_mod_short.zkasm | 49 ++++---- main/modexp/array_lib/utils/array_trim.zkasm | 4 +- main/precompiled/pre-modexp.zkasm | 1 + test/testArrayArith.zkasm | 2 + test/testArrayUtils.zkasm | 42 +++---- 8 files changed, 134 insertions(+), 83 deletions(-) delete mode 100644 main/modexp/README.md diff --git a/main/modexp/README.md b/main/modexp/README.md deleted file mode 100644 index 737e93d1..00000000 --- a/main/modexp/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Notes - -- We work with unbounded and unsigned integers represented in (little-endian) chunks of $256$ bits. -- The maximum input array lengths for the ModExp are justified [here](https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43), in particular: -$$\text{BLen} \leq 75.894, \quad \text{MLen} \leq 75.894, \quad \text{ELen} \leq 720M + 32.$$ - - This is important because it allows us to use the `JMPZ` instruction against the registers holding these values, instead of a binary `EQ` instruction, which is more costly. Here, remember that `JMPZ` only takes into account the first $32$ bits of the registers it is used for (i.e., you can safely use it as long as the register is between $0$ and $2^{32}$). \ No newline at end of file diff --git a/main/modexp/array_lib/array_div_mod.zkasm b/main/modexp/array_lib/array_div_mod.zkasm index d2fe0399..05b74585 100644 --- a/main/modexp/array_lib/array_div_mod.zkasm +++ b/main/modexp/array_lib/array_div_mod.zkasm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PRE: The input arrays have been trimmed; -;; POST: If div_mod_long, then the remainer is trimmed; if div_mod_short, then the quotient (and naturally the remainder) is trimmed +;; POST: The quotient and remainder are trimmed. ;; ;; array_div_mod: ;; in: diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm index 89aec571..f37dc514 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PRE: The input arrays have been trimmed. -;; POST: The remainder is trimmed. +;; POST: The quotient and remainder are trimmed. ;; ;; array_div_mod_long: ;; in: @@ -50,7 +50,7 @@ VAR GLOBAL array_div_mod_long_RR ; 1 - inB is zero array_div_mod_long: - %MAX_CNT_BINARY - CNT_BINARY - 4 - C - D :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_div_mod_long_RR) @@ -94,8 +94,8 @@ array_div_mod_long_compare_inB1: array_div_mod_long_compare1: :CALL(array_compare) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_long_prep_inALTinB) 1 => B @@ -104,7 +104,7 @@ array_div_mod_long_compare1: $${MPdiv(addr.array_div_mod_long_inA,mem.array_div_mod_long_len_inA,addr.array_div_mod_long_inB,mem.array_div_mod_long_len_inB)} - :JMP(array_div_mod_long_prepare_trim_rem) + :JMP(array_div_mod_long_prepare_mul_quo_inB) ; Begin of edge cases array_div_mod_long_inA_is_zero: @@ -155,33 +155,31 @@ array_div_mod_long_inALTinB_before_end: 0 => B :JMP(array_div_mod_long_end) ; End of edge cases -array_div_mod_long_prepare_trim_rem: - ${receiveLenRemainder()} => C - C => RR - - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) - -array_div_mod_long_trim_rem_in: - RR - 1 => RR - ${receiveRemainderChunk(RR)} => A - A :MSTORE(array_trim_in + RR) - RR :JMPZ(array_div_mod_long_trim_rem, array_div_mod_long_trim_rem_in) - -array_div_mod_long_trim_rem: - :CALL(array_trim) - - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) - - C :MSTORE(array_div_mod_long_len_rem) - array_div_mod_long_prepare_mul_quo_inB: ${receiveLenQuotient()} => C + + ; The received length must be between 1 and %ARRAY_MAX_LEN + C => A + 0 => B + 0 :EQ + %ARRAY_MAX_LEN_PLUS_ONE => B + 1 :LT + ; From here, 1 <= C <= %ARRAY_MAX_LEN + + ; To avoid non-determinism, we must ensure that the quotient is trimmed + ; i.e., that its last chunk is not 0 + C - 1 => RR + ${receiveQuotientChunk(RR)} => A + 0 => B + 0 :EQ + ; From here, the quotient is trimmed + C :MSTORE(array_div_mod_long_len_quo) $ => D :MLOAD(array_div_mod_long_len_inB) C => RR D => E - %MAX_CNT_STEPS - STEP - 5*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4*D - 1 :JMPN(outOfCountersStep) array_div_mod_long_quo_to_mul: RR - 1 => RR @@ -199,11 +197,58 @@ array_div_mod_long_inB_to_mul: array_div_mod_long_mul_quo_inB: :CALL(array_mul) - %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 14 :JMPN(outOfCountersStep) - ; prepare next + ; Check the remainder + ${receiveLenRemainder()} => D + + ; 1] The received length must be between 1 and %ARRAY_MAX_LEN + D => A + 0 => B + 0 :EQ + %ARRAY_MAX_LEN_PLUS_ONE => B + 1 :LT + ; From here, 1 <= C <= %ARRAY_MAX_LEN + + ; 2] To avoid non-determinism, we must ensure that the remainder is trimmed + ; i.e., that its last chunk is not 0 + D - 1 => E + ${receiveRemainderChunk(E)} => A + 0 => B + 0 :EQ + ; From here, the remainder is trimmed + + ; 3] Finally, we must ensure that the remainder is lower than inB + $ => C :MLOAD(array_div_mod_long_len_inB) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) + +array_div_mod_long_compare_inB2: + RR - 1 => RR + $ => A :MLOAD(array_div_mod_inB + RR) + A :MSTORE(array_compare_inA + RR) + RR :JMPZ(array_div_mod_long_compare_rem, array_div_mod_long_compare_inB2) + +array_div_mod_long_compare_rem: + E - 1 => E + ${receiveRemainderChunk(E)} => A + A :MSTORE(array_compare_inB + E) + E :JMPZ(array_div_mod_long_compare2, array_div_mod_long_compare_rem) + +array_div_mod_long_compare2: + :CALL(array_compare) + + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + + 2 :MLOAD(array_compare_result) + + D :MSTORE(array_div_mod_long_len_rem) + + ; prepare output and remainder to be added $ => C :MLOAD(array_mul_len_out) - $ => D :MLOAD(array_div_mod_long_len_rem) C => RR D => E @@ -225,7 +270,7 @@ array_div_mod_long_rem_to_add: array_div_mod_long_add_res_rem: :CALL(array_add_AGTB) - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) ; prepare next $ => C :MLOAD(array_add_AGTB_len_out) @@ -239,15 +284,15 @@ array_div_mod_long_compare_inA2: RR - 1 => RR $ => A :MLOAD(array_add_AGTB_out + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_mod_long_compare_inB2, array_div_mod_long_compare_inA2) + RR :JMPZ(array_div_mod_long_compare_inB3, array_div_mod_long_compare_inA2) -array_div_mod_long_compare_inB2: +array_div_mod_long_compare_inB3: E - 1 => E $ => A :MLOAD(array_div_mod_long_inA + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_mod_long_compare2, array_div_mod_long_compare_inB2) + E :JMPZ(array_div_mod_long_compare3, array_div_mod_long_compare_inB3) -array_div_mod_long_compare2: +array_div_mod_long_compare3: :CALL(array_compare) %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm index cf09c6c0..a804bd32 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -86,8 +86,8 @@ array_div_mod_short_inB_to_compare: array_div_mod_short_compare_inA_inB: :CALL(array_compare) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 18 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_short_inALTinB) 1 => B @@ -98,7 +98,7 @@ array_div_mod_short_compare_inA_inB: ; Strategy: Divide outside and check the result inside $${MPdiv_short(addr.array_div_mod_short_inA,mem.array_div_mod_short_len_inA,mem.array_div_mod_short_inB)} - :JMP(array_div_mod_short_prepare_trim_quo) + :JMP(array_div_mod_short_prepare_mul_quo_inB) ; Begin of edge cases array_div_mod_short_inA_is_zero: @@ -133,29 +133,30 @@ array_div_mod_short_inALTinB: 0 => B :JMP(array_div_mod_short_end) ; End of edge cases -array_div_mod_short_prepare_trim_quo: +array_div_mod_short_prepare_mul_quo_inB: ${receiveLenQuotient_short()} => C - C => RR - - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) -array_div_mod_short_trim_quo_in: - RR - 1 => RR + ; The received length must be between 1 and %ARRAY_MAX_LEN + C => A + 0 => B + 0 :EQ + %ARRAY_MAX_LEN_PLUS_ONE => B + 1 :LT + ; From here, 1 <= C <= %ARRAY_MAX_LEN + + ; To avoid non-determinism, we must ensure that the quotient is trimmed + ; i.e., that its last chunk is not 0 + C - 1 => RR ${receiveQuotientChunk_short(RR)} => A - A :MSTORE(array_trim_in + RR) - RR :JMPZ(array_div_mod_short_trim_quo, array_div_mod_short_trim_quo_in) - -array_div_mod_short_trim_quo: - :CALL(array_trim) - - %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) + 0 => B + 0 :EQ + ; From here, the quotient is trimmed C :MSTORE(array_div_mod_short_len_quo) -array_div_mod_short_prepare_mul_quo_inB: C => RR - %MAX_CNT_STEPS - STEP - 5*C - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4 :JMPN(outOfCountersStep) array_div_mod_short_quo_to_mul: RR - 1 => RR @@ -171,13 +172,14 @@ array_div_mod_short_inB_to_mul: array_div_mod_short_mul_quo_inB: :CALL(array_mul_short) - %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) ; prepare next $ => C :MLOAD(array_mul_short_len_out) C => RR - %MAX_CNT_STEPS - STEP - 4*C - 4 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 4*C - 6 :JMPN(outOfCountersStep) array_div_mod_short_result_to_add: RR - 1 => RR @@ -187,13 +189,18 @@ array_div_mod_short_result_to_add: array_div_mod_short_rem_to_add: ${receiveRemainderChunk_short()} => A + + ; We must ensure the the remaider is lower than inB + $ => B :MLOAD(array_div_mod_short_inB) + 1 :LT + A :MSTORE(array_div_mod_short_rem) A :MSTORE(array_add_short_inB) array_div_mod_short_add_result_rem: :CALL(array_add_short) - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) ; prepare next $ => C :MLOAD(array_add_short_len_out) diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm index 0c4bdf48..e0d5341f 100644 --- a/main/modexp/array_lib/utils/array_trim.zkasm +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -23,7 +23,7 @@ VAR GLOBAL array_trim_in[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_trim_RR array_trim: - %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) RR :MSTORE(array_trim_RR) @@ -32,7 +32,7 @@ array_trim: ; in case of zero input array, we return 1 array_trim_loop: %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) E - 1 => E :JMPZ(array_trim_end) $ => A :MLOAD(array_trim_in + E) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 7844c9fd..532ae62c 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -7,6 +7,7 @@ * @process-precompiled * - stack input: [x1, y1, x2, y2] * - stack output: [x, y] + * @note We work with unbounded and unsigned integers represented in (little-endian) chunks of 256 bits. * @note After a few discussions, we decided to set the maximum input length of the base, modulus and exponent to 32. * See [https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43] for more details. */ diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index 7ff129b1..6e1a95d9 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -975,6 +975,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/modexp/constants.zkasm" + INCLUDE "../main/modexp/array_lib/utils/array_trim.zkasm" INCLUDE "../main/modexp/array_lib/utils/array_compare.zkasm" diff --git a/test/testArrayUtils.zkasm b/test/testArrayUtils.zkasm index 6ff5f055..ec858436 100644 --- a/test/testArrayUtils.zkasm +++ b/test/testArrayUtils.zkasm @@ -50,7 +50,7 @@ start: ; array_compare ; --------------------------------------------------------------- ; 1] len(inA) > len(inB) should return 2 -array_compare_test_1: +array_compare_test_1: 5n :MSTORE(inA) 1 => E 6n :MSTORE(inA + E) @@ -85,7 +85,7 @@ array_compare_test_1_compare: 2 :MLOAD(array_compare_result) ; 2] len(inA) < len(inB) should return 0 -array_compare_test_2: +array_compare_test_2: 5n :MSTORE(inA) 1 => E 6n :MSTORE(inA + E) @@ -122,7 +122,7 @@ array_compare_test_2_compare: ; 3] len(inA) = len(inB) but inA > inB should return 2 -array_compare_test_3: +array_compare_test_3: 5n :MSTORE(inA) 1 => E 6n :MSTORE(inA + E) @@ -159,7 +159,7 @@ array_compare_test_3_compare: 2 :MLOAD(array_compare_result) ; 4] len(inA) = len(inB) but inA < inB should return 0 -array_compare_test_4: +array_compare_test_4: 5n :MSTORE(inA) 1 => E 6n :MSTORE(inA + E) @@ -196,7 +196,7 @@ array_compare_test_4_compare: 0 :MLOAD(array_compare_result) ; 5] inA = inB should return 1 -array_compare_test_5: +array_compare_test_5: 5n :MSTORE(inA) 1 => E 6n :MSTORE(inA + E) @@ -231,7 +231,7 @@ array_compare_test_5_memory_copy_inB_loop: array_compare_test_5_compare: :CALL(array_compare) 1 :MLOAD(array_compare_result) -; --------------------------------------------------------------- +; --------------------------------------------------------------- ; array unshift ; --------------------------------------------------------------- @@ -242,7 +242,7 @@ array_compare_test_5_compare: 5 :MLOAD(array_unshift_in) 1 :MLOAD(array_unshift_len) -array_unshift_test_1: +array_unshift_test_1: 2n :MSTORE(inA) 1 => E 1n :MSTORE(inA + E) @@ -281,7 +281,7 @@ array_unshift_test_1_dump: ; array trim ; --------------------------------------------------------------- ; 1] [2,1,0] should return 2 -array_trim_test_1: +array_trim_test_1: 2n :MSTORE(inA) 1 => E 1n :MSTORE(inA + E) @@ -304,7 +304,7 @@ array_trim_test_1_trim: C :ASSERT ; 2] [2,1,0,2] should return 4 -array_trim_test_2: +array_trim_test_2: 2n :MSTORE(inA) 1 => E 1n :MSTORE(inA + E) @@ -329,7 +329,7 @@ array_trim_test_2_trim: C :ASSERT ; 3] [0,0,0,0,0,0] should return 1 -array_trim_test_3: +array_trim_test_3: 0n :MSTORE(inA) 1 => E 0n :MSTORE(inA + E) @@ -358,7 +358,7 @@ array_trim_test_3_trim: C :ASSERT ; 4] [0] should return 1 -array_trim_test_4: +array_trim_test_4: 1 => C 0n :MSTORE(array_trim_in) :CALL(array_trim) @@ -369,7 +369,7 @@ array_trim_test_4: ; array is zero ; --------------------------------------------------------------- ; 1] [2,1] should return 0 -array_is_zero_test_1: +array_is_zero_test_1: 2 => C 2n :MSTORE(array_is_zero_in) 1 => E @@ -378,14 +378,14 @@ array_is_zero_test_1: 0 :MLOAD(array_is_zero_result) ; 2] [0] should return 1 -array_is_zero_test_2: +array_is_zero_test_2: 1 => C 0n :MSTORE(array_is_zero_in) :CALL(array_is_zero) 1 :MLOAD(array_is_zero_result) ; 3] [5] should return 0 -array_is_zero_test_3: +array_is_zero_test_3: 1 => C 5n :MSTORE(array_is_zero_in) :CALL(array_is_zero) @@ -395,7 +395,7 @@ array_is_zero_test_3: ; array is one ; --------------------------------------------------------------- ; 1] [2,1] should return 0 -array_is_one_test_1: +array_is_one_test_1: 2 => C 2n :MSTORE(array_is_one_in) 1 => E @@ -404,14 +404,14 @@ array_is_one_test_1: 0 :MLOAD(array_is_one_result) ; 2] [1] should return 1 -array_is_one_test_2: +array_is_one_test_2: 1 => C 1n :MSTORE(array_is_one_in) :CALL(array_is_one) 1 :MLOAD(array_is_one_result) ; 3] [5] should return 0 -array_is_one_test_3: +array_is_one_test_3: 1 => C 5n :MSTORE(array_is_one_in) :CALL(array_is_one) @@ -421,7 +421,7 @@ array_is_one_test_3: ; array is odd ; --------------------------------------------------------------- ; 1] [2,1] should return 0 -array_is_odd_test_1: +array_is_odd_test_1: 2n :MSTORE(array_is_odd_in) 1 => E 1n :MSTORE(array_is_odd_in + E) @@ -429,13 +429,13 @@ array_is_odd_test_1: 0 :MLOAD(array_is_odd_result) ; 2] [5] should return 1 -array_is_odd_test_2: +array_is_odd_test_2: 5n :MSTORE(array_is_odd_in) :CALL(array_is_odd) 1 :MLOAD(array_is_odd_result) ; 2] [3, 2] should return 1 -array_is_odd_test_3: +array_is_odd_test_3: 3n :MSTORE(array_is_odd_in) 1 => E 2n :MSTORE(array_is_odd_in + E) @@ -472,6 +472,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/modexp/constants.zkasm" + INCLUDE "../main/modexp/array_lib/utils/array_compare.zkasm" INCLUDE "../main/modexp/array_lib/utils/array_trim.zkasm" From db4f00b8eafad11d5f5f5cda5df5cb8b98160dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 28 Nov 2023 17:30:16 +0100 Subject: [PATCH 039/121] Added the constants --- main/precompiled/pre-modexp.zkasm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 532ae62c..e9784e46 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -11,6 +11,8 @@ * @note After a few discussions, we decided to set the maximum input length of the base, modulus and exponent to 32. * See [https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43] for more details. */ +INCLUDE "../modexp/constants.zkasm" + INCLUDE "../modexp/modexp.zkasm" INCLUDE "../modexp/modexp_utils.zkasm" From 331b36a8dfc3a5d9333c7f671164d3ca67795623 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Mon, 27 Nov 2023 13:39:53 +0100 Subject: [PATCH 040/121] Add effective percentage at l2 tx hash --- main/load-tx-rlp.zkasm | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index fd7c5d52..07de1701 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -365,6 +365,9 @@ checkAndSaveFrom: $ => E :MLOAD(l2TxHashPointer) $ => HASHPOS :MLOAD(l2HASHP) A :HASHP(E) + ; Add effective percentage to hash + $ => A :MLOAD(effectivePercentageRLP) + A :HASHP1(E) HASHPOS :HASHPLEN(E) $ => B :HASHPDIGEST(E) B :MSTORE(l2TxHash),JMP(txLoopRLP) diff --git a/package.json b/package.json index 98cd8c60..48a125d6 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/ep-l2txhash", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From dea225e5f51a07acfb45275adb78e0b347c74c8d Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 28 Nov 2023 13:47:40 +0100 Subject: [PATCH 041/121] Refactor effective percentage: secure in block info tree --- main/block-info.zkasm | 8 ++++++++ main/constants.zkasm | 1 + main/load-tx-rlp.zkasm | 3 --- package.json | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index b1c61a32..87fe348f 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -127,6 +127,14 @@ fillBlockInfoTreeWithTxReceipt: $ => D :MLOAD(cumulativeGasUsed) $ => SR :SSTORE + ; Insert transaction effectivePercentage + ; key: H([txIndex[0:4], txIndex[4:8], txIndex[8:12], txIndex[12:16], txIndex[16:20], 0, SMT_KEY_BLOCK_HEADER_CUMULATIVE_GAS_USED, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) + ; value: effectivePercentage + %SMT_KEY_BLOCK_HEADER_EFFECTIVE_PERCENTAGE => B + 0 => C + $ => D :MLOAD(effectivePercentageRLP) + $ => SR :SSTORE + ; Restore current SR SR :MSTORE(blockInfoSR) $ => SR :MLOAD(tmpBlockInfoSR), RETURN diff --git a/main/constants.zkasm b/main/constants.zkasm index 26726832..fd23a450 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -42,6 +42,7 @@ CONST %SMT_KEY_BLOCK_HEADER_TRANSACTION_HASH = 8 CONST %SMT_KEY_BLOCK_HEADER_STATUS = 9 CONST %SMT_KEY_BLOCK_HEADER_CUMULATIVE_GAS_USED = 10 CONST %SMT_KEY_BLOCK_HEADER_LOGS = 11 +CONST %SMT_KEY_BLOCK_HEADER_EFFECTIVE_PERCENTAGE = 12 ; SMT block header data leaf keys CONST %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH = 0 diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 07de1701..fd7c5d52 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -365,9 +365,6 @@ checkAndSaveFrom: $ => E :MLOAD(l2TxHashPointer) $ => HASHPOS :MLOAD(l2HASHP) A :HASHP(E) - ; Add effective percentage to hash - $ => A :MLOAD(effectivePercentageRLP) - A :HASHP1(E) HASHPOS :HASHPLEN(E) $ => B :HASHPDIGEST(E) B :MSTORE(l2TxHash),JMP(txLoopRLP) diff --git a/package.json b/package.json index 48a125d6..d1f388d5 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/ep-l2txhash", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/secure-effective-percentage", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 12e49fb45d6b3655659291d2a374b9cfa41cd61e Mon Sep 17 00:00:00 2001 From: Carlos Matallana <44141767+krlosMata@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:00:01 +0100 Subject: [PATCH 042/121] Update package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d1f388d5..a4bea130 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/secure-effective-percentage", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", @@ -51,4 +51,4 @@ "eslint-plugin-mocha": "^10.1.0", "mocha": "^10.2.0" } -} \ No newline at end of file +} From db93ed52398133007769a410a7fa31e510ae41d2 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 29 Nov 2023 12:51:24 +0100 Subject: [PATCH 043/121] optimize arrays --- main/modexp/array_lib/array_div_mod_long.zkasm | 14 +++++++------- main/modexp/array_lib/array_div_mod_short.zkasm | 16 +++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm index f37dc514..ecf38f06 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -156,14 +156,14 @@ array_div_mod_long_inALTinB_before_end: ; End of edge cases array_div_mod_long_prepare_mul_quo_inB: - ${receiveLenQuotient()} => C + ${receiveLenQuotient()} => C :JMPN(failAssert) - ; The received length must be between 1 and %ARRAY_MAX_LEN - C => A - 0 => B - 0 :EQ - %ARRAY_MAX_LEN_PLUS_ONE => B - 1 :LT + ; ensure C0 > 0 + C - 1 :JMPN(failAssert) + ; if C > %ARRAY_MAX_LEN --> does not jump to `continue_xx` label + C - %ARRAY_MAX_LEN_PLUS_ONE :JMPN(continue_array_div_mod_long_prepare_mul_quo_inB, failAssert) + +continue_array_div_mod_long_prepare_mul_quo_inB: ; From here, 1 <= C <= %ARRAY_MAX_LEN ; To avoid non-determinism, we must ensure that the quotient is trimmed diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm index a804bd32..f6ed18db 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -134,14 +134,16 @@ array_div_mod_short_inALTinB: ; End of edge cases array_div_mod_short_prepare_mul_quo_inB: - ${receiveLenQuotient_short()} => C + ; C = [c7, c6, ..., c0] + ; JMPN instruction assures c0 is within the range [0, 2**32 - 1] + ${receiveLenQuotient_short()} => C :JMPN(failAssert) - ; The received length must be between 1 and %ARRAY_MAX_LEN - C => A - 0 => B - 0 :EQ - %ARRAY_MAX_LEN_PLUS_ONE => B - 1 :LT + ; ensure C0 > 0 + C - 1 :JMPN(failAssert) + ; if C > %ARRAY_MAX_LEN --> does not jump to `continue_xx` label + C - %ARRAY_MAX_LEN_PLUS_ONE :JMPN(continue_array_div_mod_short_prepare_mul_quo_inB, failAssert) + +continue_array_div_mod_short_prepare_mul_quo_inB: ; From here, 1 <= C <= %ARRAY_MAX_LEN ; To avoid non-determinism, we must ensure that the quotient is trimmed From 3d8d880dcddc0bbae99a11e6c8bbc16f25b2daa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 29 Nov 2023 17:42:25 +0100 Subject: [PATCH 044/121] Fixed the optimization. Moved an unused folder --- .../modexp/array_lib/array_div_mod_long.zkasm | 24 +++++++------------ .../array_lib/array_div_mod_short.zkasm | 15 ++++-------- package.json | 4 ++-- test/testArrayArith.zkasm | 5 ++++ test/testModExp.zkasm | 5 ++++ {test => tools}/modexp-utils/README.md | 0 .../modexp-utils/modexp-test-gen.js | 0 .../modexp-utils/modexp-test-int.sage | 0 8 files changed, 24 insertions(+), 29 deletions(-) rename {test => tools}/modexp-utils/README.md (100%) rename {test => tools}/modexp-utils/modexp-test-gen.js (100%) rename {test => tools}/modexp-utils/modexp-test-int.sage (100%) diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_mod_long.zkasm index ecf38f06..ac0e98f6 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_mod_long.zkasm @@ -156,19 +156,15 @@ array_div_mod_long_inALTinB_before_end: ; End of edge cases array_div_mod_long_prepare_mul_quo_inB: - ${receiveLenQuotient()} => C :JMPN(failAssert) + $0{receiveLenQuotient()} => C - ; ensure C0 > 0 - C - 1 :JMPN(failAssert) - ; if C > %ARRAY_MAX_LEN --> does not jump to `continue_xx` label - C - %ARRAY_MAX_LEN_PLUS_ONE :JMPN(continue_array_div_mod_long_prepare_mul_quo_inB, failAssert) - -continue_array_div_mod_long_prepare_mul_quo_inB: + ; The received length must be between 1 and %ARRAY_MAX_LEN + C - 1 => RR :JMPN(failAssert) ; If C = 0, then fail + %ARRAY_MAX_LEN - C :JMPN(failAssert) ; If C > %ARRAY_MAX_LEN, then fail ; From here, 1 <= C <= %ARRAY_MAX_LEN ; To avoid non-determinism, we must ensure that the quotient is trimmed ; i.e., that its last chunk is not 0 - C - 1 => RR ${receiveQuotientChunk(RR)} => A 0 => B 0 :EQ @@ -201,19 +197,15 @@ array_div_mod_long_mul_quo_inB: %MAX_CNT_STEPS - STEP - 14 :JMPN(outOfCountersStep) ; Check the remainder - ${receiveLenRemainder()} => D + $0{receiveLenRemainder()} => D ; 1] The received length must be between 1 and %ARRAY_MAX_LEN - D => A - 0 => B - 0 :EQ - %ARRAY_MAX_LEN_PLUS_ONE => B - 1 :LT - ; From here, 1 <= C <= %ARRAY_MAX_LEN + D - 1 => E :JMPN(failAssert) ; If D = 0, then fail + %ARRAY_MAX_LEN - D :JMPN(failAssert) ; If D > %ARRAY_MAX_LEN, then fail + ; From here, 1 <= D <= %ARRAY_MAX_LEN ; 2] To avoid non-determinism, we must ensure that the remainder is trimmed ; i.e., that its last chunk is not 0 - D - 1 => E ${receiveRemainderChunk(E)} => A 0 => B 0 :EQ diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_mod_short.zkasm index f6ed18db..f2f37e43 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_mod_short.zkasm @@ -134,28 +134,21 @@ array_div_mod_short_inALTinB: ; End of edge cases array_div_mod_short_prepare_mul_quo_inB: - ; C = [c7, c6, ..., c0] - ; JMPN instruction assures c0 is within the range [0, 2**32 - 1] - ${receiveLenQuotient_short()} => C :JMPN(failAssert) + $0{receiveLenQuotient_short()} => C - ; ensure C0 > 0 - C - 1 :JMPN(failAssert) - ; if C > %ARRAY_MAX_LEN --> does not jump to `continue_xx` label - C - %ARRAY_MAX_LEN_PLUS_ONE :JMPN(continue_array_div_mod_short_prepare_mul_quo_inB, failAssert) - -continue_array_div_mod_short_prepare_mul_quo_inB: + ; The received length must be between 1 and %ARRAY_MAX_LEN + C - 1 => RR :JMPN(failAssert) ; If C = 0, then fail + %ARRAY_MAX_LEN - C :JMPN(failAssert) ; If C > %ARRAY_MAX_LEN, then fail ; From here, 1 <= C <= %ARRAY_MAX_LEN ; To avoid non-determinism, we must ensure that the quotient is trimmed ; i.e., that its last chunk is not 0 - C - 1 => RR ${receiveQuotientChunk_short(RR)} => A 0 => B 0 :EQ ; From here, the quotient is trimmed C :MSTORE(array_div_mod_short_len_quo) - C => RR %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4 :JMPN(outOfCountersStep) diff --git a/package.json b/package.json index 98cd8c60..8efa574f 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,12 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/infree0", "yargs": "^17.5.1" }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/infree0", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index 6e1a95d9..6b8b821a 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -949,6 +949,11 @@ outOfCountersStep: outOfCountersArith: ${dump(CNT_ARITH)} :JMP(end) +;@info function to force a failed assert +failAssert: + 1 => A + 2 :ASSERT + end: $ => A :MLOAD(initial_A) diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index a12774e3..2ef55605 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -506,6 +506,11 @@ outOfCountersStep: outOfCountersArith: ${dump(CNT_ARITH)} :JMP(end) +;@info function to force a failed assert +failAssert: + 1 => A + 2 :ASSERT + end: $ => A :MLOAD(initial_A) diff --git a/test/modexp-utils/README.md b/tools/modexp-utils/README.md similarity index 100% rename from test/modexp-utils/README.md rename to tools/modexp-utils/README.md diff --git a/test/modexp-utils/modexp-test-gen.js b/tools/modexp-utils/modexp-test-gen.js similarity index 100% rename from test/modexp-utils/modexp-test-gen.js rename to tools/modexp-utils/modexp-test-gen.js diff --git a/test/modexp-utils/modexp-test-int.sage b/tools/modexp-utils/modexp-test-int.sage similarity index 100% rename from test/modexp-utils/modexp-test-int.sage rename to tools/modexp-utils/modexp-test-int.sage From fbed9b35e4df16de1f036f93a7d707ab7e1d5e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip=20Ardevol?= Date: Wed, 29 Nov 2023 17:55:09 +0100 Subject: [PATCH 045/121] Update package.json --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8efa574f..a4bea130 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,12 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/infree0", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", "yargs": "^17.5.1" }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/infree0", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", @@ -51,4 +51,4 @@ "eslint-plugin-mocha": "^10.1.0", "mocha": "^10.2.0" } -} \ No newline at end of file +} From 6de849d352dbd512f96aa18111e2f7b581caac60 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Thu, 30 Nov 2023 15:54:53 +0100 Subject: [PATCH 046/121] Small fixes, typos, optimizations, renamings... --- main/block-info.zkasm | 22 +++++++++++----------- main/load-tx-rlp.zkasm | 4 +--- main/opcodes/block.zkasm | 2 +- main/process-change-l2-block.zkasm | 10 +++++----- main/utils.zkasm | 3 +-- main/vars.zkasm | 4 ++-- 6 files changed, 21 insertions(+), 24 deletions(-) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index 87fe348f..a05ce1ff 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -1,4 +1,4 @@ -VAR GLOBAL tmpBlockInfoSR +VAR GLOBAL tmpSR VAR GLOBAL currentLogIndex initBlockInfoTree: @@ -22,9 +22,9 @@ revertBlockInfoTree: setupNewBlockInfoTree: ; checks zk-counters %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*6 :JMPN(outOfCountersPoseidon) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*7 :JMPN(outOfCountersPoseidon) ; save current state root & load block info root - SR :MSTORE(tmpBlockInfoSR) + SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) ; Insert previous block hash @@ -87,12 +87,12 @@ setupNewBlockInfoTree: %INDEX_BLOCK_HEADER_PARAM_BLOCK_HASH_L1 => A %SMT_KEY_BLOCK_HEADER_PARAM => B 0 => C - $ => D :MLOAD(blockchashL1InfoTree) + $ => D :MLOAD(blockHashL1InfoTree) $ => SR :SSTORE ; Restore current SR SR :MSTORE(blockInfoSR) - $ => SR :MLOAD(tmpBlockInfoSR), RETURN + $ => SR :MLOAD(tmpSR), RETURN ; @info Fill Block Info tree with tx receipt values fillBlockInfoTreeWithTxReceipt: @@ -100,7 +100,7 @@ fillBlockInfoTreeWithTxReceipt: %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon) ; save current state root & load block info root - SR :MSTORE(tmpBlockInfoSR) + SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) ; Insert transaction hash ; key: H([txIndex[0:4], txIndex[4:8], txIndex[8:12], txIndex[12:16], txIndex[16:20], 0, SMT_KEY_BLOCK_HEADER_TRANSACTION_HASH, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) @@ -137,7 +137,7 @@ fillBlockInfoTreeWithTxReceipt: ; Restore current SR SR :MSTORE(blockInfoSR) - $ => SR :MLOAD(tmpBlockInfoSR), RETURN + $ => SR :MLOAD(tmpSR), RETURN ; @info Fill Block Info tree with block gas used at the end of block processing and Store block Info Root in storage consolidateBlock: @@ -145,7 +145,7 @@ consolidateBlock: %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) ; save current state root & load block info root - SR :MSTORE(tmpBlockInfoSR) + SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) ; Insert transaction cumulativeGasUsed @@ -159,7 +159,7 @@ consolidateBlock: ; Restore current SR SR :MSTORE(blockInfoSR) - $ => SR :MLOAD(tmpBlockInfoSR) + $ => SR :MLOAD(tmpSR) finalConsolidateBlockInfoTree: ; Store block Info Root in storage @@ -177,7 +177,7 @@ fillBlockInfoTreeWithLog: %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE :JMPN(outOfCountersPoseidon) ; save current state root & load block info root - SR :MSTORE(tmpBlockInfoSR) + SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) ; Retrieve and update curentLogIndex @@ -194,4 +194,4 @@ fillBlockInfoTreeWithLog: ; Restore current SR SR :MSTORE(blockInfoSR) - $ => SR :MLOAD(tmpBlockInfoSR), RETURN \ No newline at end of file + $ => SR :MLOAD(tmpSR), RETURN \ No newline at end of file diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index fd7c5d52..765f7e18 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -88,8 +88,7 @@ nonceREAD: A - 0x89 :JMPN(shortNonce, invalidTxRLP) nonce0: - 0 => A :MSTORE(lengthNonce) - :JMP(endNonce) + 0 => A :MSTORE(lengthNonce), JMP(endNonce) shortNonce: A - 0x80 => D @@ -155,7 +154,6 @@ toREAD: A - 0x95 :JMPN(shortTo, invalidTxRLP) noTo: - 0 => A 1 :MSTORE(isCreateContract), JMP(endTo) shortTo: diff --git a/main/opcodes/block.zkasm b/main/opcodes/block.zkasm index 78ea3e08..2f2c4f7a 100644 --- a/main/opcodes/block.zkasm +++ b/main/opcodes/block.zkasm @@ -34,7 +34,7 @@ opBLOCKHASH: B :HASHK(E) %STATE_ROOT_STORAGE_POS :HASHK(E) HASHPOS :HASHKLEN(E) - ; blockhash key = hash(blockNumber, BLOCK_INFO_ROOT_STORAGE_POS) + ; blockhash key = hash(blockNumber, STATE_ROOT_STORAGE_POS) $ => C :HASHKDIGEST(E) %ADDRESS_SYSTEM => A ; set key for smt storage query diff --git a/main/process-change-l2-block.zkasm b/main/process-change-l2-block.zkasm index e8cd6cf9..b55d7fc4 100644 --- a/main/process-change-l2-block.zkasm +++ b/main/process-change-l2-block.zkasm @@ -62,7 +62,7 @@ continueProcessChangeL2Block: ; - update timestamp only if currentTimestamp < limitTimestamp ; - set blockHash to default $ => C :MLOAD(forcedBlockHashL1) - C :MSTORE(blockchashL1InfoTree) + C :MSTORE(blockHashL1InfoTree) A :MSTORE(timestamp) $ :LT, JMPNC(initSetGERL1InfoTree) @@ -89,7 +89,7 @@ verifyTimestampAndL1InfoRoot: $ :MLOAD(indexL1InfoTree), JMPZ(skipSetGERL1InfoTree) ${getL1InfoGER(mem.indexL1InfoTree)} => A :MSTORE(gerL1InfoTree) - ${getL1InfoBlockHash(mem.indexL1InfoTree)} => B :MSTORE(blockchashL1InfoTree) + ${getL1InfoBlockHash(mem.indexL1InfoTree)} => B :MSTORE(blockHashL1InfoTree) ${getL1InfoTimestamp(mem.indexL1InfoTree)} => C :MSTORE(timestampL1InfoTree) :CALL(verifyMerkleProof) @@ -128,7 +128,7 @@ setGERL1InfoTree: HASHPOS :HASHKLEN(E) $ => C :HASHKDIGEST(E) - ; read blockchashL1InfoTree given the l1InfoRoot + ; read blockHashL1InfoTree given the l1InfoRoot ; skip overwrite blockHashL1 if it is different than 0 (already set) %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A %SMT_KEY_SC_STORAGE => B @@ -139,8 +139,8 @@ setGERL1InfoTree: ; write blockhashL1 %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A %SMT_KEY_SC_STORAGE => B - $ => D :MLOAD(blockchashL1InfoTree) - $ => SR :SSTORE ; Store 'blockchashL1InfoTree' in storage position 'keccak256(gerL1InfoTree, 0)' + $ => D :MLOAD(blockHashL1InfoTree) + $ => SR :SSTORE ; Store 'blockHashL1InfoTree' in storage position 'keccak256(gerL1InfoTree, 0)' skipSetGERL1InfoTree: :CALL(setupNewBlockInfoTree) diff --git a/main/utils.zkasm b/main/utils.zkasm index 17a93e2a..56814ff1 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -1566,8 +1566,7 @@ hashLeft: hashBranchEnd: HASHPOS :HASHKLEN(E) $ => C :HASHKDIGEST(E) - B => D ; recover loop iteration - D + 1 => D :JMP(verifyMerkleProofLoop) + B + 1 => D :JMP(verifyMerkleProofLoop) verifyMerkleProofEnd: $ => A :MLOAD(l1InfoRoot) diff --git a/main/vars.zkasm b/main/vars.zkasm index b22c667e..9b3d6063 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -9,7 +9,7 @@ VAR GLOBAL timestampLimit ; timestampLimit of the batch VAR GLOBAL timestamp ; Current batch timestamp VAR GLOBAL chainID ; Current batch chain id VAR GLOBAL forkID ; Fork identifier -VAR GLOBAL forcedBlockHashL1 ; blockHash ¡L1 when a forced transaction ahs been done +VAR GLOBAL forcedBlockHashL1 ; blockHash ¡n L1 when a forced transaction has been done VAR GLOBAL isForced ; Flag to determine if the batch is forced VAR GLOBAL cumulativeGasUsed ; cumulative gas used in the block @@ -111,6 +111,6 @@ VAR CTX initLogIndex ; log index once a new context begins VAR CTX deltaTimestamp ; delta timestamp of the current change L2 block tx VAR CTX indexL1InfoTree ; indexL1InfoTree of the current change L2 block tx VAR CTX gerL1InfoTree ; new GER of the current change L2 block tx -VAR CTX blockchashL1InfoTree ; new BlockchashL1 of the current change L2 block tx +VAR CTX blockHashL1InfoTree ; new BlockchashL1 of the current change L2 block tx VAR CTX timestampL1InfoTree ; new timestamp of the current change L2 block tx VAR CTX isChangeL2BlockTx ; flag to determine if the current tx is a change L2 block tx From 6d9d5afba2298123a75b809252dcd834e44afe7c Mon Sep 17 00:00:00 2001 From: Ignasi Date: Thu, 30 Nov 2023 16:58:41 +0100 Subject: [PATCH 047/121] Typos at comments + 1 typo at a constant --- .gitignore | 2 ++ main/block-info.zkasm | 2 +- main/constants.zkasm | 2 +- main/ecrecover/ecrecover.zkasm | 4 ++-- main/ecrecover/mulPointEc.zkasm | 8 ++++---- main/end.zkasm | 2 +- main/load-tx-rlp.zkasm | 2 +- main/opcodes/arithmetic.zkasm | 2 +- main/opcodes/block.zkasm | 2 +- main/opcodes/calldata-returndata-code.zkasm | 10 +++++----- main/opcodes/context-information.zkasm | 2 +- main/opcodes/create-terminate-context.zkasm | 14 +++++++------- main/opcodes/stack-operations.zkasm | 2 +- main/precompiled/pre-ecPairing.zkasm | 2 +- main/precompiled/pre-sha2-256.zkasm | 2 +- main/process-tx.zkasm | 8 ++++---- main/utils.zkasm | 6 +++--- main/vars.zkasm | 4 ++-- 18 files changed, 39 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 6b7d518d..e9602ef7 100644 --- a/.gitignore +++ b/.gitignore @@ -75,3 +75,5 @@ tools/parallel-tests .vscode/launch.json + +.vscode/settings.json diff --git a/main/block-info.zkasm b/main/block-info.zkasm index a05ce1ff..fc8cd16e 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -180,7 +180,7 @@ fillBlockInfoTreeWithLog: SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) - ; Retrieve and update curentLogIndex + ; Retrieve and update currentLogIndex $ => C :MLOAD(currentLogIndex) C + 1 :MSTORE(currentLogIndex) diff --git a/main/constants.zkasm b/main/constants.zkasm index fd23a450..73f913e1 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -80,7 +80,7 @@ CONST %KECCAK_WORD_GAS = 6 ; Once per word of the KECCAK256 operation's data. CONST %LOG_GAS = 375 ; Per LOG* operation. CONST %LOG_TOPIC_GAS = 375 ; Per LOG topic operation. CONST %JUMP_DEST_GAS = 1 ; Once per JUMPDEST operation. -CONST %WARM_STORGE_READ_GAS = 100 ; WarmStorageReadCostEIP2929 +CONST %WARM_STORAGE_READ_GAS = 100 ; WarmStorageReadCostEIP2929 CONST %COLD_ACCOUNT_ACCESS_COST_REDUCED = 2500 ; ColdAccountAccessCostEIP2929 reduced(2600) CONST %COLD_ACCOUNT_ACCESS_COST = 2600 ; ColdAccountAccessCostEIP2929 CONST %EXP_BYTE_GAS = 50 ; was raised to 50 during Eip158 (Spurious Dragon) diff --git a/main/ecrecover/ecrecover.zkasm b/main/ecrecover/ecrecover.zkasm index 29294bbc..ebe99b09 100644 --- a/main/ecrecover/ecrecover.zkasm +++ b/main/ecrecover/ecrecover.zkasm @@ -181,7 +181,7 @@ k1_c_is_not_zero: ; FNEC - A = FNEC - (hash * inv_r) % FNEC A => B %FNEC => A - ; B != 0 ==> multPointEc_k1 = FNEC - B + ; B != 0 ==> mulPointEc_k1 = FNEC - B ; k1 is alias-free $ :SUB, MSTORE(mulPointEc_k1) @@ -208,7 +208,7 @@ k1_calculated: A :MSTORE(mulPointEc_p2_x) ; y isn't an alias because was checked before - ; (r,y) is a point of curve because it satisfacts the curve equation + ; (r,y) is a point of curve because it satisfies the curve equation $ => A :MLOAD(ecrecover_y) ; [steps: 120, bin: 10, arith: 15] A :MSTORE(mulPointEc_p2_y),CALL(mulPointEc) diff --git a/main/ecrecover/mulPointEc.zkasm b/main/ecrecover/mulPointEc.zkasm index 648382e5..2f25b941 100644 --- a/main/ecrecover/mulPointEc.zkasm +++ b/main/ecrecover/mulPointEc.zkasm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; mulPointEc (p1_x,p1_y,p2_x,p2_y,k1,k2) = (p3_x, p3_y, HASPOS) +;; mulPointEc (p1_x,p1_y,p2_x,p2_y,k1,k2) = (p3_x, p3_y, HASHPOS) ;; ;; PRE: p1_x, p1_y, p2_x, p2_y, k1, k2 are alias-free ;; POST: p3_x, p3_y is alias-free HASHPOS = [0,1] @@ -41,10 +41,10 @@ VAR GLOBAL mulPointEc_RCX ; + number_of_bits_1(k1|k2) * arith // additions ; + (256 - left_bits_zero(k1|k2) * arith // squares ; + 24 * 256 steps // get bits k1,k2 + additions + squares (steps, regular) -; - (24 - 8) * left_bits_zero(k1|k2) * steps // get bits k1,k2 + additions + squares (steps firts bits = 0) +; - (24 - 8) * left_bits_zero(k1|k2) * steps // get bits k1,k2 + additions + squares (steps first bits = 0) ; - (24 - 12) * number_of_bits_1(k1|k2) * steps // get bits k1,k2 + additions + squares (k1,k2 bits = 0) ; + (3 - 5) steps // last part - last part square no done -; - 1 arith // first asignation +; - 1 arith // first assignation ; ; ; RESOURCES (worst case): 512 arith + 512 binaries + 6160 steps // 18 + 256 * 24 - 2 = 6160 @@ -265,7 +265,7 @@ mulPointEc_x_equals_before_add: ; C: point2.x ; D: point2.y - ; p3_x == C, check if points are same or a point was oposite point + ; p3_x == C, check if points are same or a point was opposite point ${ D == mem.mulPointEc_p3_y } :JMPNZ(mulPointEc_same_point_to_add) diff --git a/main/end.zkasm b/main/end.zkasm index c10363de..78d7e172 100644 --- a/main/end.zkasm +++ b/main/end.zkasm @@ -1,4 +1,4 @@ finalWait: ${beforeLast()} :JMPN(finalWait) - ; Set all registers to 0 except inputs: B (oldstateRoot), C (oldAccInputHash), SP (oldNumBatch), GAS (chainID) & CTX (forkID) + ; Set all registers to 0 except inputs: B (oldStateRoot), C (oldAccInputHash), SP (oldNumBatch), GAS (chainID) & CTX (forkID) 0 => A, D, E, PC, SR, HASHPOS, RR, RCX :JMP(start) \ No newline at end of file diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 765f7e18..c568bdb3 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -70,7 +70,7 @@ shortList: endList: A + C => B :MSTORE(txRLPLength) ; Check enough keccak zk counters to digest tx hash - ; We don't check poseidon counters spent for l2 tx hash computing because the number of poseidon counters available is x100 the number of keccack available + ; We don't check poseidon counters spent for l2 tx hash computing because the number of poseidon counters available is x100 the number of keccak available ; so while rlp parsing, keccaks will always be the bottleneck B + 1 :MSTORE(arithA) 136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] diff --git a/main/opcodes/arithmetic.zkasm b/main/opcodes/arithmetic.zkasm index ae78d117..6656350d 100644 --- a/main/opcodes/arithmetic.zkasm +++ b/main/opcodes/arithmetic.zkasm @@ -1,6 +1,6 @@ /** - * @link [Link EVM behaviour --> evm.codes?] + * @link [Link EVM behavior --> evm.codes?] * @zk-counters * - 20 steps * - 1 binary diff --git a/main/opcodes/block.zkasm b/main/opcodes/block.zkasm index 2f2c4f7a..a1059329 100644 --- a/main/opcodes/block.zkasm +++ b/main/opcodes/block.zkasm @@ -22,7 +22,7 @@ opBLOCKHASH: GAS - %GAS_EXT_STEP => GAS :JMPN(outOfGas) $ => B :MLOAD(SP) ; [blockNumber => B] - ; If block number does not exist in the smart conract system, it will return 0 + ; If block number does not exist in the smart contract system, it will return 0 ; Create key for the batch hash mapping key ; set bytes length to D diff --git a/main/opcodes/calldata-returndata-code.zkasm b/main/opcodes/calldata-returndata-code.zkasm index fd85e440..02d1ff45 100644 --- a/main/opcodes/calldata-returndata-code.zkasm +++ b/main/opcodes/calldata-returndata-code.zkasm @@ -97,7 +97,7 @@ opCALLDATACOPY: $ => E :MLOAD(lastMemOffset) ; Recover size at C $ => C :MLOAD(lastMemLength) - ; If is a calldataCopy called from codeCopy, copy code from calldata alloccation, else if is a create contract, return 0 + ; If is a calldataCopy called from codeCopy, copy code from calldata allocation, else if is a create contract, return 0 $ :MLOAD(isCalldataCopyFromCodeCopy), JMPNZ(continueOpCalldatacopyFromCodeCopy) $ :MLOAD(isCreateContract), JMPNZ(opCALLDATACOPY0, continueOpCalldatacopy) continueOpCalldatacopyFromCodeCopy: @@ -351,7 +351,7 @@ opEXTCODESIZE: $ => A :MLOAD(SP), CALL(maskAddress); [address => A]; in: [A: address] out: [A: masked address] :CALL(isColdAddress); in: [A: address] out: [D: 0 if warm, 1 if cold] ; check out-of-gas - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) ; set key for smt smart contract length query %SMT_KEY_SC_LENGTH => B 0 => C @@ -386,7 +386,7 @@ opEXTCODECOPY: :CALL(isColdAddress); in: [A: address] out: [D: 0 if warm, 1 if cold] ; check out-of-gas - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) :CALL(opEXTCODECOPYLoadBytecode) $ => C :MLOAD(SP+2); [destOffset => C] $ => D :MLOAD(SP+1); [offset => D] @@ -543,7 +543,7 @@ opRETURNDATACOPY: ; if retDataLength < offset + size -> OOG A - B - C :JMPN(outOfGas) - ; E ret data offset (memory pointer) of last context, B offset in return data that want to retrive + ; E ret data offset (memory pointer) of last context, B offset in return data that want to retrieve E + B => B ; memory pointer where start to copy memory ;${3*((C+31)/32)} C+31 => A @@ -615,7 +615,7 @@ opEXTCODEHASH: $ => A :MLOAD(SP), CALL(maskAddress); [address => A]; in: [A: address] out: [A: masked address] :CALL(isColdAddress); in: [A: address] out: [D: 0 if warm, 1 if cold] ; check out-of-gas - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) ; set key for smt smart contract code hash query %SMT_KEY_SC_CODE => B 0 => C diff --git a/main/opcodes/context-information.zkasm b/main/opcodes/context-information.zkasm index 2c105471..372a6961 100644 --- a/main/opcodes/context-information.zkasm +++ b/main/opcodes/context-information.zkasm @@ -73,7 +73,7 @@ opBALANCE: $ => D :SLOAD D :MSTORE(SP-1), CALL(isColdAddress); [balance(D) => SP]; in: [A: address] out: [D: 0 if warm, 1 if cold] ; check out-of-gas - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas, readCode) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas, readCode) /** * @link [https://www.evm.codes/#32?fork=berlin] diff --git a/main/opcodes/create-terminate-context.zkasm b/main/opcodes/create-terminate-context.zkasm index f4f38e2c..676a9efa 100644 --- a/main/opcodes/create-terminate-context.zkasm +++ b/main/opcodes/create-terminate-context.zkasm @@ -28,7 +28,7 @@ opSTOPend: CTX :MSTORE(currentCTX) ; restore retDataCTX, no return data in stop 0 :MSTORE(retDataCTX) - ; handle gas reund + ; handle gas refund $ => B :MLOAD(gasCTX) A :MSTORE(gasRefund) GAS + B => GAS @@ -228,7 +228,7 @@ opCALL2: ;gas_cost = memory_expansion_cost + code_execution_cost + address_access_cost + positive_value_cost + value_to_empty_account_cost ; Calculate address_access_cost: 100 for warm account, 2600 for cold account - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) ; Calculate positive_value_cost, if value call > 0 -> 9000 $ => B :MLOAD(valueCall) 0 => A @@ -340,12 +340,12 @@ opCALLCODE: ;gas_cost = memory_expansion_cost + code_execution_cost + address_access_cost + positive_value_cost ; Calculate address_access_cost: 100 for warm account, 2600 for cold account - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) ; Calculate positive_value_cost, if value call > 0 -> 9000 $ => B :MLOAD(valueCall) 0 => A $ :EQ,JMPC(opCALLCODEend) - ; Substract gas if the call has value + ; Subtract gas if the call has value GAS - %CALL_VALUE_TRANSFER_GAS => GAS :JMPN(outOfGas) opCALLCODEend: @@ -588,7 +588,7 @@ opDELEGATECALL: $ => A :MLOAD(addrCall) :CALL(isColdAddress); in: [A: address] out: [D: 0 if warm, 1 if cold] ;gas_cost = base_gas + gas_sent_with_call - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) ; transition to new CTX $ => C :MLOAD(txSrcAddr) @@ -675,7 +675,7 @@ opCREATE2: ; store current CTX to auxiliary var for later usage CTX :MSTORE(originAuxCTX) - ; cost to hash the initialisation code + ; cost to hash the initialization code C + 31 :MSTORE(arithA) 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => C :MLOAD(arithRes1) @@ -800,7 +800,7 @@ opSTATICCALL: ; check if an address is cold. If it is, add it to the touched tree $ => A :MLOAD(addrCall), CALL(isColdAddress); in: [A: address] out: [D: 0 if warm, 1 if cold] ;gas_cost = base_gas + gas_sent_with_call - GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) + GAS - %WARM_STORAGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_REDUCED => GAS :JMPN(outOfGas) ; setup vars for next CTX $ => D :MLOAD(storageAddr) diff --git a/main/opcodes/stack-operations.zkasm b/main/opcodes/stack-operations.zkasm index b19dbc50..5bd3af0b 100644 --- a/main/opcodes/stack-operations.zkasm +++ b/main/opcodes/stack-operations.zkasm @@ -234,7 +234,7 @@ opAuxPUSHBcreate: B - PC => C :JMPZ(opfinalPUSHBcreate) opAuxPUSHBcreate2: - ; set length to read to C for MOLADX call + ; set length to read to C for MLOADX call :CALL(MLOADX); in: [E: offset, C: length] out: [A: value, E: new offset] ; increase to PC the length of the read bytes PC + D => PC diff --git a/main/precompiled/pre-ecPairing.zkasm b/main/precompiled/pre-ecPairing.zkasm index 481342f7..299f450b 100644 --- a/main/precompiled/pre-ecPairing.zkasm +++ b/main/precompiled/pre-ecPairing.zkasm @@ -2,7 +2,7 @@ * @link [https://www.evm.codes/precompiled#0x08?fork=shanghai] * @zk-counters * - dynamic steps: 50000, 550000, 700000,... - * - dynamic airth: 4000, 43000, 56000,... + * - dynamic arith: 4000, 43000, 56000,... * - dynamic binary: 400, 700, 1100,... * @process-precompiled * - stack input: [x1, y1, x2, y2, ..., xk, yk] diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index d5eb6578..3425c257 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -76,7 +76,7 @@ SHA256dataReturn: :CALL(MLOADX) $ => E :MLOAD(retCallOffset) $ => CTX :MLOAD(originCTX) - ; MSTORE memory origint CTX + ; MSTORE memory origin CTX A :MSTORE(bytesToStore), CALL(MSTOREX) ; set currentCTX CTX :MSTORE(currentCTX), JMP(preEnd) diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index c61f6fe4..3ec27cf6 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -182,16 +182,16 @@ endCalldataIntrinsicGas: C => A $ :LT, JMPC(invalidIntrinsicTxBalance) - ; Substract (gas price * gas limit) from caller balance + ; Subtract (gas price * gas limit) from caller balance C :MSTORE(arithA) D :MSTORE(arithB), CALL(subARITH) - ; Substracted balance result in D + ; Subtracted balance result in D $ => D :MLOAD(arithRes1) $ => A :MLOAD(txSrcOriginAddr) 0 => B,C $ => SR :SSTORE - ; Store state root with upfront cost substracted and nonce increased + ; Store state root with upfront cost subtracted and nonce increased SR :MSTORE(initSR) ; Substract intrinsic gas @@ -274,7 +274,7 @@ create2: 136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => B :MLOAD(arithRes1) $ => A :MLOAD(cntKeccakPreProcess) - ; -2 because we will use one more keccack for generating contract address + ; -2 because we will use one more keccak for generating contract address %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 2 - B :JMPN(outOfCountersKeccak) $ => CTX :MLOAD(originCTX) diff --git a/main/utils.zkasm b/main/utils.zkasm index 56814ff1..37c26f88 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -1,6 +1,6 @@ ; @info Get absolute value and sign ; @in A => number to convert -; @out A => Absolut value of A +; @out A => Absolute value of A ; @out B => Sign of A [1 if negative, 0 positive] abs: ; check zk-counters @@ -299,7 +299,7 @@ MLOAD32: initMLOAD: :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] - ; if C has value, bytes splitted in two memory slots + ; if C has value, bytes split in two memory slots C :JMPNZ(memAlignOptionMLOAD) ; load memory from one slot $ => A :MLOAD(MEM:E) @@ -559,7 +559,7 @@ setAddArithOverflow: finishAddArith: $ => RR :MLOAD(tmpZkPCArith), JMP(loadTmp) -; @info binary substraction +; @info binary subtraction ; @in: arithA: minuend value ; @in: arithB: subtrahend value ; @out: arithRes1: arithA - arithB diff --git a/main/vars.zkasm b/main/vars.zkasm index 9b3d6063..a15dc95a 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -78,7 +78,7 @@ VAR CTX isCreateContract ; flag to determine if a transaction will create a new VAR CTX createContractAddress ; address computed of a new contract VAR CTX lengthNonce ; 'nonce' length used when computing a new contract address VAR CTX gasRefund ; keeps track of the transaction gas refund -VAR CTX initSR ; state-tree once the initial upfront cost is substracted and nonce is increased +VAR CTX initSR ; state-tree once the initial upfront cost is subtracted and nonce is increased VAR CTX memLength ; current memory size VAR CTX lastMemLength ; length of bytes to copy to memory VAR CTX lastMemoryExpansionCost ; cost of the last memory expansion @@ -111,6 +111,6 @@ VAR CTX initLogIndex ; log index once a new context begins VAR CTX deltaTimestamp ; delta timestamp of the current change L2 block tx VAR CTX indexL1InfoTree ; indexL1InfoTree of the current change L2 block tx VAR CTX gerL1InfoTree ; new GER of the current change L2 block tx -VAR CTX blockHashL1InfoTree ; new BlockchashL1 of the current change L2 block tx +VAR CTX blockHashL1InfoTree ; new BlockhashL1 of the current change L2 block tx VAR CTX timestampL1InfoTree ; new timestamp of the current change L2 block tx VAR CTX isChangeL2BlockTx ; flag to determine if the current tx is a change L2 block tx From 2cfef0d271c49f6f39cc9b5c9f5ee0048affdaa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Thu, 30 Nov 2023 18:49:21 +0100 Subject: [PATCH 048/121] Cleanup and some bugs fixed --- main/pairings/BN254/addPointBN254.zkasm | 28 ++++----- main/pairings/BN254/ecAdd.zkasm | 30 +++++----- main/pairings/BN254/lineDiffPointsBN254.zkasm | 4 +- main/pairings/BN254/lineSamePointsBN254.zkasm | 12 ++-- .../CYCLOFP12BN254/decompressFp12BN254.zkasm | 25 ++++---- .../expByXCompCycloFp12BN254.zkasm | 4 +- .../squareCompCycloFp12BN254.zkasm | 14 ++--- .../CYCLOFP12BN254/squareCycloFp12BN254.zkasm | 15 ++--- .../CYCLOFP12BN254/xBinDecompBN254.zkasm | 2 +- main/pairings/FP12BN254/frob2Fp12BN254.zkasm | 1 + main/pairings/FP12BN254/frob3Fp12BN254.zkasm | 3 +- main/pairings/FP12BN254/frobFp12BN254.zkasm | 1 + .../pairings/FP12BN254/inverseFp12BN254.zkasm | 1 + main/pairings/FP12BN254/mulFp12BN254.zkasm | 7 ++- .../FP12BN254/sparseMulAFp12BN254.zkasm | 3 +- .../FP12BN254/sparseMulBFp12BN254.zkasm | 1 + main/pairings/FP12BN254/squareFp12BN254.zkasm | 9 +-- main/pairings/FP2BN254/addFp2BN254.zkasm | 1 + .../FP2BN254/escalarMulFp2BN254.zkasm | 1 + main/pairings/FP2BN254/invFp2BN254.zkasm | 49 +++++++++++++++- main/pairings/FP2BN254/mulFp2BN254.zkasm | 1 + main/pairings/FP2BN254/squareFp2BN254.zkasm | 1 + main/pairings/FP2BN254/subFp2BN254.zkasm | 1 + main/pairings/FP4BN254/squareFp4BN254.zkasm | 7 ++- main/pairings/FP6BN254/addFp6BN254.zkasm | 3 +- .../FP6BN254/escalarMulFp6BN254.zkasm | 1 + main/pairings/FP6BN254/inverseFp6BN254.zkasm | 19 ++++--- main/pairings/FP6BN254/mulFp6BN254.zkasm | 13 +++-- .../FP6BN254/sparseMulAFp6BN254.zkasm | 5 +- .../FP6BN254/sparseMulBFp6BN254.zkasm | 9 +-- .../FP6BN254/sparseMulCFp6BN254.zkasm | 9 +-- main/pairings/FP6BN254/squareFp6BN254.zkasm | 17 +++--- main/pairings/FP6BN254/subFp6BN254.zkasm | 3 +- main/pairings/FPBN254/addFpBN254.zkasm | 3 +- main/pairings/FPBN254/invFpBN254.zkasm | 14 +++-- main/pairings/FPBN254/mulFpBN254.zkasm | 3 +- main/pairings/FPBN254/reduceFpBN254.zkasm | 3 +- main/pairings/FPBN254/squareFpBN254.zkasm | 3 +- main/pairings/FPBN254/subFpBN254.zkasm | 3 +- main/pairings/FRBN254/reduceFrBN254.zkasm | 3 +- main/pairings/constants.zkasm | 2 +- main/pairings/ecPairing.zkasm | 2 +- main/pairings/finalExpBN254.zkasm | 5 +- main/pairings/halfPairingBN254.zkasm | 20 +++---- main/pairings/loopLengthBN254.zkasm | 2 +- main/pairings/millerLoopBN254.zkasm | 13 +++-- main/pairings/pairingBN254.zkasm | 18 +++--- .../utilsTests/expCycloFp12BN254.zkasm | 3 +- test/testCycloFp12ArithBN254.zkasm | 7 ++- test/testEcAdd.zkasm | 5 +- test/testEcMul.zkasm | 1 + test/testEcPairing.zkasm | 20 +++---- test/testFinalExpBn254.zkasm | 3 + test/testFp12ArithBN254.zkasm | 28 +++++++++ test/testFp2ArithBN254.zkasm | 57 ++++++++++++++----- test/testFp4ArithBN254.zkasm | 2 +- test/testFp6ArithBN254.zkasm | 18 +++++- test/testFpArithBN254.zkasm | 4 +- test/testFrArithBN254.zkasm | 12 ++-- test/testHalfPairingBN254.zkasm | 1 + test/testPairingBN254.zkasm | 5 +- test/testPointArithBN254.zkasm | 2 + 62 files changed, 366 insertions(+), 196 deletions(-) diff --git a/main/pairings/BN254/addPointBN254.zkasm b/main/pairings/BN254/addPointBN254.zkasm index bcb9e62e..a5090e44 100644 --- a/main/pairings/BN254/addPointBN254.zkasm +++ b/main/pairings/BN254/addPointBN254.zkasm @@ -100,7 +100,7 @@ addPointBN254_P2_is_zero: C :MSTORE(addPointBN254_P3_y1) D :MSTORE(addPointBN254_P3_y2) - :JMP(addPointBN254_end) + :JMP(addPointBN254_end) addPointBN254_P1_and_P2_are_inverted: ; Check -P1.y == P2.y @@ -112,7 +112,7 @@ addPointBN254_P1_and_P2_are_inverted: $ => A :MLOAD(addPointBN254_P2_y1) C :ASSERT - $ => A :MLOAD(addPointBN254_P2_y2) + $ => A :MLOAD(addPointBN254_P2_y2) D :ASSERT ; P3 = O @@ -123,7 +123,7 @@ addPointBN254_P1_and_P2_are_inverted: :JMP(addPointBN254_end) -addPointBN254_same: +addPointBN254_same: $ => A :MLOAD(addPointBN254_P1_y1) $ => B :MLOAD(addPointBN254_P1_y2) $ => C :MLOAD(addPointBN254_P1_y1) @@ -157,14 +157,14 @@ addPointBN254_same: C => B :CALL(squareFp2BN254) ; E + C·u = lambda² - E => A - C => B + E => A + C => B $ => C :MLOAD(addPointBN254_P1_x1) $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) ; E + C·u = lambda² - x - E => A - C => B + E => A + C => B $ => C :MLOAD(addPointBN254_P1_x1) $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) ; E + C·u = lambda² - x - x @@ -200,7 +200,7 @@ addPointBN254_different: E => A C => B :CALL(squareFp2BN254) - ; E + C·u = lambda² + ; E + C·u = lambda² E => A C => B @@ -216,9 +216,9 @@ addPointBN254_different: addPointBN254_common_calculate: E :MSTORE(addPointBN254_P3_x1) - C :MSTORE(addPointBN254_P3_x2) - ; P3.x = lambda² - P1.x - P2.x - + C :MSTORE(addPointBN254_P3_x2) + ; P3.x = lambda² - P1.x - P2.x + $ => A :MLOAD(addPointBN254_P1_x1) $ => B :MLOAD(addPointBN254_P1_x2) C => D @@ -229,10 +229,10 @@ addPointBN254_common_calculate: $ => B :MLOAD(addPointBN254_lambda_y) C => D E => C :CALL(mulFp2BN254) - ; E + C·u = lambda·(P1.x - P3.x) + ; E + C·u = lambda·(P1.x - P3.x) - E => A - C => B + E => A + C => B $ => C :MLOAD(addPointBN254_P1_y1) $ => D :MLOAD(addPointBN254_P1_y2), CALL(subFp2BN254) ; E + C·u = lambda·(P1.x - P3.x) - P1.y diff --git a/main/pairings/BN254/ecAdd.zkasm b/main/pairings/BN254/ecAdd.zkasm index 324eb7ec..4197b046 100644 --- a/main/pairings/BN254/ecAdd.zkasm +++ b/main/pairings/BN254/ecAdd.zkasm @@ -48,7 +48,7 @@ ecAdd: $ => A :MLOAD(ecAdd_P1_y) $ :EQ, JMPC(ecAdd_P1_is_zero) ecAdd_P1_continue: - + ; Is P2 = O? 0n => B $ => A :MLOAD(ecAdd_P2_x) @@ -75,7 +75,7 @@ ecAdd: ; 1.2] Check if LHS == RHS B => A - $ => B :MLOAD(ecAdd_P3_x) + $ => B :MLOAD(ecAdd_P3_x) $ :EQ, JMPNC(ecAdd_P1_is_not_in_E) ; 2] check if P2 is in E(Fp) @@ -96,7 +96,7 @@ ecAdd: ; 2.2] Check if LHS == RHS B => A - $ => B :MLOAD(ecAdd_P3_x) + $ => B :MLOAD(ecAdd_P3_x) $ :EQ, JMPNC(ecAdd_P2_is_not_in_E) ; P1 and P2 are not 0, let's check whether they are different points, the same point or inverses of each other @@ -141,7 +141,7 @@ ecAdd_P1_is_zero: ; 2] Check if LHS == RHS B => A - $ => B :MLOAD(ecAdd_P3_x) + $ => B :MLOAD(ecAdd_P3_x) $ :EQ, JMPNC(ecAdd_P2_is_not_in_E) ; P3 = P2 @@ -170,7 +170,7 @@ ecAdd_P2_is_zero: ; 2] Check if LHS == RHS B => A - $ => B :MLOAD(ecAdd_P3_x) + $ => B :MLOAD(ecAdd_P3_x) $ :EQ, JMPNC(ecAdd_P1_is_not_in_E) ; P3 = P1 @@ -179,14 +179,14 @@ ecAdd_P2_is_zero: A :MSTORE(ecAdd_P3_x) B :MSTORE(ecAdd_P3_y) - :JMP(ecAdd_correct) + :JMP(ecAdd_correct) ecAdd_P1_and_P2_are_zero: ; P3 = 0 0n :MSTORE(ecAdd_P3_x) 0n :MSTORE(ecAdd_P3_y) - :JMP(ecAdd_correct) + :JMP(ecAdd_correct) ecAdd_P1_and_P2_are_inverted: ; P3 = 0 @@ -223,11 +223,11 @@ ecAdd_same: C => A :CALL(squareFpBN254) ; B = lambda² - B => A + B => A $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) ; C = lambda² - x - C => A + C => A $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) ; C = lambda² - x - x @@ -252,7 +252,7 @@ ecAdd_different: C :MSTORE(ecAdd_lambda) C => A :CALL(squareFpBN254) - ; B = lambda² + ; B = lambda² B => A $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) @@ -263,17 +263,17 @@ ecAdd_different: ; C = lambda² - P1.x - P2.x ecAdd_common_calculate: - C :MSTORE(ecAdd_P3_x) - ; P3.x = lambda² - P1.x - P2.x - + C :MSTORE(ecAdd_P3_x) + ; P3.x = lambda² - P1.x - P2.x + $ => A :MLOAD(ecAdd_P1_x), CALL(subFpBN254) ; C = P1.x - P3.x $ => A :MLOAD(ecAdd_lambda) C => B :CALL(mulFpBN254) - ; C = lambda·(P1.x - P3.x) + ; C = lambda·(P1.x - P3.x) - C => A + C => A $ => C :MLOAD(ecAdd_P1_y), CALL(subFpBN254) ; C = lambda·(P1.x - P3.x) - P1.y diff --git a/main/pairings/BN254/lineDiffPointsBN254.zkasm b/main/pairings/BN254/lineDiffPointsBN254.zkasm index d4885dbf..5aa9d305 100644 --- a/main/pairings/BN254/lineDiffPointsBN254.zkasm +++ b/main/pairings/BN254/lineDiffPointsBN254.zkasm @@ -41,7 +41,7 @@ lineDiffPointsBN254: $ => C :MLOAD(lineDiffPointsBN254_P1_x1) $ => D :MLOAD(lineDiffPointsBN254_P1_x2), CALL(subFp2BN254) $ => A :MLOAD(lineDiffPointsBN254_Q_y) - C => D + C => D E => C :CALL(escalarMulFp2BN254) E :MSTORE(lineDiffPointsBN254_l12_x) C :MSTORE(lineDiffPointsBN254_l12_y) @@ -75,6 +75,6 @@ lineDiffPointsBN254: $ => D :MLOAD(lineDiffPointsBN254_P2x_P1y_y), CALL(subFp2BN254) E :MSTORE(lineDiffPointsBN254_l23_x) C :MSTORE(lineDiffPointsBN254_l23_y) - + $ => RR :MLOAD(lineDiffPointsBN254_RR) :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/lineSamePointsBN254.zkasm b/main/pairings/BN254/lineSamePointsBN254.zkasm index 2ae95b5d..1b3388d8 100644 --- a/main/pairings/BN254/lineSamePointsBN254.zkasm +++ b/main/pairings/BN254/lineSamePointsBN254.zkasm @@ -54,7 +54,7 @@ lineSamePointsBN254: E => C 3n => A :CALL(escalarMulFp2BN254) - E => A + E => A C => B $ => C :MLOAD(lineSamePointsBN254_P_y1_square) $ => D :MLOAD(lineSamePointsBN254_P_y2_square), CALL(subFp2BN254) @@ -63,7 +63,7 @@ lineSamePointsBN254: C => B 9n => C 1n => D :CALL(mulFp2BN254) - + E :MSTORE(lineSamePointsBN254_l11_x) C :MSTORE(lineSamePointsBN254_l11_y) @@ -72,20 +72,20 @@ lineSamePointsBN254: 2n => A $ => B :MLOAD(lineSamePointsBN254_Q_y), CALL(mulFpBN254) - C => A + C => A $ => C :MLOAD(lineSamePointsBN254_P_y1) $ => D :MLOAD(lineSamePointsBN254_P_y2), CALL(escalarMulFp2BN254) - + E :MSTORE(lineSamePointsBN254_l22_x) C :MSTORE(lineSamePointsBN254_l22_y) ; 3] -3·Q.x·P.x1² - %BN254_P - 3n => A + %BN254_P - 3n => A ; This clearly assumes that %BN254_P >= 3n $ => B :MLOAD(lineSamePointsBN254_Q_x), CALL(mulFpBN254) C => A $ => C :MLOAD(lineSamePointsBN254_P_x1_square) $ => D :MLOAD(lineSamePointsBN254_P_x2_square), CALL(escalarMulFp2BN254) - + E :MSTORE(lineSamePointsBN254_l13_x) C :MSTORE(lineSamePointsBN254_l13_y) diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm index cb030b5f..f5059abb 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; decompressFp12BN254: ;; in: [a2,a3,a4,a5] ∈ Fp2⁴, where ai ∈ Fp2 @@ -108,8 +109,8 @@ decompressFp12BN254_Ca2_is_zero: ; 2] Compute a0 = (2·a1² - 3·a3·a4)(9+u) + 1 $ => A :MLOAD(decompressFp12BN254_a1_x) $ => B :MLOAD(decompressFp12BN254_a1_y), CALL(squareFp2BN254) - 2n => A - C => D + 2n => A + C => D E => C :CALL(escalarMulFp2BN254) E :MSTORE(decompressFp12BN254_twoCa1sq_x) C :MSTORE(decompressFp12BN254_twoCa1sq_y) @@ -130,10 +131,12 @@ decompressFp12BN254_Ca2_is_zero: E => C :CALL(subFp2BN254) E => A C => B - 9n => C + 9n => C 1n => D :CALL(mulFp2BN254) - E + 1n :MSTORE(decompressFp12BN254_a0_x) ; TODO: Take care of this sum C :MSTORE(decompressFp12BN254_a0_y) + E => A + 1n => C :CALL(addFpBN254) + C :MSTORE(decompressFp12BN254_a0_x) :JMP(decompressFp12BN254_end) @@ -160,7 +163,7 @@ decompressFp12BN254_Ca2_is_not_zero: $ => A :MLOAD(decompressFp12BN254_Ca4_x) $ => B :MLOAD(decompressFp12BN254_Ca4_y), CALL(squareFp2BN254) 3n => A - C => D + C => D E => C :CALL(escalarMulFp2BN254) E :MSTORE(decompressFp12BN254_threeCa4sq_x) C :MSTORE(decompressFp12BN254_threeCa4sq_y) @@ -186,8 +189,8 @@ decompressFp12BN254_Ca2_is_not_zero: ; 2] Compute a0 = (2·a1² + a2·a5 - 3·a3·a4)(9+u) + 1 $ => A :MLOAD(decompressFp12BN254_a1_x) $ => B :MLOAD(decompressFp12BN254_a1_y), CALL(squareFp2BN254) - 2n => A - C => D + 2n => A + C => D E => C :CALL(escalarMulFp2BN254) E :MSTORE(decompressFp12BN254_twoCa1sq2_x) C :MSTORE(decompressFp12BN254_twoCa1sq2_y) @@ -219,13 +222,13 @@ decompressFp12BN254_Ca2_is_not_zero: C => B 9n => C 1n => D :CALL(mulFp2BN254) - E + 1n :MSTORE(decompressFp12BN254_a0_x) ; TODO: Take care of this sum C :MSTORE(decompressFp12BN254_a0_y) + E => A + 1n => C :CALL(addFpBN254) + C :MSTORE(decompressFp12BN254_a0_x) :JMP(decompressFp12BN254_end) decompressFp12BN254_end: $ => RR :MLOAD(decompressFp12BN254_RR) - :RETURN - - \ No newline at end of file + :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm index fb5797a7..f829fc9b 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP12 arithmetic ;; ;; expByXCompCycloFp12BN254: ;; in: x, a = a0 + a2·w + a4·w² + a1·w³ + a3·w⁴ + a5·w⁵ ∈ GΦ6(p²), where x = 4965661367192848881 and ai ∈ Fp2 @@ -310,7 +311,7 @@ expByXCompCycloFp12BN254_a_is_one: :JMP(expByXCompCycloFp12BN254_end) expByXCompCycloFp12BN254_loop: - RCX - 1 => RCX :JMPZ(expByXCompCycloFp12BN254_last) + RCX - 1 => RCX :JMPZ(expByXCompCycloFp12BN254_last) ; We always square (in compressed form): C(c²) ; We square C(c²) and store the result @@ -440,4 +441,3 @@ expByXCompCycloFp12BN254_end: $ => RR :MLOAD(expByXCompCycloFp12BN254_RR) :RETURN - \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm index 3c9207b5..433b6e4e 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; squareCompCycloFp12BN254: ;; in: [a2,a3,a4,a5] ∈ Fp2⁴, where ai ∈ Fp2 @@ -72,7 +73,7 @@ squareCompCycloFp12BN254: C :MSTORE(squareCompCycloFp12BN254_B45_y) ; 2] A23 = (a2 + a3)·(a2 + (9+u)·a3) - 9n => A + 9n => A 1n => B $ => C :MLOAD(squareCompCycloFp12BN254_Ca3_x) $ => D :MLOAD(squareCompCycloFp12BN254_Ca3_y), CALL(mulFp2BN254) @@ -95,7 +96,7 @@ squareCompCycloFp12BN254: C :MSTORE(squareCompCycloFp12BN254_A23_y) ; 3] A45 = (a4 + a5)·(a4 + (9+u)·a5) - 9n => A + 9n => A 1n => B $ => C :MLOAD(squareCompCycloFp12BN254_Ca5_x) $ => D :MLOAD(squareCompCycloFp12BN254_Ca5_y), CALL(mulFp2BN254) @@ -130,7 +131,7 @@ squareCompCycloFp12BN254: $ => C :MLOAD(squareCompCycloFp12BN254_Ca2_x) $ => D :MLOAD(squareCompCycloFp12BN254_Ca2_y), CALL(addFp2BN254) 2n => A - C => D + C => D E => C :CALL(escalarMulFp2BN254) E :MSTORE(squareCompCycloFp12BN254_Cb2_x) C :MSTORE(squareCompCycloFp12BN254_Cb2_y) @@ -154,7 +155,7 @@ squareCompCycloFp12BN254: 3n => A C => D E => C :CALL(escalarMulFp2BN254) - + E => A C => B $ => C :MLOAD(squareCompCycloFp12BN254_twoCa3_x) @@ -193,18 +194,17 @@ squareCompCycloFp12BN254: 3n => A $ => C :MLOAD(squareCompCycloFp12BN254_B23_x) $ => D :MLOAD(squareCompCycloFp12BN254_B23_y), CALL(escalarMulFp2BN254) - E => A + E => A C => B $ => C :MLOAD(squareCompCycloFp12BN254_Ca5_x) $ => D :MLOAD(squareCompCycloFp12BN254_Ca5_y), CALL(addFp2BN254) 2n => A C => D E => C :CALL(escalarMulFp2BN254) - + E :MSTORE(squareCompCycloFp12BN254_Cb5_x) C :MSTORE(squareCompCycloFp12BN254_Cb5_y) $ => RR :MLOAD(squareCompCycloFp12BN254_RR) :RETURN - \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm index 6f7033ab..5ea95584 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP4/FP2 arithmetic ;; ;; squareCycloFp12BN254: ;; in: (a1 + a2·w) ∈ GΦ6(p²), where ai ∈ Fp6 @@ -108,7 +109,7 @@ squareCycloFp12BN254: ; 4] t21 = aux·(9+u) $ => A :MLOAD(squareCycloFp12BN254_aux_x) $ => B :MLOAD(squareCycloFp12BN254_aux_y) - 9n => C + 9n => C 1n => D :CALL(mulFp2BN254) E :MSTORE(squareCycloFp12BN254_t21_x) C :MSTORE(squareCycloFp12BN254_t21_y) @@ -118,7 +119,7 @@ squareCycloFp12BN254: $ => C :MLOAD(squareCycloFp12BN254_a11_x) $ => D :MLOAD(squareCycloFp12BN254_a11_y), CALL(escalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a11_x) - C :MSTORE(squareCycloFp12BN254_a11_y) + C :MSTORE(squareCycloFp12BN254_a11_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t11_x) @@ -136,7 +137,7 @@ squareCycloFp12BN254: $ => C :MLOAD(squareCycloFp12BN254_a12_x) $ => D :MLOAD(squareCycloFp12BN254_a12_y), CALL(escalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a12_x) - C :MSTORE(squareCycloFp12BN254_a12_y) + C :MSTORE(squareCycloFp12BN254_a12_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t23_x) @@ -154,7 +155,7 @@ squareCycloFp12BN254: $ => C :MLOAD(squareCycloFp12BN254_a13_x) $ => D :MLOAD(squareCycloFp12BN254_a13_y), CALL(escalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a13_x) - C :MSTORE(squareCycloFp12BN254_a13_y) + C :MSTORE(squareCycloFp12BN254_a13_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t13_x) @@ -172,7 +173,7 @@ squareCycloFp12BN254: $ => C :MLOAD(squareCycloFp12BN254_a21_x) $ => D :MLOAD(squareCycloFp12BN254_a21_y), CALL(escalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a21_x) - C :MSTORE(squareCycloFp12BN254_a21_y) + C :MSTORE(squareCycloFp12BN254_a21_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t21_x) @@ -190,7 +191,7 @@ squareCycloFp12BN254: $ => C :MLOAD(squareCycloFp12BN254_a22_x) $ => D :MLOAD(squareCycloFp12BN254_a22_y), CALL(escalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a22_x) - C :MSTORE(squareCycloFp12BN254_a22_y) + C :MSTORE(squareCycloFp12BN254_a22_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t22_x) @@ -208,7 +209,7 @@ squareCycloFp12BN254: $ => C :MLOAD(squareCycloFp12BN254_a23_x) $ => D :MLOAD(squareCycloFp12BN254_a23_y), CALL(escalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a23_x) - C :MSTORE(squareCycloFp12BN254_a23_y) + C :MSTORE(squareCycloFp12BN254_a23_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t12_x) diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm index 54359be4..2aae4630 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm @@ -13,7 +13,7 @@ xBinDecompBN254: 0 => B :RETURN 1 => B :RETURN 1 => B :RETURN - 1 => B :RETURN + 1 => B :RETURN 0 => B :RETURN 1 => B :RETURN 0 => B :RETURN diff --git a/main/pairings/FP12BN254/frob2Fp12BN254.zkasm b/main/pairings/FP12BN254/frob2Fp12BN254.zkasm index 057b6ebb..b09bcfec 100644 --- a/main/pairings/FP12BN254/frob2Fp12BN254.zkasm +++ b/main/pairings/FP12BN254/frob2Fp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; frob2Fp12BN254: ;; in: (a1 + a2·w) = ((a11 + a12v + a13v²) + (a21 + a22v + a23v²)) ∈ Fp12, where ai ∈ Fp6 and aij ∈ Fp2 diff --git a/main/pairings/FP12BN254/frob3Fp12BN254.zkasm b/main/pairings/FP12BN254/frob3Fp12BN254.zkasm index 3b49a543..a1731e36 100644 --- a/main/pairings/FP12BN254/frob3Fp12BN254.zkasm +++ b/main/pairings/FP12BN254/frob3Fp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; frob3Fp12BN254: ;; in: (a1 + a2·w) = ((a11 + a12v + a13v²) + (a21 + a22v + a23v²)) ∈ Fp12, where ai ∈ Fp6 and aij ∈ Fp2 @@ -44,7 +45,7 @@ frob3Fp12BN254: %BN254_P => A $ => B :MLOAD(frob3Fp12BN254_a11_y) $ :SUB, MSTORE(frob3Fp12BN254_c11_y) - + %BN254_P => A $ => B :MLOAD(frob3Fp12BN254_a12_y) $ => B :SUB diff --git a/main/pairings/FP12BN254/frobFp12BN254.zkasm b/main/pairings/FP12BN254/frobFp12BN254.zkasm index f879f8ea..8e951c64 100644 --- a/main/pairings/FP12BN254/frobFp12BN254.zkasm +++ b/main/pairings/FP12BN254/frobFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; frobFp12BN254: ;; in: (a1 + a2·w) = ((a11 + a12v + a13v²) + (a21 + a22v + a23v²)·w) ∈ Fp12, where ai ∈ Fp6 and aij ∈ Fp2 diff --git a/main/pairings/FP12BN254/inverseFp12BN254.zkasm b/main/pairings/FP12BN254/inverseFp12BN254.zkasm index f3016f17..6d9a1b09 100644 --- a/main/pairings/FP12BN254/inverseFp12BN254.zkasm +++ b/main/pairings/FP12BN254/inverseFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP6 arithmetic ;; ;; inverseFp12BN254: ;; in: (a1 + a2·w) ∈ Fp12, where ai ∈ Fp6 diff --git a/main/pairings/FP12BN254/mulFp12BN254.zkasm b/main/pairings/FP12BN254/mulFp12BN254.zkasm index f773a393..6d721c1e 100644 --- a/main/pairings/FP12BN254/mulFp12BN254.zkasm +++ b/main/pairings/FP12BN254/mulFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP6 arithmetic ;; ;; mulFp12BN254: ;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai,bi ∈ Fp6 @@ -242,7 +243,7 @@ mulFp12BN254: $ => B :MLOAD(mulFp12BN254_a13_y) A :MSTORE(addFp6BN254_a3_x) B :MSTORE(addFp6BN254_a3_y) - + $ => A :MLOAD(mulFp12BN254_a21_x) $ => B :MLOAD(mulFp12BN254_a21_y) A :MSTORE(addFp6BN254_b1_x) @@ -269,7 +270,7 @@ mulFp12BN254: A :MSTORE(mulFp12BN254_a1a2sum3_x) B :MSTORE(mulFp12BN254_a1a2sum3_y) - + ; 5] b1+b2 $ => A :MLOAD(mulFp12BN254_b11_x) $ => B :MLOAD(mulFp12BN254_b11_y) @@ -323,7 +324,7 @@ mulFp12BN254: $ => B :MLOAD(mulFp12BN254_a1a2sum3_y) A :MSTORE(mulFp6BN254_a3_x) B :MSTORE(mulFp6BN254_a3_y) - + $ => A :MLOAD(mulFp12BN254_b1b2sum1_x) $ => B :MLOAD(mulFp12BN254_b1b2sum1_y) diff --git a/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm b/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm index cc73d495..9646b0a3 100644 --- a/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm +++ b/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP6 arithmetic ;; ;; sparseMulAFp12BN254: ;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai ∈ Fp6, b1 = b12·v and b2 = b22·v + b23·v², with b12,b22,b23 ∈ Fp2 @@ -183,7 +184,7 @@ sparseMulAFp12BN254: $ => C :MLOAD(sparseMulAFp12BN254_b22_x) $ => D :MLOAD(sparseMulAFp12BN254_b22_y), CALL(addFp2BN254) E :MSTORE(sparseMulAFp12BN254_aux2_x) - C :MSTORE(sparseMulAFp12BN254_aux2_y) + C :MSTORE(sparseMulAFp12BN254_aux2_y) ; 4] c2 = (a1+a2)·aux - a1·b1 - a2·b2 $ => A :MLOAD(sparseMulAFp12BN254_a11_x) diff --git a/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm b/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm index 751ab5a3..535ca8dd 100644 --- a/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm +++ b/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP6 arithmetic ;; ;; sparseMulBFp12BN254: ;; in: (a1 + a2·w),(b1 + b2·w) ∈ Fp12, where ai ∈ Fp6, b1 = b11 + b13·v² and b2 = b22·v, with b11,b13,b22 ∈ Fp2 diff --git a/main/pairings/FP12BN254/squareFp12BN254.zkasm b/main/pairings/FP12BN254/squareFp12BN254.zkasm index 7d351abd..b554b83d 100644 --- a/main/pairings/FP12BN254/squareFp12BN254.zkasm +++ b/main/pairings/FP12BN254/squareFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP6 arithmetic ;; ;; squareFp12BN254: ;; in: (a1 + a2·w) ∈ Fp12, where ai ∈ Fp6 @@ -210,7 +211,7 @@ squareFp12BN254: $ => B :MLOAD(squareFp12BN254_a13_y) A :MSTORE(subFp6BN254_a3_x) B :MSTORE(subFp6BN254_a3_y) - + $ => A :MLOAD(squareFp12BN254_a21_x) $ => B :MLOAD(squareFp12BN254_a21_y) A :MSTORE(subFp6BN254_b1_x) @@ -237,7 +238,7 @@ squareFp12BN254: A :MSTORE(squareFp12BN254_a1a2sub3_x) B :MSTORE(squareFp12BN254_a1a2sub3_y) - + ; 5] a1-a2·v $ => A :MLOAD(squareFp12BN254_a11_x) $ => B :MLOAD(squareFp12BN254_a11_y) @@ -251,7 +252,7 @@ squareFp12BN254: $ => B :MLOAD(squareFp12BN254_a13_y) A :MSTORE(subFp6BN254_a3_x) B :MSTORE(subFp6BN254_a3_y) - + $ => A :MLOAD(squareFp12BN254_a2vmul1_x) $ => B :MLOAD(squareFp12BN254_a2vmul1_y) A :MSTORE(subFp6BN254_b1_x) @@ -291,7 +292,7 @@ squareFp12BN254: $ => B :MLOAD(squareFp12BN254_a1a2sub3_y) A :MSTORE(mulFp6BN254_a3_x) B :MSTORE(mulFp6BN254_a3_y) - + $ => A :MLOAD(squareFp12BN254_a1a2vsub1_x) $ => B :MLOAD(squareFp12BN254_a1a2vsub1_y) diff --git a/main/pairings/FP2BN254/addFp2BN254.zkasm b/main/pairings/FP2BN254/addFp2BN254.zkasm index e769eb5c..a48b9a9e 100644 --- a/main/pairings/FP2BN254/addFp2BN254.zkasm +++ b/main/pairings/FP2BN254/addFp2BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: ARITH_BN254_ADDFP2 ensures that the result is in the range [0,BN254_P) ;; ;; addFp2BN254: ;; in: (A + B·u), (C + D·u) ∈ Fp2, where A,B,C,D ∈ Fp diff --git a/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm b/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm index 867be4f6..1814aec3 100644 --- a/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm +++ b/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) ;; ;; escalarMulFp2BN254: ;; in: A ∈ Fp, (C + D·u) ∈ Fp2, where C,D ∈ Fp diff --git a/main/pairings/FP2BN254/invFp2BN254.zkasm b/main/pairings/FP2BN254/invFp2BN254.zkasm index 4fbd696f..7f35f7cb 100644 --- a/main/pairings/FP2BN254/invFp2BN254.zkasm +++ b/main/pairings/FP2BN254/invFp2BN254.zkasm @@ -1,17 +1,60 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) ;; ;; invFp2BN254 ;; in: (A + B·u) ∈ Fp2, where A,B ∈ Fp ;; out: C + D·u = (A·(A² + B²)⁻¹) + (-B·(A² + B²)⁻¹)·u ∈ Fp2 ;; +;; NOTE: On input 0, it returns 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +VAR GLOBAL invFp2BN254_x +VAR GLOBAL invFp2BN254_y + +VAR GLOBAL invFp2BN254_RR + invFp2BN254: + RR :MSTORE(invFp2BN254_RR) + + B :MSTORE(invFp2BN254_y) + ; Normalization of A,B + %BN254_P => B + $ :LT, JMPC(__invFp2BN254_reduce_A_continue) + :CALL(reduceFpBN254) + __invFp2BN254_reduce_A_continue: + A :MSTORE(invFp2BN254_x) + $ => A :MLOAD(invFp2BN254_y) + %BN254_P => B + $ :LT, JMPC(__invFp2BN254_reduce_B_continue) + :CALL(reduceFpBN254) + __invFp2BN254_reduce_B_continue: + A :MSTORE(invFp2BN254_y) + ; From here, it is guaranteed that A,B ∈ [0,BN254_P) + +invFp2BN254_iz_zero: + ; Check if A = B = 0 and if so, return 0 + $ => B :MLOAD(invFp2BN254_x) + 0 => A + $ :EQ, JMPNC(invFp2BN254_normalized) + $ => B :MLOAD(invFp2BN254_y) + $ :EQ, JMPC(invFp2BN254_input_is_zero) + +invFp2BN254_normalized: + $ => A :MLOAD(invFp2BN254_x) + $ => B :MLOAD(invFp2BN254_y) ; Remember that an element y ∈ Fp2 is the inverse of x ∈ Fp2 if and only if x·y = 1 in Fp2 ; We therefore check that (A + B·u)·(C + D·u) = 1 + 0·u ; A·[C] - B·[D] = 1 + (q0·BN254_P) ; A·[D] + B·[C] = 0 + (q1·BN254_P) - ${fp2InvBN254_x(A,B)} => C - ${fp2InvBN254_y(A,B)} => D + ${fp2InvBN254_x(mem.invFp2BN254_x,mem.invFp2BN254_y)} => C + ${fp2InvBN254_y(mem.invFp2BN254_x,mem.invFp2BN254_y)} => D 1n => E - 0n :ARITH_BN254_MULFP2, RETURN \ No newline at end of file + 0n :ARITH_BN254_MULFP2 + :JMP(invFp2BN254_end) + +invFp2BN254_input_is_zero: + 0 => C,D + +invFp2BN254_end: + $ => RR :MLOAD(invFp2BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/mulFp2BN254.zkasm b/main/pairings/FP2BN254/mulFp2BN254.zkasm index dc7981df..46c85799 100644 --- a/main/pairings/FP2BN254/mulFp2BN254.zkasm +++ b/main/pairings/FP2BN254/mulFp2BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) ;; ;; mulFp2BN254: ;; in: (A + B·u), (C + D·u) ∈ Fp2, where A,B,C,D ∈ Fp diff --git a/main/pairings/FP2BN254/squareFp2BN254.zkasm b/main/pairings/FP2BN254/squareFp2BN254.zkasm index ebfda250..e5d738e6 100644 --- a/main/pairings/FP2BN254/squareFp2BN254.zkasm +++ b/main/pairings/FP2BN254/squareFp2BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) ;; ;; squareFp2BN254: ;; in: (A + B·u) ∈ Fp2, where A,B ∈ Fp diff --git a/main/pairings/FP2BN254/subFp2BN254.zkasm b/main/pairings/FP2BN254/subFp2BN254.zkasm index 7542647b..9dc84720 100644 --- a/main/pairings/FP2BN254/subFp2BN254.zkasm +++ b/main/pairings/FP2BN254/subFp2BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: ARITH_BN254_SUBFP2 ensures that the result is in the range [0,BN254_P) ;; ;; subFp2BN254: ;; in: (A + B·u), (C + D·u) ∈ Fp2, where A,B,C,D ∈ Fp diff --git a/main/pairings/FP4BN254/squareFp4BN254.zkasm b/main/pairings/FP4BN254/squareFp4BN254.zkasm index 10940f4f..ef064800 100644 --- a/main/pairings/FP4BN254/squareFp4BN254.zkasm +++ b/main/pairings/FP4BN254/squareFp4BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; squareFp4BN254: ;; in: (a1 + a2·V) ∈ Fp4, where ai ∈ Fp2 @@ -42,10 +43,10 @@ squareFp4BN254: ; 3] c1 = a2²·(9 + u) + a1² $ => A :MLOAD(squareFp4BN254_a2square_x) $ => B :MLOAD(squareFp4BN254_a2square_y) - 9n => C + 9n => C 1n => D :CALL(mulFp2BN254) - E => A + E => A C => B $ => C :MLOAD(squareFp4BN254_a1square_x) $ => D :MLOAD(squareFp4BN254_a1square_y), CALL(addFp2BN254) @@ -59,7 +60,7 @@ squareFp4BN254: $ => D :MLOAD(squareFp4BN254_a2_y), CALL(addFp2BN254) E => A C => B :CALL(squareFp2BN254) - + E => A C => B $ => C :MLOAD(squareFp4BN254_a1square_x) diff --git a/main/pairings/FP6BN254/addFp6BN254.zkasm b/main/pairings/FP6BN254/addFp6BN254.zkasm index c4a4a0a5..8854b6bd 100644 --- a/main/pairings/FP6BN254/addFp6BN254.zkasm +++ b/main/pairings/FP6BN254/addFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; addFp6BN254: ;; in: (a1 + a2·v + a3·v²),(b1 + b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 @@ -45,7 +46,7 @@ addFp6BN254: $ => D :MLOAD(addFp6BN254_b2_y), CALL(addFp2BN254) E :MSTORE(addFp6BN254_c2_x) C :MSTORE(addFp6BN254_c2_y) - + ; 3] c3 = a3+b3 $ => A :MLOAD(addFp6BN254_a3_x) $ => B :MLOAD(addFp6BN254_a3_y) diff --git a/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm b/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm index 3e64ca87..878abcd5 100644 --- a/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm +++ b/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; escalarMulFp6BN254: ;; in: b ∈ Fp, (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 diff --git a/main/pairings/FP6BN254/inverseFp6BN254.zkasm b/main/pairings/FP6BN254/inverseFp6BN254.zkasm index 884bb80b..d43a0a7f 100644 --- a/main/pairings/FP6BN254/inverseFp6BN254.zkasm +++ b/main/pairings/FP6BN254/inverseFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; inverseFp6BN254: ;; in: (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 @@ -120,8 +121,8 @@ inverseFp6BN254: 1n => B $ => C :MLOAD(inverseFp6BN254_a3square_x) $ => D :MLOAD(inverseFp6BN254_a3square_y), CALL(mulFp2BN254) - E => A - C => B + E => A + C => B $ => C :MLOAD(inverseFp6BN254_a1a2mul_x) $ => D :MLOAD(inverseFp6BN254_a1a2mul_y), CALL(subFp2BN254) E :MSTORE(inverseFp6BN254_c2mid_x) @@ -155,29 +156,29 @@ inverseFp6BN254: $ => B :MLOAD(inverseFp6BN254_a2_y) $ => C :MLOAD(inverseFp6BN254_c3mid_x) $ => D :MLOAD(inverseFp6BN254_c3mid_y), CALL(mulFp2BN254) - + $ => A :MLOAD(inverseFp6BN254_a3c2mid_x) $ => B :MLOAD(inverseFp6BN254_a3c2mid_y) - C => D + C => D E => C :CALL(addFp2BN254) 9n => A 1n => B - C => D + C => D E => C :CALL(mulFp2BN254) $ => A :MLOAD(inverseFp6BN254_im_x) $ => B :MLOAD(inverseFp6BN254_im_y) - C => D + C => D E => C :CALL(addFp2BN254) - E => A + E => A C => B $ => C :MLOAD(inverseFp6BN254_xia2c3mid_x) $ => D :MLOAD(inverseFp6BN254_xia2c3mid_y), CALL(addFp2BN254) - E => A + E => A C => B :CALL(invFp2BN254) - + C :MSTORE(inverseFp6BN254_last_x) D :MSTORE(inverseFp6BN254_last_y) diff --git a/main/pairings/FP6BN254/mulFp6BN254.zkasm b/main/pairings/FP6BN254/mulFp6BN254.zkasm index 6469c823..a907ab17 100644 --- a/main/pairings/FP6BN254/mulFp6BN254.zkasm +++ b/main/pairings/FP6BN254/mulFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; mulFp6BN254: ;; in: (a1 + a2·v + a3·v²),(b1 + b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 @@ -69,7 +70,7 @@ mulFp6BN254: $ => D :MLOAD(mulFp6BN254_b2_y), CALL(mulFp2BN254) E :MSTORE(mulFp6BN254_a2b2mul_x) C :MSTORE(mulFp6BN254_a2b2mul_y) - + $ => A :MLOAD(mulFp6BN254_a3_x) $ => B :MLOAD(mulFp6BN254_a3_y) $ => C :MLOAD(mulFp6BN254_b3_x) @@ -99,7 +100,7 @@ mulFp6BN254: $ => D :MLOAD(mulFp6BN254_b3_y), CALL(addFp2BN254) E :MSTORE(mulFp6BN254_b2b3sum_x) C :MSTORE(mulFp6BN254_b2b3sum_y) - + $ => A :MLOAD(mulFp6BN254_a1_x) $ => B :MLOAD(mulFp6BN254_a1_y) $ => C :MLOAD(mulFp6BN254_a2_x) @@ -133,7 +134,7 @@ mulFp6BN254: $ => B :MLOAD(mulFp6BN254_a2a3sum_y) $ => C :MLOAD(mulFp6BN254_b2b3sum_x) $ => D :MLOAD(mulFp6BN254_b2b3sum_y), CALL(mulFp2BN254) - + E => A C => B $ => C :MLOAD(mulFp6BN254_a2b2mul_x) @@ -146,7 +147,7 @@ mulFp6BN254: C => B 9n => C 1n => D :CALL(mulFp2BN254) - + E => A C => B $ => C :MLOAD(mulFp6BN254_a1b1mul_x) @@ -159,7 +160,7 @@ mulFp6BN254: $ => B :MLOAD(mulFp6BN254_a1a2sum_y) $ => C :MLOAD(mulFp6BN254_b1b2sum_x) $ => D :MLOAD(mulFp6BN254_b1b2sum_y), CALL(mulFp2BN254) - + E => A C => B $ => C :MLOAD(mulFp6BN254_a1b1mul_x) @@ -180,7 +181,7 @@ mulFp6BN254: $ => B :MLOAD(mulFp6BN254_a1a3sum_y) $ => C :MLOAD(mulFp6BN254_b1b3sum_x) $ => D :MLOAD(mulFp6BN254_b1b3sum_y), CALL(mulFp2BN254) - + E => A C => B $ => C :MLOAD(mulFp6BN254_a1b1mul_x) diff --git a/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm index 10379a90..76d33d26 100644 --- a/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm +++ b/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; sparseMulAFp6BN254: ;; in: (a1 + a2·v + a3·v²),b2·v ∈ Fp6, where ai,b2 ∈ Fp2 @@ -36,11 +37,11 @@ sparseMulAFp6BN254: $ => B :MLOAD(sparseMulAFp6BN254_b2_y) $ => C :MLOAD(sparseMulAFp6BN254_a3_x) $ => D :MLOAD(sparseMulAFp6BN254_a3_y), CALL(mulFp2BN254) - E => A + E => A C => B 9n => C 1n => D :CALL(mulFp2BN254) - + E :MSTORE(sparseMulAFp6BN254_c1_x) C :MSTORE(sparseMulAFp6BN254_c1_y) diff --git a/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm index 094e7b32..e5353ee5 100644 --- a/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm +++ b/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; sparseMulBFp6BN254: ;; in: (a1 + a2·v + a3·v²),(b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 @@ -49,7 +50,7 @@ sparseMulBFp6BN254: $ => D :MLOAD(sparseMulBFp6BN254_b2_y), CALL(mulFp2BN254) E :MSTORE(sparseMulBFp6BN254_a2b2_x) C :MSTORE(sparseMulBFp6BN254_a2b2_y) - + $ => A :MLOAD(sparseMulBFp6BN254_a3_x) $ => B :MLOAD(sparseMulBFp6BN254_a3_y) $ => C :MLOAD(sparseMulBFp6BN254_b3_x) @@ -69,7 +70,7 @@ sparseMulBFp6BN254: $ => B :MLOAD(sparseMulBFp6BN254_b2_y) $ => C :MLOAD(sparseMulBFp6BN254_b3_x) $ => D :MLOAD(sparseMulBFp6BN254_b3_y), CALL(addFp2BN254) - E => A + E => A C => B $ => C :MLOAD(sparseMulBFp6BN254_a2a3sum_x) $ => D :MLOAD(sparseMulBFp6BN254_a2a3sum_y), CALL(mulFp2BN254) @@ -83,7 +84,7 @@ sparseMulBFp6BN254: $ => D :MLOAD(sparseMulBFp6BN254_a3b3_y), CALL(subFp2BN254) E => A C => B - 9n => C + 9n => C 1n => D :CALL(mulFp2BN254) E :MSTORE(sparseMulBFp6BN254_c1_x) @@ -101,7 +102,7 @@ sparseMulBFp6BN254: $ => B :MLOAD(sparseMulBFp6BN254_a3b3_y) 9n => C 1n => D :CALL(mulFp2BN254) - + E => A C => B $ => C :MLOAD(sparseMulBFp6BN254_a1b2_x) diff --git a/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm index d4246cb6..6c07be82 100644 --- a/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm +++ b/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; sparseMulCFp6BN254: ;; in: (a1 + a2·v + a3·v²),(b1 + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 @@ -49,7 +50,7 @@ sparseMulCFp6BN254: $ => D :MLOAD(sparseMulCFp6BN254_b1_y), CALL(mulFp2BN254) E :MSTORE(sparseMulCFp6BN254_a1b1_x) C :MSTORE(sparseMulCFp6BN254_a1b1_y) - + $ => A :MLOAD(sparseMulCFp6BN254_a3_x) $ => B :MLOAD(sparseMulCFp6BN254_a3_y) $ => C :MLOAD(sparseMulCFp6BN254_b3_x) @@ -86,7 +87,7 @@ sparseMulCFp6BN254: $ => B :MLOAD(sparseMulCFp6BN254_a3b3_y) 9n => C 1n => D :CALL(mulFp2BN254) - + E => A C => B $ => C :MLOAD(sparseMulCFp6BN254_a2b1_x) @@ -107,7 +108,7 @@ sparseMulCFp6BN254: $ => B :MLOAD(sparseMulCFp6BN254_b1_y) $ => C :MLOAD(sparseMulCFp6BN254_b3_x) $ => D :MLOAD(sparseMulCFp6BN254_b3_y), CALL(addFp2BN254) - E => A + E => A C => B $ => C :MLOAD(sparseMulCFp6BN254_a1a3sum_x) $ => D :MLOAD(sparseMulCFp6BN254_a1a3sum_y), CALL(mulFp2BN254) @@ -121,7 +122,7 @@ sparseMulCFp6BN254: $ => D :MLOAD(sparseMulCFp6BN254_a3b3_y), CALL(subFp2BN254) E :MSTORE(sparseMulCFp6BN254_c3_x) C :MSTORE(sparseMulCFp6BN254_c3_y) - + $ => RR :MLOAD(sparseMulCFp6BN254_RR) :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/squareFp6BN254.zkasm b/main/pairings/FP6BN254/squareFp6BN254.zkasm index 4c3e1fd3..fc9b62af 100644 --- a/main/pairings/FP6BN254/squareFp6BN254.zkasm +++ b/main/pairings/FP6BN254/squareFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; squareFp6BN254: ;; in: (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 @@ -46,9 +47,9 @@ squareFp6BN254: $ => C :MLOAD(squareFp6BN254_a2_x) $ => D :MLOAD(squareFp6BN254_a2_y), CALL(mulFp2BN254) 2n => A - C => D + C => D E => C :CALL(escalarMulFp2BN254) - + E :MSTORE(squareFp6BN254_2a1a2mul_x) C :MSTORE(squareFp6BN254_2a1a2mul_y) @@ -57,7 +58,7 @@ squareFp6BN254: $ => B :MLOAD(squareFp6BN254_a3_y), CALL(squareFp2BN254) E :MSTORE(squareFp6BN254_a3square_x) C :MSTORE(squareFp6BN254_a3square_y) - + ; 3] c2 = a3²·(9 + u) + 2·a1·a2 $ => A :MLOAD(squareFp6BN254_a3square_x) $ => B :MLOAD(squareFp6BN254_a3square_y) @@ -66,7 +67,7 @@ squareFp6BN254: $ => A :MLOAD(squareFp6BN254_2a1a2mul_x) $ => B :MLOAD(squareFp6BN254_2a1a2mul_y) - C => D + C => D E => C :CALL(addFp2BN254) E :MSTORE(squareFp6BN254_c2_x) @@ -91,7 +92,7 @@ squareFp6BN254: $ => B :MLOAD(squareFp6BN254_a1_y) $ => C :MLOAD(squareFp6BN254_a2_x) $ => D :MLOAD(squareFp6BN254_a2_y), CALL(subFp2BN254) - E => A + E => A C => B $ => C :MLOAD(squareFp6BN254_a3_x) $ => D :MLOAD(squareFp6BN254_a3_y), CALL(addFp2BN254) @@ -107,7 +108,7 @@ squareFp6BN254: $ => C :MLOAD(squareFp6BN254_a3_x) $ => D :MLOAD(squareFp6BN254_a3_y), CALL(mulFp2BN254) 2n => A - C => D + C => D E => C :CALL(escalarMulFp2BN254) E :MSTORE(squareFp6BN254_2a2a3mul_x) @@ -118,8 +119,8 @@ squareFp6BN254: $ => B :MLOAD(squareFp6BN254_2a2a3mul_y) 9n => C 1n => D :CALL(mulFp2BN254) - - E => A + + E => A C => B $ => C :MLOAD(squareFp6BN254_a1square_x) $ => D :MLOAD(squareFp6BN254_a1square_y), CALL(addFp2BN254) diff --git a/main/pairings/FP6BN254/subFp6BN254.zkasm b/main/pairings/FP6BN254/subFp6BN254.zkasm index 2109d69b..af0ab16f 100644 --- a/main/pairings/FP6BN254/subFp6BN254.zkasm +++ b/main/pairings/FP6BN254/subFp6BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; subFp6BN254: ;; in: (a1 + a2·v + a3·v²),(b1 + b2·v + b3·v²) ∈ Fp6, where ai,bi ∈ Fp2 @@ -45,7 +46,7 @@ subFp6BN254: $ => D :MLOAD(subFp6BN254_b2_y), CALL(subFp2BN254) E :MSTORE(subFp6BN254_c2_x) C :MSTORE(subFp6BN254_c2_y) - + ; 3] c3 = a3-b3 $ => A :MLOAD(subFp6BN254_a3_x) $ => B :MLOAD(subFp6BN254_a3_y) diff --git a/main/pairings/FPBN254/addFpBN254.zkasm b/main/pairings/FPBN254/addFpBN254.zkasm index e347cfc4..366897ee 100644 --- a/main/pairings/FPBN254/addFpBN254.zkasm +++ b/main/pairings/FPBN254/addFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) ;; ;; addFpBN254: ;; in: A,C ∈ Fp @@ -21,7 +22,7 @@ addFpBN254: ${_addFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) ${_addFpBN254_AC % const.BN254_P} => C ; residue (256 bits) E :ARITH - + A => B C => A 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/invFpBN254.zkasm b/main/pairings/FPBN254/invFpBN254.zkasm index 0d2547e2..0f573b5d 100644 --- a/main/pairings/FPBN254/invFpBN254.zkasm +++ b/main/pairings/FPBN254/invFpBN254.zkasm @@ -1,9 +1,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) ;; ;; invFpBN254: ;; in: A ∈ Fp ;; out: B = A⁻¹ (mod BN254_P) ∈ Fp ;; +;; NOTE: On input 0, it returns 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VAR GLOBAL invFpBN254_tmp @@ -23,7 +25,7 @@ invFpBN254_iz_zero: invFpBN254_normalized: ; 1] Compute and check the inverse over Z - ; A·B + [0] = [D]·2²⁵⁶ + [E] + ; A·A⁻¹ + [0] = [D]·2²⁵⁶ + [E] 0 => C ${var _invFpBN254_A = fpBN254inv(A)} => B :MSTORE(invFpBN254_tmp); $${var _invFpBN254_AB = A * _invFpBN254_A} @@ -31,15 +33,17 @@ invFpBN254_normalized: ${_invFpBN254_AB} => E :ARITH ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[A·A⁻¹] + [1] = D·2²⁵⁶ + E + ; [BN254_P]·[A·A⁻¹ / BN254_P] + [1] = D·2²⁵⁶ + E %BN254_P => A ${_invFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) 1n => C ; residue (1 bit) - E :ARITH - $ => RR :MLOAD(invFpBN254_RR) - $ => B :MLOAD(invFpBN254_tmp), JMP(invFpBN254_end) + ; 3] Check that is lower than BN254_P + A => B + $ => A :MLOAD(invFpBN254_tmp) + 1 :LT + A => B :JMP(invFpBN254_end) invFpBN254_A_is_zero: 0 => B diff --git a/main/pairings/FPBN254/mulFpBN254.zkasm b/main/pairings/FPBN254/mulFpBN254.zkasm index a5d87e89..e2af79c1 100644 --- a/main/pairings/FPBN254/mulFpBN254.zkasm +++ b/main/pairings/FPBN254/mulFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) ;; ;; mulFpBN254: ;; in: A,B ∈ Fp @@ -21,7 +22,7 @@ mulFpBN254: ${_mulFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) ${_mulFpBN254_AB % const.BN254_P} => C ; residue (256 bits) E :ARITH - + A => B C => A 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/reduceFpBN254.zkasm b/main/pairings/FPBN254/reduceFpBN254.zkasm index 551fc031..59929e79 100644 --- a/main/pairings/FPBN254/reduceFpBN254.zkasm +++ b/main/pairings/FPBN254/reduceFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) ;; ;; reduceFpBN254: ;; in: A ∈ [0, 2²⁵⁶-1] @@ -15,7 +16,7 @@ reduceFpBN254: ${A / const.BN254_P} => B ; quotient (256 bits) ${A % const.BN254_P} => C ; residue (256 bits) %BN254_P => A - 0n => D + 0n => D $ :MLOAD(reduceFpBN254_tmp), ARITH ; 2] Check the the residue is less than p diff --git a/main/pairings/FPBN254/squareFpBN254.zkasm b/main/pairings/FPBN254/squareFpBN254.zkasm index f7c9c1ce..8a14d185 100644 --- a/main/pairings/FPBN254/squareFpBN254.zkasm +++ b/main/pairings/FPBN254/squareFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) ;; ;; squareFpBN254: ;; in: A ∈ Fp @@ -22,7 +23,7 @@ squareFpBN254: ${_squareFpBN254_AA / const.BN254_P} => B ; quotient (256 bits) ${_squareFpBN254_AA % const.BN254_P} => C ; residue (256 bits) E :ARITH - + A => B C => A 1 :LT diff --git a/main/pairings/FPBN254/subFpBN254.zkasm b/main/pairings/FPBN254/subFpBN254.zkasm index e36037c3..719bf4aa 100644 --- a/main/pairings/FPBN254/subFpBN254.zkasm +++ b/main/pairings/FPBN254/subFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) ;; ;; subFpBN254: ;; in: A,C ∈ Fp @@ -22,7 +23,7 @@ subFpBN254: ${_subFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) ${_subFpBN254_AC % const.BN254_P} => C ; residue (256 bits) E :ARITH - + A => B C => A 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FRBN254/reduceFrBN254.zkasm b/main/pairings/FRBN254/reduceFrBN254.zkasm index 63530f60..927bf85b 100644 --- a/main/pairings/FRBN254/reduceFrBN254.zkasm +++ b/main/pairings/FRBN254/reduceFrBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,r) ;; ;; reduceFrBN254: ;; in: B ∈ [0, 2²⁵⁶-1] @@ -15,7 +16,7 @@ reduceFrBN254: ${B % const.BN254_R} => C ; residue (256 bits) ${B / const.BN254_R} => B ; quotient (256 bits) %BN254_R => A - 0n => D + 0n => D $ :MLOAD(reduceFrBN254_tmp), ARITH ; 2] Check the the residue is less than r diff --git a/main/pairings/constants.zkasm b/main/pairings/constants.zkasm index 8327fddb..2f469ae0 100644 --- a/main/pairings/constants.zkasm +++ b/main/pairings/constants.zkasm @@ -10,7 +10,7 @@ ; Basic constants: X = "BN family parameter", P = "base field order", R = "scalar field order" CONSTL %BN254_X = 4965661367192848881n ; Unused, just for reference CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n ; 36n * X ** 4n + 36n * X ** 3n + 24n * X ** 2n + 6n * X + 1n -; NOTE: It is satisfied that 5·p < 2²⁵⁶ < 6·p +; NOTE: It is satisfied that 5·p < 2²⁵⁶ < 6·p CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n CONSTL %BN254_R = 21888242871839275222246405745257275088548364400416034343698204186575808495617n ; 36n * X ** 4n + 36n * X ** 3n + 18n * X ** 2n + 6n * X + 1n CONSTL %BN254_R_MINUS_ONE = 21888242871839275222246405745257275088548364400416034343698204186575808495616n diff --git a/main/pairings/ecPairing.zkasm b/main/pairings/ecPairing.zkasm index 41701079..ceb65dbe 100644 --- a/main/pairings/ecPairing.zkasm +++ b/main/pairings/ecPairing.zkasm @@ -3,7 +3,7 @@ ;; ecPairing: ;; input: P1,...,Pn ∈ G1 and Q1,...,Qn ∈ G2, where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and ;; the curves are E/Fp: y² = x³ + 3 and E'/Fp2: y² = x³ + 3/(9+u) -;; output: 1 if e(P1,Q1)·...·e(Pn,Qn) = 1, 0 otherwise; where e: G1 x G2 -> GT is +;; output: 1 if e(P1,Q1)·...·e(Pn,Qn) = 1, 0 otherwise; where e: G1 x G2 -> GT is ;; the optimal Ate pairing over the BN254 curve and GT = mu_r (the r-th roots of unity over (Fp12)^*) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/main/pairings/finalExpBN254.zkasm b/main/pairings/finalExpBN254.zkasm index dde67154..8dfae38a 100644 --- a/main/pairings/finalExpBN254.zkasm +++ b/main/pairings/finalExpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP12 arithmetic ;; ;; finalExpBN254: ;; input: f ∈ Fp12 @@ -693,7 +694,7 @@ finalExpBN254: $ => B :MLOAD(frobFp12BN254_c23_y) A :MSTORE(finalExpBN254_mp23_x) B :MSTORE(finalExpBN254_mp23_y) - + $ => A :MLOAD(finalExpBN254_f11_x) $ => B :MLOAD(finalExpBN254_f11_y) A :MSTORE(frob2Fp12BN254_a11_x) @@ -1934,7 +1935,7 @@ finalExpBN254: $ => B :MLOAD(mulFp12BN254_c23_y) A :MSTORE(finalExpBN254_T24_23_x) B :MSTORE(finalExpBN254_T24_23_y) - + ; 10.7] T13 = T23·y2 $ => A :MLOAD(finalExpBN254_T23_11_x) diff --git a/main/pairings/halfPairingBN254.zkasm b/main/pairings/halfPairingBN254.zkasm index 82c84149..6b88d7ad 100644 --- a/main/pairings/halfPairingBN254.zkasm +++ b/main/pairings/halfPairingBN254.zkasm @@ -6,7 +6,7 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL halfPairingBN254_P_x +VAR GLOBAL halfPairingBN254_P_x VAR GLOBAL halfPairingBN254_P_y VAR GLOBAL halfPairingBN254_Q_x1 VAR GLOBAL halfPairingBN254_Q_x2 @@ -34,7 +34,7 @@ VAR GLOBAL halfPairingBN254_Q_RHS_y VAR GLOBAL halfPairingBN254_psi_x1 VAR GLOBAL halfPairingBN254_psi_x2 VAR GLOBAL halfPairingBN254_psi_y1 -VAR GLOBAL halfPairingBN254_psi_y2 +VAR GLOBAL halfPairingBN254_psi_y2 ; ERROR CODES (B) ; 0 - no error @@ -135,9 +135,9 @@ halfPairingBN254_P_is_zero: $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) ; 2] Check if psi(Q) == [6x²]Q - ; 2.1] Compute psi(Q) + ; 2.1] Compute psi(Q) %BN254_P => A - $ => B :MLOAD(halfPairingBN254_Q_x2) + $ => B :MLOAD(halfPairingBN254_Q_x2) $ => D :SUB ; D = -Qx2 %FROBENIUS_GAMMA121 => A %FROBENIUS_GAMMA122 => B @@ -146,7 +146,7 @@ halfPairingBN254_P_is_zero: C :MSTORE(halfPairingBN254_psi_x2) %BN254_P => A - $ => B :MLOAD(halfPairingBN254_Q_y2) + $ => B :MLOAD(halfPairingBN254_Q_y2) $ => D :SUB ; D = -Qy2 %FROBENIUS_GAMMA131 => A %FROBENIUS_GAMMA132 => B @@ -214,7 +214,7 @@ halfPairingBN254_Q_is_zero: ; 2] Check if LHS == RHS C => A - $ => B :MLOAD(halfPairingBN254_P_x3) + $ => B :MLOAD(halfPairingBN254_P_x3) $ :EQ, JMPNC(halfPairingBN254_P_is_not_in_G1) ; e(P,O) = 1 @@ -265,7 +265,7 @@ halfPairingBN254_P_subgroup_check: ; 2] Check if LHS == RHS C => A - $ => B :MLOAD(halfPairingBN254_P_x3) + $ => B :MLOAD(halfPairingBN254_P_x3) $ :EQ, JMPNC(halfPairingBN254_P_is_not_in_G1) halfPairingBN254_Q_subgroup_check: @@ -307,9 +307,9 @@ halfPairingBN254_Q_subgroup_check: $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) ; 2] Check if psi(Q) == [6x²]Q - ; 2.1] Compute psi(Q) + ; 2.1] Compute psi(Q) %BN254_P => A - $ => B :MLOAD(halfPairingBN254_Q_x2) + $ => B :MLOAD(halfPairingBN254_Q_x2) $ => D :SUB ; D = -Qx2 %FROBENIUS_GAMMA121 => A %FROBENIUS_GAMMA122 => B @@ -318,7 +318,7 @@ halfPairingBN254_Q_subgroup_check: C :MSTORE(halfPairingBN254_psi_x2) %BN254_P => A - $ => B :MLOAD(halfPairingBN254_Q_y2) + $ => B :MLOAD(halfPairingBN254_Q_y2) $ => D :SUB ; D = -Qx2 %FROBENIUS_GAMMA131 => A %FROBENIUS_GAMMA132 => B diff --git a/main/pairings/loopLengthBN254.zkasm b/main/pairings/loopLengthBN254.zkasm index 3f07d384..8e92a82f 100644 --- a/main/pairings/loopLengthBN254.zkasm +++ b/main/pairings/loopLengthBN254.zkasm @@ -1,7 +1,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; loopLengthBN254: -;; output: A digit of the (little-endian) pseudobinary representation of the loop length +;; output: A digit of the (little-endian) pseudobinary representation of the loop length ;; of the optimal ate pairing over the BN254. The loop length is precisely 6·x + 2. ;; and is represented as follows: ;; 0001010-1001-100100110-10010-1000011100-100100000-1001100-1000110-1001011 diff --git a/main/pairings/millerLoopBN254.zkasm b/main/pairings/millerLoopBN254.zkasm index 10f09505..c85ac8b5 100644 --- a/main/pairings/millerLoopBN254.zkasm +++ b/main/pairings/millerLoopBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP12 arithmetic ;; ;; millerLoopBN254: ;; input: P ∈ G1 and Q ∈ G2 @@ -212,7 +213,7 @@ millerLoopBN254_loop: A :MSTORE(millerLoopBN254_f23_x) B :MSTORE(millerLoopBN254_f23_y) - ; 2] R = 2·R + ; 2] R = 2·R $ => A :MLOAD(millerLoopBN254_R_x1) $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) @@ -237,7 +238,7 @@ millerLoopBN254_loop: RCX-1 => RR :CALL(@loopLengthBN254 + RR) - + ; if bit = -1, then "sub" B :JMPN(millerLoopBN254_sub) @@ -496,7 +497,7 @@ millerLoopBN254_last_two_lines: $ => A :MLOAD(millerLoopBN254_Q_x1) %FROBENIUS_GAMMA121 => C %FROBENIUS_GAMMA122 => D :CALL(mulFp2BN254) - + E :MSTORE(millerLoopBN254_Frobenius1_Q_x1) C :MSTORE(millerLoopBN254_Frobenius1_Q_x2) @@ -506,7 +507,7 @@ millerLoopBN254_last_two_lines: $ => A :MLOAD(millerLoopBN254_Q_y1) %FROBENIUS_GAMMA131 => C %FROBENIUS_GAMMA132 => D :CALL(mulFp2BN254) - + E :MSTORE(millerLoopBN254_Frobenius1_Q_y1) C :MSTORE(millerLoopBN254_Frobenius1_Q_y2) @@ -634,7 +635,7 @@ millerLoopBN254_last_two_lines: $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_x1) %FROBENIUS_GAMMA121 => C %FROBENIUS_GAMMA122 => D :CALL(mulFp2BN254) - + E :MSTORE(millerLoopBN254_nFrobenius2_Q_x1) C :MSTORE(millerLoopBN254_nFrobenius2_Q_x2) @@ -645,7 +646,7 @@ millerLoopBN254_last_two_lines: $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_y1) %FROBENIUS_GAMMA131_NEGATED => C %FROBENIUS_GAMMA132_NEGATED => D :CALL(mulFp2BN254) - + ; 5] f = f · line_{twist(R),twist(-Frobenius2(Q))}(P) ; line_{twist(R),twist(-Frobenius2(Q))}(P) diff --git a/main/pairings/pairingBN254.zkasm b/main/pairings/pairingBN254.zkasm index 68ca252b..7698b793 100644 --- a/main/pairings/pairingBN254.zkasm +++ b/main/pairings/pairingBN254.zkasm @@ -37,7 +37,7 @@ VAR GLOBAL pairingBN254_Q_RHS_y VAR GLOBAL pairingBN254_psi_x1 VAR GLOBAL pairingBN254_psi_x2 VAR GLOBAL pairingBN254_psi_y1 -VAR GLOBAL pairingBN254_psi_y2 +VAR GLOBAL pairingBN254_psi_y2 ; ERROR CODES (B) ; 0 - no error @@ -139,9 +139,9 @@ pairingBN254_P_is_zero: $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) ; 2] Check if psi(Q) == [6x²]Q - ; 2.1] Compute psi(Q) + ; 2.1] Compute psi(Q) %BN254_P => A - $ => B :MLOAD(pairingBN254_Q_x2) + $ => B :MLOAD(pairingBN254_Q_x2) $ => D :SUB ; D = -Qx2 %FROBENIUS_GAMMA121 => A %FROBENIUS_GAMMA122 => B @@ -150,7 +150,7 @@ pairingBN254_P_is_zero: C :MSTORE(pairingBN254_psi_x2) %BN254_P => A - $ => B :MLOAD(pairingBN254_Q_y2) + $ => B :MLOAD(pairingBN254_Q_y2) $ => D :SUB ; D = -Qy2 %FROBENIUS_GAMMA131 => A %FROBENIUS_GAMMA132 => B @@ -218,7 +218,7 @@ pairingBN254_Q_is_zero: ; 2] Check if LHS == RHS C => A - $ => B :MLOAD(pairingBN254_P_x3) + $ => B :MLOAD(pairingBN254_P_x3) $ :EQ, JMPNC(pairingBN254_P_is_not_in_G1) ; e(P,O) = 1 @@ -267,7 +267,7 @@ pairingBN254_P_subgroup_check: ; 2] Check if LHS == RHS C => A - $ => B :MLOAD(pairingBN254_P_x3) + $ => B :MLOAD(pairingBN254_P_x3) $ :EQ, JMPNC(pairingBN254_P_is_not_in_G1) pairingBN254_Q_subgroup_check: @@ -309,9 +309,9 @@ pairingBN254_Q_subgroup_check: $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) ; 2] Check if psi(Q) == [6x²]Q - ; 2.1] Compute psi(Q) + ; 2.1] Compute psi(Q) %BN254_P => A - $ => B :MLOAD(pairingBN254_Q_x2) + $ => B :MLOAD(pairingBN254_Q_x2) $ => D :SUB ; D = -Qx2 %FROBENIUS_GAMMA121 => A %FROBENIUS_GAMMA122 => B @@ -320,7 +320,7 @@ pairingBN254_Q_subgroup_check: C :MSTORE(pairingBN254_psi_x2) %BN254_P => A - $ => B :MLOAD(pairingBN254_Q_y2) + $ => B :MLOAD(pairingBN254_Q_y2) $ => D :SUB ; D = -Qx2 %FROBENIUS_GAMMA131 => A %FROBENIUS_GAMMA132 => B diff --git a/main/pairings/utilsTests/expCycloFp12BN254.zkasm b/main/pairings/utilsTests/expCycloFp12BN254.zkasm index fabaa317..1f73a81c 100644 --- a/main/pairings/utilsTests/expCycloFp12BN254.zkasm +++ b/main/pairings/utilsTests/expCycloFp12BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP12 arithmetic ;; ;; expCycloFp12BN254: ;; in: e, (a1 + a2·w) ∈ GΦ6(p²), where e ∈ [0,p¹²-2] ai ∈ Fp6 @@ -191,7 +192,7 @@ expCycloFp12BN254_find_MSB_e: expCycloFp12BN254_loop: - RCX - 1 => RCX :JMPZ(expCycloFp12BN254_end) + RCX - 1 => RCX :JMPZ(expCycloFp12BN254_end) ; We always square: c = c^2 $ => A :MLOAD(expCycloFp12BN254_c11_x) diff --git a/test/testCycloFp12ArithBN254.zkasm b/test/testCycloFp12ArithBN254.zkasm index 4de6ae43..7cb8ac48 100644 --- a/test/testCycloFp12ArithBN254.zkasm +++ b/test/testCycloFp12ArithBN254.zkasm @@ -8,7 +8,7 @@ CONST %MAX_CNT_KECCAK_F_LIMIT = %N CONST %MAX_CNT_PADDING_PG_LIMIT = %N CONST %MAX_CNT_POSEIDON_G_LIMIT = %N -CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n VAR GLOBAL test @@ -175,7 +175,7 @@ start: 8625093555241362381542545391636743832938050376057983419042860774659518282797n :MLOAD(decompressFp12BN254_a3_y) 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(decompressFp12BN254_a5_x) 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(decompressFp12BN254_a5_y) - + ; 4] Exponentiation 0n :MSTORE(expCycloFp12BN254_e) 0n :MSTORE(expCycloFp12BN254_a11_x) @@ -470,6 +470,9 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" + INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" diff --git a/test/testEcAdd.zkasm b/test/testEcAdd.zkasm index d5d76ae6..e4ba1d6f 100644 --- a/test/testEcAdd.zkasm +++ b/test/testEcAdd.zkasm @@ -156,7 +156,7 @@ start: 21039565435327757486054843320102702720990930294403178719740356721829973864651n :MSTORE(ecAdd_P2_y) :CALL(ecAdd) 0n :MLOAD(ecAdd_P3_x) - 0n :MLOAD(ecAdd_P3_y) + 0n :MLOAD(ecAdd_P3_y) ; 9] P + Q when P != Q 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) @@ -206,7 +206,7 @@ start: 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P2_y) :CALL(ecAdd) 4444740815889402603535294170722302758225367627362056425101568584910268024244n :MLOAD(ecAdd_P3_x) - 10537263096529483164618820017164668921386457028564663708352735080900270541420n :MLOAD(ecAdd_P3_y) + 10537263096529483164618820017164668921386457028564663708352735080900270541420n :MLOAD(ecAdd_P3_y) ; 10] Worst case scenario in terms of ARITH calls and therefore in terms of number of steps ; In this case, we only need to perform a doubling, since the cost of ecAdd is constant @@ -248,6 +248,7 @@ checkAndSaveFrom: INCLUDE "../main/pairings/BN254/ecAdd.zkasm" +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/subFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" diff --git a/test/testEcMul.zkasm b/test/testEcMul.zkasm index 4049a718..ff60e89b 100644 --- a/test/testEcMul.zkasm +++ b/test/testEcMul.zkasm @@ -229,6 +229,7 @@ INCLUDE "../main/pairings/BN254/ecAdd.zkasm" INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/subFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" diff --git a/test/testEcPairing.zkasm b/test/testEcPairing.zkasm index 88c477a7..eacd279b 100644 --- a/test/testEcPairing.zkasm +++ b/test/testEcPairing.zkasm @@ -58,7 +58,7 @@ start: ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;0n :MSTORE(ecPairing6_P_x) @@ -68,7 +68,7 @@ start: ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;1n :MSTORE(ecPairing6_P_x) @@ -78,7 +78,7 @@ start: ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;1n :MSTORE(ecPairing6_P_x) @@ -88,7 +88,7 @@ start: ;0n :MSTORE(ecPairing6_Q_y1) ;0n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;; 1.1] Fails if some input is not in range @@ -99,7 +99,7 @@ start: ;0n :MSTORE(ecPairing6_Q_y1) ;0n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;1n :MSTORE(ecPairing6_P_x) @@ -109,7 +109,7 @@ start: ;0n :MSTORE(ecPairing6_Q_y1) ;0n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;1n :MSTORE(ecPairing6_P_x) @@ -119,7 +119,7 @@ start: ;0n :MSTORE(ecPairing6_Q_y1) ;0n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;1n :MSTORE(ecPairing6_P_x) @@ -129,7 +129,7 @@ start: ;0n :MSTORE(ecPairing6_Q_y1) ;0n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;1n :MSTORE(ecPairing6_P_x) @@ -139,7 +139,7 @@ start: ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_y1) ;0n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;1n :MSTORE(ecPairing6_P_x) @@ -149,7 +149,7 @@ start: ;0n :MSTORE(ecPairing6_Q_y1) ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_y2) ; :CALL(ecPairing6) - ;1 => A + ;1 => A ;B :ASSERT ; ;; 1.2] Degenerate tests: e(0,Q) = 1 and e(P,0) = 1 therefore the pairing equation is trivally satisfied diff --git a/test/testFinalExpBn254.zkasm b/test/testFinalExpBn254.zkasm index b15120ae..6e182304 100644 --- a/test/testFinalExpBn254.zkasm +++ b/test/testFinalExpBn254.zkasm @@ -106,6 +106,9 @@ INCLUDE "../main/pairings/constants.zkasm" INCLUDE "../main/pairings/finalExpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" + INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" diff --git a/test/testFp12ArithBN254.zkasm b/test/testFp12ArithBN254.zkasm index 61cc64a2..61042e6d 100644 --- a/test/testFp12ArithBN254.zkasm +++ b/test/testFp12ArithBN254.zkasm @@ -258,6 +258,32 @@ start: 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(squareFp12BN254_c23_x) 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(squareFp12BN254_c23_y) + 0n :MSTORE(inverseFp12BN254_a11_x) + 0n :MSTORE(inverseFp12BN254_a11_y) + 0n :MSTORE(inverseFp12BN254_a12_x) + 0n :MSTORE(inverseFp12BN254_a12_y) + 0n :MSTORE(inverseFp12BN254_a13_x) + 0n :MSTORE(inverseFp12BN254_a13_y) + 0n :MSTORE(inverseFp12BN254_a21_x) + 0n :MSTORE(inverseFp12BN254_a21_y) + 0n :MSTORE(inverseFp12BN254_a22_x) + 0n :MSTORE(inverseFp12BN254_a22_y) + 0n :MSTORE(inverseFp12BN254_a23_x) + 0n :MSTORE(inverseFp12BN254_a23_y) + :CALL(inverseFp12BN254) + 0n :MLOAD(inverseFp12BN254_c11_x) + 0n :MLOAD(inverseFp12BN254_c11_y) + 0n :MLOAD(inverseFp12BN254_c12_x) + 0n :MLOAD(inverseFp12BN254_c12_y) + 0n :MLOAD(inverseFp12BN254_c13_x) + 0n :MLOAD(inverseFp12BN254_c13_y) + 0n :MLOAD(inverseFp12BN254_c21_x) + 0n :MLOAD(inverseFp12BN254_c21_y) + 0n :MLOAD(inverseFp12BN254_c22_x) + 0n :MLOAD(inverseFp12BN254_c22_y) + 0n :MLOAD(inverseFp12BN254_c23_x) + 0n :MLOAD(inverseFp12BN254_c23_y) + 2n :MSTORE(inverseFp12BN254_a11_x) 4n :MSTORE(inverseFp12BN254_a11_y) 0n :MSTORE(inverseFp12BN254_a12_x) @@ -587,6 +613,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" + INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" diff --git a/test/testFp2ArithBN254.zkasm b/test/testFp2ArithBN254.zkasm index 234f6863..1796eaa4 100644 --- a/test/testFp2ArithBN254.zkasm +++ b/test/testFp2ArithBN254.zkasm @@ -8,7 +8,7 @@ CONST %MAX_CNT_KECCAK_F_LIMIT = %N CONST %MAX_CNT_PADDING_PG_LIMIT = %N CONST %MAX_CNT_POSEIDON_G_LIMIT = %N -CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n VAR GLOBAL lastHashKId VAR GLOBAL lastHashPId @@ -51,58 +51,87 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) + ; 1] addFp2BN254 1n => A 2n => B 3n => C 4n => D :CALL(addFp2BN254) E => A - 4n => B :ASSERT + 4n :ASSERT C => A - 6n => B :ASSERT + 6n :ASSERT + ; 2] subFp2BN254 1n => A 4n => B 3n => C 2n => D :CALL(subFp2BN254) E => A - 21888242871839275222246405745257275088696311157297823662689037894645226208581n => B :ASSERT + 21888242871839275222246405745257275088696311157297823662689037894645226208581n :ASSERT C => A - 2n => B :ASSERT + 2n :ASSERT + + ; 3] invFp2BN254 + 0n => A + 0n => B + :CALL(invFp2BN254) + C => A + 0 :ASSERT + D => A + 0 :ASSERT + + 2n => A + 0n => B + :CALL(invFp2BN254) + C => A + 10944121435919637611123202872628637544348155578648911831344518947322613104292n :ASSERT + D => A + 0 :ASSERT + + 0n => A + 2n => B + :CALL(invFp2BN254) + C => A + 0 :ASSERT + D => A + 10944121435919637611123202872628637544348155578648911831344518947322613104291n :ASSERT 1n => A 2n => B :CALL(invFp2BN254) C => A - 13132945723103565133347843447154365053217786694378694197613422736787135725150n => B :ASSERT + 13132945723103565133347843447154365053217786694378694197613422736787135725150n :ASSERT D => A - 17510594297471420177797124596205820070957048925838258930151230315716180966866n => B :ASSERT + 17510594297471420177797124596205820070957048925838258930151230315716180966866n :ASSERT 1n => A 4n => B :CALL(invFp2BN254) C => A - 5150174793373947111116801351825241197340308507599487920632714798740053225549n => B :ASSERT + 5150174793373947111116801351825241197340308507599487920632714798740053225549n :ASSERT D => A - 1287543698343486777779200337956310299335077126899871980158178699685013306387n => B :ASSERT + 1287543698343486777779200337956310299335077126899871980158178699685013306387n :ASSERT + ; 4] squareFp2BN254 1n => A 4n => B :CALL(squareFp2BN254) E => A - 21888242871839275222246405745257275088696311157297823662689037894645226208568n => B :ASSERT + 21888242871839275222246405745257275088696311157297823662689037894645226208568n :ASSERT C => A - 8n => B :ASSERT + 8n :ASSERT + ; 5] escalarMulFp2BN254 3n => A 6n => C 4n => D :CALL(escalarMulFp2BN254) E => A - 18n => B :ASSERT + 18n :ASSERT C => A - 12n => B :ASSERT + 12n :ASSERT end: @@ -131,6 +160,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" + INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" diff --git a/test/testFp4ArithBN254.zkasm b/test/testFp4ArithBN254.zkasm index 0bfa89fb..2325be32 100644 --- a/test/testFp4ArithBN254.zkasm +++ b/test/testFp4ArithBN254.zkasm @@ -8,7 +8,7 @@ CONST %MAX_CNT_KECCAK_F_LIMIT = %N CONST %MAX_CNT_PADDING_PG_LIMIT = %N CONST %MAX_CNT_POSEIDON_G_LIMIT = %N -CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n VAR GLOBAL test diff --git a/test/testFp6ArithBN254.zkasm b/test/testFp6ArithBN254.zkasm index bbd985ce..9252544d 100644 --- a/test/testFp6ArithBN254.zkasm +++ b/test/testFp6ArithBN254.zkasm @@ -8,7 +8,7 @@ CONST %MAX_CNT_KECCAK_F_LIMIT = %N CONST %MAX_CNT_PADDING_PG_LIMIT = %N CONST %MAX_CNT_POSEIDON_G_LIMIT = %N -CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n VAR GLOBAL test @@ -129,6 +129,20 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226208559n :MLOAD(squareFp6BN254_c3_x) 258n :MLOAD(squareFp6BN254_c3_y) + 0n :MSTORE(inverseFp6BN254_a1_x) + 0n :MSTORE(inverseFp6BN254_a1_y) + 0n :MSTORE(inverseFp6BN254_a2_x) + 0n :MSTORE(inverseFp6BN254_a2_y) + 0n :MSTORE(inverseFp6BN254_a3_x) + 0n :MSTORE(inverseFp6BN254_a3_y) + :CALL(inverseFp6BN254) + 0n :MLOAD(inverseFp6BN254_c1_x) + 0n :MLOAD(inverseFp6BN254_c1_y) + 0n :MLOAD(inverseFp6BN254_c2_x) + 0n :MLOAD(inverseFp6BN254_c2_y) + 0n :MLOAD(inverseFp6BN254_c3_x) + 0n :MLOAD(inverseFp6BN254_c3_y) + 10n :MSTORE(inverseFp6BN254_a1_x) 2n :MSTORE(inverseFp6BN254_a1_y) 5n :MSTORE(inverseFp6BN254_a2_x) @@ -221,6 +235,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" + INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" diff --git a/test/testFpArithBN254.zkasm b/test/testFpArithBN254.zkasm index 0a8857e3..b28cfc8e 100644 --- a/test/testFpArithBN254.zkasm +++ b/test/testFpArithBN254.zkasm @@ -8,8 +8,8 @@ CONST %MAX_CNT_KECCAK_F_LIMIT = %N CONST %MAX_CNT_PADDING_PG_LIMIT = %N CONST %MAX_CNT_POSEIDON_G_LIMIT = %N -CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n -CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n +CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n +CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n VAR GLOBAL lastHashKId VAR GLOBAL lastHashPId diff --git a/test/testFrArithBN254.zkasm b/test/testFrArithBN254.zkasm index e06aebb6..0c56acde 100644 --- a/test/testFrArithBN254.zkasm +++ b/test/testFrArithBN254.zkasm @@ -54,32 +54,32 @@ start: 3n => B :CALL(reduceFrBN254) - C => A + C => A 3n => B :ASSERT %BN254_R => B :CALL(reduceFrBN254) - C => A + C => A 0n => B :ASSERT 21888242871839275222246405745257275088548364400416034343698204186575808495618n => B :CALL(reduceFrBN254) - C => A + C => A 1n => B :ASSERT %BN254_P => B :CALL(reduceFrBN254) - C => A + C => A %BN254_SIX_TIMES_X_SQ => B :ASSERT 21888242871839275222246405745257275088696311157297823662689037894645226208584n => B :CALL(reduceFrBN254) - C => A + C => A 147946756881789318990833708069417712967n => B :ASSERT 115792089237316195423570985008687907853269984665640564039457584007913129639935n => B :CALL(reduceFrBN254) - C => A + C => A 6350874878119819312338956282401532410528162663560392320966563075034087161850n => B :ASSERT diff --git a/test/testHalfPairingBN254.zkasm b/test/testHalfPairingBN254.zkasm index b3971e4b..059bf7c1 100644 --- a/test/testHalfPairingBN254.zkasm +++ b/test/testHalfPairingBN254.zkasm @@ -101,6 +101,7 @@ INCLUDE "../main/pairings/halfPairingBN254.zkasm" INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" diff --git a/test/testPairingBN254.zkasm b/test/testPairingBN254.zkasm index 10e78a38..867f7b67 100644 --- a/test/testPairingBN254.zkasm +++ b/test/testPairingBN254.zkasm @@ -176,7 +176,7 @@ start: 8 => A 1 :EQ - ; 6] Bilinearity test: e(2P,12Q) = e(P,12Q)² = e(2P,Q)¹² = e(P,Q)²⁴ = e(12P,2Q) + ; 6] Bilinearity test: e(2P,12Q) = e(P,12Q)² = e(2P,Q)¹² = e(P,Q)²⁴ = e(12P,2Q) ; e(2P,12Q) 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) @@ -190,7 +190,7 @@ start: 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(pairingBN254_f12_x) 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(pairingBN254_f12_y) 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(pairingBN254_f13_x) - 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(pairingBN254_f13_y) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(pairingBN254_f13_y) 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(pairingBN254_f21_x) 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(pairingBN254_f21_y) 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(pairingBN254_f22_x) @@ -394,6 +394,7 @@ INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" diff --git a/test/testPointArithBN254.zkasm b/test/testPointArithBN254.zkasm index 1f7a2637..6399f868 100644 --- a/test/testPointArithBN254.zkasm +++ b/test/testPointArithBN254.zkasm @@ -249,6 +249,8 @@ checkAndSaveFrom: INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" + +INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/addFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/subFpBN254.zkasm" INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" From 138e8df101575faf9fd8a29e9e37bee6ed8bc070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Fri, 1 Dec 2023 11:12:05 +0100 Subject: [PATCH 049/121] More bugs fixed and comments added --- main/pairings/BN254/addPointBN254.zkasm | 20 +++---- main/pairings/BN254/ecAdd.zkasm | 13 ++--- main/pairings/BN254/ecMul.zkasm | 5 +- main/pairings/BN254/escalarMulBN254.zkasm | 12 ++--- main/pairings/BN254/lineDiffPointsBN254.zkasm | 7 ++- main/pairings/BN254/lineSamePointsBN254.zkasm | 7 ++- .../CYCLOFP12BN254/decompressFp12BN254.zkasm | 4 +- .../expByXCompCycloFp12BN254.zkasm | 48 ++++++++--------- main/pairings/FP2BN254/invFp2BN254.zkasm | 4 +- main/pairings/FPBN254/addFpBN254.zkasm | 3 +- main/pairings/FPBN254/invFpBN254.zkasm | 16 +++--- main/pairings/FPBN254/mulFpBN254.zkasm | 3 +- main/pairings/FPBN254/squareFpBN254.zkasm | 3 +- main/pairings/FPBN254/subFpBN254.zkasm | 3 +- main/pairings/constants.zkasm | 8 +-- main/pairings/ecPairing.zkasm | 27 +++++----- main/pairings/halfPairingBN254.zkasm | 20 +++---- main/pairings/loopLengthBN254.zkasm | 4 +- main/pairings/millerLoopBN254.zkasm | 4 +- main/pairings/pairingBN254.zkasm | 22 ++++---- .../unused/expByXCycloFp12BN254.zkasm | 54 +++++++++---------- main/pairings/unused/expFp12BN254.zkasm | 50 ++++++++--------- .../utilsTests/expCycloFp12BN254.zkasm | 48 ++++++++--------- test/testFpArithBN254.zkasm | 26 ++++----- 24 files changed, 213 insertions(+), 198 deletions(-) diff --git a/main/pairings/BN254/addPointBN254.zkasm b/main/pairings/BN254/addPointBN254.zkasm index a5090e44..8c2cf80b 100644 --- a/main/pairings/BN254/addPointBN254.zkasm +++ b/main/pairings/BN254/addPointBN254.zkasm @@ -1,11 +1,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P1,P2 ∈ E'(Fp2) +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; addPointBN254: ;; in: P1 = (P1.x1 + P1.x2·u, P1.y1 + P1.y2·u), P2 = (P2.x1 + P2.x2·u, P2.y1 + P2.y2·u) ∈ E'(Fp2) ;; out: P1 + P2 = (P3.x1 + P3.x2·u, P3.y1 + P3.y2·u) ∈ E'(Fp2) ;; -;; assumes: P1,P2 ∈ E'(Fp2) -;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; addPointBN254 assumes both P1 and P2 belong to E'(Fp2), since it is checked in the pairing. @@ -35,26 +35,26 @@ addPointBN254: ; Is P1 = O? 0n => B $ => A :MLOAD(addPointBN254_P1_x1) - $ :EQ, JMPNC(addPointBN254_P1_continue) + $ :EQ, JMPNC(__addPointBN254_P1_continue) $ => A :MLOAD(addPointBN254_P1_x2) - $ :EQ, JMPNC(addPointBN254_P1_continue) + $ :EQ, JMPNC(__addPointBN254_P1_continue) $ => A :MLOAD(addPointBN254_P1_y1) - $ :EQ, JMPNC(addPointBN254_P1_continue) + $ :EQ, JMPNC(__addPointBN254_P1_continue) $ => A :MLOAD(addPointBN254_P1_y2) $ :EQ, JMPC(addPointBN254_P1_is_zero) - addPointBN254_P1_continue: + __addPointBN254_P1_continue: ; Is P2 = 0? 0n => B $ => A :MLOAD(addPointBN254_P2_x1) - $ :EQ, JMPNC(addPointBN254_P2_continue) + $ :EQ, JMPNC(__addPointBN254_P2_continue) $ => A :MLOAD(addPointBN254_P2_x2) - $ :EQ, JMPNC(addPointBN254_P2_continue) + $ :EQ, JMPNC(__addPointBN254_P2_continue) $ => A :MLOAD(addPointBN254_P2_y1) - $ :EQ, JMPNC(addPointBN254_P2_continue) + $ :EQ, JMPNC(__addPointBN254_P2_continue) $ => A :MLOAD(addPointBN254_P2_y2) $ :EQ, JMPC(addPointBN254_P2_is_zero) - addPointBN254_P2_continue: + __addPointBN254_P2_continue: ; P1 and P2 are not 0, let's check whether they are different points, the same point or inverses of each other ; Is P1.x == P2.x? diff --git a/main/pairings/BN254/ecAdd.zkasm b/main/pairings/BN254/ecAdd.zkasm index 4197b046..089116f7 100644 --- a/main/pairings/BN254/ecAdd.zkasm +++ b/main/pairings/BN254/ecAdd.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to FP arithmetic ;; ;; ecAdd: ;; in: P1 = (P1.x, P1.y), P2 = (P2.x, P2.y) ∈ E(Fp) @@ -44,18 +45,18 @@ ecAdd: ; Is P1 = O? 0n => B $ => A :MLOAD(ecAdd_P1_x) - $ :EQ, JMPNC(ecAdd_P1_continue) + $ :EQ, JMPNC(__ecAdd_P1_continue) $ => A :MLOAD(ecAdd_P1_y) $ :EQ, JMPC(ecAdd_P1_is_zero) - ecAdd_P1_continue: + __ecAdd_P1_continue: ; Is P2 = O? 0n => B $ => A :MLOAD(ecAdd_P2_x) - $ :EQ, JMPNC(ecAdd_P2_continue1) + $ :EQ, JMPNC(__ecAdd_P2_continue1) $ => A :MLOAD(ecAdd_P2_y) $ :EQ, JMPC(ecAdd_P2_is_zero) - ecAdd_P2_continue1: + __ecAdd_P2_continue1: ; 1] Check if P1 is in E(Fp) ; P1 in E iff (P1.y)² == (P1.x)³ + 3 (mod p) @@ -119,10 +120,10 @@ ecAdd_P1_is_zero: ; Is P2 = 0? 0n => B $ => A :MLOAD(ecAdd_P2_x) - $ :EQ, JMPNC(ecAdd_P2_continue2) + $ :EQ, JMPNC(__ecAdd_P2_continue2) $ => A :MLOAD(ecAdd_P2_y) $ :EQ, JMPC(ecAdd_P1_and_P2_are_zero) - ecAdd_P2_continue2: + __ecAdd_P2_continue2: ; P2 in E iff (P2.y)² == (P2.x)³ + 3 (mod p) ; 1] Compute LHS and RHS diff --git a/main/pairings/BN254/ecMul.zkasm b/main/pairings/BN254/ecMul.zkasm index a0d27f07..1fecd4fc 100644 --- a/main/pairings/BN254/ecMul.zkasm +++ b/main/pairings/BN254/ecMul.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to FP arithmetic ;; ;; ecMul: ;; in: k, P = (P.x, P.y) ∈ E(Fp), where k ∈ [0,r-1] @@ -34,10 +35,10 @@ ecMul: ; Is P = O? 0n => B $ => A :MLOAD(ecMul_P_x) - $ :EQ, JMPNC(ecMul_P_continue) + $ :EQ, JMPNC(__ecMul_P_continue) $ => A :MLOAD(ecMul_P_y) $ :EQ, JMPC(ecMul_P_is_zero) - ecMul_P_continue: + __ecMul_P_continue: ; 1] Check if P is in E(Fp) ; P in E iff (P.y)² == (P.x)³ + 3 (mod p) diff --git a/main/pairings/BN254/escalarMulBN254.zkasm b/main/pairings/BN254/escalarMulBN254.zkasm index 923eac3e..c0e0764a 100644 --- a/main/pairings/BN254/escalarMulBN254.zkasm +++ b/main/pairings/BN254/escalarMulBN254.zkasm @@ -1,12 +1,12 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P ∈ E'(Fp2) +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to addPointBN254 ;; ;; ;; escalarMulBN254: ;; in: k, P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2), where k ∈ [0,r-1] ;; out: k·P = (Q.x1 + Q.x2·u, Q.y1 + Q.y2·u) ∈ E'(Fp2) ;; -;; assumes: P ∈ E'(Fp2) -;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; escalarMulBN254 assumes P belong to E'(Fp2), since it is checked in the pairing. @@ -33,14 +33,14 @@ escalarMulBN254: ; Is P = O? 0n => B $ => A :MLOAD(escalarMulBN254_P_x1) - $ :EQ, JMPNC(escalarMulBN254_P_continue) + $ :EQ, JMPNC(__escalarMulBN254_P_continue) $ => A :MLOAD(escalarMulBN254_P_x2) - $ :EQ, JMPNC(escalarMulBN254_P_continue) + $ :EQ, JMPNC(__escalarMulBN254_P_continue) $ => A :MLOAD(escalarMulBN254_P_y1) - $ :EQ, JMPNC(escalarMulBN254_P_continue) + $ :EQ, JMPNC(__escalarMulBN254_P_continue) $ => A :MLOAD(escalarMulBN254_P_y2) $ :EQ, JMPC(escalarMulBN254_P_is_zero) - escalarMulBN254_P_continue: + __escalarMulBN254_P_continue: ; Is k = 0? $ => B :MLOAD(escalarMulBN254_k), CALL(reduceFrBN254) diff --git a/main/pairings/BN254/lineDiffPointsBN254.zkasm b/main/pairings/BN254/lineDiffPointsBN254.zkasm index 5aa9d305..a0baac1b 100644 --- a/main/pairings/BN254/lineDiffPointsBN254.zkasm +++ b/main/pairings/BN254/lineDiffPointsBN254.zkasm @@ -1,14 +1,17 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P1,P2 ∈ E'(Fp2) with P1 != P2,-P2 and Q ∈ E(Fp) +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; lineDiffPointsBN254: ;; in: P1 = (P1.x1 + P1.x2·u, P1.y1 + P1.y2·u), P2 = (P2.x1 + P2.x2·u, P2.y1 + P2.y2·u) ∈ E'(Fp2) ;; and Q = (Q.x,Q.y) ∈ E(Fp) ;; out: line_{twist(P1), twist(P2)}(Q) = (P2.x - P1.x)·Q.y·w² + (P1.y - P2.y)·Q.x·w³ + (P1.x·P2.y - P2.x·P1.y)·w⁵ ∈ Fp12 ;; -;; assumes: P1,P2 ∈ E'(Fp2) with P1 != P2,-P2 and Q ∈ E(Fp) -;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; The precondition is ensured by the pairing. +; However, it must be implemented if lineDiffPointsBN254 wants to be used independently. + VAR GLOBAL lineDiffPointsBN254_P1_x1 VAR GLOBAL lineDiffPointsBN254_P1_x2 VAR GLOBAL lineDiffPointsBN254_P1_y1 diff --git a/main/pairings/BN254/lineSamePointsBN254.zkasm b/main/pairings/BN254/lineSamePointsBN254.zkasm index 1b3388d8..5bdec945 100644 --- a/main/pairings/BN254/lineSamePointsBN254.zkasm +++ b/main/pairings/BN254/lineSamePointsBN254.zkasm @@ -1,13 +1,16 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P ∈ E'(Fp2) and Q ∈ E(Fp) +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic ;; ;; lineSamePointsBN254: ;; in: P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2) and Q = (Q.x,Q.y) ∈ E(Fp) ;; out: line_{twist(P), twist(P)}(Q) = (3·P.x1³ - 2·P.y1²)·(9 + u) + (2·Q.y·P.y1)·w³ + (-3·Q.x·P.x1²)·w⁴ ∈ Fp12 ;; -;; assumes: P ∈ E'(Fp2) and Q ∈ E(Fp) -;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; The precondition is ensured by the pairing. +; However, it must be implemented if lineSamePointsBN254 wants to be used independently. + VAR GLOBAL lineSamePointsBN254_P_x1 VAR GLOBAL lineSamePointsBN254_P_x2 VAR GLOBAL lineSamePointsBN254_P_y1 diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm index f5059abb..6f09f440 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm @@ -78,10 +78,10 @@ decompressFp12BN254: ; Is Ca2 = 0? 0n => B $ => A :MLOAD(decompressFp12BN254_Ca2_x) - $ :EQ, JMPNC(decompressFp12BN254_Ca2_continue) + $ :EQ, JMPNC(__decompressFp12BN254_Ca2_continue) $ => A :MLOAD(decompressFp12BN254_Ca2_y) $ :EQ, JMPC(decompressFp12BN254_Ca2_is_zero) - decompressFp12BN254_Ca2_continue: + __decompressFp12BN254_Ca2_continue: :JMP(decompressFp12BN254_Ca2_is_not_zero) diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm index f829fc9b..1ac19fc6 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm @@ -40,59 +40,59 @@ expByXCompCycloFp12BN254: ; Is a = 0? 0n => B $ => A :MLOAD(expByXCompCycloFp12BN254_a0_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a0_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a2_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a2_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a4_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a4_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a1_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a1_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a3_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a3_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a5_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCompCycloFp12BN254_a5_y) $ :EQ, JMPC(expByXCompCycloFp12BN254_a_is_zero) - expByXCompCycloFp12BN254_a_continue1: + __expByXCompCycloFp12BN254_a_continue1: ; Is a = 1? 1n => B $ => A :MLOAD(expByXCompCycloFp12BN254_a0_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) 0n => B $ => A :MLOAD(expByXCompCycloFp12BN254_a0_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a2_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a2_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a4_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a4_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a1_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a1_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a3_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a3_y) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a5_x) - $ :EQ, JMPNC(expByXCompCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCompCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCompCycloFp12BN254_a5_y) $ :EQ, JMPC(expByXCompCycloFp12BN254_a_is_one) - expByXCompCycloFp12BN254_a_continue2: + __expByXCompCycloFp12BN254_a_continue2: 59 => RCX diff --git a/main/pairings/FP2BN254/invFp2BN254.zkasm b/main/pairings/FP2BN254/invFp2BN254.zkasm index 7f35f7cb..bc2da18f 100644 --- a/main/pairings/FP2BN254/invFp2BN254.zkasm +++ b/main/pairings/FP2BN254/invFp2BN254.zkasm @@ -31,8 +31,8 @@ invFp2BN254: A :MSTORE(invFp2BN254_y) ; From here, it is guaranteed that A,B ∈ [0,BN254_P) -invFp2BN254_iz_zero: - ; Check if A = B = 0 and if so, return 0 +invFp2BN254_zero_check: + ; Check if A = B = 0, and if so, return 0 $ => B :MLOAD(invFp2BN254_x) 0 => A $ :EQ, JMPNC(invFp2BN254_normalized) diff --git a/main/pairings/FPBN254/addFpBN254.zkasm b/main/pairings/FPBN254/addFpBN254.zkasm index 366897ee..3c6043c7 100644 --- a/main/pairings/FPBN254/addFpBN254.zkasm +++ b/main/pairings/FPBN254/addFpBN254.zkasm @@ -16,13 +16,14 @@ addFpBN254: ${_addFpBN254_AC} => E :ARITH ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[A+C] + [C] = D·2²⁵⁶ + E + ; [BN254_P]·[(A+C) / p] + [(A+C) % p] = D·2²⁵⁶ + E ; where C < BN254_P %BN254_P => A ${_addFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) ${_addFpBN254_AC % const.BN254_P} => C ; residue (256 bits) E :ARITH + ; 3] Check that the result is lower than BN254_P A => B C => A 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/invFpBN254.zkasm b/main/pairings/FPBN254/invFpBN254.zkasm index 0f573b5d..bf61486d 100644 --- a/main/pairings/FPBN254/invFpBN254.zkasm +++ b/main/pairings/FPBN254/invFpBN254.zkasm @@ -14,14 +14,16 @@ VAR GLOBAL invFpBN254_RR invFpBN254: RR :MSTORE(invFpBN254_RR) - ; If A >= BN254_P, then normalize so that A ∈ [0,BN254_P) + ; Normalization of A %BN254_P => B - $ :LT, JMPC(invFpBN254_iz_zero) + $ :LT, JMPC(invFpBN254_zero_check) :CALL(reduceFpBN254) + ; From here, it is guaranteed that A ∈ [0,BN254_P) -invFpBN254_iz_zero: - ; Check if A = 0 - A :JMPZ(invFpBN254_A_is_zero) +invFpBN254_zero_check: + ; Check if A = 0, and if so, return 0 + 0 => B + $ :EQ, JMPC(invFpBN254_A_is_zero) invFpBN254_normalized: ; 1] Compute and check the inverse over Z @@ -33,13 +35,13 @@ invFpBN254_normalized: ${_invFpBN254_AB} => E :ARITH ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[A·A⁻¹ / BN254_P] + [1] = D·2²⁵⁶ + E + ; [BN254_P]·[(A·A⁻¹) / BN254_P] + [1] = D·2²⁵⁶ + E %BN254_P => A ${_invFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) 1n => C ; residue (1 bit) E :ARITH - ; 3] Check that is lower than BN254_P + ; 3] Check that the result is lower than BN254_P A => B $ => A :MLOAD(invFpBN254_tmp) 1 :LT diff --git a/main/pairings/FPBN254/mulFpBN254.zkasm b/main/pairings/FPBN254/mulFpBN254.zkasm index e2af79c1..b77ac02e 100644 --- a/main/pairings/FPBN254/mulFpBN254.zkasm +++ b/main/pairings/FPBN254/mulFpBN254.zkasm @@ -16,13 +16,14 @@ mulFpBN254: ${_mulFpBN254_AB} => E :ARITH ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[A+C] + [C] = D·2²⁵⁶ + E + ; [BN254_P]·[(A·B) / p] + [C / p] = D·2²⁵⁶ + E ; where C < BN254_P %BN254_P => A ${_mulFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) ${_mulFpBN254_AB % const.BN254_P} => C ; residue (256 bits) E :ARITH + ; 3] Check that the result is lower than BN254_P A => B C => A 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/squareFpBN254.zkasm b/main/pairings/FPBN254/squareFpBN254.zkasm index 8a14d185..9b8ced1b 100644 --- a/main/pairings/FPBN254/squareFpBN254.zkasm +++ b/main/pairings/FPBN254/squareFpBN254.zkasm @@ -17,13 +17,14 @@ squareFpBN254: ${_squareFpBN254_AA} => E :ARITH ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[A²] + [C] = D·2²⁵⁶ + E + ; [BN254_P]·[A² / p] + [A² % p] = D·2²⁵⁶ + E ; where C < BN254_P %BN254_P => A ${_squareFpBN254_AA / const.BN254_P} => B ; quotient (256 bits) ${_squareFpBN254_AA % const.BN254_P} => C ; residue (256 bits) E :ARITH + ; 3] Check that the result is lower than BN254_P A => B C => A 1 :LT diff --git a/main/pairings/FPBN254/subFpBN254.zkasm b/main/pairings/FPBN254/subFpBN254.zkasm index 719bf4aa..517bcb58 100644 --- a/main/pairings/FPBN254/subFpBN254.zkasm +++ b/main/pairings/FPBN254/subFpBN254.zkasm @@ -17,13 +17,14 @@ subFpBN254: ${_subFpBN254_AC} => E :ARITH ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[A+(BN254_P-C)] + [C] = D·2²⁵⁶ + E + ; [BN254_P]·[(A - C) / p] + [(A - C) % p] = D·2²⁵⁶ + E ; where C < BN254_P %BN254_P => A ${_subFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) ${_subFpBN254_AC % const.BN254_P} => C ; residue (256 bits) E :ARITH + ; 3] Check that the result is lower than BN254_P A => B C => A 1 :LT, RETURN \ No newline at end of file diff --git a/main/pairings/constants.zkasm b/main/pairings/constants.zkasm index 2f469ae0..9811197e 100644 --- a/main/pairings/constants.zkasm +++ b/main/pairings/constants.zkasm @@ -2,13 +2,13 @@ ;; ;; Constants of the optimal Ate pairing over the BN254 curve ;; e: G1 x G2 --> GT -;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over (Fp12)^*) over the curves: +;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over Fp12* over the curves: ;; E/Fp: y² = x³ + 3, E'/Fp2: y² = x³ + 3/(9+u) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Basic constants: X = "BN family parameter", P = "base field order", R = "scalar field order" -CONSTL %BN254_X = 4965661367192848881n ; Unused, just for reference +; CONSTL %BN254_X = 4965661367192848881n ; Unused, just for reference CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n ; 36n * X ** 4n + 36n * X ** 3n + 24n * X ** 2n + 6n * X + 1n ; NOTE: It is satisfied that 5·p < 2²⁵⁶ < 6·p CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n @@ -39,8 +39,8 @@ CONSTL %FROBENIUS_GAMMA121 = 215754636382808430103983242694308260992690442743472 CONSTL %FROBENIUS_GAMMA122 = 10307601595873709700152284273816112264069230130616436755625194854815875713954n CONSTL %FROBENIUS_GAMMA131 = 2821565182194536844548159561693502659359617185244120367078079554186484126554n CONSTL %FROBENIUS_GAMMA132 = 3505843767911556378687030309984248845540243509899259641013678093033130930403n -CONSTL %FROBENIUS_GAMMA131_NEGATED = %BN254_P - %FROBENIUS_GAMMA131 -CONSTL %FROBENIUS_GAMMA132_NEGATED = %BN254_P - %FROBENIUS_GAMMA132 +CONSTL %FROBENIUS_GAMMA131_NEGATED = 19066677689644738377698246183563772429336693972053703295610958340458742082029n ;%BN254_P - %FROBENIUS_GAMMA131 +CONSTL %FROBENIUS_GAMMA132_NEGATED = 18382399103927718843559375435273026243156067647398564021675359801612095278180n ;%BN254_P - %FROBENIUS_GAMMA132 CONSTL %FROBENIUS_GAMMA141 = 2581911344467009335267311115468803099551665605076196740867805258568234346338n CONSTL %FROBENIUS_GAMMA142 = 19937756971775647987995932169929341994314640652964949448313374472400716661030n CONSTL %FROBENIUS_GAMMA151 = 685108087231508774477564247770172212460312782337200605669322048753928464687n diff --git a/main/pairings/ecPairing.zkasm b/main/pairings/ecPairing.zkasm index ceb65dbe..0e49608b 100644 --- a/main/pairings/ecPairing.zkasm +++ b/main/pairings/ecPairing.zkasm @@ -1,10 +1,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The number of inputs n is no larger than 2³²-1 ;; ;; ecPairing: ;; input: P1,...,Pn ∈ G1 and Q1,...,Qn ∈ G2, where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and ;; the curves are E/Fp: y² = x³ + 3 and E'/Fp2: y² = x³ + 3/(9+u) ;; output: 1 if e(P1,Q1)·...·e(Pn,Qn) = 1, 0 otherwise; where e: G1 x G2 -> GT is -;; the optimal Ate pairing over the BN254 curve and GT = mu_r (the r-th roots of unity over (Fp12)^*) +;; the optimal Ate pairing over the BN254 curve and GT = mu_r (the r-th roots of unity over Fp12* ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -190,31 +191,31 @@ ecPairing_final_exponentiation: ; Check whether the result is 1 or not 1n => B $ => A :MLOAD(finalExpBN254_f11_x) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) 0n => B $ => A :MLOAD(finalExpBN254_f11_y) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f12_x) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f12_y) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f13_x) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f13_y) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f21_x) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f21_y) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f22_x) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f22_y) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f23_x) - $ :EQ, JMPNC(finalExpBN254_result_continue) + $ :EQ, JMPNC(__finalExpBN254_result_continue) $ => A :MLOAD(finalExpBN254_f23_y) $ :EQ, JMPC(ecPairing_equation_is_satisfied) - finalExpBN254_result_continue: + __finalExpBN254_result_continue: ; the pairing equation is not satisfied, then output 0 0 :MSTORE(ecPairing_result) diff --git a/main/pairings/halfPairingBN254.zkasm b/main/pairings/halfPairingBN254.zkasm index 6b88d7ad..98250839 100644 --- a/main/pairings/halfPairingBN254.zkasm +++ b/main/pairings/halfPairingBN254.zkasm @@ -67,35 +67,35 @@ halfPairingBN254: ; Is P = O? 0n => B $ => A :MLOAD(halfPairingBN254_P_x) - $ :EQ, JMPNC(halfPairingBN254_P_continue) + $ :EQ, JMPNC(__halfPairingBN254_P_continue) $ => A :MLOAD(halfPairingBN254_P_y) $ :EQ, JMPC(halfPairingBN254_P_is_zero) - halfPairingBN254_P_continue: + __halfPairingBN254_P_continue: ; Is Q = O? $ => A :MLOAD(halfPairingBN254_Q_x1) - $ :EQ, JMPNC(halfPairingBN254_Q_continue1) + $ :EQ, JMPNC(__halfPairingBN254_Q_continue1) $ => A :MLOAD(halfPairingBN254_Q_x2) - $ :EQ, JMPNC(halfPairingBN254_Q_continue1) + $ :EQ, JMPNC(__halfPairingBN254_Q_continue1) $ => A :MLOAD(halfPairingBN254_Q_y1) - $ :EQ, JMPNC(halfPairingBN254_Q_continue1) + $ :EQ, JMPNC(__halfPairingBN254_Q_continue1) $ => A :MLOAD(halfPairingBN254_Q_y2) $ :EQ, JMPC(halfPairingBN254_Q_is_zero) - halfPairingBN254_Q_continue1: + __halfPairingBN254_Q_continue1: :JMP(halfPairingBN254_P_subgroup_check) halfPairingBN254_P_is_zero: ; Is Q = O? $ => A :MLOAD(halfPairingBN254_Q_x1) - $ :EQ, JMPNC(halfPairingBN254_Q_continue2) + $ :EQ, JMPNC(__halfPairingBN254_Q_continue2) $ => A :MLOAD(halfPairingBN254_Q_x2) - $ :EQ, JMPNC(halfPairingBN254_Q_continue2) + $ :EQ, JMPNC(__halfPairingBN254_Q_continue2) $ => A :MLOAD(halfPairingBN254_Q_y1) - $ :EQ, JMPNC(halfPairingBN254_Q_continue2) + $ :EQ, JMPNC(__halfPairingBN254_Q_continue2) $ => A :MLOAD(halfPairingBN254_Q_y2) $ :EQ, JMPC(halfPairingBN254_P_and_Q_are_zero) - halfPairingBN254_Q_continue2: + __halfPairingBN254_Q_continue2: ; Check that Q is in G2 ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 diff --git a/main/pairings/loopLengthBN254.zkasm b/main/pairings/loopLengthBN254.zkasm index 8e92a82f..38896eb9 100644 --- a/main/pairings/loopLengthBN254.zkasm +++ b/main/pairings/loopLengthBN254.zkasm @@ -2,10 +2,10 @@ ;; ;; loopLengthBN254: ;; output: A digit of the (little-endian) pseudobinary representation of the loop length -;; of the optimal ate pairing over the BN254. The loop length is precisely 6·x + 2. -;; and is represented as follows: +;; of the optimal ate pairing over the BN254: ;; 0001010-1001-100100110-10010-1000011100-100100000-1001100-1000110-1001011 ;; +;; NOTE: The loop length is precisely 6·%BN254_X + 2, that is 29793968203157093288. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; loopLengthBN254: diff --git a/main/pairings/millerLoopBN254.zkasm b/main/pairings/millerLoopBN254.zkasm index c85ac8b5..2e339258 100644 --- a/main/pairings/millerLoopBN254.zkasm +++ b/main/pairings/millerLoopBN254.zkasm @@ -239,13 +239,13 @@ millerLoopBN254_loop: RCX-1 => RR :CALL(@loopLengthBN254 + RR) - ; if bit = -1, then "sub" + ; if bit = -1, then sub B :JMPN(millerLoopBN254_sub) ; if bit = 0, then repeat B :JMPZ(millerLoopBN254_loop) - ; if bit = -1, then "add" + ; if bit = 1, then add millerLoopBN254_add: ; 1] f = f · line_{twist(R),twist(Q)}(P) diff --git a/main/pairings/pairingBN254.zkasm b/main/pairings/pairingBN254.zkasm index 7698b793..4ab37b6f 100644 --- a/main/pairings/pairingBN254.zkasm +++ b/main/pairings/pairingBN254.zkasm @@ -1,7 +1,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Optimal Ate Pairing e: G1 x G2 -> GT over the BN254 curve -;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over (Fp12)^*) +;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over Fp12* ;; the involved curves are E/Fp: y² = x³ + 3 and E'/Fp2: y² = x³ + 3/(9+u) ;; pairingBN254: ;; input: P ∈ G1 and Q ∈ G2 @@ -70,21 +70,21 @@ pairingBN254: ; Is P = O? 0n => B $ => A :MLOAD(pairingBN254_P_x) - $ :EQ, JMPNC(pairingBN254_P_continue) + $ :EQ, JMPNC(__pairingBN254_P_continue) $ => A :MLOAD(pairingBN254_P_y) $ :EQ, JMPC(pairingBN254_P_is_zero) - pairingBN254_P_continue: + __pairingBN254_P_continue: ; Is Q = O? $ => A :MLOAD(pairingBN254_Q_x1) - $ :EQ, JMPNC(pairingBN254_Q_continue1) + $ :EQ, JMPNC(__pairingBN254_Q_continue1) $ => A :MLOAD(pairingBN254_Q_x2) - $ :EQ, JMPNC(pairingBN254_Q_continue1) + $ :EQ, JMPNC(__pairingBN254_Q_continue1) $ => A :MLOAD(pairingBN254_Q_y1) - $ :EQ, JMPNC(pairingBN254_Q_continue1) + $ :EQ, JMPNC(__pairingBN254_Q_continue1) $ => A :MLOAD(pairingBN254_Q_y2) $ :EQ, JMPC(pairingBN254_Q_is_zero) - pairingBN254_Q_continue1: + __pairingBN254_Q_continue1: :JMP(pairingBN254_P_subgroup_check) @@ -92,14 +92,14 @@ pairingBN254: pairingBN254_P_is_zero: ; Is Q = O? $ => A :MLOAD(pairingBN254_Q_x1) - $ :EQ, JMPNC(pairingBN254_Q_continue2) + $ :EQ, JMPNC(__pairingBN254_Q_continue2) $ => A :MLOAD(pairingBN254_Q_x2) - $ :EQ, JMPNC(pairingBN254_Q_continue2) + $ :EQ, JMPNC(__pairingBN254_Q_continue2) $ => A :MLOAD(pairingBN254_Q_y1) - $ :EQ, JMPNC(pairingBN254_Q_continue2) + $ :EQ, JMPNC(__pairingBN254_Q_continue2) $ => A :MLOAD(pairingBN254_Q_y2) $ :EQ, JMPC(pairingBN254_P_and_Q_are_zero) - pairingBN254_Q_continue2: + __pairingBN254_Q_continue2: ; Check that Q is in G2 ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 diff --git a/main/pairings/unused/expByXCycloFp12BN254.zkasm b/main/pairings/unused/expByXCycloFp12BN254.zkasm index da0ffcc1..4fe01f18 100644 --- a/main/pairings/unused/expByXCycloFp12BN254.zkasm +++ b/main/pairings/unused/expByXCycloFp12BN254.zkasm @@ -46,59 +46,59 @@ expByXCycloFp12BN254: ; Is a = 0? 0n => B $ => A :MLOAD(expByXCycloFp12BN254_a11_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a11_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a12_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a12_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a13_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a13_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a21_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a21_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a22_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a22_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a23_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue1) $ => A :MLOAD(expByXCycloFp12BN254_a23_y) $ :EQ, JMPC(expByXCycloFp12BN254_a_is_zero) - expByXCycloFp12BN254_a_continue1: + __expByXCycloFp12BN254_a_continue1: ; Is a = 1? 1n => B $ => A :MLOAD(expByXCycloFp12BN254_a11_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) 0n => B $ => A :MLOAD(expByXCycloFp12BN254_a11_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a12_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a12_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a13_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a13_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a21_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a21_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a22_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a22_y) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a23_x) - $ :EQ, JMPNC(expByXCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expByXCycloFp12BN254_a_continue2) $ => A :MLOAD(expByXCycloFp12BN254_a23_y) $ :EQ, JMPC(expByXCycloFp12BN254_a_is_one) - expByXCycloFp12BN254_a_continue2: + __expByXCycloFp12BN254_a_continue2: 63 => RCX @@ -178,7 +178,7 @@ expByXCycloFp12BN254_a_is_one: :JMP(expByXCycloFp12BN254_end) expByXCycloFp12BN254_loop: - RCX - 1 => RCX :JMPZ(expByXCycloFp12BN254_end) + RCX - 1 => RCX :JMPZ(expByXCycloFp12BN254_end) ; We always square: c = c^2 $ => A :MLOAD(expByXCycloFp12BN254_c11_x) @@ -235,13 +235,13 @@ expByXCycloFp12BN254_loop: ; For the following, keep in mind that a ∈ GΦ6(p²) and therefore ; computing the conjugate is the same as computing the inverse. - ; We check if the MSB b of x is either 1, 0 or -1. + ; We check if the MSB b of x is either 1, 0 or -1. ; - If b == 1, we should multiply a to c. ; - If b == -1, we should multiply a̅ to c. RCX-1 => RR :CALL(@xPseudoBinDecompBN254 + RR) - + ; if bit = -1, then multiply by conjugate B :JMPN(expByXCycloFp12BN254_multiply_by_conjugate) diff --git a/main/pairings/unused/expFp12BN254.zkasm b/main/pairings/unused/expFp12BN254.zkasm index e98f9b8e..b6c5e463 100644 --- a/main/pairings/unused/expFp12BN254.zkasm +++ b/main/pairings/unused/expFp12BN254.zkasm @@ -44,59 +44,59 @@ expFp12BN254: ; 1] Is a = 0? 0n => B $ => A :MLOAD(expFp12BN254_a11_x) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a11_y) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a12_x) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a12_y) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a13_x) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a13_y) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a21_x) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a21_y) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a22_x) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a22_y) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a23_x) - $ :EQ, JMPNC(expFp12BN254_a_continue1) + $ :EQ, JMPNC(__expFp12BN254_a_continue1) $ => A :MLOAD(expFp12BN254_a23_y) $ :EQ, JMPC(expFp12BN254_a_is_zero) - expFp12BN254_a_continue1: + __expFp12BN254_a_continue1: ; 2] Is a = 1? 1n => B $ => A :MLOAD(expFp12BN254_a11_x) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) 0n => B $ => A :MLOAD(expFp12BN254_a11_y) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a12_x) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a12_y) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a13_x) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a13_y) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a21_x) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a21_y) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a22_x) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a22_y) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a23_x) - $ :EQ, JMPNC(expFp12BN254_a_continue2) + $ :EQ, JMPNC(__expFp12BN254_a_continue2) $ => A :MLOAD(expFp12BN254_a23_y) $ :EQ, JMPC(expFp12BN254_a_is_one) - expFp12BN254_a_continue2: + __expFp12BN254_a_continue2: ; 3] Is e = 0? $ => A :MLOAD(expFp12BN254_e) @@ -191,7 +191,7 @@ expFp12BN254_find_MSB_e: expFp12BN254_loop: - RCX - 1 => RCX :JMPZ(expFp12BN254_end) + RCX - 1 => RCX :JMPZ(expFp12BN254_end) ; We always square: c = c^2 $ => A :MLOAD(expFp12BN254_c11_x) diff --git a/main/pairings/utilsTests/expCycloFp12BN254.zkasm b/main/pairings/utilsTests/expCycloFp12BN254.zkasm index 1f73a81c..6dac4e07 100644 --- a/main/pairings/utilsTests/expCycloFp12BN254.zkasm +++ b/main/pairings/utilsTests/expCycloFp12BN254.zkasm @@ -45,59 +45,59 @@ expCycloFp12BN254: ; 1] Is a = 0? 0n => B $ => A :MLOAD(expCycloFp12BN254_a11_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a11_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a12_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a12_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a13_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a13_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a21_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a21_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a22_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a22_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a23_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue1) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue1) $ => A :MLOAD(expCycloFp12BN254_a23_y) $ :EQ, JMPC(expCycloFp12BN254_a_is_zero) - expCycloFp12BN254_a_continue1: + __expCycloFp12BN254_a_continue1: ; 2] Is a = 1? 1n => B $ => A :MLOAD(expCycloFp12BN254_a11_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) 0n => B $ => A :MLOAD(expCycloFp12BN254_a11_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a12_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a12_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a13_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a13_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a21_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a21_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a22_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a22_y) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a23_x) - $ :EQ, JMPNC(expCycloFp12BN254_a_continue2) + $ :EQ, JMPNC(__expCycloFp12BN254_a_continue2) $ => A :MLOAD(expCycloFp12BN254_a23_y) $ :EQ, JMPC(expCycloFp12BN254_a_is_one) - expCycloFp12BN254_a_continue2: + __expCycloFp12BN254_a_continue2: ; 3] Check if e = 0 $ => A :MLOAD(expCycloFp12BN254_e) diff --git a/test/testFpArithBN254.zkasm b/test/testFpArithBN254.zkasm index b28cfc8e..e9741b73 100644 --- a/test/testFpArithBN254.zkasm +++ b/test/testFpArithBN254.zkasm @@ -57,59 +57,59 @@ start: 3n => C :CALL(addFpBN254) C => A - 4n => B :ASSERT + 4n :ASSERT 2n => A 3n => C :CALL(subFpBN254) C => A - 21888242871839275222246405745257275088696311157297823662689037894645226208582n => B :ASSERT + 21888242871839275222246405745257275088696311157297823662689037894645226208582n :ASSERT ${const.BN254_P - 2} => A :CALL(squareFpBN254) B => A - 4n => B :ASSERT + 4n :ASSERT 0n => A :CALL(invFpBN254) B => A - 0n => B :ASSERT + 0n :ASSERT %BN254_P + %BN254_P => A :CALL(invFpBN254) - 0n => B :ASSERT + 0n :ASSERT %BN254_P + %BN254_P + %BN254_P => A :CALL(invFpBN254) - 0n => B :ASSERT + 0n :ASSERT %BN254_P + %BN254_P + %BN254_P + %BN254_P => A :CALL(invFpBN254) - 0n => B :ASSERT + 0n :ASSERT %BN254_P + %BN254_P + %BN254_P + %BN254_P + %BN254_P => A :CALL(invFpBN254) - 0n => B :ASSERT + 0n :ASSERT 0n => A :CALL(reduceFpBN254) - 0n => B :ASSERT + 0n :ASSERT %BN254_P => A :CALL(reduceFpBN254) - 0n => B :ASSERT + 0n :ASSERT %BN254_P + 1n => A :CALL(reduceFpBN254) - 1n => B :ASSERT + 1n :ASSERT %BN254_P + 21888242871839275222246405745257275088696311157297823662689037894645226208582n => A :CALL(reduceFpBN254) - 21888242871839275222246405745257275088696311157297823662689037894645226208582n => B :ASSERT + 21888242871839275222246405745257275088696311157297823662689037894645226208582n :ASSERT 43776485743678550444492811490514550177392622314595647325378075789290452417166n => A :CALL(reduceFpBN254) - 0n => B :ASSERT + 0n :ASSERT end: From 59b10ab77ad0bb6638bb7e2992482d35304ec4d0 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Fri, 1 Dec 2023 11:29:39 +0100 Subject: [PATCH 050/121] Remove unused depth var --- main/opcodes/create-terminate-context.zkasm | 52 ++++----------------- main/precompiled/end.zkasm | 7 +-- main/precompiled/revert-precompiled.zkasm | 6 +-- main/process-tx.zkasm | 3 +- main/utils.zkasm | 9 +--- main/vars.zkasm | 1 - 6 files changed, 13 insertions(+), 65 deletions(-) diff --git a/main/opcodes/create-terminate-context.zkasm b/main/opcodes/create-terminate-context.zkasm index 676a9efa..7e10e43d 100644 --- a/main/opcodes/create-terminate-context.zkasm +++ b/main/opcodes/create-terminate-context.zkasm @@ -36,10 +36,7 @@ opSTOPend: $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) ; store stack output - D :MSTORE(SP++) - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) + D :MSTORE(SP++), JMP(readCode) /** * @link [https://www.evm.codes/#f0?fork=berlin] @@ -61,10 +58,6 @@ opCREATE: GAS - %CREATE_GAS => GAS :JMPN(outOfGas) GAS :MSTORE(gasCall) - ; increase depth - $ => A :MLOAD(depth) - A + 1 :MSTORE(depth) - ; check stack underflow SP - 3 :JMPN(stackUnderflow) ; check is static @@ -154,10 +147,7 @@ opCREATE: :JMP(txType) opCreateFail: - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth) - + ; return 0 if create fails 0 :MSTORE(retDataCTX) 0 :MSTORE(SP++), JMP(readCode); [0 => SP] @@ -175,9 +165,6 @@ opCALL: ; checks zk-counters %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) - ; increase depth - $ => A :MLOAD(depth) - A + 1 :MSTORE(depth) ; check stack underflow SP - 7 :JMPN(stackUnderflow) SP - 1 => SP @@ -297,9 +284,6 @@ opCALLCODE: ; checks zk-counters %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) - ; increase depth - $ => A :MLOAD(depth) - A + 1 :MSTORE(depth) ; check stack underflow SP - 7 :JMPN(stackUnderflow) SP - 1 => SP @@ -482,10 +466,7 @@ opRETURNend: ; restore origin CTX values $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - 1 :MSTORE(SP++); [1 => SP] - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) + 1 :MSTORE(SP++), JMP(readCode); [1 => SP] opRETURNdeploy: ; code size limit = 0x6000 @@ -531,10 +512,7 @@ opRETURNcreateEnd: ; set SP and PC $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - A :MSTORE(SP++); [createContractAddress(A) => SP] - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) + A :MSTORE(SP++), JMP(readCode); [createContractAddress(A) => SP] /** * @link [https://www.evm.codes/#f4?fork=berlin] @@ -547,9 +525,7 @@ opRETURNcreateEnd: opDELEGATECALL: ; checks zk-counters %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) - ; increase depth - $ => A :MLOAD(depth) - A + 1 :MSTORE(depth) + ; check stack underflow SP - 6 :JMPN(stackUnderflow) SP - 1 => SP @@ -649,10 +625,6 @@ opCREATE2: ; check out-of-gas GAS - %CREATE_2_GAS => GAS :JMPN(outOfGas) - ; increase depth - $ => A :MLOAD(depth) - A + 1 :MSTORE(depth) - ; check stack underflow SP - 4 :JMPN(stackUnderflow) ; check is static @@ -765,9 +737,6 @@ opCREATE2: opSTATICCALL: ; checks zk-counters %MAX_CNT_STEPS - STEP - 300 :JMPN(outOfCountersStep) - ; increase depth - $ => A :MLOAD(depth) - A + 1 :MSTORE(depth) ; check stack underflow SP - 6 :JMPN(stackUnderflow) SP - 1 => SP @@ -921,10 +890,7 @@ opREVERTend: CTX :MSTORE(currentCTX) $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - 0 :MSTORE(SP++); [0 => SP] - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) + 0 :MSTORE(SP++), JMP(readCode); [0 => SP] VAR GLOBAL sendAllAddress ; SELFDESTRUCT is deprecated and EIP-4758 is implemented: https://eips.ethereum.org/EIPS/eip-4758 @@ -1030,10 +996,8 @@ opSENDALLendContinue: ; restore origin CTX values $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - D :MSTORE(SP++); [output => SP] - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) + D :MSTORE(SP++), JMP(readCode); [output => SP] + /** * @link [https://www.evm.codes/#fe?fork=berlin] * @zk-counters diff --git a/main/precompiled/end.zkasm b/main/precompiled/end.zkasm index 2393ffa6..3dbdfd2b 100644 --- a/main/precompiled/end.zkasm +++ b/main/precompiled/end.zkasm @@ -1,9 +1,6 @@ preEnd: $ => B :MLOAD(gasCTX) B + GAS => GAS - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth) $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) 1 :MSTORE(SP++), JMP(readCode) @@ -21,6 +18,4 @@ preEndFail: $ => GAS :MLOAD(gasCTX) $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - 0 :MSTORE(SP++) - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) \ No newline at end of file + 0 :MSTORE(SP++), JMP(readCode) \ No newline at end of file diff --git a/main/precompiled/revert-precompiled.zkasm b/main/precompiled/revert-precompiled.zkasm index 118a0a2e..dc7b7cf4 100644 --- a/main/precompiled/revert-precompiled.zkasm +++ b/main/precompiled/revert-precompiled.zkasm @@ -22,8 +22,4 @@ revertPrecompiled: $ => PC :MLOAD(lastPC) ; write 0 in previous context stack - 0 :MSTORE(SP++) - - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) \ No newline at end of file + 0 :MSTORE(SP++), JMP(readCode) \ No newline at end of file diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index 3ec27cf6..3ec43eab 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -62,10 +62,9 @@ endCheckChainId: ;; Reset warm/cold information $ => A :MLOAD(txSrcOriginAddr), CALL(initTouchedTree) :CALL(isColdAddress) ; add tx.origin to touched addresses - 0 :MSTORE(depth) ,CALL(checkpointBlockInfoTree) ; Initial depth is 0 ; Set tx status to success by default - 1 :MSTORE(txStatus) + 1 :MSTORE(txStatus),CALL(checkpointBlockInfoTree) ;; Set gasPrice global var depending on effectivePercentage [0-255] -> txGasPrice = Floor((gasPrice * (effectivePercentage + 1)) / 256) ; gasPrice => A $ => A :MLOAD(txGasPriceRLP) diff --git a/main/utils.zkasm b/main/utils.zkasm index 37c26f88..59cee4ee 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -878,9 +878,7 @@ handleError: $ => GAS :MLOAD(gasCTX) $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - 0 :MSTORE(SP++) - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) + 0 :MSTORE(SP++), JMP(readCode) handleBatchError: ; restore init state root and finish batch @@ -987,10 +985,7 @@ invalidCall: GAS + A => GAS $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) - 0 :MSTORE(SP++) - ; decrease depth - $ => A :MLOAD(depth) - A - 1 :MSTORE(depth), JMP(readCode) + 0 :MSTORE(SP++), JMP(readCode) VAR GLOBAL pushBytes VAR GLOBAL numBlocks diff --git a/main/vars.zkasm b/main/vars.zkasm index a15dc95a..85252c22 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -38,7 +38,6 @@ VAR GLOBAL valueCall ; value parameter when creating a new context VAR GLOBAL argsLengthCall ; size of the calldata creating a new context VAR GLOBAL txSrcOriginAddr ; origin address of a tx VAR GLOBAL txGasPrice ; transaction parameter: 'gasPrice' global var -VAR GLOBAL depth ; Current depth execution VAR GLOBAL cntKeccakPreProcess ; Number of keccak counters needed to finish the batch VAR GLOBAL originSR ; State root before processing each transaction From 35af14b533b249a01aa08bc60d85e150794e3864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Fri, 1 Dec 2023 18:36:15 +0100 Subject: [PATCH 051/121] Fixing the tests... --- .../CYCLOFP12BN254/compressFp12BN254.zkasm | 2 + .../CYCLOFP12BN254/decompressFp12BN254.zkasm | 2 + .../expByXCompCycloFp12BN254.zkasm | 1 + .../squareCompCycloFp12BN254.zkasm | 2 + .../CYCLOFP12BN254/squareCycloFp12BN254.zkasm | 1 + main/pairings/ecPairing.zkasm | 3 + test/testCycloFp12ArithBN254.zkasm | 437 +++++------ test/testEcAdd.zkasm | 258 ++++--- test/testEcMul.zkasm | 234 +++--- test/testEcPairing.zkasm | 694 ++++++++---------- 10 files changed, 803 insertions(+), 831 deletions(-) diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm index 68c3be83..4908a396 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm @@ -4,6 +4,8 @@ ;; in: a = a0 + a2·w + a4·w² + a1·w³ + a3·w⁴ + a5·w⁵ ∈ GΦ6(p²), where ai ∈ Fp2 ;; out: C(a) = [a2,a3,a4,a5] ∈ Fp2⁴ ;; +;; NOTE: If the input does not belong to the cyclotomic subgroup GΦ6(p²), then the compression-decompression +;; technique is not well defined. This means that D(C(a)) != a. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VAR GLOBAL compressFp12BN254_a0_x diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm index 6f09f440..64cd2665 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm @@ -11,6 +11,8 @@ ;; · a1 = (2·a4·a5)/a3 ;; · a0 = (2·a1² - 3·a3·a4)(9+u) + 1 ;; +;; NOTE: If the input is not of the form C(a), where a ∈ GΦ6(p²), then the compression-decompression +;; technique is not well defined. This means that D(C(a)) != a. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VAR GLOBAL decompressFp12BN254_Ca2_x diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm index 1ac19fc6..4cfad725 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm @@ -5,6 +5,7 @@ ;; in: x, a = a0 + a2·w + a4·w² + a1·w³ + a3·w⁴ + a5·w⁵ ∈ GΦ6(p²), where x = 4965661367192848881 and ai ∈ Fp2 ;; out: a^x = c0 + c2·w + c4·w² + c1·w³ + c3·w⁴ + c5·w⁵ ∈ ∈ GΦ6(p²) ;; +;; NOTE: The output is not guaranteed to be in GΦ6(p²), if the input isn't. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VAR GLOBAL expByXCompCycloFp12BN254_a0_x diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm index 433b6e4e..63d576d5 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm @@ -13,6 +13,8 @@ ;; - B23 = a2·a3 ;; - B45 = a4·a5 ;; +;; NOTE: If the input is not of the form C(a), where a ∈ GΦ6(p²), then the compression-decompression +;; technique will not be well defined after the squaring. This means that D(C(a²)) != a². ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VAR GLOBAL squareCompCycloFp12BN254_Ca2_x diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm index 5ea95584..6b965120 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm @@ -5,6 +5,7 @@ ;; in: (a1 + a2·w) ∈ GΦ6(p²), where ai ∈ Fp6 ;; out: (c1 + c2·w) = (a1 + a2·w)² ∈ GΦ6(p²) ;; +;; NOTE: The output is not guaranteed to be in GΦ6(p²), if the input isn't. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VAR GLOBAL squareCycloFp12BN254_a11_x diff --git a/main/pairings/ecPairing.zkasm b/main/pairings/ecPairing.zkasm index 0e49608b..16c235d2 100644 --- a/main/pairings/ecPairing.zkasm +++ b/main/pairings/ecPairing.zkasm @@ -35,6 +35,9 @@ VAR GLOBAL ecPairing_RR ecPairing: RR :MSTORE(ecPairing_RR) + ; clean the result + 0n :MSTORE(ecPairing_result) + $ => A :MLOAD(ecPairing_ninputs), JMPZ(ecPairing_0_inputs) ; Initialize the multiplication with 1 diff --git a/test/testCycloFp12ArithBN254.zkasm b/test/testCycloFp12ArithBN254.zkasm index 7cb8ac48..d4574f82 100644 --- a/test/testCycloFp12ArithBN254.zkasm +++ b/test/testCycloFp12ArithBN254.zkasm @@ -53,23 +53,20 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - - ; TODO: Find an example with a2 = 0 - ; 1] Compression and decompression: It must happen that D(C(a)) = a - 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(compressFp12BN254_a0_x) - 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(compressFp12BN254_a0_y) - 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(compressFp12BN254_a2_x) - 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(compressFp12BN254_a2_y) - 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(compressFp12BN254_a4_x) - 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(compressFp12BN254_a4_y) - 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(compressFp12BN254_a1_x) - 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(compressFp12BN254_a1_y) - 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(compressFp12BN254_a3_x) - 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(compressFp12BN254_a3_y) - 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(compressFp12BN254_a5_x) - 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(compressFp12BN254_a5_y) - :CALL(compressFp12BN254) + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(compressFp12BN254_a0_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(compressFp12BN254_a0_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(compressFp12BN254_a2_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(compressFp12BN254_a2_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(compressFp12BN254_a4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(compressFp12BN254_a4_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(compressFp12BN254_a1_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(compressFp12BN254_a1_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(compressFp12BN254_a3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(compressFp12BN254_a3_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(compressFp12BN254_a5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(compressFp12BN254_a5_y) + :CALL(compressFp12BN254) 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MLOAD(compressFp12BN254_Ca2_x) 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MLOAD(compressFp12BN254_Ca2_y) 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MLOAD(compressFp12BN254_Ca3_x) @@ -87,7 +84,7 @@ start: 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(decompressFp12BN254_Ca4_y) 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(decompressFp12BN254_Ca5_x) 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(decompressFp12BN254_Ca5_y) - :CALL(decompressFp12BN254) + :CALL(decompressFp12BN254) 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MLOAD(decompressFp12BN254_a0_x) 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MLOAD(decompressFp12BN254_a0_y) 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MLOAD(decompressFp12BN254_a2_x) @@ -101,6 +98,28 @@ start: 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MLOAD(decompressFp12BN254_a5_x) 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MLOAD(decompressFp12BN254_a5_y) + 0n :MSTORE(decompressFp12BN254_Ca2_x) + 0n :MSTORE(decompressFp12BN254_Ca2_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(decompressFp12BN254_Ca3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(decompressFp12BN254_Ca3_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(decompressFp12BN254_Ca4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(decompressFp12BN254_Ca4_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(decompressFp12BN254_Ca5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(decompressFp12BN254_Ca5_y) + :CALL(decompressFp12BN254) + 3082566802732947271293720222661142209591143484576084617328875773438864732397n :MLOAD(decompressFp12BN254_a0_x) + 6753192725715184303833194625336959866779003056329959595176212784417709284236n :MLOAD(decompressFp12BN254_a0_y) + 0n :MLOAD(decompressFp12BN254_a2_x) + 0n :MLOAD(decompressFp12BN254_a2_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MLOAD(decompressFp12BN254_a4_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MLOAD(decompressFp12BN254_a4_y) + 19725038294210990876095311608776995374658210593840653608871004828604621493298n :MLOAD(decompressFp12BN254_a1_x) + 9667536184264952931246834743665147146209943690267032273162296061012209804352n :MLOAD(decompressFp12BN254_a1_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MLOAD(decompressFp12BN254_a3_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MLOAD(decompressFp12BN254_a3_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MLOAD(decompressFp12BN254_a5_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MLOAD(decompressFp12BN254_a5_y) + ; 2] Squaring 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(squareCycloFp12BN254_a11_x) 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(squareCycloFp12BN254_a11_y) @@ -146,23 +165,23 @@ start: 17209588680055969912485542074372495831925486815137906387799790601911548657525n :MLOAD(squareCompCycloFp12BN254_Cb4_y) 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(squareCompCycloFp12BN254_Cb5_x) 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(squareCompCycloFp12BN254_Cb5_y) - $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) - $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) - $ => C :MLOAD(squareCompCycloFp12BN254_Cb3_x) - $ => D :MLOAD(squareCompCycloFp12BN254_Cb3_y) - A :MSTORE(decompressFp12BN254_Ca2_x) - B :MSTORE(decompressFp12BN254_Ca2_y) - C :MSTORE(decompressFp12BN254_Ca3_x) - D :MSTORE(decompressFp12BN254_Ca3_y) - $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) - $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) - $ => C :MLOAD(squareCompCycloFp12BN254_Cb5_x) - $ => D :MLOAD(squareCompCycloFp12BN254_Cb5_y) - A :MSTORE(decompressFp12BN254_Ca4_x) - B :MSTORE(decompressFp12BN254_Ca4_y) - C :MSTORE(decompressFp12BN254_Ca5_x) - D :MSTORE(decompressFp12BN254_Ca5_y) - :CALL(decompressFp12BN254) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Cb3_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Cb3_y) + A :MSTORE(decompressFp12BN254_Ca2_x) + B :MSTORE(decompressFp12BN254_Ca2_y) + C :MSTORE(decompressFp12BN254_Ca3_x) + D :MSTORE(decompressFp12BN254_Ca3_y) + $ => A :MLOAD(squareCompCycloFp12BN254_Cb4_x) + $ => B :MLOAD(squareCompCycloFp12BN254_Cb4_y) + $ => C :MLOAD(squareCompCycloFp12BN254_Cb5_x) + $ => D :MLOAD(squareCompCycloFp12BN254_Cb5_y) + A :MSTORE(decompressFp12BN254_Ca4_x) + B :MSTORE(decompressFp12BN254_Ca4_y) + C :MSTORE(decompressFp12BN254_Ca5_x) + D :MSTORE(decompressFp12BN254_Ca5_y) + :CALL(decompressFp12BN254) 2098026393950394559493690260865166581266928315924710629633888310320006689795n :MLOAD(decompressFp12BN254_a0_x) 1846888720299666666109042029094532002505741710678796245911331796963733914187n :MLOAD(decompressFp12BN254_a0_y) 14351778565182200844681812560787756136192441388960773363087263587389322671562n :MLOAD(decompressFp12BN254_a2_x) @@ -177,86 +196,86 @@ start: 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(decompressFp12BN254_a5_y) ; 4] Exponentiation - 0n :MSTORE(expCycloFp12BN254_e) - 0n :MSTORE(expCycloFp12BN254_a11_x) - 0n :MSTORE(expCycloFp12BN254_a11_y) - 0n :MSTORE(expCycloFp12BN254_a12_x) - 0n :MSTORE(expCycloFp12BN254_a12_y) - 0n :MSTORE(expCycloFp12BN254_a13_x) - 0n :MSTORE(expCycloFp12BN254_a13_y) - 0n :MSTORE(expCycloFp12BN254_a21_x) - 0n :MSTORE(expCycloFp12BN254_a21_y) - 0n :MSTORE(expCycloFp12BN254_a22_x) - 0n :MSTORE(expCycloFp12BN254_a22_y) - 0n :MSTORE(expCycloFp12BN254_a23_x) - 0n :MSTORE(expCycloFp12BN254_a23_y) + 0n :MSTORE(expCycloFp12BN254_e) + 0n :MSTORE(expCycloFp12BN254_a11_x) + 0n :MSTORE(expCycloFp12BN254_a11_y) + 0n :MSTORE(expCycloFp12BN254_a12_x) + 0n :MSTORE(expCycloFp12BN254_a12_y) + 0n :MSTORE(expCycloFp12BN254_a13_x) + 0n :MSTORE(expCycloFp12BN254_a13_y) + 0n :MSTORE(expCycloFp12BN254_a21_x) + 0n :MSTORE(expCycloFp12BN254_a21_y) + 0n :MSTORE(expCycloFp12BN254_a22_x) + 0n :MSTORE(expCycloFp12BN254_a22_y) + 0n :MSTORE(expCycloFp12BN254_a23_x) + 0n :MSTORE(expCycloFp12BN254_a23_y) :CALL(expCycloFp12BN254) - 0n :MLOAD(expCycloFp12BN254_c11_x) - 0n :MLOAD(expCycloFp12BN254_c11_y) - 0n :MLOAD(expCycloFp12BN254_c12_x) - 0n :MLOAD(expCycloFp12BN254_c12_y) - 0n :MLOAD(expCycloFp12BN254_c13_x) - 0n :MLOAD(expCycloFp12BN254_c13_y) - 0n :MLOAD(expCycloFp12BN254_c21_x) - 0n :MLOAD(expCycloFp12BN254_c21_y) - 0n :MLOAD(expCycloFp12BN254_c22_x) - 0n :MLOAD(expCycloFp12BN254_c22_y) - 0n :MLOAD(expCycloFp12BN254_c23_x) - 0n :MLOAD(expCycloFp12BN254_c23_y) - - 10n :MSTORE(expCycloFp12BN254_e) - 0n :MSTORE(expCycloFp12BN254_a11_x) - 0n :MSTORE(expCycloFp12BN254_a11_y) - 0n :MSTORE(expCycloFp12BN254_a12_x) - 0n :MSTORE(expCycloFp12BN254_a12_y) - 0n :MSTORE(expCycloFp12BN254_a13_x) - 0n :MSTORE(expCycloFp12BN254_a13_y) - 0n :MSTORE(expCycloFp12BN254_a21_x) - 0n :MSTORE(expCycloFp12BN254_a21_y) - 0n :MSTORE(expCycloFp12BN254_a22_x) - 0n :MSTORE(expCycloFp12BN254_a22_y) - 0n :MSTORE(expCycloFp12BN254_a23_x) - 0n :MSTORE(expCycloFp12BN254_a23_y) + 0n :MLOAD(expCycloFp12BN254_c11_x) + 0n :MLOAD(expCycloFp12BN254_c11_y) + 0n :MLOAD(expCycloFp12BN254_c12_x) + 0n :MLOAD(expCycloFp12BN254_c12_y) + 0n :MLOAD(expCycloFp12BN254_c13_x) + 0n :MLOAD(expCycloFp12BN254_c13_y) + 0n :MLOAD(expCycloFp12BN254_c21_x) + 0n :MLOAD(expCycloFp12BN254_c21_y) + 0n :MLOAD(expCycloFp12BN254_c22_x) + 0n :MLOAD(expCycloFp12BN254_c22_y) + 0n :MLOAD(expCycloFp12BN254_c23_x) + 0n :MLOAD(expCycloFp12BN254_c23_y) + + 10n :MSTORE(expCycloFp12BN254_e) + 0n :MSTORE(expCycloFp12BN254_a11_x) + 0n :MSTORE(expCycloFp12BN254_a11_y) + 0n :MSTORE(expCycloFp12BN254_a12_x) + 0n :MSTORE(expCycloFp12BN254_a12_y) + 0n :MSTORE(expCycloFp12BN254_a13_x) + 0n :MSTORE(expCycloFp12BN254_a13_y) + 0n :MSTORE(expCycloFp12BN254_a21_x) + 0n :MSTORE(expCycloFp12BN254_a21_y) + 0n :MSTORE(expCycloFp12BN254_a22_x) + 0n :MSTORE(expCycloFp12BN254_a22_y) + 0n :MSTORE(expCycloFp12BN254_a23_x) + 0n :MSTORE(expCycloFp12BN254_a23_y) :CALL(expCycloFp12BN254) - 0n :MLOAD(expCycloFp12BN254_c11_x) - 0n :MLOAD(expCycloFp12BN254_c11_y) - 0n :MLOAD(expCycloFp12BN254_c12_x) - 0n :MLOAD(expCycloFp12BN254_c12_y) - 0n :MLOAD(expCycloFp12BN254_c13_x) - 0n :MLOAD(expCycloFp12BN254_c13_y) - 0n :MLOAD(expCycloFp12BN254_c21_x) - 0n :MLOAD(expCycloFp12BN254_c21_y) - 0n :MLOAD(expCycloFp12BN254_c22_x) - 0n :MLOAD(expCycloFp12BN254_c22_y) - 0n :MLOAD(expCycloFp12BN254_c23_x) - 0n :MLOAD(expCycloFp12BN254_c23_y) - - 0n :MSTORE(expCycloFp12BN254_e) - 1n :MSTORE(expCycloFp12BN254_a11_x) - 0n :MSTORE(expCycloFp12BN254_a11_y) - 0n :MSTORE(expCycloFp12BN254_a12_x) - 0n :MSTORE(expCycloFp12BN254_a12_y) - 0n :MSTORE(expCycloFp12BN254_a13_x) - 0n :MSTORE(expCycloFp12BN254_a13_y) - 0n :MSTORE(expCycloFp12BN254_a21_x) - 0n :MSTORE(expCycloFp12BN254_a21_y) - 0n :MSTORE(expCycloFp12BN254_a22_x) - 0n :MSTORE(expCycloFp12BN254_a22_y) - 0n :MSTORE(expCycloFp12BN254_a23_x) - 0n :MSTORE(expCycloFp12BN254_a23_y) + 0n :MLOAD(expCycloFp12BN254_c11_x) + 0n :MLOAD(expCycloFp12BN254_c11_y) + 0n :MLOAD(expCycloFp12BN254_c12_x) + 0n :MLOAD(expCycloFp12BN254_c12_y) + 0n :MLOAD(expCycloFp12BN254_c13_x) + 0n :MLOAD(expCycloFp12BN254_c13_y) + 0n :MLOAD(expCycloFp12BN254_c21_x) + 0n :MLOAD(expCycloFp12BN254_c21_y) + 0n :MLOAD(expCycloFp12BN254_c22_x) + 0n :MLOAD(expCycloFp12BN254_c22_y) + 0n :MLOAD(expCycloFp12BN254_c23_x) + 0n :MLOAD(expCycloFp12BN254_c23_y) + + 0n :MSTORE(expCycloFp12BN254_e) + 1n :MSTORE(expCycloFp12BN254_a11_x) + 0n :MSTORE(expCycloFp12BN254_a11_y) + 0n :MSTORE(expCycloFp12BN254_a12_x) + 0n :MSTORE(expCycloFp12BN254_a12_y) + 0n :MSTORE(expCycloFp12BN254_a13_x) + 0n :MSTORE(expCycloFp12BN254_a13_y) + 0n :MSTORE(expCycloFp12BN254_a21_x) + 0n :MSTORE(expCycloFp12BN254_a21_y) + 0n :MSTORE(expCycloFp12BN254_a22_x) + 0n :MSTORE(expCycloFp12BN254_a22_y) + 0n :MSTORE(expCycloFp12BN254_a23_x) + 0n :MSTORE(expCycloFp12BN254_a23_y) :CALL(expCycloFp12BN254) - 1n :MLOAD(expCycloFp12BN254_c11_x) - 0n :MLOAD(expCycloFp12BN254_c11_y) - 0n :MLOAD(expCycloFp12BN254_c12_x) - 0n :MLOAD(expCycloFp12BN254_c12_y) - 0n :MLOAD(expCycloFp12BN254_c13_x) - 0n :MLOAD(expCycloFp12BN254_c13_y) - 0n :MLOAD(expCycloFp12BN254_c21_x) - 0n :MLOAD(expCycloFp12BN254_c21_y) - 0n :MLOAD(expCycloFp12BN254_c22_x) - 0n :MLOAD(expCycloFp12BN254_c22_y) - 0n :MLOAD(expCycloFp12BN254_c23_x) - 0n :MLOAD(expCycloFp12BN254_c23_y) + 1n :MLOAD(expCycloFp12BN254_c11_x) + 0n :MLOAD(expCycloFp12BN254_c11_y) + 0n :MLOAD(expCycloFp12BN254_c12_x) + 0n :MLOAD(expCycloFp12BN254_c12_y) + 0n :MLOAD(expCycloFp12BN254_c13_x) + 0n :MLOAD(expCycloFp12BN254_c13_y) + 0n :MLOAD(expCycloFp12BN254_c21_x) + 0n :MLOAD(expCycloFp12BN254_c21_y) + 0n :MLOAD(expCycloFp12BN254_c22_x) + 0n :MLOAD(expCycloFp12BN254_c22_y) + 0n :MLOAD(expCycloFp12BN254_c23_x) + 0n :MLOAD(expCycloFp12BN254_c23_y) 4965661367192848881n :MSTORE(expCycloFp12BN254_e) 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expCycloFp12BN254_a11_x) @@ -286,57 +305,57 @@ start: 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expCycloFp12BN254_c23_y) ; 5] Exponentiation by x - 0n :MSTORE(expByXCycloFp12BN254_a11_x) - 0n :MSTORE(expByXCycloFp12BN254_a11_y) - 0n :MSTORE(expByXCycloFp12BN254_a12_x) - 0n :MSTORE(expByXCycloFp12BN254_a12_y) - 0n :MSTORE(expByXCycloFp12BN254_a13_x) - 0n :MSTORE(expByXCycloFp12BN254_a13_y) - 0n :MSTORE(expByXCycloFp12BN254_a21_x) - 0n :MSTORE(expByXCycloFp12BN254_a21_y) - 0n :MSTORE(expByXCycloFp12BN254_a22_x) - 0n :MSTORE(expByXCycloFp12BN254_a22_y) - 0n :MSTORE(expByXCycloFp12BN254_a23_x) - 0n :MSTORE(expByXCycloFp12BN254_a23_y) + 0n :MSTORE(expByXCycloFp12BN254_a11_x) + 0n :MSTORE(expByXCycloFp12BN254_a11_y) + 0n :MSTORE(expByXCycloFp12BN254_a12_x) + 0n :MSTORE(expByXCycloFp12BN254_a12_y) + 0n :MSTORE(expByXCycloFp12BN254_a13_x) + 0n :MSTORE(expByXCycloFp12BN254_a13_y) + 0n :MSTORE(expByXCycloFp12BN254_a21_x) + 0n :MSTORE(expByXCycloFp12BN254_a21_y) + 0n :MSTORE(expByXCycloFp12BN254_a22_x) + 0n :MSTORE(expByXCycloFp12BN254_a22_y) + 0n :MSTORE(expByXCycloFp12BN254_a23_x) + 0n :MSTORE(expByXCycloFp12BN254_a23_y) :CALL(expByXCycloFp12BN254) - 0n :MLOAD(expByXCycloFp12BN254_c11_x) - 0n :MLOAD(expByXCycloFp12BN254_c11_y) - 0n :MLOAD(expByXCycloFp12BN254_c12_x) - 0n :MLOAD(expByXCycloFp12BN254_c12_y) - 0n :MLOAD(expByXCycloFp12BN254_c13_x) - 0n :MLOAD(expByXCycloFp12BN254_c13_y) - 0n :MLOAD(expByXCycloFp12BN254_c21_x) - 0n :MLOAD(expByXCycloFp12BN254_c21_y) - 0n :MLOAD(expByXCycloFp12BN254_c22_x) - 0n :MLOAD(expByXCycloFp12BN254_c22_y) - 0n :MLOAD(expByXCycloFp12BN254_c23_x) - 0n :MLOAD(expByXCycloFp12BN254_c23_y) - - 1n :MSTORE(expByXCycloFp12BN254_a11_x) - 0n :MSTORE(expByXCycloFp12BN254_a11_y) - 0n :MSTORE(expByXCycloFp12BN254_a12_x) - 0n :MSTORE(expByXCycloFp12BN254_a12_y) - 0n :MSTORE(expByXCycloFp12BN254_a13_x) - 0n :MSTORE(expByXCycloFp12BN254_a13_y) - 0n :MSTORE(expByXCycloFp12BN254_a21_x) - 0n :MSTORE(expByXCycloFp12BN254_a21_y) - 0n :MSTORE(expByXCycloFp12BN254_a22_x) - 0n :MSTORE(expByXCycloFp12BN254_a22_y) - 0n :MSTORE(expByXCycloFp12BN254_a23_x) - 0n :MSTORE(expByXCycloFp12BN254_a23_y) + 0n :MLOAD(expByXCycloFp12BN254_c11_x) + 0n :MLOAD(expByXCycloFp12BN254_c11_y) + 0n :MLOAD(expByXCycloFp12BN254_c12_x) + 0n :MLOAD(expByXCycloFp12BN254_c12_y) + 0n :MLOAD(expByXCycloFp12BN254_c13_x) + 0n :MLOAD(expByXCycloFp12BN254_c13_y) + 0n :MLOAD(expByXCycloFp12BN254_c21_x) + 0n :MLOAD(expByXCycloFp12BN254_c21_y) + 0n :MLOAD(expByXCycloFp12BN254_c22_x) + 0n :MLOAD(expByXCycloFp12BN254_c22_y) + 0n :MLOAD(expByXCycloFp12BN254_c23_x) + 0n :MLOAD(expByXCycloFp12BN254_c23_y) + + 1n :MSTORE(expByXCycloFp12BN254_a11_x) + 0n :MSTORE(expByXCycloFp12BN254_a11_y) + 0n :MSTORE(expByXCycloFp12BN254_a12_x) + 0n :MSTORE(expByXCycloFp12BN254_a12_y) + 0n :MSTORE(expByXCycloFp12BN254_a13_x) + 0n :MSTORE(expByXCycloFp12BN254_a13_y) + 0n :MSTORE(expByXCycloFp12BN254_a21_x) + 0n :MSTORE(expByXCycloFp12BN254_a21_y) + 0n :MSTORE(expByXCycloFp12BN254_a22_x) + 0n :MSTORE(expByXCycloFp12BN254_a22_y) + 0n :MSTORE(expByXCycloFp12BN254_a23_x) + 0n :MSTORE(expByXCycloFp12BN254_a23_y) :CALL(expByXCycloFp12BN254) - 1n :MLOAD(expByXCycloFp12BN254_c11_x) - 0n :MLOAD(expByXCycloFp12BN254_c11_y) - 0n :MLOAD(expByXCycloFp12BN254_c12_x) - 0n :MLOAD(expByXCycloFp12BN254_c12_y) - 0n :MLOAD(expByXCycloFp12BN254_c13_x) - 0n :MLOAD(expByXCycloFp12BN254_c13_y) - 0n :MLOAD(expByXCycloFp12BN254_c21_x) - 0n :MLOAD(expByXCycloFp12BN254_c21_y) - 0n :MLOAD(expByXCycloFp12BN254_c22_x) - 0n :MLOAD(expByXCycloFp12BN254_c22_y) - 0n :MLOAD(expByXCycloFp12BN254_c23_x) - 0n :MLOAD(expByXCycloFp12BN254_c23_y) + 1n :MLOAD(expByXCycloFp12BN254_c11_x) + 0n :MLOAD(expByXCycloFp12BN254_c11_y) + 0n :MLOAD(expByXCycloFp12BN254_c12_x) + 0n :MLOAD(expByXCycloFp12BN254_c12_y) + 0n :MLOAD(expByXCycloFp12BN254_c13_x) + 0n :MLOAD(expByXCycloFp12BN254_c13_y) + 0n :MLOAD(expByXCycloFp12BN254_c21_x) + 0n :MLOAD(expByXCycloFp12BN254_c21_y) + 0n :MLOAD(expByXCycloFp12BN254_c22_x) + 0n :MLOAD(expByXCycloFp12BN254_c22_y) + 0n :MLOAD(expByXCycloFp12BN254_c23_x) + 0n :MLOAD(expByXCycloFp12BN254_c23_y) 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expByXCycloFp12BN254_a11_x) 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expByXCycloFp12BN254_a11_y) @@ -366,57 +385,57 @@ start: ; 6] Exponentiation by x using the compression/decompression technique - 0n :MSTORE(expByXCompCycloFp12BN254_a0_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a0_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a2_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a2_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a4_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a4_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a1_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a1_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a3_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a3_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a5_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a5_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a0_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a0_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_y) :CALL(expByXCompCycloFp12BN254) - 0n :MLOAD(expByXCompCycloFp12BN254_c0_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c0_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c2_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c2_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c4_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c4_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c1_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c1_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c3_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c3_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c5_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c5_y) - - 1n :MSTORE(expByXCompCycloFp12BN254_a0_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a0_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a2_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a2_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a4_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a4_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a1_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a1_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a3_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a3_y) - 0n :MSTORE(expByXCompCycloFp12BN254_a5_x) - 0n :MSTORE(expByXCompCycloFp12BN254_a5_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c0_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c0_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_y) + + 1n :MSTORE(expByXCompCycloFp12BN254_a0_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a0_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a2_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a4_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a1_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a3_y) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_x) + 0n :MSTORE(expByXCompCycloFp12BN254_a5_y) :CALL(expByXCompCycloFp12BN254) - 1n :MLOAD(expByXCompCycloFp12BN254_c0_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c0_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c2_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c2_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c4_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c4_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c1_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c1_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c3_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c3_y) - 0n :MLOAD(expByXCompCycloFp12BN254_c5_x) - 0n :MLOAD(expByXCompCycloFp12BN254_c5_y) + 1n :MLOAD(expByXCompCycloFp12BN254_c0_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c0_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c2_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c4_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c1_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c3_y) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_x) + 0n :MLOAD(expByXCompCycloFp12BN254_c5_y) 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expByXCompCycloFp12BN254_a0_x) 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expByXCompCycloFp12BN254_a0_y) diff --git a/test/testEcAdd.zkasm b/test/testEcAdd.zkasm index e4ba1d6f..20d75426 100644 --- a/test/testEcAdd.zkasm +++ b/test/testEcAdd.zkasm @@ -54,170 +54,166 @@ start: -1 :MSTORE(lastHashPId) ; 1] 0 + 0 = 0 - 0n :MSTORE(ecAdd_P1_x) - 0n :MSTORE(ecAdd_P1_y) - 0n :MSTORE(ecAdd_P2_x) - 0n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 0n :MLOAD(ecAdd_P3_x) - 0n :MLOAD(ecAdd_P3_y) + 0n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 0n :MLOAD(ecAdd_P3_x) + 0n :MLOAD(ecAdd_P3_y) ; 2] 0 + P = P - 0n :MSTORE(ecAdd_P1_x) - 0n :MSTORE(ecAdd_P1_y) - 1n :MSTORE(ecAdd_P2_x) - 2n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 1n :MLOAD(ecAdd_P3_x) - 2n :MLOAD(ecAdd_P3_y) + 0n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 2n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 1n :MLOAD(ecAdd_P3_x) + 2n :MLOAD(ecAdd_P3_y) ; 3] P + 0 = P - 1n :MSTORE(ecAdd_P1_x) - 2n :MSTORE(ecAdd_P1_y) - 0n :MSTORE(ecAdd_P2_x) - 0n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 1n :MLOAD(ecAdd_P3_x) - 2n :MLOAD(ecAdd_P3_y) + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 1n :MLOAD(ecAdd_P3_x) + 2n :MLOAD(ecAdd_P3_y) ; 4] P1 not in range - 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecAdd_P1_x) - 2n :MSTORE(ecAdd_P1_y) - 3n :MSTORE(ecAdd_P2_x) - 3n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 3n :MSTORE(ecAdd_P2_x) + 3n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 1 => A - 1 :EQ + 1 :EQ - 1n :MSTORE(ecAdd_P1_x) - 21888242871839275222246405745257275088696311157297823662689037894645226208585n :MSTORE(ecAdd_P1_y) - 3n :MSTORE(ecAdd_P2_x) - 3n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 1n :MSTORE(ecAdd_P1_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208585n :MSTORE(ecAdd_P1_y) + 3n :MSTORE(ecAdd_P2_x) + 3n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 2 => A - 1 :EQ + 1 :EQ ; 5] P2 not in range - 1n :MSTORE(ecAdd_P1_x) - 2n :MSTORE(ecAdd_P1_y) - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecAdd_P2_x) - 0n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 3 => A - 1 :EQ + 1 :EQ - 1n :MSTORE(ecAdd_P1_x) - 2n :MSTORE(ecAdd_P1_y) - 0n :MSTORE(ecAdd_P2_x) - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 4 => A - 1 :EQ + 1 :EQ ; 6] P1 not in E - 1n :MSTORE(ecAdd_P1_x) - 0n :MSTORE(ecAdd_P1_y) - 0n :MSTORE(ecAdd_P2_x) - 0n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 1n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 0n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 5 => A - 1 :EQ + 1 :EQ - 1n :MSTORE(ecAdd_P1_x) - 0n :MSTORE(ecAdd_P1_y) - 1n :MSTORE(ecAdd_P2_x) - 2n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 1n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 2n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 5 => A - 1 :EQ + 1 :EQ ; 7] P2 not in E - 0n :MSTORE(ecAdd_P1_x) - 0n :MSTORE(ecAdd_P1_y) - 1n :MSTORE(ecAdd_P2_x) - 0n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 0n :MSTORE(ecAdd_P1_x) + 0n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 6 => A - 1 :EQ + 1 :EQ - 1n :MSTORE(ecAdd_P1_x) - 2n :MSTORE(ecAdd_P1_y) - 1n :MSTORE(ecAdd_P2_x) - 0n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) + 1n :MSTORE(ecAdd_P1_x) + 2n :MSTORE(ecAdd_P1_y) + 1n :MSTORE(ecAdd_P2_x) + 0n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) 6 => A - 1 :EQ + 1 :EQ ; 8] P + (-P) = 0 - 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P1_x) - 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P1_y) - 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) - 21039565435327757486054843320102702720990930294403178719740356721829973864651n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 0n :MLOAD(ecAdd_P3_x) - 0n :MLOAD(ecAdd_P3_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P1_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P1_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) + 21039565435327757486054843320102702720990930294403178719740356721829973864651n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 0n :MLOAD(ecAdd_P3_x) + 0n :MLOAD(ecAdd_P3_y) ; 9] P + Q when P != Q - 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) - 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) - 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P2_x) - 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 13154776318592227270778558029295227935378730842313609923118896637591559850250n :MLOAD(ecAdd_P3_x) - 11035980320923476543935377623718958678920911311849399323950347759358969041431n :MLOAD(ecAdd_P3_y) - - 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P1_x) - 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P1_y) - 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) - 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 20109137777308224484751705964830245061785572657602899297228633767392913518415n :MLOAD(ecAdd_P3_x) - 14499175368639637950478596677291617168262069295802020711454610174461584835979n :MLOAD(ecAdd_P3_y) + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) + 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P2_x) + 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 13154776318592227270778558029295227935378730842313609923118896637591559850250n :MLOAD(ecAdd_P3_x) + 11035980320923476543935377623718958678920911311849399323950347759358969041431n :MLOAD(ecAdd_P3_y) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P1_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P1_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 20109137777308224484751705964830245061785572657602899297228633767392913518415n :MLOAD(ecAdd_P3_x) + 14499175368639637950478596677291617168262069295802020711454610174461584835979n :MLOAD(ecAdd_P3_y) ; 10] P + P - 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) - 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) - 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P2_x) - 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 11220622501868821308995844886766009822833441579384302982823096531245924405698n :MLOAD(ecAdd_P3_x) - 2355690023525969090855462437460037724073976772193253577110863269987724684477n :MLOAD(ecAdd_P3_y) - - 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P1_x) - 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P1_y) - 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P2_x) - 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 14301632400969957113316344359548233118734763289927867040319376723985850943059n :MLOAD(ecAdd_P3_x) - 19259402839901377893267670172732143592044261932601111690978918426524987173751n :MLOAD(ecAdd_P3_y) - - 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P1_x) - 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P1_y) - 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P2_x) - 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 7635241416710394435863784018619353890364763495262225661273147225960091861733n :MLOAD(ecAdd_P3_x) - 21716464559528323959695889215160185865818678200951896286120725092340748527691n :MLOAD(ecAdd_P3_y) - - 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P1_x) - 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P1_y) - 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) - 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 4444740815889402603535294170722302758225367627362056425101568584910268024244n :MLOAD(ecAdd_P3_x) - 10537263096529483164618820017164668921386457028564663708352735080900270541420n :MLOAD(ecAdd_P3_y) - - ; 10] Worst case scenario in terms of ARITH calls and therefore in terms of number of steps + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P2_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 11220622501868821308995844886766009822833441579384302982823096531245924405698n :MLOAD(ecAdd_P3_x) + 2355690023525969090855462437460037724073976772193253577110863269987724684477n :MLOAD(ecAdd_P3_y) + 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P1_x) + 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P1_y) + 15490799329273967747501973647822742581714860109251269127154113506193693607878n :MSTORE(ecAdd_P2_x) + 4229358293223510599397432508631487048670295788986070026939193461742686527076n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 14301632400969957113316344359548233118734763289927867040319376723985850943059n :MLOAD(ecAdd_P3_x) + 19259402839901377893267670172732143592044261932601111690978918426524987173751n :MLOAD(ecAdd_P3_y) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P1_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P1_y) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecAdd_P2_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 7635241416710394435863784018619353890364763495262225661273147225960091861733n :MLOAD(ecAdd_P3_x) + 21716464559528323959695889215160185865818678200951896286120725092340748527691n :MLOAD(ecAdd_P3_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P1_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P1_y) + 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) + 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 4444740815889402603535294170722302758225367627362056425101568584910268024244n :MLOAD(ecAdd_P3_x) + 10537263096529483164618820017164668921386457028564663708352735080900270541420n :MLOAD(ecAdd_P3_y) + + ; 11] Worst case scenario in terms of ARITH calls and therefore in terms of number of steps ; In this case, we only need to perform a doubling, since the cost of ecAdd is constant ; on its input and doubling strictly dominates addition in terms of cost. - 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) - 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) - 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P2_x) - 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P2_y) - :CALL(ecAdd) - 11220622501868821308995844886766009822833441579384302982823096531245924405698n :MLOAD(ecAdd_P3_x) - 2355690023525969090855462437460037724073976772193253577110863269987724684477n :MLOAD(ecAdd_P3_y) + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P1_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P1_y) + 2893332206675025542079383054128180540025417352513932043566889211329192179032n :MSTORE(ecAdd_P2_x) + 6530629491743359417280396166892081514007566149119717903717756741482263401518n :MSTORE(ecAdd_P2_y) + :CALL(ecAdd) + 11220622501868821308995844886766009822833441579384302982823096531245924405698n :MLOAD(ecAdd_P3_x) + 2355690023525969090855462437460037724073976772193253577110863269987724684477n :MLOAD(ecAdd_P3_y) end: diff --git a/test/testEcMul.zkasm b/test/testEcMul.zkasm index ff60e89b..992b61fc 100644 --- a/test/testEcMul.zkasm +++ b/test/testEcMul.zkasm @@ -55,146 +55,140 @@ start: -1 :MSTORE(lastHashPId) ; 1] 0·O = O - 0n :MSTORE(ecMul_k) - 0n :MSTORE(ecMul_P_x) - 0n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 0n :MLOAD(ecMul_Q_x) - 0n :MLOAD(ecMul_Q_y) + 0n :MSTORE(ecMul_k) + 0n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) ; 2] k·O = O - 5n :MSTORE(ecMul_k) - 0n :MSTORE(ecMul_P_x) - 0n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 0n :MLOAD(ecMul_Q_x) - 0n :MLOAD(ecMul_Q_y) + 5n :MSTORE(ecMul_k) + 0n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) ; 3] 0·P = O, where P != O - 0n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 0n :MLOAD(ecMul_Q_x) - 0n :MLOAD(ecMul_Q_y) + 0n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) ; 4] P not in range - 0n :MSTORE(ecMul_k) - 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) + 0n :MSTORE(ecMul_k) + 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) 1 => A - 1 :EQ + 1 :EQ - 0n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 21888242871839275222246405745257275088696311157297823662689037894645226208585n :MSTORE(ecMul_P_y) - :CALL(ecMul) + 0n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208585n :MSTORE(ecMul_P_y) + :CALL(ecMul) 2 => A - 1 :EQ + 1 :EQ ; 5] P not in E - 0n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 0n :MSTORE(ecMul_P_y) - :CALL(ecMul) + 0n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) 3 => A - 1 :EQ + 1 :EQ - 65n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 0n :MSTORE(ecMul_P_y) - :CALL(ecMul) + 65n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 0n :MSTORE(ecMul_P_y) + :CALL(ecMul) 3 => A - 1 :EQ + 1 :EQ ; 6] k·P when k != 0 - 1n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 1n :MLOAD(ecMul_Q_x) - 2n :MLOAD(ecMul_Q_y) - - 2n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MLOAD(ecMul_Q_x) - 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MLOAD(ecMul_Q_y) - - 65n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 21184532036463169063041779836861514142873086093180850953095098556309204188255n :MLOAD(ecMul_Q_x) - 16870949628445799017882714788639508275834535486794531840392367353784571921174n :MLOAD(ecMul_Q_y) - - 10000000089n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 4768044760451824005417871472283223457728569810854115125480649095031772328870n :MLOAD(ecMul_Q_x) - 21389337952468851259287213083493638952853622949895525580347877121675081015727n :MLOAD(ecMul_Q_y) - - 57n :MSTORE(ecMul_k) - 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) - 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 21092868577100313210583214784627729175513062432513303686654820611840644382013n :MLOAD(ecMul_Q_x) - 10293123368529248350591404721829100625076077203595282162629899903703630633665n :MLOAD(ecMul_Q_y) - - 123456789n :MSTORE(ecMul_k) - 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) - 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 9551410454255481932113938269904288675272239827491596157984458647610565008967n :MLOAD(ecMul_Q_x) - 17781856861347070862134441477208204792978952663354273425763774350233183876915n :MLOAD(ecMul_Q_y) - - 21888242871839275222246405745257275088548364400416034343698204186575808495617n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 0n :MLOAD(ecMul_Q_x) - 0n :MLOAD(ecMul_Q_y) - - 21888242871839275222246405745257275088548364400416034343698204186575808495618n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 1n :MLOAD(ecMul_Q_x) - 2n :MLOAD(ecMul_Q_y) - - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 7793429943220682609834519115512946233910458086191548249060013461061457526887n :MLOAD(ecMul_Q_x) - 16460968250425543446028981775631045522280113359306664586749259656855967130574n :MLOAD(ecMul_Q_y) - - 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 15886422571275617715400903250697722692198979607302343556925904858625057687404n :MLOAD(ecMul_Q_x) - 9788557113822741943783365060165103517008620829146475047263378292709661309554n :MLOAD(ecMul_Q_y) - - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 21415159568991615317144600033915305503576371596506956373206836402282692989778n :MLOAD(ecMul_Q_x) - 8573070896319864868535933562264623076420652926303237982078693068147657243287n :MLOAD(ecMul_Q_y) + 1n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 1n :MLOAD(ecMul_Q_x) + 2n :MLOAD(ecMul_Q_y) + + 2n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MLOAD(ecMul_Q_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MLOAD(ecMul_Q_y) + 65n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 21184532036463169063041779836861514142873086093180850953095098556309204188255n :MLOAD(ecMul_Q_x) + 16870949628445799017882714788639508275834535486794531840392367353784571921174n :MLOAD(ecMul_Q_y) + 10000000089n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 4768044760451824005417871472283223457728569810854115125480649095031772328870n :MLOAD(ecMul_Q_x) + 21389337952468851259287213083493638952853622949895525580347877121675081015727n :MLOAD(ecMul_Q_y) + 57n :MSTORE(ecMul_k) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 21092868577100313210583214784627729175513062432513303686654820611840644382013n :MLOAD(ecMul_Q_x) + 10293123368529248350591404721829100625076077203595282162629899903703630633665n :MLOAD(ecMul_Q_y) + 123456789n :MSTORE(ecMul_k) + 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) + 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 9551410454255481932113938269904288675272239827491596157984458647610565008967n :MLOAD(ecMul_Q_x) + 17781856861347070862134441477208204792978952663354273425763774350233183876915n :MLOAD(ecMul_Q_y) + 21888242871839275222246405745257275088548364400416034343698204186575808495617n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 0n :MLOAD(ecMul_Q_x) + 0n :MLOAD(ecMul_Q_y) + + 21888242871839275222246405745257275088548364400416034343698204186575808495618n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 1n :MLOAD(ecMul_Q_x) + 2n :MLOAD(ecMul_Q_y) + + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 7793429943220682609834519115512946233910458086191548249060013461061457526887n :MLOAD(ecMul_Q_x) + 16460968250425543446028981775631045522280113359306664586749259656855967130574n :MLOAD(ecMul_Q_y) + + 21888242871839275222246405745257275088696311157297823662689037894645226208584n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 15886422571275617715400903250697722692198979607302343556925904858625057687404n :MLOAD(ecMul_Q_x) + 9788557113822741943783365060165103517008620829146475047263378292709661309554n :MLOAD(ecMul_Q_y) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 21415159568991615317144600033915305503576371596506956373206836402282692989778n :MLOAD(ecMul_Q_x) + 8573070896319864868535933562264623076420652926303237982078693068147657243287n :MLOAD(ecMul_Q_y) ; 7] Worst case scenario in terms of ARITH calls and therefore in terms of number of steps. ; In ecMul, this should be the scalar multiplication with scalar with higer Hamming weight ; that is lower than r, which in this case is 2^253 - 1. - 14474011154664524427946373126085988481658748083205070504932198000989141204991n :MSTORE(ecMul_k) - 1n :MSTORE(ecMul_P_x) - 2n :MSTORE(ecMul_P_y) - :CALL(ecMul) - 3739418567393436576913511739065691570763034865122368432616000129799288055432n :MLOAD(ecMul_Q_x) - 18298856760603404171434473181920219106007178146585940397845192637485681860518n :MLOAD(ecMul_Q_y) + 14474011154664524427946373126085988481658748083205070504932198000989141204991n :MSTORE(ecMul_k) + 1n :MSTORE(ecMul_P_x) + 2n :MSTORE(ecMul_P_y) + :CALL(ecMul) + 3739418567393436576913511739065691570763034865122368432616000129799288055432n :MLOAD(ecMul_Q_x) + 18298856760603404171434473181920219106007178146585940397845192637485681860518n :MLOAD(ecMul_Q_y) end: diff --git a/test/testEcPairing.zkasm b/test/testEcPairing.zkasm index eacd279b..a29a5be1 100644 --- a/test/testEcPairing.zkasm +++ b/test/testEcPairing.zkasm @@ -1,4 +1,4 @@ -; constants needed by executor C++ // TODO +; constants needed by executor C++ CONST %N = 2**19 ;CONST %MAX_CNT_STEPS_LIMIT = %N ;CONST %MAX_CNT_ARITH_LIMIT = %N @@ -26,10 +26,8 @@ VAR GLOBAL initial_HASHPOS VAR GLOBAL initial_RCX start: - STEP => A - 0 :ASSERT - + 0 :ASSERT A :MSTORE(initial_A) B :MSTORE(initial_B) @@ -49,382 +47,360 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; 1] Tests with 6 inputs - ; 1.1] Fails and returns nothing if the input is invalid - ;0n :MSTORE(ecPairing6_P_x) - ;1n :MSTORE(ecPairing6_P_y) - ;4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(ecPairing6_Q_x1) - ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) - ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) - ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;0n :MSTORE(ecPairing6_P_x) - ;0n :MSTORE(ecPairing6_P_y) - ;4351401811647638138392695977895401859084096897123577305203754529537814663108n :MSTORE(ecPairing6_Q_x1) - ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) - ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) - ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;1n :MSTORE(ecPairing6_P_x) - ;2n :MSTORE(ecPairing6_P_y) - ;4351401811647638138392695977895401859084096897123577305203754529537814663108n :MSTORE(ecPairing6_Q_x1) - ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) - ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) - ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;1n :MSTORE(ecPairing6_P_x) - ;1n :MSTORE(ecPairing6_P_y) - ;0n :MSTORE(ecPairing6_Q_x1) - ;0n :MSTORE(ecPairing6_Q_x2) - ;0n :MSTORE(ecPairing6_Q_y1) - ;0n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;; 1.1] Fails if some input is not in range - ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_P_x) - ;1n :MSTORE(ecPairing6_P_y) - ;0n :MSTORE(ecPairing6_Q_x1) - ;0n :MSTORE(ecPairing6_Q_x2) - ;0n :MSTORE(ecPairing6_Q_y1) - ;0n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;1n :MSTORE(ecPairing6_P_x) - ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_P_y) - ;0n :MSTORE(ecPairing6_Q_x1) - ;0n :MSTORE(ecPairing6_Q_x2) - ;0n :MSTORE(ecPairing6_Q_y1) - ;0n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;1n :MSTORE(ecPairing6_P_x) - ;2n :MSTORE(ecPairing6_P_y) - ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_x1) - ;0n :MSTORE(ecPairing6_Q_x2) - ;0n :MSTORE(ecPairing6_Q_y1) - ;0n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;1n :MSTORE(ecPairing6_P_x) - ;2n :MSTORE(ecPairing6_P_y) - ;0n :MSTORE(ecPairing6_Q_x1) - ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_x2) - ;0n :MSTORE(ecPairing6_Q_y1) - ;0n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;1n :MSTORE(ecPairing6_P_x) - ;2n :MSTORE(ecPairing6_P_y) - ;0n :MSTORE(ecPairing6_Q_x1) - ;0n :MSTORE(ecPairing6_Q_x2) - ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_y1) - ;0n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;1n :MSTORE(ecPairing6_P_x) - ;2n :MSTORE(ecPairing6_P_y) - ;0n :MSTORE(ecPairing6_Q_x1) - ;0n :MSTORE(ecPairing6_Q_x2) - ;0n :MSTORE(ecPairing6_Q_y1) - ;21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 => A - ;B :ASSERT -; - ;; 1.2] Degenerate tests: e(0,Q) = 1 and e(P,0) = 1 therefore the pairing equation is trivally satisfied - ;; and in fact this is the only possibility for the pairing equation to be satisfied with one pair of P,Q - ;0n :MSTORE(ecPairing6_P_x) - ;0n :MSTORE(ecPairing6_P_y) - ;4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(ecPairing6_Q_x1) - ;2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(ecPairing6_Q_x2) - ;322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(ecPairing6_Q_y1) - ;14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 :MLOAD(ecPairing6_result) -; - ;1n :MSTORE(ecPairing6_P_x) - ;2n :MSTORE(ecPairing6_P_y) - ;0n :MSTORE(ecPairing6_Q_x1) - ;0n :MSTORE(ecPairing6_Q_x2) - ;0n :MSTORE(ecPairing6_Q_y1) - ;0n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 :MLOAD(ecPairing6_result) -; - ;0n :MSTORE(ecPairing6_P_x) - ;0n :MSTORE(ecPairing6_P_y) - ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing6_Q_x1) - ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing6_Q_x2) - ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing6_Q_y1) - ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing6_Q_y2) - ; :CALL(ecPairing6) - ;1 :MLOAD(ecPairing6_result) -; - ;; 2] Tests with 12 inputs -; - ;; Ethereum example - ;20333349487611174579608837001148061570648440167819460274134014152400656275674n :MSTORE(ecPairing12_P1_x) - ;19928268888036365434500215951569291213336085054454884806456691094014419998198n :MSTORE(ecPairing12_P1_y) - ;15548973838770842196102442698708122006189018193868154757846481038796366125273n :MSTORE(ecPairing12_Q1_x1) - ;14335504872549532354210489828671972911333347940534076142795111812609903378108n :MSTORE(ecPairing12_Q1_x2) - ;21654797034782659092642090020723114658730107139270194997413654453096686856286n :MSTORE(ecPairing12_Q1_y1) - ;19822981108166058814837087071162475941148726886187076297764129491697321004944n :MSTORE(ecPairing12_Q1_y2) - ;1n :MSTORE(ecPairing12_P2_x) - ;21888242871839275222246405745257275088696311157297823662689037894645226208581n :MSTORE(ecPairing12_P2_y) - ;4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(ecPairing12_Q2_x1) - ;11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(ecPairing12_Q2_x2) - ;16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(ecPairing12_Q2_y1) - ;19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(ecPairing12_Q2_y2) - ; :CALL(ecPairing12) - ;1 :MLOAD(ecPairing12_result) -; - ;; KZG proof with one poly and one evaluation - ;20593188969319011263398594823255811823444990825298196162496264072013322991388n :MSTORE(ecPairing12_P1_x) - ;20958531318718262179638310844977035402258325676941759254411716094948903283238n :MSTORE(ecPairing12_P1_y) - ;4011274991290276638756079424799286249285264639232842260296401218902340006571n :MSTORE(ecPairing12_Q1_x1) - ;19014538453489502551198430834271851224745298622671277274539119640314913863353n :MSTORE(ecPairing12_Q1_x2) - ;18471742500483808444303896273620229467289887099913869033627754256214290219997n :MSTORE(ecPairing12_Q1_y1) - ;5493217260886730300768636259682920882409386426126823957476482234761131640151n :MSTORE(ecPairing12_Q1_y2) - ;3526892542800189419786189901545486150149308978725362430328886936745555020543n :MSTORE(ecPairing12_P2_x) - ;2119286186166371280112264238015778473404141003919064027522145193839708208181n :MSTORE(ecPairing12_P2_y) - ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing12_Q2_x1) - ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing12_Q2_x2) - ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing12_Q2_y1) - ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing12_Q2_y2) - ; :CALL(ecPairing12) - ;1 :MLOAD(ecPairing12_result) -; - ;; KZG proof with one poly and one evaluation - ;7732322222446307127032679746925673403013840763103947213960757438494804067267n :MSTORE(ecPairing12_P1_x) - ;8619360092012773279112944586645719683585858765189162557863470404130431808723n :MSTORE(ecPairing12_P1_y) - ;4480687189204505779534873101802061566996023148878380905742776654135663383221n :MSTORE(ecPairing12_Q1_x1) - ;7754062701624777074058760614745676120554164137217320298195308357000412149840n :MSTORE(ecPairing12_Q1_x2) - ;16667361185745910936700318129097219900413959552154798924397125501722669434888n :MSTORE(ecPairing12_Q1_y1) - ;18744429014512523574338799100424477374744612401726532054975840530120472566n :MSTORE(ecPairing12_Q1_y2) - ;595801121933130257838893357109567932541713044978712091132608377833002940532n :MSTORE(ecPairing12_P2_x) - ;15681552092527426161541501125159206079106959026991100968107368848241580050483n :MSTORE(ecPairing12_P2_y) - ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing12_Q2_x1) - ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing12_Q2_x2) - ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing12_Q2_y1) - ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing12_Q2_y2) - ; :CALL(ecPairing12) - ;1 :MLOAD(ecPairing12_result) -; - ;; 3] Tests with 18 inputs -; - ;7732322222446307127032679746925673403013840763103947213960757438494804067267n :MSTORE(ecPairing18_P1_x) - ;8619360092012773279112944586645719683585858765189162557863470404130431808723n :MSTORE(ecPairing18_P1_y) - ;4480687189204505779534873101802061566996023148878380905742776654135663383221n :MSTORE(ecPairing18_Q1_x1) - ;7754062701624777074058760614745676120554164137217320298195308357000412149840n :MSTORE(ecPairing18_Q1_x2) - ;16667361185745910936700318129097219900413959552154798924397125501722669434888n :MSTORE(ecPairing18_Q1_y1) - ;18744429014512523574338799100424477374744612401726532054975840530120472566n :MSTORE(ecPairing18_Q1_y2) - ;595801121933130257838893357109567932541713044978712091132608377833002940532n :MSTORE(ecPairing18_P2_x) - ;15681552092527426161541501125159206079106959026991100968107368848241580050483n :MSTORE(ecPairing18_P2_y) - ;10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(ecPairing18_Q2_x1) - ;11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(ecPairing18_Q2_x2) - ;8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(ecPairing18_Q2_y1) - ;4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(ecPairing18_Q2_y2) - ;1n :MSTORE(ecPairing18_P3_x) - ;2n :MSTORE(ecPairing18_P3_y) - ;0n :MSTORE(ecPairing18_Q3_x1) - ;0n :MSTORE(ecPairing18_Q3_x2) - ;0n :MSTORE(ecPairing18_Q3_y1) - ;0n :MSTORE(ecPairing18_Q3_y2) - ; :CALL(ecPairing18) - ;1 :MLOAD(ecPairing18_result) -; -; - ;;======================================================================================= - ; Tests generic - ; 1] 0 inputs should return 1 - 0 :MSTORE(ecPairing_ninputs) - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) + 0 :MSTORE(ecPairing_ninputs) + :CALL(ecPairing) 0 => A - 1 :EQ + B :ASSERT + 1 :MLOAD(ecPairing_result) + + ; 2] Tests with 6 inputs + ; 2.1] Fails and returns nothing if the input is invalid + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 0n :MSTORE(MEM:E) + 1n :MSTORE(MEM:E + 1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(MEM:E + 2) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(MEM:E + 3) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(MEM:E + 4) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT - ; 2] 6 inputs should return 1 iff either P or Q is the identity - 1 :MSTORE(ecPairing_ninputs) - 32*6 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E + 1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(MEM:E + 2) + 4351401811647638138392695977895401859084096897123577305203754529537814663108n :MSTORE(MEM:E + 3) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(MEM:E + 4) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E - 1n :MSTORE(MEM:E) - 2n :MSTORE(MEM:E+1) - 0n :MSTORE(MEM:E+2) - 0n :MSTORE(MEM:E+3) - 0n :MSTORE(MEM:E+4) - 0n :MSTORE(MEM:E+5) + 1n :MSTORE(MEM:E) + 2n :MSTORE(MEM:E + 1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(MEM:E + 2) + 4351401811647638138392695977895401859084096897123577305203754529537814663108n :MSTORE(MEM:E + 3) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(MEM:E + 4) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) - 0 => A - 1 :EQ + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 1n :MSTORE(MEM:E) + 1n :MSTORE(MEM:E + 1) + 0n :MSTORE(MEM:E + 2) + 0n :MSTORE(MEM:E + 3) + 0n :MSTORE(MEM:E + 4) + 0n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT - 1 :MSTORE(ecPairing_ninputs) - 32*6 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E + 1) + 1n :MSTORE(MEM:E + 2) + 2n :MSTORE(MEM:E + 3) + 3n :MSTORE(MEM:E + 4) + 3n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT + ; 2.2] Fails if some input is not in range + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E - 0n :MSTORE(MEM:E) - 0n :MSTORE(MEM:E+1) - 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(MEM:E+2) - 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(MEM:E+3) - 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(MEM:E+4) - 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(MEM:E+5) - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) - 0 => A - 1 :EQ + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(MEM:E) + 1n :MSTORE(MEM:E + 1) + 0n :MSTORE(MEM:E + 2) + 0n :MSTORE(MEM:E + 3) + 0n :MSTORE(MEM:E + 4) + 0n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT - 1 :MSTORE(ecPairing_ninputs) - 32*6 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 1n :MSTORE(MEM:E) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(MEM:E + 1) + 0n :MSTORE(MEM:E + 2) + 0n :MSTORE(MEM:E + 3) + 0n :MSTORE(MEM:E + 4) + 0n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E - 0n :MSTORE(MEM:E) - 0n :MSTORE(MEM:E+1) - 11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(MEM:E+2) - 4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(MEM:E+3) - 19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(MEM:E+4) - 16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(MEM:E+5) - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) - 0 => A - 1 :EQ + 1n :MSTORE(MEM:E) + 2n :MSTORE(MEM:E + 1) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(MEM:E + 2) + 0n :MSTORE(MEM:E + 3) + 0n :MSTORE(MEM:E + 4) + 0n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT - ; The following should fail - 1 :MSTORE(ecPairing_ninputs) - 32*6 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 1n :MSTORE(MEM:E) + 2n :MSTORE(MEM:E + 1) + 0n :MSTORE(MEM:E + 2) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(MEM:E + 3) + 0n :MSTORE(MEM:E + 4) + 0n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT + + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 1n :MSTORE(MEM:E) + 2n :MSTORE(MEM:E + 1) + 0n :MSTORE(MEM:E + 2) + 0n :MSTORE(MEM:E + 3) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(MEM:E + 4) + 0n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 1 => A + B :ASSERT + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E - 0n :MSTORE(MEM:E) - 0n :MSTORE(MEM:E+1) - 1n :MSTORE(MEM:E+2) - 2n :MSTORE(MEM:E+3) - 3n :MSTORE(MEM:E+4) - 3n :MSTORE(MEM:E+5) - :CALL(ecPairing) + 1n :MSTORE(MEM:E) + 2n :MSTORE(MEM:E + 1) + 0n :MSTORE(MEM:E + 2) + 0n :MSTORE(MEM:E + 3) + 0n :MSTORE(MEM:E + 4) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(MEM:E + 5) + :CALL(ecPairing) 1 => A - 1 :EQ + B :ASSERT + + ; 2.3] Degenerate tests: e(0,Q) = 1 or e(P,0) = 1 therefore the pairing equation is trivally satisfied + ; and in fact this is the only possibility for the pairing equation to be satisfied with one pair of P,Q + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E + 1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(MEM:E + 2) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(MEM:E + 3) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(MEM:E + 4) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 0 => A + B :ASSERT + 1 :MLOAD(ecPairing_result) + + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 1n :MSTORE(MEM:E) + 2n :MSTORE(MEM:E + 1) + 0n :MSTORE(MEM:E + 2) + 0n :MSTORE(MEM:E + 3) + 0n :MSTORE(MEM:E + 4) + 0n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 0 => A + B :ASSERT + 1 :MLOAD(ecPairing_result) + + 1 :MSTORE(ecPairing_ninputs) + 32*6 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E + 1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E + 2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E + 3) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E + 4) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 0 => A + B :ASSERT + 1 :MLOAD(ecPairing_result) 1 :MSTORE(ecPairing_ninputs) 32*6 :MSTORE(txCalldataLen) -32 :MSTORE(readXFromCalldataOffset) 0 => E - 1n :MSTORE(MEM:E) - 1n :MSTORE(MEM:E+1) - 0n :MSTORE(MEM:E+2) - 0n :MSTORE(MEM:E+3) - 0n :MSTORE(MEM:E+4) - 0n :MSTORE(MEM:E+5) - :CALL(ecPairing) - 1 => A - 1 :EQ + 0n :MSTORE(MEM:E) + 0n :MSTORE(MEM:E + 1) + 11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(MEM:E + 2) + 4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(MEM:E + 3) + 19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(MEM:E + 4) + 16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(MEM:E + 5) + :CALL(ecPairing) + 0 => A + B :ASSERT + 1 :MLOAD(ecPairing_result) - ; 3] 12 inputs - 2 :MSTORE(ecPairing_ninputs) - 32*6*2 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + ; 3] Tests with 12 inputs + ; Ethereum example + 2 :MSTORE(ecPairing_ninputs) + 32*6*2 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E 20333349487611174579608837001148061570648440167819460274134014152400656275674n :MSTORE(MEM:E) - 19928268888036365434500215951569291213336085054454884806456691094014419998198n :MSTORE(MEM:E+1) - 14335504872549532354210489828671972911333347940534076142795111812609903378108n :MSTORE(MEM:E+2) - 15548973838770842196102442698708122006189018193868154757846481038796366125273n :MSTORE(MEM:E+3) - 19822981108166058814837087071162475941148726886187076297764129491697321004944n :MSTORE(MEM:E+4) - 21654797034782659092642090020723114658730107139270194997413654453096686856286n :MSTORE(MEM:E+5) - 1n :MSTORE(MEM:E+6) - 21888242871839275222246405745257275088696311157297823662689037894645226208581n :MSTORE(MEM:E+7) - 11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(MEM:E+8) - 4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(MEM:E+9) - 19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(MEM:E+10) - 16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(MEM:E+11) - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) + 19928268888036365434500215951569291213336085054454884806456691094014419998198n :MSTORE(MEM:E + 1) + 14335504872549532354210489828671972911333347940534076142795111812609903378108n :MSTORE(MEM:E + 2) + 15548973838770842196102442698708122006189018193868154757846481038796366125273n :MSTORE(MEM:E + 3) + 19822981108166058814837087071162475941148726886187076297764129491697321004944n :MSTORE(MEM:E + 4) + 21654797034782659092642090020723114658730107139270194997413654453096686856286n :MSTORE(MEM:E + 5) + 1n :MSTORE(MEM:E + 6) + 21888242871839275222246405745257275088696311157297823662689037894645226208581n :MSTORE(MEM:E + 7) + 11509234998032783125480266028213992619847908725038453197451386571405359529652n :MSTORE(MEM:E + 8) + 4099696940551850412667065443628214990719002449715926250279745743126938401735n :MSTORE(MEM:E + 9) + 19060191254988907833052035421850065496347936631097225966803157637464336346786n :MSTORE(MEM:E + 10) + 16129402215257578064845163124174157135534373400489420174780024516864802406908n :MSTORE(MEM:E + 11) + :CALL(ecPairing) 0 => A - 1 :EQ - - 2 :MSTORE(ecPairing_ninputs) - 32*6*2 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + B :ASSERT + 1 :MLOAD(ecPairing_result) + ; KZG proof with one poly and one evaluation + 2 :MSTORE(ecPairing_ninputs) + 32*6*2 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E 20593188969319011263398594823255811823444990825298196162496264072013322991388n :MSTORE(MEM:E) - 20958531318718262179638310844977035402258325676941759254411716094948903283238n :MSTORE(MEM:E+1) - 19014538453489502551198430834271851224745298622671277274539119640314913863353n :MSTORE(MEM:E+2) - 4011274991290276638756079424799286249285264639232842260296401218902340006571n :MSTORE(MEM:E+3) - 5493217260886730300768636259682920882409386426126823957476482234761131640151n :MSTORE(MEM:E+4) - 18471742500483808444303896273620229467289887099913869033627754256214290219997n :MSTORE(MEM:E+5) - 3526892542800189419786189901545486150149308978725362430328886936745555020543n :MSTORE(MEM:E+6) - 2119286186166371280112264238015778473404141003919064027522145193839708208181n :MSTORE(MEM:E+7) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E+8) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E+9) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E+10) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E+11) - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) + 20958531318718262179638310844977035402258325676941759254411716094948903283238n :MSTORE(MEM:E + 1) + 19014538453489502551198430834271851224745298622671277274539119640314913863353n :MSTORE(MEM:E + 2) + 4011274991290276638756079424799286249285264639232842260296401218902340006571n :MSTORE(MEM:E + 3) + 5493217260886730300768636259682920882409386426126823957476482234761131640151n :MSTORE(MEM:E + 4) + 18471742500483808444303896273620229467289887099913869033627754256214290219997n :MSTORE(MEM:E + 5) + 3526892542800189419786189901545486150149308978725362430328886936745555020543n :MSTORE(MEM:E + 6) + 2119286186166371280112264238015778473404141003919064027522145193839708208181n :MSTORE(MEM:E + 7) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E + 8) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E + 9) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E + 10) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E + 11) + :CALL(ecPairing) 0 => A - 1 :EQ + B :ASSERT + 1 :MLOAD(ecPairing_result) - ; 3] 18 inputs - 3 :MSTORE(ecPairing_ninputs) - 32*6*3 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + ; KZG proof with one poly and one evaluation + 2 :MSTORE(ecPairing_ninputs) + 32*6*2 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 7732322222446307127032679746925673403013840763103947213960757438494804067267n :MSTORE(MEM:E) + 8619360092012773279112944586645719683585858765189162557863470404130431808723n :MSTORE(MEM:E + 1) + 7754062701624777074058760614745676120554164137217320298195308357000412149840n :MSTORE(MEM:E + 2) + 4480687189204505779534873101802061566996023148878380905742776654135663383221n :MSTORE(MEM:E + 3) + 18744429014512523574338799100424477374744612401726532054975840530120472566n :MSTORE(MEM:E + 4) + 16667361185745910936700318129097219900413959552154798924397125501722669434888n :MSTORE(MEM:E + 5) + 595801121933130257838893357109567932541713044978712091132608377833002940532n :MSTORE(MEM:E + 6) + 15681552092527426161541501125159206079106959026991100968107368848241580050483n :MSTORE(MEM:E + 7) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E + 8) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E + 9) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E + 10) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E + 11) + :CALL(ecPairing) + 0 => A + B :ASSERT + 1 :MLOAD(ecPairing_result) + ; 4] Tests with 18 inputs + 3 :MSTORE(ecPairing_ninputs) + 32*6*3 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E - 20408625067408993290064640368727791004970573998302586029702220794326757674498n :MSTORE(MEM:E) - 16305464745216061320718924810220361252899630638785881184214175311729150579496n :MSTORE(MEM:E+1) - 19366297632879679637284621799459008574776307690134846433263569915955921902826n :MSTORE(MEM:E+2) - 7402184029652592179271650707149396214555402416834379616679103713331638701004n :MSTORE(MEM:E+3) - 13233069919494729038860025360853108843397419493559475327647450442468969143158n :MSTORE(MEM:E+4) - 10493112377715503836766497500954305714610771526749266396762372159550562853087n :MSTORE(MEM:E+5) - 6065896804174124393372571703959114319291624137637105019419069942189555692569n :MSTORE(MEM:E+6) - 1817372094771574002977021734119138264961743925299214620753363200235482672254n :MSTORE(MEM:E+7) - 19366297632879679637284621799459008574776307690134846433263569915955921902826n :MSTORE(MEM:E+8) - 7402184029652592179271650707149396214555402416834379616679103713331638701004n :MSTORE(MEM:E+9) - 13233069919494729038860025360853108843397419493559475327647450442468969143158n :MSTORE(MEM:E+10) - 10493112377715503836766497500954305714610771526749266396762372159550562853087n :MSTORE(MEM:E+11) - 5155695327752856721154364733178772660419613502017586895566245903460009198248n :MSTORE(MEM:E+12) - 17870951736543108265510715325941304521966082260796939666348236029204261385066n :MSTORE(MEM:E+13) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E+14) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E+15) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E+16) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E+17) - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) + 7732322222446307127032679746925673403013840763103947213960757438494804067267n :MSTORE(MEM:E) + 8619360092012773279112944586645719683585858765189162557863470404130431808723n :MSTORE(MEM:E + 1) + 7754062701624777074058760614745676120554164137217320298195308357000412149840n :MSTORE(MEM:E + 2) + 4480687189204505779534873101802061566996023148878380905742776654135663383221n :MSTORE(MEM:E + 3) + 18744429014512523574338799100424477374744612401726532054975840530120472566n :MSTORE(MEM:E + 4) + 16667361185745910936700318129097219900413959552154798924397125501722669434888n :MSTORE(MEM:E + 5) + 595801121933130257838893357109567932541713044978712091132608377833002940532n :MSTORE(MEM:E + 6) + 15681552092527426161541501125159206079106959026991100968107368848241580050483n :MSTORE(MEM:E + 7) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E + 8) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E + 9) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E + 10) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E + 11) + 1n :MSTORE(MEM:E + 12) + 2n :MSTORE(MEM:E + 13) + 0n :MSTORE(MEM:E + 14) + 0n :MSTORE(MEM:E + 15) + 0n :MSTORE(MEM:E + 16) + 0n :MSTORE(MEM:E + 17) + :CALL(ecPairing) 0 => A - 1 :EQ + B :ASSERT + 1 :MLOAD(ecPairing_result) - ; 3] 24 inputs - 4 :MSTORE(ecPairing_ninputs) - 32*6*4 :MSTORE(txCalldataLen) - -32 :MSTORE(readXFromCalldataOffset) + 3 :MSTORE(ecPairing_ninputs) + 32*6*3 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) + 0 => E + 20408625067408993290064640368727791004970573998302586029702220794326757674498n :MSTORE(MEM:E) + 16305464745216061320718924810220361252899630638785881184214175311729150579496n :MSTORE(MEM:E + 1) + 19366297632879679637284621799459008574776307690134846433263569915955921902826n :MSTORE(MEM:E + 2) + 7402184029652592179271650707149396214555402416834379616679103713331638701004n :MSTORE(MEM:E + 3) + 13233069919494729038860025360853108843397419493559475327647450442468969143158n :MSTORE(MEM:E + 4) + 10493112377715503836766497500954305714610771526749266396762372159550562853087n :MSTORE(MEM:E + 5) + 6065896804174124393372571703959114319291624137637105019419069942189555692569n :MSTORE(MEM:E + 6) + 1817372094771574002977021734119138264961743925299214620753363200235482672254n :MSTORE(MEM:E + 7) + 19366297632879679637284621799459008574776307690134846433263569915955921902826n :MSTORE(MEM:E + 8) + 7402184029652592179271650707149396214555402416834379616679103713331638701004n :MSTORE(MEM:E + 9) + 13233069919494729038860025360853108843397419493559475327647450442468969143158n :MSTORE(MEM:E + 10) + 10493112377715503836766497500954305714610771526749266396762372159550562853087n :MSTORE(MEM:E + 11) + 5155695327752856721154364733178772660419613502017586895566245903460009198248n :MSTORE(MEM:E + 12) + 17870951736543108265510715325941304521966082260796939666348236029204261385066n :MSTORE(MEM:E + 13) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(MEM:E + 14) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E + 15) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E + 16) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E + 17) + :CALL(ecPairing) + 0 => A + B :ASSERT + 1 :MLOAD(ecPairing_result) + ; 5] Tests with 24 inputs + 4 :MSTORE(ecPairing_ninputs) + 32*6*4 :MSTORE(txCalldataLen) + -32 :MSTORE(readXFromCalldataOffset) 0 => E 1153563745531144946586097928621095258348432585499389732309707300454996283289n :MSTORE(MEM:E) 7370404687973809887690049462468892748861464831518247317487007737601322454777n :MSTORE(MEM:E+1) @@ -450,35 +426,11 @@ start: 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(MEM:E+21) 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(MEM:E+22) 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(MEM:E+23) - :CALL(ecPairing) - 1 :MLOAD(ecPairing_result) + :CALL(ecPairing) 0 => A - 1 :EQ - -end: - - $ => A :MLOAD(initial_A) - $ => B :MLOAD(initial_B) - $ => C :MLOAD(initial_C) - $ => D :MLOAD(initial_D) - $ => E :MLOAD(initial_E) - $ => CTX :MLOAD(initial_CTX) - $ => SP :MLOAD(initial_SP) - $ => PC :MLOAD(initial_PC) - $ => GAS :MLOAD(initial_GAS) - $ => SR :MLOAD(initial_SR) - $ => RR :MLOAD(initial_RR) - $ => HASHPOS :MLOAD(initial_HASHPOS) - $ => RCX :MLOAD(initial_RCX) - -; label finalizeExecution needed by executor C++ -finalizeExecution: - ${beforeLast()} : JMPN(finalizeExecution) + B :ASSERT + 1 :MLOAD(ecPairing_result) - : JMP(start) -opINVALID: -; label checkAndSaveFrom needed by executor C++ -checkAndSaveFrom: - :JMP(opINVALID) + :JMP(finalizeExecution) INCLUDE "../main/main.zkasm" \ No newline at end of file From 0e2f8106b0a7d8364c4ee5d4ac8b227091aaa933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Fri, 1 Dec 2023 19:31:15 +0100 Subject: [PATCH 052/121] All tests fixed!!!! --- test/testFp12ArithBN254.zkasm | 687 +++++++++++++++++---------------- test/testFp2ArithBN254.zkasm | 60 +-- test/testFp4ArithBN254.zkasm | 36 +- test/testFp6ArithBN254.zkasm | 280 +++++++------- test/testFpArithBN254.zkasm | 63 +-- test/testFrArithBN254.zkasm | 26 +- test/testModExp.zkasm | 194 +++++----- test/testPairingBN254.zkasm | 282 +++++++------- test/testPointArithBN254.zkasm | 40 +- 9 files changed, 845 insertions(+), 823 deletions(-) diff --git a/test/testFp12ArithBN254.zkasm b/test/testFp12ArithBN254.zkasm index 61042e6d..894dfa09 100644 --- a/test/testFp12ArithBN254.zkasm +++ b/test/testFp12ArithBN254.zkasm @@ -53,70 +53,71 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - - 10n :MSTORE(addFp12BN254_a11_x) - 2n :MSTORE(addFp12BN254_a11_y) - 5n :MSTORE(addFp12BN254_a12_x) - 13n :MSTORE(addFp12BN254_a12_y) - 7n :MSTORE(addFp12BN254_a13_x) - 5n :MSTORE(addFp12BN254_a13_y) - 10n :MSTORE(addFp12BN254_a21_x) - 2n :MSTORE(addFp12BN254_a21_y) - 5n :MSTORE(addFp12BN254_a22_x) - 13n :MSTORE(addFp12BN254_a22_y) - 7n :MSTORE(addFp12BN254_a23_x) - 5n :MSTORE(addFp12BN254_a23_y) - 78n :MSTORE(addFp12BN254_b11_x) - 5n :MSTORE(addFp12BN254_b11_y) - 3n :MSTORE(addFp12BN254_b12_x) - 193n :MSTORE(addFp12BN254_b12_y) - 20n :MSTORE(addFp12BN254_b13_x) - 2n :MSTORE(addFp12BN254_b13_y) - 1n :MSTORE(addFp12BN254_b21_x) - 0n :MSTORE(addFp12BN254_b21_y) - 0n :MSTORE(addFp12BN254_b22_x) - 3n :MSTORE(addFp12BN254_b22_y) - 69n :MSTORE(addFp12BN254_b23_x) - 27n :MSTORE(addFp12BN254_b23_y) - :CALL(addFp12BN254) - 88n :MLOAD(addFp12BN254_c11_x) - 7n :MLOAD(addFp12BN254_c11_y) - 8n :MLOAD(addFp12BN254_c12_x) - 206n :MLOAD(addFp12BN254_c12_y) - 27n :MLOAD(addFp12BN254_c13_x) - 7n :MLOAD(addFp12BN254_c13_y) - 11n :MLOAD(addFp12BN254_c21_x) - 2n :MLOAD(addFp12BN254_c21_y) - 5n :MLOAD(addFp12BN254_c22_x) - 16n :MLOAD(addFp12BN254_c22_y) - 76n :MLOAD(addFp12BN254_c23_x) - 32n :MLOAD(addFp12BN254_c23_y) - - 10n :MSTORE(subFp12BN254_a11_x) - 2n :MSTORE(subFp12BN254_a11_y) - 5n :MSTORE(subFp12BN254_a12_x) - 13n :MSTORE(subFp12BN254_a12_y) - 7n :MSTORE(subFp12BN254_a13_x) - 5n :MSTORE(subFp12BN254_a13_y) - 10n :MSTORE(subFp12BN254_a21_x) - 2n :MSTORE(subFp12BN254_a21_y) - 5n :MSTORE(subFp12BN254_a22_x) - 13n :MSTORE(subFp12BN254_a22_y) - 7n :MSTORE(subFp12BN254_a23_x) - 5n :MSTORE(subFp12BN254_a23_y) - 78n :MSTORE(subFp12BN254_b11_x) - 5n :MSTORE(subFp12BN254_b11_y) - 3n :MSTORE(subFp12BN254_b12_x) - 193n :MSTORE(subFp12BN254_b12_y) - 20n :MSTORE(subFp12BN254_b13_x) - 2n :MSTORE(subFp12BN254_b13_y) - 1n :MSTORE(subFp12BN254_b21_x) - 0n :MSTORE(subFp12BN254_b21_y) - 0n :MSTORE(subFp12BN254_b22_x) - 3n :MSTORE(subFp12BN254_b22_y) - 69n :MSTORE(subFp12BN254_b23_x) - 27n :MSTORE(subFp12BN254_b23_y) - :CALL(subFp12BN254) + ; 1] Addition + 10n :MSTORE(addFp12BN254_a11_x) + 2n :MSTORE(addFp12BN254_a11_y) + 5n :MSTORE(addFp12BN254_a12_x) + 13n :MSTORE(addFp12BN254_a12_y) + 7n :MSTORE(addFp12BN254_a13_x) + 5n :MSTORE(addFp12BN254_a13_y) + 10n :MSTORE(addFp12BN254_a21_x) + 2n :MSTORE(addFp12BN254_a21_y) + 5n :MSTORE(addFp12BN254_a22_x) + 13n :MSTORE(addFp12BN254_a22_y) + 7n :MSTORE(addFp12BN254_a23_x) + 5n :MSTORE(addFp12BN254_a23_y) + 78n :MSTORE(addFp12BN254_b11_x) + 5n :MSTORE(addFp12BN254_b11_y) + 3n :MSTORE(addFp12BN254_b12_x) + 193n :MSTORE(addFp12BN254_b12_y) + 20n :MSTORE(addFp12BN254_b13_x) + 2n :MSTORE(addFp12BN254_b13_y) + 1n :MSTORE(addFp12BN254_b21_x) + 0n :MSTORE(addFp12BN254_b21_y) + 0n :MSTORE(addFp12BN254_b22_x) + 3n :MSTORE(addFp12BN254_b22_y) + 69n :MSTORE(addFp12BN254_b23_x) + 27n :MSTORE(addFp12BN254_b23_y) + :CALL(addFp12BN254) + 88n :MLOAD(addFp12BN254_c11_x) + 7n :MLOAD(addFp12BN254_c11_y) + 8n :MLOAD(addFp12BN254_c12_x) + 206n :MLOAD(addFp12BN254_c12_y) + 27n :MLOAD(addFp12BN254_c13_x) + 7n :MLOAD(addFp12BN254_c13_y) + 11n :MLOAD(addFp12BN254_c21_x) + 2n :MLOAD(addFp12BN254_c21_y) + 5n :MLOAD(addFp12BN254_c22_x) + 16n :MLOAD(addFp12BN254_c22_y) + 76n :MLOAD(addFp12BN254_c23_x) + 32n :MLOAD(addFp12BN254_c23_y) + + ; 2] Subtraction + 10n :MSTORE(subFp12BN254_a11_x) + 2n :MSTORE(subFp12BN254_a11_y) + 5n :MSTORE(subFp12BN254_a12_x) + 13n :MSTORE(subFp12BN254_a12_y) + 7n :MSTORE(subFp12BN254_a13_x) + 5n :MSTORE(subFp12BN254_a13_y) + 10n :MSTORE(subFp12BN254_a21_x) + 2n :MSTORE(subFp12BN254_a21_y) + 5n :MSTORE(subFp12BN254_a22_x) + 13n :MSTORE(subFp12BN254_a22_y) + 7n :MSTORE(subFp12BN254_a23_x) + 5n :MSTORE(subFp12BN254_a23_y) + 78n :MSTORE(subFp12BN254_b11_x) + 5n :MSTORE(subFp12BN254_b11_y) + 3n :MSTORE(subFp12BN254_b12_x) + 193n :MSTORE(subFp12BN254_b12_y) + 20n :MSTORE(subFp12BN254_b13_x) + 2n :MSTORE(subFp12BN254_b13_y) + 1n :MSTORE(subFp12BN254_b21_x) + 0n :MSTORE(subFp12BN254_b21_y) + 0n :MSTORE(subFp12BN254_b22_x) + 3n :MSTORE(subFp12BN254_b22_y) + 69n :MSTORE(subFp12BN254_b23_x) + 27n :MSTORE(subFp12BN254_b23_y) + :CALL(subFp12BN254) 21888242871839275222246405745257275088696311157297823662689037894645226208515n :MLOAD(subFp12BN254_c11_x) 21888242871839275222246405745257275088696311157297823662689037894645226208580n :MLOAD(subFp12BN254_c11_y) 2n :MLOAD(subFp12BN254_c12_x) @@ -130,31 +131,32 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226208521n :MLOAD(subFp12BN254_c23_x) 21888242871839275222246405745257275088696311157297823662689037894645226208561n :MLOAD(subFp12BN254_c23_y) - 10n :MSTORE(mulFp12BN254_a11_x) - 2n :MSTORE(mulFp12BN254_a11_y) - 5n :MSTORE(mulFp12BN254_a12_x) - 13n :MSTORE(mulFp12BN254_a12_y) - 7n :MSTORE(mulFp12BN254_a13_x) - 5n :MSTORE(mulFp12BN254_a13_y) - 10n :MSTORE(mulFp12BN254_a21_x) - 2n :MSTORE(mulFp12BN254_a21_y) - 5n :MSTORE(mulFp12BN254_a22_x) - 13n :MSTORE(mulFp12BN254_a22_y) - 7n :MSTORE(mulFp12BN254_a23_x) - 5n :MSTORE(mulFp12BN254_a23_y) - 78n :MSTORE(mulFp12BN254_b11_x) - 5n :MSTORE(mulFp12BN254_b11_y) - 3n :MSTORE(mulFp12BN254_b12_x) - 193n :MSTORE(mulFp12BN254_b12_y) - 20n :MSTORE(mulFp12BN254_b13_x) - 2n :MSTORE(mulFp12BN254_b13_y) - 1n :MSTORE(mulFp12BN254_b21_x) - 0n :MSTORE(mulFp12BN254_b21_y) - 0n :MSTORE(mulFp12BN254_b22_x) - 3n :MSTORE(mulFp12BN254_b22_y) - 69n :MSTORE(mulFp12BN254_b23_x) - 27n :MSTORE(mulFp12BN254_b23_y) - :CALL(mulFp12BN254) + ; 3] Multiplication + 10n :MSTORE(mulFp12BN254_a11_x) + 2n :MSTORE(mulFp12BN254_a11_y) + 5n :MSTORE(mulFp12BN254_a12_x) + 13n :MSTORE(mulFp12BN254_a12_y) + 7n :MSTORE(mulFp12BN254_a13_x) + 5n :MSTORE(mulFp12BN254_a13_y) + 10n :MSTORE(mulFp12BN254_a21_x) + 2n :MSTORE(mulFp12BN254_a21_y) + 5n :MSTORE(mulFp12BN254_a22_x) + 13n :MSTORE(mulFp12BN254_a22_y) + 7n :MSTORE(mulFp12BN254_a23_x) + 5n :MSTORE(mulFp12BN254_a23_y) + 78n :MSTORE(mulFp12BN254_b11_x) + 5n :MSTORE(mulFp12BN254_b11_y) + 3n :MSTORE(mulFp12BN254_b12_x) + 193n :MSTORE(mulFp12BN254_b12_y) + 20n :MSTORE(mulFp12BN254_b13_x) + 2n :MSTORE(mulFp12BN254_b13_y) + 1n :MSTORE(mulFp12BN254_b21_x) + 0n :MSTORE(mulFp12BN254_b21_y) + 0n :MSTORE(mulFp12BN254_b22_x) + 3n :MSTORE(mulFp12BN254_b22_y) + 69n :MSTORE(mulFp12BN254_b23_x) + 27n :MSTORE(mulFp12BN254_b23_y) + :CALL(mulFp12BN254) 21888242871839275222246405745257275088696311157297823662689037894645226204895n :MLOAD(mulFp12BN254_c11_x) 18516n :MLOAD(mulFp12BN254_c11_y) 21888242871839275222246405745257275088696311157297823662689037894645226208376n :MLOAD(mulFp12BN254_c12_x) @@ -168,31 +170,31 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226207410n :MLOAD(mulFp12BN254_c23_x) 1917n :MLOAD(mulFp12BN254_c23_y) - 2n :MSTORE(mulFp12BN254_a11_x) - 4n :MSTORE(mulFp12BN254_a11_y) - 0n :MSTORE(mulFp12BN254_a12_x) - 0n :MSTORE(mulFp12BN254_a12_y) - 0n :MSTORE(mulFp12BN254_a13_x) - 5n :MSTORE(mulFp12BN254_a13_y) - 5n :MSTORE(mulFp12BN254_a21_x) - 10n :MSTORE(mulFp12BN254_a21_y) - 20n :MSTORE(mulFp12BN254_a22_x) - 30n :MSTORE(mulFp12BN254_a22_y) - 7n :MSTORE(mulFp12BN254_a23_x) - 69n :MSTORE(mulFp12BN254_a23_y) - 78n :MSTORE(mulFp12BN254_b11_x) - 14n :MSTORE(mulFp12BN254_b11_y) - 2n :MSTORE(mulFp12BN254_b12_x) - 1n :MSTORE(mulFp12BN254_b12_y) - 2n :MSTORE(mulFp12BN254_b13_x) - 10n :MSTORE(mulFp12BN254_b13_y) - 100n :MSTORE(mulFp12BN254_b21_x) - 99n :MSTORE(mulFp12BN254_b21_y) - 88n :MSTORE(mulFp12BN254_b22_x) - 77n :MSTORE(mulFp12BN254_b22_y) - 20n :MSTORE(mulFp12BN254_b23_x) - 2n :MSTORE(mulFp12BN254_b23_y) - :CALL(mulFp12BN254) + 2n :MSTORE(mulFp12BN254_a11_x) + 4n :MSTORE(mulFp12BN254_a11_y) + 0n :MSTORE(mulFp12BN254_a12_x) + 0n :MSTORE(mulFp12BN254_a12_y) + 0n :MSTORE(mulFp12BN254_a13_x) + 5n :MSTORE(mulFp12BN254_a13_y) + 5n :MSTORE(mulFp12BN254_a21_x) + 10n :MSTORE(mulFp12BN254_a21_y) + 20n :MSTORE(mulFp12BN254_a22_x) + 30n :MSTORE(mulFp12BN254_a22_y) + 7n :MSTORE(mulFp12BN254_a23_x) + 69n :MSTORE(mulFp12BN254_a23_y) + 78n :MSTORE(mulFp12BN254_b11_x) + 14n :MSTORE(mulFp12BN254_b11_y) + 2n :MSTORE(mulFp12BN254_b12_x) + 1n :MSTORE(mulFp12BN254_b12_y) + 2n :MSTORE(mulFp12BN254_b13_x) + 10n :MSTORE(mulFp12BN254_b13_y) + 100n :MSTORE(mulFp12BN254_b21_x) + 99n :MSTORE(mulFp12BN254_b21_y) + 88n :MSTORE(mulFp12BN254_b22_x) + 77n :MSTORE(mulFp12BN254_b22_y) + 20n :MSTORE(mulFp12BN254_b23_x) + 2n :MSTORE(mulFp12BN254_b23_y) + :CALL(mulFp12BN254) 21888242871839275222246405745257275088696311157297823662689037894645226137236n :MLOAD(mulFp12BN254_c11_x) 101671n :MLOAD(mulFp12BN254_c11_y) 21888242871839275222246405745257275088696311157297823662689037894645226161169n :MLOAD(mulFp12BN254_c12_x) @@ -206,19 +208,20 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226207620n :MLOAD(mulFp12BN254_c23_x) 6214n :MLOAD(mulFp12BN254_c23_y) - 2n :MSTORE(squareFp12BN254_a11_x) - 4n :MSTORE(squareFp12BN254_a11_y) - 0n :MSTORE(squareFp12BN254_a12_x) - 0n :MSTORE(squareFp12BN254_a12_y) - 0n :MSTORE(squareFp12BN254_a13_x) - 5n :MSTORE(squareFp12BN254_a13_y) - 5n :MSTORE(squareFp12BN254_a21_x) - 10n :MSTORE(squareFp12BN254_a21_y) - 20n :MSTORE(squareFp12BN254_a22_x) - 30n :MSTORE(squareFp12BN254_a22_y) - 7n :MSTORE(squareFp12BN254_a23_x) - 69n :MSTORE(squareFp12BN254_a23_y) - :CALL(squareFp12BN254) + ; 4] Squaring + 2n :MSTORE(squareFp12BN254_a11_x) + 4n :MSTORE(squareFp12BN254_a11_y) + 0n :MSTORE(squareFp12BN254_a12_x) + 0n :MSTORE(squareFp12BN254_a12_y) + 0n :MSTORE(squareFp12BN254_a13_x) + 5n :MSTORE(squareFp12BN254_a13_y) + 5n :MSTORE(squareFp12BN254_a21_x) + 10n :MSTORE(squareFp12BN254_a21_y) + 20n :MSTORE(squareFp12BN254_a22_x) + 30n :MSTORE(squareFp12BN254_a22_y) + 7n :MSTORE(squareFp12BN254_a23_x) + 69n :MSTORE(squareFp12BN254_a23_y) + :CALL(squareFp12BN254) 21888242871839275222246405745257275088696311157297823662689037894645226190251n :MLOAD(squareFp12BN254_c11_x) 16476n :MLOAD(squareFp12BN254_c11_y) 21888242871839275222246405745257275088696311157297823662689037894645226170363n :MLOAD(squareFp12BN254_c12_x) @@ -258,45 +261,46 @@ start: 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(squareFp12BN254_c23_x) 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(squareFp12BN254_c23_y) - 0n :MSTORE(inverseFp12BN254_a11_x) - 0n :MSTORE(inverseFp12BN254_a11_y) - 0n :MSTORE(inverseFp12BN254_a12_x) - 0n :MSTORE(inverseFp12BN254_a12_y) - 0n :MSTORE(inverseFp12BN254_a13_x) - 0n :MSTORE(inverseFp12BN254_a13_y) - 0n :MSTORE(inverseFp12BN254_a21_x) - 0n :MSTORE(inverseFp12BN254_a21_y) - 0n :MSTORE(inverseFp12BN254_a22_x) - 0n :MSTORE(inverseFp12BN254_a22_y) - 0n :MSTORE(inverseFp12BN254_a23_x) - 0n :MSTORE(inverseFp12BN254_a23_y) - :CALL(inverseFp12BN254) - 0n :MLOAD(inverseFp12BN254_c11_x) - 0n :MLOAD(inverseFp12BN254_c11_y) - 0n :MLOAD(inverseFp12BN254_c12_x) - 0n :MLOAD(inverseFp12BN254_c12_y) - 0n :MLOAD(inverseFp12BN254_c13_x) - 0n :MLOAD(inverseFp12BN254_c13_y) - 0n :MLOAD(inverseFp12BN254_c21_x) - 0n :MLOAD(inverseFp12BN254_c21_y) - 0n :MLOAD(inverseFp12BN254_c22_x) - 0n :MLOAD(inverseFp12BN254_c22_y) - 0n :MLOAD(inverseFp12BN254_c23_x) - 0n :MLOAD(inverseFp12BN254_c23_y) - - 2n :MSTORE(inverseFp12BN254_a11_x) - 4n :MSTORE(inverseFp12BN254_a11_y) - 0n :MSTORE(inverseFp12BN254_a12_x) - 0n :MSTORE(inverseFp12BN254_a12_y) - 0n :MSTORE(inverseFp12BN254_a13_x) - 5n :MSTORE(inverseFp12BN254_a13_y) - 5n :MSTORE(inverseFp12BN254_a21_x) - 10n :MSTORE(inverseFp12BN254_a21_y) - 20n :MSTORE(inverseFp12BN254_a22_x) - 30n :MSTORE(inverseFp12BN254_a22_y) - 7n :MSTORE(inverseFp12BN254_a23_x) - 69n :MSTORE(inverseFp12BN254_a23_y) - :CALL(inverseFp12BN254) + ; 5] Inversion + 0n :MSTORE(inverseFp12BN254_a11_x) + 0n :MSTORE(inverseFp12BN254_a11_y) + 0n :MSTORE(inverseFp12BN254_a12_x) + 0n :MSTORE(inverseFp12BN254_a12_y) + 0n :MSTORE(inverseFp12BN254_a13_x) + 0n :MSTORE(inverseFp12BN254_a13_y) + 0n :MSTORE(inverseFp12BN254_a21_x) + 0n :MSTORE(inverseFp12BN254_a21_y) + 0n :MSTORE(inverseFp12BN254_a22_x) + 0n :MSTORE(inverseFp12BN254_a22_y) + 0n :MSTORE(inverseFp12BN254_a23_x) + 0n :MSTORE(inverseFp12BN254_a23_y) + :CALL(inverseFp12BN254) + 0n :MLOAD(inverseFp12BN254_c11_x) + 0n :MLOAD(inverseFp12BN254_c11_y) + 0n :MLOAD(inverseFp12BN254_c12_x) + 0n :MLOAD(inverseFp12BN254_c12_y) + 0n :MLOAD(inverseFp12BN254_c13_x) + 0n :MLOAD(inverseFp12BN254_c13_y) + 0n :MLOAD(inverseFp12BN254_c21_x) + 0n :MLOAD(inverseFp12BN254_c21_y) + 0n :MLOAD(inverseFp12BN254_c22_x) + 0n :MLOAD(inverseFp12BN254_c22_y) + 0n :MLOAD(inverseFp12BN254_c23_x) + 0n :MLOAD(inverseFp12BN254_c23_y) + + 2n :MSTORE(inverseFp12BN254_a11_x) + 4n :MSTORE(inverseFp12BN254_a11_y) + 0n :MSTORE(inverseFp12BN254_a12_x) + 0n :MSTORE(inverseFp12BN254_a12_y) + 0n :MSTORE(inverseFp12BN254_a13_x) + 5n :MSTORE(inverseFp12BN254_a13_y) + 5n :MSTORE(inverseFp12BN254_a21_x) + 10n :MSTORE(inverseFp12BN254_a21_y) + 20n :MSTORE(inverseFp12BN254_a22_x) + 30n :MSTORE(inverseFp12BN254_a22_y) + 7n :MSTORE(inverseFp12BN254_a23_x) + 69n :MSTORE(inverseFp12BN254_a23_y) + :CALL(inverseFp12BN254) 20888671201298710215559703514044964345994874487104175886056878644554404140739n :MLOAD(inverseFp12BN254_c11_x) 18341611945458884647361257454040416792770938911765857382502174274013923134382n :MLOAD(inverseFp12BN254_c11_y) 17212264596994956074343974726440644554067711720592905218425974958919607539075n :MLOAD(inverseFp12BN254_c12_x) @@ -310,19 +314,20 @@ start: 8570196145412438361611057965650768730501569553533068267820731323855389368346n :MLOAD(inverseFp12BN254_c23_x) 7491118698937156772874143978394611345783939114329232646099076078308797709778n :MLOAD(inverseFp12BN254_c23_y) - 2n :MSTORE(frobFp12BN254_a11_x) - 4n :MSTORE(frobFp12BN254_a11_y) - 0n :MSTORE(frobFp12BN254_a12_x) - 0n :MSTORE(frobFp12BN254_a12_y) - 0n :MSTORE(frobFp12BN254_a13_x) - 5n :MSTORE(frobFp12BN254_a13_y) - 5n :MSTORE(frobFp12BN254_a21_x) - 10n :MSTORE(frobFp12BN254_a21_y) - 20n :MSTORE(frobFp12BN254_a22_x) - 30n :MSTORE(frobFp12BN254_a22_y) - 7n :MSTORE(frobFp12BN254_a23_x) - 69n :MSTORE(frobFp12BN254_a23_y) - :CALL(frobFp12BN254) + ; 6] Frobenius 1 + 2n :MSTORE(frobFp12BN254_a11_x) + 4n :MSTORE(frobFp12BN254_a11_y) + 0n :MSTORE(frobFp12BN254_a12_x) + 0n :MSTORE(frobFp12BN254_a12_y) + 0n :MSTORE(frobFp12BN254_a13_x) + 5n :MSTORE(frobFp12BN254_a13_y) + 5n :MSTORE(frobFp12BN254_a21_x) + 10n :MSTORE(frobFp12BN254_a21_y) + 20n :MSTORE(frobFp12BN254_a22_x) + 30n :MSTORE(frobFp12BN254_a22_y) + 7n :MSTORE(frobFp12BN254_a23_x) + 69n :MSTORE(frobFp12BN254_a23_y) + :CALL(frobFp12BN254) 2n :MLOAD(frobFp12BN254_c11_x) 21888242871839275222246405745257275088696311157297823662689037894645226208579n :MLOAD(frobFp12BN254_c11_y) 0n :MLOAD(frobFp12BN254_c12_x) @@ -336,19 +341,20 @@ start: 18558562840876269057841639761243305870292532112761084078231157243871160309578n :MLOAD(frobFp12BN254_c23_x) 11857974535903257516183381046246360366676403947472414230254839754001932999778n :MLOAD(frobFp12BN254_c23_y) - 2n :MSTORE(frob2Fp12BN254_a11_x) - 4n :MSTORE(frob2Fp12BN254_a11_y) - 0n :MSTORE(frob2Fp12BN254_a12_x) - 0n :MSTORE(frob2Fp12BN254_a12_y) - 0n :MSTORE(frob2Fp12BN254_a13_x) - 5n :MSTORE(frob2Fp12BN254_a13_y) - 5n :MSTORE(frob2Fp12BN254_a21_x) - 10n :MSTORE(frob2Fp12BN254_a21_y) - 20n :MSTORE(frob2Fp12BN254_a22_x) - 30n :MSTORE(frob2Fp12BN254_a22_y) - 7n :MSTORE(frob2Fp12BN254_a23_x) - 69n :MSTORE(frob2Fp12BN254_a23_y) - :CALL(frob2Fp12BN254) + ; 7] Frobenius 2 + 2n :MSTORE(frob2Fp12BN254_a11_x) + 4n :MSTORE(frob2Fp12BN254_a11_y) + 0n :MSTORE(frob2Fp12BN254_a12_x) + 0n :MSTORE(frob2Fp12BN254_a12_y) + 0n :MSTORE(frob2Fp12BN254_a13_x) + 5n :MSTORE(frob2Fp12BN254_a13_y) + 5n :MSTORE(frob2Fp12BN254_a21_x) + 10n :MSTORE(frob2Fp12BN254_a21_y) + 20n :MSTORE(frob2Fp12BN254_a22_x) + 30n :MSTORE(frob2Fp12BN254_a22_y) + 7n :MSTORE(frob2Fp12BN254_a23_x) + 69n :MSTORE(frob2Fp12BN254_a23_y) + :CALL(frob2Fp12BN254) 2n :MLOAD(frob2Fp12BN254_c11_x) 4n :MLOAD(frob2Fp12BN254_c11_y) 0n :MLOAD(frob2Fp12BN254_c12_x) @@ -362,19 +368,20 @@ start: 15427723396036853449930226199780334146819954812161439563769n :MLOAD(frob2Fp12BN254_c23_x) 152073273475220412577883658254977579447225268862734189985723n :MLOAD(frob2Fp12BN254_c23_y) - 2n :MSTORE(frob3Fp12BN254_a11_x) - 4n :MSTORE(frob3Fp12BN254_a11_y) - 0n :MSTORE(frob3Fp12BN254_a12_x) - 0n :MSTORE(frob3Fp12BN254_a12_y) - 0n :MSTORE(frob3Fp12BN254_a13_x) - 5n :MSTORE(frob3Fp12BN254_a13_y) - 5n :MSTORE(frob3Fp12BN254_a21_x) - 10n :MSTORE(frob3Fp12BN254_a21_y) - 20n :MSTORE(frob3Fp12BN254_a22_x) - 30n :MSTORE(frob3Fp12BN254_a22_y) - 7n :MSTORE(frob3Fp12BN254_a23_x) - 69n :MSTORE(frob3Fp12BN254_a23_y) - :CALL(frob3Fp12BN254) + ; 8] Frobenius 3 + 2n :MSTORE(frob3Fp12BN254_a11_x) + 4n :MSTORE(frob3Fp12BN254_a11_y) + 0n :MSTORE(frob3Fp12BN254_a12_x) + 0n :MSTORE(frob3Fp12BN254_a12_y) + 0n :MSTORE(frob3Fp12BN254_a13_x) + 5n :MSTORE(frob3Fp12BN254_a13_y) + 5n :MSTORE(frob3Fp12BN254_a21_x) + 10n :MSTORE(frob3Fp12BN254_a21_y) + 20n :MSTORE(frob3Fp12BN254_a22_x) + 30n :MSTORE(frob3Fp12BN254_a22_y) + 7n :MSTORE(frob3Fp12BN254_a23_x) + 69n :MSTORE(frob3Fp12BN254_a23_y) + :CALL(frob3Fp12BN254) 2n :MLOAD(frob3Fp12BN254_c11_x) 21888242871839275222246405745257275088696311157297823662689037894645226208579n :MLOAD(frob3Fp12BN254_c11_y) 0n :MLOAD(frob3Fp12BN254_c12_x) @@ -388,102 +395,102 @@ start: 9835836312269481659124129352040423254366959727421963915440501313066399824733n :MLOAD(frob3Fp12BN254_c23_x) 2627768430169233579625702931774614886811535516639531274999928953109345755919n :MLOAD(frob3Fp12BN254_c23_y) - ; exp - 0n :MSTORE(expFp12BN254_e) - 0n :MSTORE(expFp12BN254_a11_x) - 0n :MSTORE(expFp12BN254_a11_y) - 0n :MSTORE(expFp12BN254_a12_x) - 0n :MSTORE(expFp12BN254_a12_y) - 0n :MSTORE(expFp12BN254_a13_x) - 0n :MSTORE(expFp12BN254_a13_y) - 0n :MSTORE(expFp12BN254_a21_x) - 0n :MSTORE(expFp12BN254_a21_y) - 0n :MSTORE(expFp12BN254_a22_x) - 0n :MSTORE(expFp12BN254_a22_y) - 0n :MSTORE(expFp12BN254_a23_x) - 0n :MSTORE(expFp12BN254_a23_y) - :CALL(expFp12BN254) - 0n :MLOAD(expFp12BN254_c11_x) - 0n :MLOAD(expFp12BN254_c11_y) - 0n :MLOAD(expFp12BN254_c12_x) - 0n :MLOAD(expFp12BN254_c12_y) - 0n :MLOAD(expFp12BN254_c13_x) - 0n :MLOAD(expFp12BN254_c13_y) - 0n :MLOAD(expFp12BN254_c21_x) - 0n :MLOAD(expFp12BN254_c21_y) - 0n :MLOAD(expFp12BN254_c22_x) - 0n :MLOAD(expFp12BN254_c22_y) - 0n :MLOAD(expFp12BN254_c23_x) - 0n :MLOAD(expFp12BN254_c23_y) - - 10n :MSTORE(expFp12BN254_e) - 0n :MSTORE(expFp12BN254_a11_x) - 0n :MSTORE(expFp12BN254_a11_y) - 0n :MSTORE(expFp12BN254_a12_x) - 0n :MSTORE(expFp12BN254_a12_y) - 0n :MSTORE(expFp12BN254_a13_x) - 0n :MSTORE(expFp12BN254_a13_y) - 0n :MSTORE(expFp12BN254_a21_x) - 0n :MSTORE(expFp12BN254_a21_y) - 0n :MSTORE(expFp12BN254_a22_x) - 0n :MSTORE(expFp12BN254_a22_y) - 0n :MSTORE(expFp12BN254_a23_x) - 0n :MSTORE(expFp12BN254_a23_y) - :CALL(expFp12BN254) - 0n :MLOAD(expFp12BN254_c11_x) - 0n :MLOAD(expFp12BN254_c11_y) - 0n :MLOAD(expFp12BN254_c12_x) - 0n :MLOAD(expFp12BN254_c12_y) - 0n :MLOAD(expFp12BN254_c13_x) - 0n :MLOAD(expFp12BN254_c13_y) - 0n :MLOAD(expFp12BN254_c21_x) - 0n :MLOAD(expFp12BN254_c21_y) - 0n :MLOAD(expFp12BN254_c22_x) - 0n :MLOAD(expFp12BN254_c22_y) - 0n :MLOAD(expFp12BN254_c23_x) - 0n :MLOAD(expFp12BN254_c23_y) - - 0n :MSTORE(expFp12BN254_e) - 1n :MSTORE(expFp12BN254_a11_x) - 0n :MSTORE(expFp12BN254_a11_y) - 0n :MSTORE(expFp12BN254_a12_x) - 0n :MSTORE(expFp12BN254_a12_y) - 0n :MSTORE(expFp12BN254_a13_x) - 0n :MSTORE(expFp12BN254_a13_y) - 0n :MSTORE(expFp12BN254_a21_x) - 0n :MSTORE(expFp12BN254_a21_y) - 0n :MSTORE(expFp12BN254_a22_x) - 0n :MSTORE(expFp12BN254_a22_y) - 0n :MSTORE(expFp12BN254_a23_x) - 0n :MSTORE(expFp12BN254_a23_y) - :CALL(expFp12BN254) - 1n :MLOAD(expFp12BN254_c11_x) - 0n :MLOAD(expFp12BN254_c11_y) - 0n :MLOAD(expFp12BN254_c12_x) - 0n :MLOAD(expFp12BN254_c12_y) - 0n :MLOAD(expFp12BN254_c13_x) - 0n :MLOAD(expFp12BN254_c13_y) - 0n :MLOAD(expFp12BN254_c21_x) - 0n :MLOAD(expFp12BN254_c21_y) - 0n :MLOAD(expFp12BN254_c22_x) - 0n :MLOAD(expFp12BN254_c22_y) - 0n :MLOAD(expFp12BN254_c23_x) - 0n :MLOAD(expFp12BN254_c23_y) - - 167n :MSTORE(expFp12BN254_e) - 2n :MSTORE(expFp12BN254_a11_x) - 4n :MSTORE(expFp12BN254_a11_y) - 0n :MSTORE(expFp12BN254_a12_x) - 0n :MSTORE(expFp12BN254_a12_y) - 0n :MSTORE(expFp12BN254_a13_x) - 5n :MSTORE(expFp12BN254_a13_y) - 5n :MSTORE(expFp12BN254_a21_x) - 10n :MSTORE(expFp12BN254_a21_y) - 20n :MSTORE(expFp12BN254_a22_x) - 30n :MSTORE(expFp12BN254_a22_y) - 7n :MSTORE(expFp12BN254_a23_x) - 69n :MSTORE(expFp12BN254_a23_y) - :CALL(expFp12BN254) + ; 9] Exponentiation + 0n :MSTORE(expFp12BN254_e) + 0n :MSTORE(expFp12BN254_a11_x) + 0n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 0n :MSTORE(expFp12BN254_a13_y) + 0n :MSTORE(expFp12BN254_a21_x) + 0n :MSTORE(expFp12BN254_a21_y) + 0n :MSTORE(expFp12BN254_a22_x) + 0n :MSTORE(expFp12BN254_a22_y) + 0n :MSTORE(expFp12BN254_a23_x) + 0n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 0n :MLOAD(expFp12BN254_c11_x) + 0n :MLOAD(expFp12BN254_c11_y) + 0n :MLOAD(expFp12BN254_c12_x) + 0n :MLOAD(expFp12BN254_c12_y) + 0n :MLOAD(expFp12BN254_c13_x) + 0n :MLOAD(expFp12BN254_c13_y) + 0n :MLOAD(expFp12BN254_c21_x) + 0n :MLOAD(expFp12BN254_c21_y) + 0n :MLOAD(expFp12BN254_c22_x) + 0n :MLOAD(expFp12BN254_c22_y) + 0n :MLOAD(expFp12BN254_c23_x) + 0n :MLOAD(expFp12BN254_c23_y) + + 10n :MSTORE(expFp12BN254_e) + 0n :MSTORE(expFp12BN254_a11_x) + 0n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 0n :MSTORE(expFp12BN254_a13_y) + 0n :MSTORE(expFp12BN254_a21_x) + 0n :MSTORE(expFp12BN254_a21_y) + 0n :MSTORE(expFp12BN254_a22_x) + 0n :MSTORE(expFp12BN254_a22_y) + 0n :MSTORE(expFp12BN254_a23_x) + 0n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 0n :MLOAD(expFp12BN254_c11_x) + 0n :MLOAD(expFp12BN254_c11_y) + 0n :MLOAD(expFp12BN254_c12_x) + 0n :MLOAD(expFp12BN254_c12_y) + 0n :MLOAD(expFp12BN254_c13_x) + 0n :MLOAD(expFp12BN254_c13_y) + 0n :MLOAD(expFp12BN254_c21_x) + 0n :MLOAD(expFp12BN254_c21_y) + 0n :MLOAD(expFp12BN254_c22_x) + 0n :MLOAD(expFp12BN254_c22_y) + 0n :MLOAD(expFp12BN254_c23_x) + 0n :MLOAD(expFp12BN254_c23_y) + + 0n :MSTORE(expFp12BN254_e) + 1n :MSTORE(expFp12BN254_a11_x) + 0n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 0n :MSTORE(expFp12BN254_a13_y) + 0n :MSTORE(expFp12BN254_a21_x) + 0n :MSTORE(expFp12BN254_a21_y) + 0n :MSTORE(expFp12BN254_a22_x) + 0n :MSTORE(expFp12BN254_a22_y) + 0n :MSTORE(expFp12BN254_a23_x) + 0n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 1n :MLOAD(expFp12BN254_c11_x) + 0n :MLOAD(expFp12BN254_c11_y) + 0n :MLOAD(expFp12BN254_c12_x) + 0n :MLOAD(expFp12BN254_c12_y) + 0n :MLOAD(expFp12BN254_c13_x) + 0n :MLOAD(expFp12BN254_c13_y) + 0n :MLOAD(expFp12BN254_c21_x) + 0n :MLOAD(expFp12BN254_c21_y) + 0n :MLOAD(expFp12BN254_c22_x) + 0n :MLOAD(expFp12BN254_c22_y) + 0n :MLOAD(expFp12BN254_c23_x) + 0n :MLOAD(expFp12BN254_c23_y) + + 167n :MSTORE(expFp12BN254_e) + 2n :MSTORE(expFp12BN254_a11_x) + 4n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 5n :MSTORE(expFp12BN254_a13_y) + 5n :MSTORE(expFp12BN254_a21_x) + 10n :MSTORE(expFp12BN254_a21_y) + 20n :MSTORE(expFp12BN254_a22_x) + 30n :MSTORE(expFp12BN254_a22_y) + 7n :MSTORE(expFp12BN254_a23_x) + 69n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) 20586466107674193719139483068538172518814581654122963093910816135984072539339n :MLOAD(expFp12BN254_c11_x) 5953152173779773418366712639682598574554542297764337418575574775937014969989n :MLOAD(expFp12BN254_c11_y) 3661221552326322626584296132914038982026189413490444409336642019079026110580n :MLOAD(expFp12BN254_c12_x) @@ -524,25 +531,26 @@ start: 2894810207171007395751896130534905544170418813733418015224386592699923578372n :MLOAD(expFp12BN254_c23_x) 18124993142426825678658622810384924838784371007656354124172463271771994460493n :MLOAD(expFp12BN254_c23_y) - 2n :MSTORE(sparseMulAFp12BN254_a11_x) - 4n :MSTORE(sparseMulAFp12BN254_a11_y) - 0n :MSTORE(sparseMulAFp12BN254_a12_x) - 0n :MSTORE(sparseMulAFp12BN254_a12_y) - 0n :MSTORE(sparseMulAFp12BN254_a13_x) - 5n :MSTORE(sparseMulAFp12BN254_a13_y) - 5n :MSTORE(sparseMulAFp12BN254_a21_x) - 10n :MSTORE(sparseMulAFp12BN254_a21_y) - 20n :MSTORE(sparseMulAFp12BN254_a22_x) - 30n :MSTORE(sparseMulAFp12BN254_a22_y) - 7n :MSTORE(sparseMulAFp12BN254_a23_x) - 69n :MSTORE(sparseMulAFp12BN254_a23_y) - 7n :MSTORE(sparseMulAFp12BN254_b12_x) - 6n :MSTORE(sparseMulAFp12BN254_b12_y) - 7n :MSTORE(sparseMulAFp12BN254_b22_x) - 83n :MSTORE(sparseMulAFp12BN254_b22_y) - 2n :MSTORE(sparseMulAFp12BN254_b23_x) - 29n :MSTORE(sparseMulAFp12BN254_b23_y) - :CALL(sparseMulAFp12BN254) + ; 10] Sparse Multiplication A + 2n :MSTORE(sparseMulAFp12BN254_a11_x) + 4n :MSTORE(sparseMulAFp12BN254_a11_y) + 0n :MSTORE(sparseMulAFp12BN254_a12_x) + 0n :MSTORE(sparseMulAFp12BN254_a12_y) + 0n :MSTORE(sparseMulAFp12BN254_a13_x) + 5n :MSTORE(sparseMulAFp12BN254_a13_y) + 5n :MSTORE(sparseMulAFp12BN254_a21_x) + 10n :MSTORE(sparseMulAFp12BN254_a21_y) + 20n :MSTORE(sparseMulAFp12BN254_a22_x) + 30n :MSTORE(sparseMulAFp12BN254_a22_y) + 7n :MSTORE(sparseMulAFp12BN254_a23_x) + 69n :MSTORE(sparseMulAFp12BN254_a23_y) + 7n :MSTORE(sparseMulAFp12BN254_b12_x) + 6n :MSTORE(sparseMulAFp12BN254_b12_y) + 7n :MSTORE(sparseMulAFp12BN254_b22_x) + 83n :MSTORE(sparseMulAFp12BN254_b22_y) + 2n :MSTORE(sparseMulAFp12BN254_b23_x) + 29n :MSTORE(sparseMulAFp12BN254_b23_y) + :CALL(sparseMulAFp12BN254) 21888242871839275222246405745257275088696311157297823662689037894645226182573n :MLOAD(sparseMulAFp12BN254_c11_x) 15970n :MLOAD(sparseMulAFp12BN254_c11_y) 21888242871839275222246405745257275088696311157297823662689037894645226148297n :MLOAD(sparseMulAFp12BN254_c12_x) @@ -556,25 +564,26 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226208431n :MLOAD(sparseMulAFp12BN254_c23_x) 396n :MLOAD(sparseMulAFp12BN254_c23_y) - 2n :MSTORE(sparseMulBFp12BN254_a11_x) - 4n :MSTORE(sparseMulBFp12BN254_a11_y) - 0n :MSTORE(sparseMulBFp12BN254_a12_x) - 0n :MSTORE(sparseMulBFp12BN254_a12_y) - 0n :MSTORE(sparseMulBFp12BN254_a13_x) - 5n :MSTORE(sparseMulBFp12BN254_a13_y) - 5n :MSTORE(sparseMulBFp12BN254_a21_x) - 10n :MSTORE(sparseMulBFp12BN254_a21_y) - 20n :MSTORE(sparseMulBFp12BN254_a22_x) - 30n :MSTORE(sparseMulBFp12BN254_a22_y) - 7n :MSTORE(sparseMulBFp12BN254_a23_x) - 69n :MSTORE(sparseMulBFp12BN254_a23_y) - 7n :MSTORE(sparseMulBFp12BN254_b11_x) - 6n :MSTORE(sparseMulBFp12BN254_b11_y) - 7n :MSTORE(sparseMulBFp12BN254_b13_x) - 83n :MSTORE(sparseMulBFp12BN254_b13_y) - 2n :MSTORE(sparseMulBFp12BN254_b22_x) - 29n :MSTORE(sparseMulBFp12BN254_b22_y) - :CALL(sparseMulBFp12BN254) + ; 11] Sparse Multiplication B + 2n :MSTORE(sparseMulBFp12BN254_a11_x) + 4n :MSTORE(sparseMulBFp12BN254_a11_y) + 0n :MSTORE(sparseMulBFp12BN254_a12_x) + 0n :MSTORE(sparseMulBFp12BN254_a12_y) + 0n :MSTORE(sparseMulBFp12BN254_a13_x) + 5n :MSTORE(sparseMulBFp12BN254_a13_y) + 5n :MSTORE(sparseMulBFp12BN254_a21_x) + 10n :MSTORE(sparseMulBFp12BN254_a21_y) + 20n :MSTORE(sparseMulBFp12BN254_a22_x) + 30n :MSTORE(sparseMulBFp12BN254_a22_y) + 7n :MSTORE(sparseMulBFp12BN254_a23_x) + 69n :MSTORE(sparseMulBFp12BN254_a23_y) + 7n :MSTORE(sparseMulBFp12BN254_b11_x) + 6n :MSTORE(sparseMulBFp12BN254_b11_y) + 7n :MSTORE(sparseMulBFp12BN254_b13_x) + 83n :MSTORE(sparseMulBFp12BN254_b13_y) + 2n :MSTORE(sparseMulBFp12BN254_b22_x) + 29n :MSTORE(sparseMulBFp12BN254_b22_y) + :CALL(sparseMulBFp12BN254) 21888242871839275222246405745257275088696311157297823662689037894645226200463n :MLOAD(sparseMulBFp12BN254_c11_x) 4970n :MLOAD(sparseMulBFp12BN254_c11_y) 21888242871839275222246405745257275088696311157297823662689037894645226186589n :MLOAD(sparseMulBFp12BN254_c12_x) diff --git a/test/testFp2ArithBN254.zkasm b/test/testFp2ArithBN254.zkasm index 1796eaa4..5e5edca8 100644 --- a/test/testFp2ArithBN254.zkasm +++ b/test/testFp2ArithBN254.zkasm @@ -51,56 +51,56 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; 1] addFp2BN254 + ; 1] Addition 1n => A 2n => B 3n => C 4n => D - :CALL(addFp2BN254) + :CALL(addFp2BN254) E => A - 4n :ASSERT + 4n :ASSERT C => A - 6n :ASSERT + 6n :ASSERT - ; 2] subFp2BN254 + ; 2] Subtraction 1n => A 4n => B 3n => C 2n => D - :CALL(subFp2BN254) + :CALL(subFp2BN254) E => A - 21888242871839275222246405745257275088696311157297823662689037894645226208581n :ASSERT + 21888242871839275222246405745257275088696311157297823662689037894645226208581n :ASSERT C => A - 2n :ASSERT + 2n :ASSERT - ; 3] invFp2BN254 + ; 3] Inversion 0n => A 0n => B - :CALL(invFp2BN254) + :CALL(invFp2BN254) C => A - 0 :ASSERT + 0 :ASSERT D => A - 0 :ASSERT + 0 :ASSERT 2n => A 0n => B - :CALL(invFp2BN254) + :CALL(invFp2BN254) C => A - 10944121435919637611123202872628637544348155578648911831344518947322613104292n :ASSERT + 10944121435919637611123202872628637544348155578648911831344518947322613104292n :ASSERT D => A - 0 :ASSERT + 0 :ASSERT 0n => A 2n => B - :CALL(invFp2BN254) + :CALL(invFp2BN254) C => A - 0 :ASSERT + 0 :ASSERT D => A - 10944121435919637611123202872628637544348155578648911831344518947322613104291n :ASSERT + 10944121435919637611123202872628637544348155578648911831344518947322613104291n :ASSERT 1n => A 2n => B - :CALL(invFp2BN254) + :CALL(invFp2BN254) C => A 13132945723103565133347843447154365053217786694378694197613422736787135725150n :ASSERT D => A @@ -108,30 +108,30 @@ start: 1n => A 4n => B - :CALL(invFp2BN254) + :CALL(invFp2BN254) C => A - 5150174793373947111116801351825241197340308507599487920632714798740053225549n :ASSERT + 5150174793373947111116801351825241197340308507599487920632714798740053225549n :ASSERT D => A - 1287543698343486777779200337956310299335077126899871980158178699685013306387n :ASSERT + 1287543698343486777779200337956310299335077126899871980158178699685013306387n :ASSERT - ; 4] squareFp2BN254 + ; 4] Squaring 1n => A 4n => B - :CALL(squareFp2BN254) + :CALL(squareFp2BN254) E => A - 21888242871839275222246405745257275088696311157297823662689037894645226208568n :ASSERT + 21888242871839275222246405745257275088696311157297823662689037894645226208568n :ASSERT C => A - 8n :ASSERT + 8n :ASSERT - ; 5] escalarMulFp2BN254 + ; 5] Escalar Multiplication 3n => A 6n => C 4n => D - :CALL(escalarMulFp2BN254) + :CALL(escalarMulFp2BN254) E => A - 18n :ASSERT + 18n :ASSERT C => A - 12n :ASSERT + 12n :ASSERT end: diff --git a/test/testFp4ArithBN254.zkasm b/test/testFp4ArithBN254.zkasm index 2325be32..eb7eb356 100644 --- a/test/testFp4ArithBN254.zkasm +++ b/test/testFp4ArithBN254.zkasm @@ -53,12 +53,12 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - - 10n :MSTORE(squareFp4BN254_a1_x) - 2n :MSTORE(squareFp4BN254_a1_y) - 5n :MSTORE(squareFp4BN254_a2_x) - 13n :MSTORE(squareFp4BN254_a2_y) - :CALL(squareFp4BN254) + ; 1] Squaring + 10n :MSTORE(squareFp4BN254_a1_x) + 2n :MSTORE(squareFp4BN254_a1_y) + 5n :MSTORE(squareFp4BN254_a2_x) + 13n :MSTORE(squareFp4BN254_a2_y) + :CALL(squareFp4BN254) 21888242871839275222246405745257275088696311157297823662689037894645226207253n :MLOAD(squareFp4BN254_c1_x) 1066n :MLOAD(squareFp4BN254_c1_y) 48n :MLOAD(squareFp4BN254_c2_x) @@ -68,31 +68,31 @@ start: 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(squareFp4BN254_a1_y) 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(squareFp4BN254_a2_x) 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(squareFp4BN254_a2_y) - :CALL(squareFp4BN254) + :CALL(squareFp4BN254) 15642230407184709854191402253941510745542675973646512616778035989040585383674n :MLOAD(squareFp4BN254_c1_x) - 10571263136441780241186417424383296989551244467442137323566769601209939419494n :MLOAD(squareFp4BN254_c1_y) - 6170062994267544397251278503016502296650869661919757709986684938219961904903n :MLOAD(squareFp4BN254_c2_x) - 12649805430863841208195335781539094665986469361747095927044787835518047599036n :MLOAD(squareFp4BN254_c2_y) + 10571263136441780241186417424383296989551244467442137323566769601209939419494n :MLOAD(squareFp4BN254_c1_y) + 6170062994267544397251278503016502296650869661919757709986684938219961904903n :MLOAD(squareFp4BN254_c2_x) + 12649805430863841208195335781539094665986469361747095927044787835518047599036n :MLOAD(squareFp4BN254_c2_y) 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(squareFp4BN254_a1_x) 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(squareFp4BN254_a1_y) 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(squareFp4BN254_a2_x) 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(squareFp4BN254_a2_y) - :CALL(squareFp4BN254) + :CALL(squareFp4BN254) 16581870619415451126551726594735526085487022283882461718257601048476775174962n :MLOAD(squareFp4BN254_c1_x) - 17425425191459276292844278407733970229852884109311293307835712217611024800631n :MLOAD(squareFp4BN254_c1_y) - 8575705441614264531578658232489896441903287755517533490443707322133595575350n :MLOAD(squareFp4BN254_c2_x) - 1420704269848014824822507372800732975177532865526459851528139384475759777251n :MLOAD(squareFp4BN254_c2_y) + 17425425191459276292844278407733970229852884109311293307835712217611024800631n :MLOAD(squareFp4BN254_c1_y) + 8575705441614264531578658232489896441903287755517533490443707322133595575350n :MLOAD(squareFp4BN254_c2_x) + 1420704269848014824822507372800732975177532865526459851528139384475759777251n :MLOAD(squareFp4BN254_c2_y) 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(squareFp4BN254_a1_x) 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(squareFp4BN254_a1_y) 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(squareFp4BN254_a2_x) 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(squareFp4BN254_a2_y) - :CALL(squareFp4BN254) + :CALL(squareFp4BN254) 21619634434169277903921567747458615807087054226321025796441846170083311843089n :MLOAD(squareFp4BN254_c1_x) - 11114801799445547818360302932473536671091998531326283968259951405183921806320n :MLOAD(squareFp4BN254_c1_y) - 13146343736154811194795223124891192023354979304499035796722737687445144937601n :MLOAD(squareFp4BN254_c2_x) - 4599958258989867272310306821691486925189277480266178822728743054647870795549n :MLOAD(squareFp4BN254_c2_y) + 11114801799445547818360302932473536671091998531326283968259951405183921806320n :MLOAD(squareFp4BN254_c1_y) + 13146343736154811194795223124891192023354979304499035796722737687445144937601n :MLOAD(squareFp4BN254_c2_x) + 4599958258989867272310306821691486925189277480266178822728743054647870795549n :MLOAD(squareFp4BN254_c2_y) end: diff --git a/test/testFp6ArithBN254.zkasm b/test/testFp6ArithBN254.zkasm index 9252544d..5259b73b 100644 --- a/test/testFp6ArithBN254.zkasm +++ b/test/testFp6ArithBN254.zkasm @@ -53,103 +53,106 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) + ; 1] Addition + 10n :MSTORE(addFp6BN254_a1_x) + 2n :MSTORE(addFp6BN254_a1_y) + 5n :MSTORE(addFp6BN254_a2_x) + 13n :MSTORE(addFp6BN254_a2_y) + 7n :MSTORE(addFp6BN254_a3_x) + 5n :MSTORE(addFp6BN254_a3_y) + 9n :MSTORE(addFp6BN254_b1_x) + 1n :MSTORE(addFp6BN254_b1_y) + 1n :MSTORE(addFp6BN254_b2_x) + 2n :MSTORE(addFp6BN254_b2_y) + 14n :MSTORE(addFp6BN254_b3_x) + 3n :MSTORE(addFp6BN254_b3_y) + :CALL(addFp6BN254) + 19n :MLOAD(addFp6BN254_c1_x) + 3n :MLOAD(addFp6BN254_c1_y) + 6n :MLOAD(addFp6BN254_c2_x) + 15n :MLOAD(addFp6BN254_c2_y) + 21n :MLOAD(addFp6BN254_c3_x) + 8n :MLOAD(addFp6BN254_c3_y) - 10n :MSTORE(addFp6BN254_a1_x) - 2n :MSTORE(addFp6BN254_a1_y) - 5n :MSTORE(addFp6BN254_a2_x) - 13n :MSTORE(addFp6BN254_a2_y) - 7n :MSTORE(addFp6BN254_a3_x) - 5n :MSTORE(addFp6BN254_a3_y) - 9n :MSTORE(addFp6BN254_b1_x) - 1n :MSTORE(addFp6BN254_b1_y) - 1n :MSTORE(addFp6BN254_b2_x) - 2n :MSTORE(addFp6BN254_b2_y) - 14n :MSTORE(addFp6BN254_b3_x) - 3n :MSTORE(addFp6BN254_b3_y) - :CALL(addFp6BN254) - 19n :MLOAD(addFp6BN254_c1_x) - 3n :MLOAD(addFp6BN254_c1_y) - 6n :MLOAD(addFp6BN254_c2_x) - 15n :MLOAD(addFp6BN254_c2_y) - 21n :MLOAD(addFp6BN254_c3_x) - 8n :MLOAD(addFp6BN254_c3_y) - - - 10n :MSTORE(subFp6BN254_a1_x) - 2n :MSTORE(subFp6BN254_a1_y) - 5n :MSTORE(subFp6BN254_a2_x) - 13n :MSTORE(subFp6BN254_a2_y) - 7n :MSTORE(subFp6BN254_a3_x) - 5n :MSTORE(subFp6BN254_a3_y) - 9n :MSTORE(subFp6BN254_b1_x) - 1n :MSTORE(subFp6BN254_b1_y) - 1n :MSTORE(subFp6BN254_b2_x) - 2n :MSTORE(subFp6BN254_b2_y) - 14n :MSTORE(subFp6BN254_b3_x) - 3n :MSTORE(subFp6BN254_b3_y) - :CALL(subFp6BN254) - 1n :MLOAD(subFp6BN254_c1_x) - 1n :MLOAD(subFp6BN254_c1_y) - 4n :MLOAD(subFp6BN254_c2_x) - 11n :MLOAD(subFp6BN254_c2_y) + ; 2] Subtraction + 10n :MSTORE(subFp6BN254_a1_x) + 2n :MSTORE(subFp6BN254_a1_y) + 5n :MSTORE(subFp6BN254_a2_x) + 13n :MSTORE(subFp6BN254_a2_y) + 7n :MSTORE(subFp6BN254_a3_x) + 5n :MSTORE(subFp6BN254_a3_y) + 9n :MSTORE(subFp6BN254_b1_x) + 1n :MSTORE(subFp6BN254_b1_y) + 1n :MSTORE(subFp6BN254_b2_x) + 2n :MSTORE(subFp6BN254_b2_y) + 14n :MSTORE(subFp6BN254_b3_x) + 3n :MSTORE(subFp6BN254_b3_y) + :CALL(subFp6BN254) + 1n :MLOAD(subFp6BN254_c1_x) + 1n :MLOAD(subFp6BN254_c1_y) + 4n :MLOAD(subFp6BN254_c2_x) + 11n :MLOAD(subFp6BN254_c2_y) 21888242871839275222246405745257275088696311157297823662689037894645226208576n :MLOAD(subFp6BN254_c3_x) - 2n :MLOAD(subFp6BN254_c3_y) - - 10n :MSTORE(mulFp6BN254_a1_x) - 2n :MSTORE(mulFp6BN254_a1_y) - 5n :MSTORE(mulFp6BN254_a2_x) - 13n :MSTORE(mulFp6BN254_a2_y) - 7n :MSTORE(mulFp6BN254_a3_x) - 5n :MSTORE(mulFp6BN254_a3_y) - 9n :MSTORE(mulFp6BN254_b1_x) - 1n :MSTORE(mulFp6BN254_b1_y) - 1n :MSTORE(mulFp6BN254_b2_x) - 2n :MSTORE(mulFp6BN254_b2_y) - 14n :MSTORE(mulFp6BN254_b3_x) - 2n :MSTORE(mulFp6BN254_b3_y) - :CALL(mulFp6BN254) - 246n :MLOAD(mulFp6BN254_c1_x) - 1968n :MLOAD(mulFp6BN254_c1_y) - 746n :MLOAD(mulFp6BN254_c2_x) - 988n :MLOAD(mulFp6BN254_c2_y) - 173n :MLOAD(mulFp6BN254_c3_x) - 123n :MLOAD(mulFp6BN254_c3_y) - - 10n :MSTORE(squareFp6BN254_a1_x) - 2n :MSTORE(squareFp6BN254_a1_y) - 5n :MSTORE(squareFp6BN254_a2_x) - 13n :MSTORE(squareFp6BN254_a2_y) - 7n :MSTORE(squareFp6BN254_a3_x) - 5n :MSTORE(squareFp6BN254_a3_y) - :CALL(squareFp6BN254) + 2n :MLOAD(subFp6BN254_c3_y) + + ; 3] Multiplication + 10n :MSTORE(mulFp6BN254_a1_x) + 2n :MSTORE(mulFp6BN254_a1_y) + 5n :MSTORE(mulFp6BN254_a2_x) + 13n :MSTORE(mulFp6BN254_a2_y) + 7n :MSTORE(mulFp6BN254_a3_x) + 5n :MSTORE(mulFp6BN254_a3_y) + 9n :MSTORE(mulFp6BN254_b1_x) + 1n :MSTORE(mulFp6BN254_b1_y) + 1n :MSTORE(mulFp6BN254_b2_x) + 2n :MSTORE(mulFp6BN254_b2_y) + 14n :MSTORE(mulFp6BN254_b3_x) + 2n :MSTORE(mulFp6BN254_b3_y) + :CALL(mulFp6BN254) + 246n :MLOAD(mulFp6BN254_c1_x) + 1968n :MLOAD(mulFp6BN254_c1_y) + 746n :MLOAD(mulFp6BN254_c2_x) + 988n :MLOAD(mulFp6BN254_c2_y) + 173n :MLOAD(mulFp6BN254_c3_x) + 123n :MLOAD(mulFp6BN254_c3_y) + + ; 4] Square + 10n :MSTORE(squareFp6BN254_a1_x) + 2n :MSTORE(squareFp6BN254_a1_y) + 5n :MSTORE(squareFp6BN254_a2_x) + 13n :MSTORE(squareFp6BN254_a2_y) + 7n :MSTORE(squareFp6BN254_a3_x) + 5n :MSTORE(squareFp6BN254_a3_y) + :CALL(squareFp6BN254) 21888242871839275222246405745257275088696311157297823662689037894645226207907n :MLOAD(squareFp6BN254_c1_x) - 2068n :MLOAD(squareFp6BN254_c1_y) - 194n :MLOAD(squareFp6BN254_c2_x) - 934n :MLOAD(squareFp6BN254_c2_y) + 2068n :MLOAD(squareFp6BN254_c1_y) + 194n :MLOAD(squareFp6BN254_c2_x) + 934n :MLOAD(squareFp6BN254_c2_y) 21888242871839275222246405745257275088696311157297823662689037894645226208559n :MLOAD(squareFp6BN254_c3_x) - 258n :MLOAD(squareFp6BN254_c3_y) - - 0n :MSTORE(inverseFp6BN254_a1_x) - 0n :MSTORE(inverseFp6BN254_a1_y) - 0n :MSTORE(inverseFp6BN254_a2_x) - 0n :MSTORE(inverseFp6BN254_a2_y) - 0n :MSTORE(inverseFp6BN254_a3_x) - 0n :MSTORE(inverseFp6BN254_a3_y) - :CALL(inverseFp6BN254) - 0n :MLOAD(inverseFp6BN254_c1_x) - 0n :MLOAD(inverseFp6BN254_c1_y) - 0n :MLOAD(inverseFp6BN254_c2_x) - 0n :MLOAD(inverseFp6BN254_c2_y) - 0n :MLOAD(inverseFp6BN254_c3_x) - 0n :MLOAD(inverseFp6BN254_c3_y) - - 10n :MSTORE(inverseFp6BN254_a1_x) - 2n :MSTORE(inverseFp6BN254_a1_y) - 5n :MSTORE(inverseFp6BN254_a2_x) - 13n :MSTORE(inverseFp6BN254_a2_y) - 7n :MSTORE(inverseFp6BN254_a3_x) - 5n :MSTORE(inverseFp6BN254_a3_y) - :CALL(inverseFp6BN254) + 258n :MLOAD(squareFp6BN254_c3_y) + + ; 5] Inverse + 0n :MSTORE(inverseFp6BN254_a1_x) + 0n :MSTORE(inverseFp6BN254_a1_y) + 0n :MSTORE(inverseFp6BN254_a2_x) + 0n :MSTORE(inverseFp6BN254_a2_y) + 0n :MSTORE(inverseFp6BN254_a3_x) + 0n :MSTORE(inverseFp6BN254_a3_y) + :CALL(inverseFp6BN254) + 0n :MLOAD(inverseFp6BN254_c1_x) + 0n :MLOAD(inverseFp6BN254_c1_y) + 0n :MLOAD(inverseFp6BN254_c2_x) + 0n :MLOAD(inverseFp6BN254_c2_y) + 0n :MLOAD(inverseFp6BN254_c3_x) + 0n :MLOAD(inverseFp6BN254_c3_y) + + 10n :MSTORE(inverseFp6BN254_a1_x) + 2n :MSTORE(inverseFp6BN254_a1_y) + 5n :MSTORE(inverseFp6BN254_a2_x) + 13n :MSTORE(inverseFp6BN254_a2_y) + 7n :MSTORE(inverseFp6BN254_a3_x) + 5n :MSTORE(inverseFp6BN254_a3_y) + :CALL(inverseFp6BN254) 5783650677754332851980206846879135451516056759867773021970105892178521520613n :MLOAD(inverseFp6BN254_c1_x) 18013759458838322471361728283975517938597408816356047328991338914305007310576n :MLOAD(inverseFp6BN254_c1_y) 18110874882414180653560035658613063208901925857749522062575191314371766555250n :MLOAD(inverseFp6BN254_c2_x) @@ -157,57 +160,60 @@ start: 14149695447230733832672344969363233706238986964811686150151922078523920094032n :MLOAD(inverseFp6BN254_c3_x) 8319081930844559069109603696113388970848243877139140810016204850690606105497n :MLOAD(inverseFp6BN254_c3_y) - 10n :MSTORE(sparseMulAFp6BN254_a1_x) - 2n :MSTORE(sparseMulAFp6BN254_a1_y) - 5n :MSTORE(sparseMulAFp6BN254_a2_x) - 13n :MSTORE(sparseMulAFp6BN254_a2_y) - 7n :MSTORE(sparseMulAFp6BN254_a3_x) - 5n :MSTORE(sparseMulAFp6BN254_a3_y) - 5n :MSTORE(sparseMulAFp6BN254_b2_x) - 78n :MSTORE(sparseMulAFp6BN254_b2_y) - :CALL(sparseMulAFp6BN254) + ; 6] Sparse Multiplication A + 10n :MSTORE(sparseMulAFp6BN254_a1_x) + 2n :MSTORE(sparseMulAFp6BN254_a1_y) + 5n :MSTORE(sparseMulAFp6BN254_a2_x) + 13n :MSTORE(sparseMulAFp6BN254_a2_y) + 7n :MSTORE(sparseMulAFp6BN254_a3_x) + 5n :MSTORE(sparseMulAFp6BN254_a3_y) + 5n :MSTORE(sparseMulAFp6BN254_b2_x) + 78n :MSTORE(sparseMulAFp6BN254_b2_y) + :CALL(sparseMulAFp6BN254) 21888242871839275222246405745257275088696311157297823662689037894645226204817n :MLOAD(sparseMulAFp6BN254_c1_x) - 4784n :MLOAD(sparseMulAFp6BN254_c1_y) + 4784n :MLOAD(sparseMulAFp6BN254_c1_y) 21888242871839275222246405745257275088696311157297823662689037894645226208477n :MLOAD(sparseMulAFp6BN254_c2_x) - 790n :MLOAD(sparseMulAFp6BN254_c2_y) + 790n :MLOAD(sparseMulAFp6BN254_c2_y) 21888242871839275222246405745257275088696311157297823662689037894645226207594n :MLOAD(sparseMulAFp6BN254_c3_x) - 455n :MLOAD(sparseMulAFp6BN254_c3_y) - - 10n :MSTORE(sparseMulBFp6BN254_a1_x) - 2n :MSTORE(sparseMulBFp6BN254_a1_y) - 5n :MSTORE(sparseMulBFp6BN254_a2_x) - 13n :MSTORE(sparseMulBFp6BN254_a2_y) - 7n :MSTORE(sparseMulBFp6BN254_a3_x) - 5n :MSTORE(sparseMulBFp6BN254_a3_y) - 3n :MSTORE(sparseMulBFp6BN254_b2_x) - 100n :MSTORE(sparseMulBFp6BN254_b2_y) - 17n :MSTORE(sparseMulBFp6BN254_b3_x) - 8n :MSTORE(sparseMulBFp6BN254_b3_y) - :CALL(sparseMulBFp6BN254) + 455n :MLOAD(sparseMulAFp6BN254_c3_y) + + ; 7] Sparse Multiplication B + 10n :MSTORE(sparseMulBFp6BN254_a1_x) + 2n :MSTORE(sparseMulBFp6BN254_a1_y) + 5n :MSTORE(sparseMulBFp6BN254_a2_x) + 13n :MSTORE(sparseMulBFp6BN254_a2_y) + 7n :MSTORE(sparseMulBFp6BN254_a3_x) + 5n :MSTORE(sparseMulBFp6BN254_a3_y) + 3n :MSTORE(sparseMulBFp6BN254_b2_x) + 100n :MSTORE(sparseMulBFp6BN254_b2_y) + 17n :MSTORE(sparseMulBFp6BN254_b3_x) + 8n :MSTORE(sparseMulBFp6BN254_b3_y) + :CALL(sparseMulBFp6BN254) 21888242871839275222246405745257275088696311157297823662689037894645226203125n :MLOAD(sparseMulBFp6BN254_c1_x) - 8286n :MLOAD(sparseMulBFp6BN254_c1_y) - 400n :MLOAD(sparseMulBFp6BN254_c2_x) - 2354n :MLOAD(sparseMulBFp6BN254_c2_y) - 21888242871839275222246405745257275088696311157297823662689037894645226207452n:MLOAD(sparseMulBFp6BN254_c3_x) - 653n :MLOAD(sparseMulBFp6BN254_c3_y) - - 10n :MSTORE(sparseMulCFp6BN254_a1_x) - 2n :MSTORE(sparseMulCFp6BN254_a1_y) - 5n :MSTORE(sparseMulCFp6BN254_a2_x) - 13n :MSTORE(sparseMulCFp6BN254_a2_y) - 7n :MSTORE(sparseMulCFp6BN254_a3_x) - 5n :MSTORE(sparseMulCFp6BN254_a3_y) - 3n :MSTORE(sparseMulCFp6BN254_b1_x) - 100n :MSTORE(sparseMulCFp6BN254_b1_y) - 17n :MSTORE(sparseMulCFp6BN254_b3_x) - 8n :MSTORE(sparseMulCFp6BN254_b3_y) - :CALL(sparseMulCFp6BN254) + 8286n :MLOAD(sparseMulBFp6BN254_c1_y) + 400n :MLOAD(sparseMulBFp6BN254_c2_x) + 2354n :MLOAD(sparseMulBFp6BN254_c2_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207452n :MLOAD(sparseMulBFp6BN254_c3_x) + 653n :MLOAD(sparseMulBFp6BN254_c3_y) + + ; 8] Sparse Multiplication C + 10n :MSTORE(sparseMulCFp6BN254_a1_x) + 2n :MSTORE(sparseMulCFp6BN254_a1_y) + 5n :MSTORE(sparseMulCFp6BN254_a2_x) + 13n :MSTORE(sparseMulCFp6BN254_a2_y) + 7n :MSTORE(sparseMulCFp6BN254_a3_x) + 5n :MSTORE(sparseMulCFp6BN254_a3_y) + 3n :MSTORE(sparseMulCFp6BN254_b1_x) + 100n :MSTORE(sparseMulCFp6BN254_b1_y) + 17n :MSTORE(sparseMulCFp6BN254_b3_x) + 8n :MSTORE(sparseMulCFp6BN254_b3_y) + :CALL(sparseMulCFp6BN254) 21888242871839275222246405745257275088696311157297823662689037894645226207981n :MLOAD(sparseMulCFp6BN254_c1_x) - 3336n :MLOAD(sparseMulCFp6BN254_c1_y) + 3336n :MLOAD(sparseMulCFp6BN254_c1_y) 21888242871839275222246405745257275088696311157297823662689037894645226207868n :MLOAD(sparseMulCFp6BN254_c2_x) - 1887n :MLOAD(sparseMulCFp6BN254_c2_y) + 1887n :MLOAD(sparseMulCFp6BN254_c2_y) 21888242871839275222246405745257275088696311157297823662689037894645226208258n :MLOAD(sparseMulCFp6BN254_c3_x) - 829n :MLOAD(sparseMulCFp6BN254_c3_y) + 829n :MLOAD(sparseMulCFp6BN254_c3_y) end: diff --git a/test/testFpArithBN254.zkasm b/test/testFpArithBN254.zkasm index e9741b73..d2364f18 100644 --- a/test/testFpArithBN254.zkasm +++ b/test/testFpArithBN254.zkasm @@ -10,6 +10,7 @@ CONST %MAX_CNT_POSEIDON_G_LIMIT = %N CONSTL %BN254_P = 21888242871839275222246405745257275088696311157297823662689037894645226208583n CONSTL %BN254_P_MINUS_ONE = 21888242871839275222246405745257275088696311157297823662689037894645226208582n +CONSTL %BN254_P_BY_TWO = 43776485743678550444492811490514550177392622314595647325378075789290452417166n VAR GLOBAL lastHashKId VAR GLOBAL lastHashPId @@ -52,64 +53,68 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - + ; 1] Addition 1n => A 3n => C - :CALL(addFpBN254) + :CALL(addFpBN254) C => A - 4n :ASSERT + 4n :ASSERT + ; 2] Subtraction 2n => A 3n => C - :CALL(subFpBN254) + :CALL(subFpBN254) C => A - 21888242871839275222246405745257275088696311157297823662689037894645226208582n :ASSERT + %BN254_P_MINUS_ONE :ASSERT + ; 3] Squaring ${const.BN254_P - 2} => A - :CALL(squareFpBN254) + :CALL(squareFpBN254) B => A - 4n :ASSERT + 4n :ASSERT + ; 4] Inversion 0n => A - :CALL(invFpBN254) + :CALL(invFpBN254) B => A - 0n :ASSERT + 0n :ASSERT %BN254_P + %BN254_P => A - :CALL(invFpBN254) - 0n :ASSERT + :CALL(invFpBN254) + 0n :ASSERT %BN254_P + %BN254_P + %BN254_P => A - :CALL(invFpBN254) - 0n :ASSERT + :CALL(invFpBN254) + 0n :ASSERT %BN254_P + %BN254_P + %BN254_P + %BN254_P => A - :CALL(invFpBN254) - 0n :ASSERT + :CALL(invFpBN254) + 0n :ASSERT %BN254_P + %BN254_P + %BN254_P + %BN254_P + %BN254_P => A - :CALL(invFpBN254) - 0n :ASSERT + :CALL(invFpBN254) + 0n :ASSERT + ; 5] Reduction 0n => A - :CALL(reduceFpBN254) - 0n :ASSERT + :CALL(reduceFpBN254) + 0n :ASSERT %BN254_P => A - :CALL(reduceFpBN254) - 0n :ASSERT + :CALL(reduceFpBN254) + 0n :ASSERT %BN254_P + 1n => A - :CALL(reduceFpBN254) - 1n :ASSERT + :CALL(reduceFpBN254) + 1n :ASSERT - %BN254_P + 21888242871839275222246405745257275088696311157297823662689037894645226208582n => A - :CALL(reduceFpBN254) - 21888242871839275222246405745257275088696311157297823662689037894645226208582n :ASSERT + %BN254_P + %BN254_P_MINUS_ONE => A + :CALL(reduceFpBN254) + %BN254_P_MINUS_ONE :ASSERT - 43776485743678550444492811490514550177392622314595647325378075789290452417166n => A - :CALL(reduceFpBN254) - 0n :ASSERT + %BN254_P_BY_TWO => A + :CALL(reduceFpBN254) + 0n :ASSERT end: diff --git a/test/testFrArithBN254.zkasm b/test/testFrArithBN254.zkasm index 0c56acde..0ae8cfa7 100644 --- a/test/testFrArithBN254.zkasm +++ b/test/testFrArithBN254.zkasm @@ -51,36 +51,36 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - + ; 1] Reduction 3n => B - :CALL(reduceFrBN254) + :CALL(reduceFrBN254) C => A - 3n => B :ASSERT + 3n => B :ASSERT %BN254_R => B - :CALL(reduceFrBN254) + :CALL(reduceFrBN254) C => A - 0n => B :ASSERT + 0n => B :ASSERT 21888242871839275222246405745257275088548364400416034343698204186575808495618n => B - :CALL(reduceFrBN254) + :CALL(reduceFrBN254) C => A - 1n => B :ASSERT + 1n => B :ASSERT %BN254_P => B - :CALL(reduceFrBN254) + :CALL(reduceFrBN254) C => A - %BN254_SIX_TIMES_X_SQ => B :ASSERT + %BN254_SIX_TIMES_X_SQ => B :ASSERT 21888242871839275222246405745257275088696311157297823662689037894645226208584n => B - :CALL(reduceFrBN254) + :CALL(reduceFrBN254) C => A - 147946756881789318990833708069417712967n => B :ASSERT + 147946756881789318990833708069417712967n => B :ASSERT 115792089237316195423570985008687907853269984665640564039457584007913129639935n => B - :CALL(reduceFrBN254) + :CALL(reduceFrBN254) C => A - 6350874878119819312338956282401532410528162663560392320966563075034087161850n => B :ASSERT + 6350874878119819312338956282401532410528162663560392320966563075034087161850n => B :ASSERT end: diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index 2ef55605..72567d80 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -257,175 +257,175 @@ start: ; --------------------------------------------------------------------------------------------- ; 1] B = [100n, 2831023n, 0n, 73916234139162n], E = [2n**256n - 1n], M = [0n, 0n, 8238129386n, 23102318237n] ; Hamming weight of E is 256 - 4 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 4 :MSTORE(modexp_Mlen) + 4 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 4 :MSTORE(modexp_Mlen) - 100n :MSTORE(modexp_B) + 100n :MSTORE(modexp_B) 1 => E - 2831023n :MSTORE(modexp_B + E) + 2831023n :MSTORE(modexp_B + E) 2 => E - 0n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_B + E) 3 => E - 73916234139162n :MSTORE(modexp_B + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) + 73916234139162n :MSTORE(modexp_B + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) 1 => E - 0n :MSTORE(modexp_M + E) + 0n :MSTORE(modexp_M + E) 2 => E - 8238129386n :MSTORE(modexp_M + E) + 8238129386n :MSTORE(modexp_M + E) 3 => E - 23102318237n :MSTORE(modexp_M + E) - :CALL(modexp) - 0n :MLOAD(modexp_out) + 23102318237n :MSTORE(modexp_M + E) + :CALL(modexp) + 0n :MLOAD(modexp_out) 1 => E - 0n :MLOAD(modexp_out + E) + 0n :MLOAD(modexp_out + E) 2 => E - 25636070175539943947777314844209202718110211581133019863886488575898865601868n :MLOAD(modexp_out + E) + 25636070175539943947777314844209202718110211581133019863886488575898865601868n :MLOAD(modexp_out + E) 3 => E - 4679155145n :MLOAD(modexp_out + E) - 4 :MLOAD(modexp_outlen) + 4679155145n :MLOAD(modexp_out + E) + 4 :MLOAD(modexp_outlen) ; 2] B = [100n, 2831023n, 0n, 73916234139162n, 100n, 2831023n, 0n, 73916234139162n,100n, 2831023n, 0n, 73916234139162n], E = [903741926349715234612309461283471234n], M = [0n, 0n, 8238129386n, 23102318237n, 1892397612351n, 7246598123051n, 8238129386n, 1264591241237897123126n] ; Hamming weight of E is 120 - 12 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 8 :MSTORE(modexp_Mlen) + 12 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 8 :MSTORE(modexp_Mlen) - 100n :MSTORE(modexp_B) + 100n :MSTORE(modexp_B) 1 => E - 2831023n :MSTORE(modexp_B + E) + 2831023n :MSTORE(modexp_B + E) 2 => E - 0n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_B + E) 3 => E - 73916234139162n :MSTORE(modexp_B + E) + 73916234139162n :MSTORE(modexp_B + E) 4 => E - 100n :MSTORE(modexp_B + E) + 100n :MSTORE(modexp_B + E) 5 => E - 2831023n :MSTORE(modexp_B + E) + 2831023n :MSTORE(modexp_B + E) 6 => E - 0n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_B + E) 7 => E - 73916234139162n :MSTORE(modexp_B + E) + 73916234139162n :MSTORE(modexp_B + E) 8 => E - 100n :MSTORE(modexp_B + E) + 100n :MSTORE(modexp_B + E) 9 => E - 2831023n :MSTORE(modexp_B + E) + 2831023n :MSTORE(modexp_B + E) 10 => E - 0n :MSTORE(modexp_B + E) + 0n :MSTORE(modexp_B + E) 11 => E - 73916234139162n :MSTORE(modexp_B + E) - 903741926349715234612309461283471234n :MSTORE(modexp_E) - 0n :MSTORE(modexp_M) + 73916234139162n :MSTORE(modexp_B + E) + 903741926349715234612309461283471234n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) 1 => E - 0n :MSTORE(modexp_M + E) + 0n :MSTORE(modexp_M + E) 2 => E - 8238129386n :MSTORE(modexp_M + E) + 8238129386n :MSTORE(modexp_M + E) 3 => E - 23102318237n :MSTORE(modexp_M + E) + 23102318237n :MSTORE(modexp_M + E) 4 => E - 1892397612351n :MSTORE(modexp_M + E) + 1892397612351n :MSTORE(modexp_M + E) 5 => E - 7246598123051n :MSTORE(modexp_M + E) + 7246598123051n :MSTORE(modexp_M + E) 6 => E - 8238129386n :MSTORE(modexp_M + E) + 8238129386n :MSTORE(modexp_M + E) 7 => E - 1264591241237897123126n :MSTORE(modexp_M + E) - :CALL(modexp) - 0n :MLOAD(modexp_out) + 1264591241237897123126n :MSTORE(modexp_M + E) + :CALL(modexp) + 0n :MLOAD(modexp_out) 1 => E - 0n :MLOAD(modexp_out + E) + 0n :MLOAD(modexp_out + E) 2 => E - 14984469305990977542353827078899382678368215018946198341845725551977623627446n :MLOAD(modexp_out + E) + 14984469305990977542353827078899382678368215018946198341845725551977623627446n :MLOAD(modexp_out + E) 3 => E - 68986200907052834988812862957862042564780541926701277492865197684364096948359n :MLOAD(modexp_out + E) + 68986200907052834988812862957862042564780541926701277492865197684364096948359n :MLOAD(modexp_out + E) 4 => E - 19960171666179366961875030436152164148711578520678689062449823687317995303656n :MLOAD(modexp_out + E) + 19960171666179366961875030436152164148711578520678689062449823687317995303656n :MLOAD(modexp_out + E) 5 => E - 10163909190618518832451417682132582498490814809943760852308996448668923869413n :MLOAD(modexp_out + E) + 10163909190618518832451417682132582498490814809943760852308996448668923869413n :MLOAD(modexp_out + E) 6 => E - 29735535392706191114764336807325502135962613879333248096358552087717155148899n :MLOAD(modexp_out + E) + 29735535392706191114764336807325502135962613879333248096358552087717155148899n :MLOAD(modexp_out + E) 7 => E - 511131288598502431475n :MLOAD(modexp_out + E) - 8 :MLOAD(modexp_outlen) + 511131288598502431475n :MLOAD(modexp_out + E) + 8 :MLOAD(modexp_outlen) ; 3] B = [7n], E = [110n], M = [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] ; Hamming weight of E is 5 - 1 :MSTORE(modexp_Blen) - 1 :MSTORE(modexp_Elen) - 2 :MSTORE(modexp_Mlen) + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 2 :MSTORE(modexp_Mlen) - 7n :MSTORE(modexp_B) - 110n :MSTORE(modexp_E) - 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(modexp_M) + 7n :MSTORE(modexp_B) + 110n :MSTORE(modexp_E) + 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(modexp_M) 1 => E - 17n :MSTORE(modexp_M + E) - :CALL(modexp) - 81730215206688390341255830729934766338330049967253209305087427132484271882414n :MLOAD(modexp_out) + 17n :MSTORE(modexp_M + E) + :CALL(modexp) + 81730215206688390341255830729934766338330049967253209305087427132484271882414n :MLOAD(modexp_out) 1 => E - 13n :MLOAD(modexp_out + E) - 2 :MLOAD(modexp_outlen) + 13n :MLOAD(modexp_out + E) + 2 :MLOAD(modexp_outlen) ; --------------------------------------------------------------------------------------------- ; 512 BITS EXPONENT TESTS ; --------------------------------------------------------------------------------------------- ; 1] B = [2n, 1n, 1n, 1n], E = [3n, 5n], M = [4n, 6n, 7n] ; Hamming weight of E is 4 - 4 :MSTORE(modexp_Blen) - 2 :MSTORE(modexp_Elen) - 3 :MSTORE(modexp_Mlen) + 4 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 3 :MSTORE(modexp_Mlen) - 2n :MSTORE(modexp_B) + 2n :MSTORE(modexp_B) 1 => E - 1n :MSTORE(modexp_B + E) + 1n :MSTORE(modexp_B + E) 2 => E - 1n :MSTORE(modexp_B + E) + 1n :MSTORE(modexp_B + E) 3 => E - 1n :MSTORE(modexp_B + E) - 3n :MSTORE(modexp_E) + 1n :MSTORE(modexp_B + E) + 3n :MSTORE(modexp_E) 1 => E - 5n :MSTORE(modexp_E + E) - 4n :MSTORE(modexp_M) + 5n :MSTORE(modexp_E + E) + 4n :MSTORE(modexp_M) 1 => E - 6n :MSTORE(modexp_M + E) + 6n :MSTORE(modexp_M + E) 2 => E - 7n :MSTORE(modexp_M + E) - :CALL(modexp) - 16799222018138169590613227618843456355247327644003751420511040302320945803948n :MLOAD(modexp_out) + 7n :MSTORE(modexp_M + E) + :CALL(modexp) + 16799222018138169590613227618843456355247327644003751420511040302320945803948n :MLOAD(modexp_out) 1 => E - 67226185770814561827024093064262870237432709513661454124124794094744315370418n :MLOAD(modexp_out + E) + 67226185770814561827024093064262870237432709513661454124124794094744315370418n :MLOAD(modexp_out + E) 2 => E - 1n :MLOAD(modexp_out + E) - 3 :MLOAD(modexp_outlen) + 1n :MLOAD(modexp_out + E) + 3 :MLOAD(modexp_outlen) ; 2] B = [2n, 1n, 1n, 1n], E = [2n**256n - 1n, 2n**256n - 1n], M = [4n, 6n, 7n] ; Hamming weight of E is 512 - 4 :MSTORE(modexp_Blen) - 2 :MSTORE(modexp_Elen) - 3 :MSTORE(modexp_Mlen) + 4 :MSTORE(modexp_Blen) + 2 :MSTORE(modexp_Elen) + 3 :MSTORE(modexp_Mlen) - 2n :MSTORE(modexp_B) + 2n :MSTORE(modexp_B) 1 => E - 1n :MSTORE(modexp_B + E) + 1n :MSTORE(modexp_B + E) 2 => E - 1n :MSTORE(modexp_B + E) + 1n :MSTORE(modexp_B + E) 3 => E - 1n :MSTORE(modexp_B + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) + 1n :MSTORE(modexp_B + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E + E) - 4n :MSTORE(modexp_M) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E + E) + 4n :MSTORE(modexp_M) 1 => E - 6n :MSTORE(modexp_M + E) + 6n :MSTORE(modexp_M + E) 2 => E - 7n :MSTORE(modexp_M + E) - :CALL(modexp) - 111873638420780286093512129901489267041413036926649390648147612881355784341812n :MLOAD(modexp_out) + 7n :MSTORE(modexp_M + E) + :CALL(modexp) + 111873638420780286093512129901489267041413036926649390648147612881355784341812n :MLOAD(modexp_out) 1 => E - 11181991619082508729788448443921623930160246165837402400671610626538926623319n :MLOAD(modexp_out + E) + 11181991619082508729788448443921623930160246165837402400671610626538926623319n :MLOAD(modexp_out + E) 2 => E - 2n :MLOAD(modexp_out + E) - 3 :MLOAD(modexp_outlen) + 2n :MLOAD(modexp_out + E) + 3 :MLOAD(modexp_outlen) ; --------------------------------------------------------------------------------------------- ; 768 BITS EXPONENT TESTS diff --git a/test/testPairingBN254.zkasm b/test/testPairingBN254.zkasm index 867f7b67..57fce84e 100644 --- a/test/testPairingBN254.zkasm +++ b/test/testPairingBN254.zkasm @@ -59,18 +59,18 @@ start: 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) - 1n :MLOAD(pairingBN254_f11_x) - 0n :MLOAD(pairingBN254_f11_y) - 0n :MLOAD(pairingBN254_f12_x) - 0n :MLOAD(pairingBN254_f12_y) - 0n :MLOAD(pairingBN254_f13_x) - 0n :MLOAD(pairingBN254_f13_y) - 0n :MLOAD(pairingBN254_f21_x) - 0n :MLOAD(pairingBN254_f21_y) - 0n :MLOAD(pairingBN254_f22_x) - 0n :MLOAD(pairingBN254_f22_y) - 0n :MLOAD(pairingBN254_f23_x) - 0n :MLOAD(pairingBN254_f23_y) + 1n :MLOAD(pairingBN254_f11_x) + 0n :MLOAD(pairingBN254_f11_y) + 0n :MLOAD(pairingBN254_f12_x) + 0n :MLOAD(pairingBN254_f12_y) + 0n :MLOAD(pairingBN254_f13_x) + 0n :MLOAD(pairingBN254_f13_y) + 0n :MLOAD(pairingBN254_f21_x) + 0n :MLOAD(pairingBN254_f21_y) + 0n :MLOAD(pairingBN254_f22_x) + 0n :MLOAD(pairingBN254_f22_y) + 0n :MLOAD(pairingBN254_f23_x) + 0n :MLOAD(pairingBN254_f23_y) 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) @@ -79,91 +79,91 @@ start: 0n :MSTORE(pairingBN254_Q_y1) 0n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) - 1n :MLOAD(pairingBN254_f11_x) - 0n :MLOAD(pairingBN254_f11_y) - 0n :MLOAD(pairingBN254_f12_x) - 0n :MLOAD(pairingBN254_f12_y) - 0n :MLOAD(pairingBN254_f13_x) - 0n :MLOAD(pairingBN254_f13_y) - 0n :MLOAD(pairingBN254_f21_x) - 0n :MLOAD(pairingBN254_f21_y) - 0n :MLOAD(pairingBN254_f22_x) - 0n :MLOAD(pairingBN254_f22_y) - 0n :MLOAD(pairingBN254_f23_x) - 0n :MLOAD(pairingBN254_f23_y) + 1n :MLOAD(pairingBN254_f11_x) + 0n :MLOAD(pairingBN254_f11_y) + 0n :MLOAD(pairingBN254_f12_x) + 0n :MLOAD(pairingBN254_f12_y) + 0n :MLOAD(pairingBN254_f13_x) + 0n :MLOAD(pairingBN254_f13_y) + 0n :MLOAD(pairingBN254_f21_x) + 0n :MLOAD(pairingBN254_f21_y) + 0n :MLOAD(pairingBN254_f22_x) + 0n :MLOAD(pairingBN254_f22_y) + 0n :MLOAD(pairingBN254_f23_x) + 0n :MLOAD(pairingBN254_f23_y) ; 2] P not in range 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_x) 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 1 => A - 1 :EQ + 1 :EQ 0n :MSTORE(pairingBN254_P_x) 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 2 => A - 1 :EQ + 1 :EQ ; 3] Q not in range 0n :MSTORE(pairingBN254_P_x) 0n :MSTORE(pairingBN254_P_y) 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 3 => A - 1 :EQ + 1 :EQ 0n :MSTORE(pairingBN254_P_x) 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) + 1n :MSTORE(pairingBN254_Q_x1) 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 4 => A - 1 :EQ + 1 :EQ 0n :MSTORE(pairingBN254_P_x) 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) + 4n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 5 => A - 1 :EQ + 1 :EQ 0n :MSTORE(pairingBN254_P_x) 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 6 => A - 1 :EQ + 1 :EQ ; 4] P not in G1 1n :MSTORE(pairingBN254_P_x) 1n :MSTORE(pairingBN254_P_y) - 0n :MSTORE(pairingBN254_Q_x1) - 0n :MSTORE(pairingBN254_Q_x2) - 0n :MSTORE(pairingBN254_Q_y1) - 0n :MSTORE(pairingBN254_Q_y2) + 0n :MSTORE(pairingBN254_Q_x1) + 0n :MSTORE(pairingBN254_Q_x2) + 0n :MSTORE(pairingBN254_Q_y1) + 0n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 7 => A - 1 :EQ + 1 :EQ ; 5] Q not in G2 0n :MSTORE(pairingBN254_P_x) @@ -174,7 +174,7 @@ start: 3535501093699632689489376651381121898720279562088698464643486166587401099479n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) 8 => A - 1 :EQ + 1 :EQ ; 6] Bilinearity test: e(2P,12Q) = e(P,12Q)² = e(2P,Q)¹² = e(P,Q)²⁴ = e(12P,2Q) ; e(2P,12Q) @@ -198,40 +198,40 @@ start: 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(pairingBN254_f23_x) 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(pairingBN254_f23_y) - ; e(P,12Q) - 1n :MSTORE(pairingBN254_P_x) - 2n :MSTORE(pairingBN254_P_y) + ; e(P,12Q)² + 1n :MSTORE(pairingBN254_P_x) + 2n :MSTORE(pairingBN254_P_y) 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) - 2n :MSTORE(expCycloFp12BN254_e) - $ => A :MLOAD(pairingBN254_f11_x) - $ => B :MLOAD(pairingBN254_f11_y) - A :MSTORE(expCycloFp12BN254_a11_x) - B :MSTORE(expCycloFp12BN254_a11_y) - $ => A :MLOAD(pairingBN254_f12_x) - $ => B :MLOAD(pairingBN254_f12_y) - A :MSTORE(expCycloFp12BN254_a12_x) - B :MSTORE(expCycloFp12BN254_a12_y) - $ => A :MLOAD(pairingBN254_f13_x) - $ => B :MLOAD(pairingBN254_f13_y) - A :MSTORE(expCycloFp12BN254_a13_x) - B :MSTORE(expCycloFp12BN254_a13_y) - $ => A :MLOAD(pairingBN254_f21_x) - $ => B :MLOAD(pairingBN254_f21_y) - A :MSTORE(expCycloFp12BN254_a21_x) - B :MSTORE(expCycloFp12BN254_a21_y) - $ => A :MLOAD(pairingBN254_f22_x) - $ => B :MLOAD(pairingBN254_f22_y) - A :MSTORE(expCycloFp12BN254_a22_x) - B :MSTORE(expCycloFp12BN254_a22_y) - $ => A :MLOAD(pairingBN254_f23_x) - $ => B :MLOAD(pairingBN254_f23_y) - A :MSTORE(expCycloFp12BN254_a23_x) - B :MSTORE(expCycloFp12BN254_a23_y) - :CALL(expCycloFp12BN254) + 2n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) @@ -245,7 +245,7 @@ start: 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) - ; e(2P,Q) + ; e(2P,Q)¹² 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) @@ -253,32 +253,32 @@ start: 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) - 12n :MSTORE(expCycloFp12BN254_e) - $ => A :MLOAD(pairingBN254_f11_x) - $ => B :MLOAD(pairingBN254_f11_y) - A :MSTORE(expCycloFp12BN254_a11_x) - B :MSTORE(expCycloFp12BN254_a11_y) - $ => A :MLOAD(pairingBN254_f12_x) - $ => B :MLOAD(pairingBN254_f12_y) - A :MSTORE(expCycloFp12BN254_a12_x) - B :MSTORE(expCycloFp12BN254_a12_y) - $ => A :MLOAD(pairingBN254_f13_x) - $ => B :MLOAD(pairingBN254_f13_y) - A :MSTORE(expCycloFp12BN254_a13_x) - B :MSTORE(expCycloFp12BN254_a13_y) - $ => A :MLOAD(pairingBN254_f21_x) - $ => B :MLOAD(pairingBN254_f21_y) - A :MSTORE(expCycloFp12BN254_a21_x) - B :MSTORE(expCycloFp12BN254_a21_y) - $ => A :MLOAD(pairingBN254_f22_x) - $ => B :MLOAD(pairingBN254_f22_y) - A :MSTORE(expCycloFp12BN254_a22_x) - B :MSTORE(expCycloFp12BN254_a22_y) - $ => A :MLOAD(pairingBN254_f23_x) - $ => B :MLOAD(pairingBN254_f23_y) - A :MSTORE(expCycloFp12BN254_a23_x) - B :MSTORE(expCycloFp12BN254_a23_y) - :CALL(expCycloFp12BN254) + 12n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) @@ -292,40 +292,40 @@ start: 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) - ; e(P,Q) - 1n :MSTORE(pairingBN254_P_x) - 2n :MSTORE(pairingBN254_P_y) + ; e(P,Q)²⁴ + 1n :MSTORE(pairingBN254_P_x) + 2n :MSTORE(pairingBN254_P_y) 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(pairingBN254_Q_x2) 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) - 24n :MSTORE(expCycloFp12BN254_e) - $ => A :MLOAD(pairingBN254_f11_x) - $ => B :MLOAD(pairingBN254_f11_y) - A :MSTORE(expCycloFp12BN254_a11_x) - B :MSTORE(expCycloFp12BN254_a11_y) - $ => A :MLOAD(pairingBN254_f12_x) - $ => B :MLOAD(pairingBN254_f12_y) - A :MSTORE(expCycloFp12BN254_a12_x) - B :MSTORE(expCycloFp12BN254_a12_y) - $ => A :MLOAD(pairingBN254_f13_x) - $ => B :MLOAD(pairingBN254_f13_y) - A :MSTORE(expCycloFp12BN254_a13_x) - B :MSTORE(expCycloFp12BN254_a13_y) - $ => A :MLOAD(pairingBN254_f21_x) - $ => B :MLOAD(pairingBN254_f21_y) - A :MSTORE(expCycloFp12BN254_a21_x) - B :MSTORE(expCycloFp12BN254_a21_y) - $ => A :MLOAD(pairingBN254_f22_x) - $ => B :MLOAD(pairingBN254_f22_y) - A :MSTORE(expCycloFp12BN254_a22_x) - B :MSTORE(expCycloFp12BN254_a22_y) - $ => A :MLOAD(pairingBN254_f23_x) - $ => B :MLOAD(pairingBN254_f23_y) - A :MSTORE(expCycloFp12BN254_a23_x) - B :MSTORE(expCycloFp12BN254_a23_y) - :CALL(expCycloFp12BN254) + 24n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) diff --git a/test/testPointArithBN254.zkasm b/test/testPointArithBN254.zkasm index 6399f868..786e05ae 100644 --- a/test/testPointArithBN254.zkasm +++ b/test/testPointArithBN254.zkasm @@ -69,10 +69,10 @@ start: 0n :MLOAD(addPointBN254_P3_y2) ; 0 + P2 = P2 - 0n :MSTORE(addPointBN254_P1_x1) - 0n :MSTORE(addPointBN254_P1_x2) - 0n :MSTORE(addPointBN254_P1_y1) - 0n :MSTORE(addPointBN254_P1_y2) + 0n :MSTORE(addPointBN254_P1_x1) + 0n :MSTORE(addPointBN254_P1_x2) + 0n :MSTORE(addPointBN254_P1_y1) + 0n :MSTORE(addPointBN254_P1_y2) 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P2_y1) @@ -150,21 +150,21 @@ start: 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) :CALL(escalarMulBN254) - 0n :MLOAD(escalarMulBN254_Q_x1) - 0n :MLOAD(escalarMulBN254_Q_x2) - 0n :MLOAD(escalarMulBN254_Q_y1) - 0n :MLOAD(escalarMulBN254_Q_y2) + 0n :MLOAD(escalarMulBN254_Q_x1) + 0n :MLOAD(escalarMulBN254_Q_x2) + 0n :MLOAD(escalarMulBN254_Q_y1) + 0n :MLOAD(escalarMulBN254_Q_y2) - %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k) + %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k) 0n :MSTORE(escalarMulBN254_P_x1) 0n :MSTORE(escalarMulBN254_P_x2) 0n :MSTORE(escalarMulBN254_P_y1) 0n :MSTORE(escalarMulBN254_P_y2) :CALL(escalarMulBN254) - 0n :MLOAD(escalarMulBN254_Q_x1) - 0n :MLOAD(escalarMulBN254_Q_x2) - 0n :MLOAD(escalarMulBN254_Q_y1) - 0n :MLOAD(escalarMulBN254_Q_y2) + 0n :MLOAD(escalarMulBN254_Q_x1) + 0n :MLOAD(escalarMulBN254_Q_x2) + 0n :MLOAD(escalarMulBN254_Q_y1) + 0n :MLOAD(escalarMulBN254_Q_y2) %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k) 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(escalarMulBN254_P_x1) @@ -172,8 +172,8 @@ start: 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) :CALL(escalarMulBN254) - 13824868563399673693405984206252027284526901521624614945388441201916943098448n :MLOAD(escalarMulBN254_Q_x1) - 6070174842523651825461006324987645339257276059765462992338211551285097849152n :MLOAD(escalarMulBN254_Q_x2) + 13824868563399673693405984206252027284526901521624614945388441201916943098448n :MLOAD(escalarMulBN254_Q_x1) + 6070174842523651825461006324987645339257276059765462992338211551285097849152n :MLOAD(escalarMulBN254_Q_x2) 4224873494559498571787136390356590572898009346319218613936276445484292886657n :MLOAD(escalarMulBN254_Q_y1) 14979195929948718632567968180703131754953567972706796447883440492471033097811n :MLOAD(escalarMulBN254_Q_y2) @@ -183,11 +183,12 @@ start: 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) :CALL(escalarMulBN254) - 0n :MLOAD(escalarMulBN254_Q_x1) - 0n :MLOAD(escalarMulBN254_Q_x2) - 0n :MLOAD(escalarMulBN254_Q_y1) - 0n :MLOAD(escalarMulBN254_Q_y2) + 0n :MLOAD(escalarMulBN254_Q_x1) + 0n :MLOAD(escalarMulBN254_Q_x2) + 0n :MLOAD(escalarMulBN254_Q_y1) + 0n :MLOAD(escalarMulBN254_Q_y2) + ; 3] Tangent line to a point 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(lineSamePointsBN254_P_x1) 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(lineSamePointsBN254_P_x2) 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(lineSamePointsBN254_P_y1) @@ -202,6 +203,7 @@ start: 12094372820654450448173487244699814664976451191756576932392084702582606199137n :MLOAD(lineSamePointsBN254_l22_x) 16329471503453734725328813612581742273267405310373604832422964304856480374124n :MLOAD(lineSamePointsBN254_l22_y) + ; 4] Line passing through two different points 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(lineDiffPointsBN254_P1_x1) 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(lineDiffPointsBN254_P1_x2) 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(lineDiffPointsBN254_P1_y1) From 2b160079964b771f3b5633deace8dbbbf1d2055b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 4 Dec 2023 11:30:15 +0100 Subject: [PATCH 053/121] Minor fixes --- package.json | 2 +- test/testArrayArith.zkasm | 833 +++++++++++++++++++------------------- test/testArrayUtils.zkasm | 2 +- 3 files changed, 416 insertions(+), 421 deletions(-) diff --git a/package.json b/package.json index a4bea130..3c939c4d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/zkasmtest-stats", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index 6b8b821a..a8881997 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -46,128 +46,128 @@ start: ; 1] len(inA) = len(inB) 3 => C 3 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - :CALL(array_add) - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + :CALL(array_add) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) 3 => E - 1n :MLOAD(array_add_out + E) - 4 :MLOAD(array_add_len_out) + 1n :MLOAD(array_add_out + E) + 4 :MLOAD(array_add_len_out) - ; 2] len(inA) > len(inB) + ; 2] len(inA) = len(inB) + 1 3 => C 2 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - :CALL(array_add) - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + :CALL(array_add) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) 2 => E - 0n :MLOAD(array_add_out + E) + 0n :MLOAD(array_add_out + E) 3 => E - 1n :MLOAD(array_add_out + E) - 4 :MLOAD(array_add_len_out) + 1n :MLOAD(array_add_out + E) + 4 :MLOAD(array_add_len_out) - ; 2] len(inA) > len(inB) + ; 3] len(inA) = len(inB) + 3 7 => C 4 => D - 0n :MSTORE(array_add_inA) + 0n :MSTORE(array_add_inA) 1 => E - 0n :MSTORE(array_add_inA + E) + 0n :MSTORE(array_add_inA + E) 2 => E - 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inA + E) + 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inA + E) 3 => E - 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inA + E) 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inA + E) + 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inA + E) 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inA + E) + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inA + E) 6 => E - 370491411790392985199n :MSTORE(array_add_inA + E) + 370491411790392985199n :MSTORE(array_add_inA + E) - 0n :MSTORE(array_add_inB) + 0n :MSTORE(array_add_inB) 1 => E - 0n :MSTORE(array_add_inB + E) + 0n :MSTORE(array_add_inB + E) 2 => E - 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inB + E) + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inB + E) 3 => E - 6019321230n :MSTORE(array_add_inB + E) - :CALL(array_add) - 0n :MLOAD(array_add_out) + 6019321230n :MSTORE(array_add_inB + E) + :CALL(array_add) + 0n :MLOAD(array_add_out) 1 => E - 0n :MLOAD(array_add_out + E) + 0n :MLOAD(array_add_out + E) 2 => E - 0n :MLOAD(array_add_out + E) + 0n :MLOAD(array_add_out + E) 3 => E - 0n :MLOAD(array_add_out + E) + 0n :MLOAD(array_add_out + E) 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) 6 => E - 370491411790392985199n :MLOAD(array_add_out + E) - 7 :MLOAD(array_add_len_out) + 370491411790392985199n :MLOAD(array_add_out + E) + 7 :MLOAD(array_add_len_out) - ; 2] len(inA) < len(inB) + ; 4] len(inA) = len(inB) - 3 4 => C 7 => D - 0n :MSTORE(array_add_inA) + 0n :MSTORE(array_add_inA) 1 => E - 0n :MSTORE(array_add_inA + E) + 0n :MSTORE(array_add_inA + E) 2 => E - 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inA + E) + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inA + E) 3 => E - 6019321230n :MSTORE(array_add_inA + E) - - 0n :MSTORE(array_add_inB) + 6019321230n :MSTORE(array_add_inA + E) + + 0n :MSTORE(array_add_inB) 1 => E - 0n :MSTORE(array_add_inB + E) + 0n :MSTORE(array_add_inB + E) 2 => E - 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inB + E) + 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inB + E) 3 => E - 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inB + E) 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inB + E) + 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inB + E) 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inB + E) + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inB + E) 6 => E - 370491411790392985199n :MSTORE(array_add_inB + E) - :CALL(array_add) - 0n :MLOAD(array_add_out) + 370491411790392985199n :MSTORE(array_add_inB + E) + :CALL(array_add) + 0n :MLOAD(array_add_out) 1 => E - 0n :MLOAD(array_add_out + E) + 0n :MLOAD(array_add_out + E) 2 => E - 0n :MLOAD(array_add_out + E) + 0n :MLOAD(array_add_out + E) 3 => E - 0n :MLOAD(array_add_out + E) + 0n :MLOAD(array_add_out + E) 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) 6 => E - 370491411790392985199n :MLOAD(array_add_out + E) - 7 :MLOAD(array_add_len_out) + 370491411790392985199n :MLOAD(array_add_out + E) + 7 :MLOAD(array_add_len_out) ; --------------------------------------------------------------- ; array_add AGTB @@ -175,46 +175,46 @@ start: ; 1] [2**256-1,2**256-1,2**256-1] + [2**256-1,2**256-1] 3 => C 2 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB + E) - :CALL(array_add_AGTB) - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_AGTB_out) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB + E) + :CALL(array_add_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_AGTB_out) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_AGTB_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_AGTB_out + E) 2 => E - 0n :MLOAD(array_add_AGTB_out + E) + 0n :MLOAD(array_add_AGTB_out + E) 3 => E - 1n :MLOAD(array_add_AGTB_out + E) - 4 :MLOAD(array_add_AGTB_len_out) + 1n :MLOAD(array_add_AGTB_out + E) + 4 :MLOAD(array_add_AGTB_len_out) ; --------------------------------------------------------------- ; array_add small ; --------------------------------------------------------------- ; 1] [2**256-1,2**256-1,2**256-1] + [2**256-1] 3 => C - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inB) - :CALL(array_add_short) - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_short_out) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inB) + :CALL(array_add_short) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_short_out) 1 => E - 0n :MLOAD(array_add_short_out + E) + 0n :MLOAD(array_add_short_out + E) 2 => E - 0n :MLOAD(array_add_short_out + E) + 0n :MLOAD(array_add_short_out + E) 3 => E - 1n :MLOAD(array_add_short_out + E) - 4 :MLOAD(array_add_short_len_out) + 1n :MLOAD(array_add_short_out + E) + 4 :MLOAD(array_add_short_len_out) ; --------------------------------------------------------------- ; array_sub @@ -222,104 +222,99 @@ start: ; 1] len(inA) > len(inB) and inA_i >= inb_i for all i 3 => C 2 => D - 5n :MSTORE(array_sub_AGTB_inA) + 5n :MSTORE(array_sub_AGTB_inA) 1 => E - 6n :MSTORE(array_sub_AGTB_inA + E) + 6n :MSTORE(array_sub_AGTB_inA + E) 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) + 7n :MSTORE(array_sub_AGTB_inA + E) - 2n :MSTORE(array_sub_AGTB_inB) + 2n :MSTORE(array_sub_AGTB_inB) 1 => E - 3n :MSTORE(array_sub_AGTB_inB + E) - :CALL(array_sub_AGTB) - ; 0 :MLOAD(array_sub_sign) - 3n :MLOAD(array_sub_AGTB_out) + 3n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + 3n :MLOAD(array_sub_AGTB_out) 1 => E - 3n :MLOAD(array_sub_AGTB_out + E) + 3n :MLOAD(array_sub_AGTB_out + E) 2 => E - 7n :MLOAD(array_sub_AGTB_out + E) + 7n :MLOAD(array_sub_AGTB_out + E) ; 2] len(inA) > len(inB) and inA_i < inb_i for some i 3 => C 2 => D - 5n :MSTORE(array_sub_AGTB_inA) + 5n :MSTORE(array_sub_AGTB_inA) 1 => E - 6n :MSTORE(array_sub_AGTB_inA + E) + 6n :MSTORE(array_sub_AGTB_inA + E) 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) + 7n :MSTORE(array_sub_AGTB_inA + E) - 6n :MSTORE(array_sub_AGTB_inB) + 6n :MSTORE(array_sub_AGTB_inB) 1 => E - 3n :MSTORE(array_sub_AGTB_inB + E) - :CALL(array_sub_AGTB) - ; 0 :MLOAD(array_sub_sign) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 3n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) 1 => E - 2n :MLOAD(array_sub_AGTB_out + E) + 2n :MLOAD(array_sub_AGTB_out + E) 2 => E - 7n :MLOAD(array_sub_AGTB_out + E) + 7n :MLOAD(array_sub_AGTB_out + E) ; 3] len(inA) > len(inB) and inA_i < inB_i for all i lower than len(inA) 3 => C 2 => D - 5n :MSTORE(array_sub_AGTB_inA) + 5n :MSTORE(array_sub_AGTB_inA) 1 => E - 1n :MSTORE(array_sub_AGTB_inA + E) + 1n :MSTORE(array_sub_AGTB_inA + E) 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) + 7n :MSTORE(array_sub_AGTB_inA + E) - 6n :MSTORE(array_sub_AGTB_inB) + 6n :MSTORE(array_sub_AGTB_inB) 1 => E - 8n :MSTORE(array_sub_AGTB_inB + E) - :CALL(array_sub_AGTB) - ; 0 :MLOAD(array_sub_sign) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 8n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) 2 => E - 6n :MLOAD(array_sub_AGTB_out + E) + 6n :MLOAD(array_sub_AGTB_out + E) ; 4] len(inB) > len(inA) and inB_i < inA_i for all i lower than len(inB) 3 => C 2 => D - 6n :MSTORE(array_sub_AGTB_inB) + 6n :MSTORE(array_sub_AGTB_inB) 1 => E - 8n :MSTORE(array_sub_AGTB_inB + E) + 8n :MSTORE(array_sub_AGTB_inB + E) - 5n :MSTORE(array_sub_AGTB_inA) + 5n :MSTORE(array_sub_AGTB_inA) 1 => E - 1n :MSTORE(array_sub_AGTB_inA + E) + 1n :MSTORE(array_sub_AGTB_inA + E) 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) - :CALL(array_sub_AGTB) - ; 1 :MLOAD(array_sub_sign) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 7n :MSTORE(array_sub_AGTB_inA + E) + :CALL(array_sub_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) 2 => E - 6n :MLOAD(array_sub_AGTB_out + E) + 6n :MLOAD(array_sub_AGTB_out + E) ; 5] len(inB) = len(inA) and inB > inA 3 => C 3 => D - 6n :MSTORE(array_sub_AGTB_inB) + 6n :MSTORE(array_sub_AGTB_inB) 1 => E - 8n :MSTORE(array_sub_AGTB_inB + E) + 8n :MSTORE(array_sub_AGTB_inB + E) 2 => E - 8n :MSTORE(array_sub_AGTB_inB + E) + 8n :MSTORE(array_sub_AGTB_inB + E) - 7n :MSTORE(array_sub_AGTB_inA) + 7n :MSTORE(array_sub_AGTB_inA) 1 => E - 8n :MSTORE(array_sub_AGTB_inA + E) + 8n :MSTORE(array_sub_AGTB_inA + E) 2 => E - 8n :MSTORE(array_sub_AGTB_inA + E) - :CALL(array_sub_AGTB) - ; 1 :MLOAD(array_sub_sign) - 1n :MLOAD(array_sub_AGTB_out) + 8n :MSTORE(array_sub_AGTB_inA + E) + :CALL(array_sub_AGTB) + 1n :MLOAD(array_sub_AGTB_out) 1 => E - 0n :MLOAD(array_sub_AGTB_out + E) + 0n :MLOAD(array_sub_AGTB_out + E) 2 => E - 0n :MLOAD(array_sub_AGTB_out + E) + 0n :MLOAD(array_sub_AGTB_out + E) ; --------------------------------------------------------------- ; array long mul @@ -327,50 +322,50 @@ start: ; 1] len(inB) = len(inA) and inB > inA 3 => C 3 => D - 5n :MSTORE(array_mul_inA) + 5n :MSTORE(array_mul_inA) 1 => E - 6n :MSTORE(array_mul_inA + E) + 6n :MSTORE(array_mul_inA + E) 2 => E - 7n :MSTORE(array_mul_inA + E) + 7n :MSTORE(array_mul_inA + E) - 2n :MSTORE(array_mul_inB) + 2n :MSTORE(array_mul_inB) 1 => E - 3n :MSTORE(array_mul_inB + E) + 3n :MSTORE(array_mul_inB + E) 2 => E - 4n :MSTORE(array_mul_inB + E) - :CALL(array_mul) - 10n :MLOAD(array_mul_out) + 4n :MSTORE(array_mul_inB + E) + :CALL(array_mul) + 10n :MLOAD(array_mul_out) 1 => E - 27n :MLOAD(array_mul_out + E) + 27n :MLOAD(array_mul_out + E) 2 => E - 52n :MLOAD(array_mul_out + E) + 52n :MLOAD(array_mul_out + E) 3 => E - 45n :MLOAD(array_mul_out + E) + 45n :MLOAD(array_mul_out + E) 4 => E - 28n :MLOAD(array_mul_out + E) - 5 :MLOAD(array_mul_len_out) + 28n :MLOAD(array_mul_out + E) + 5 :MLOAD(array_mul_len_out) ; 2] len(inB) != len(inA) 2 => C 3 => D - 5n :MSTORE(array_mul_inA) + 5n :MSTORE(array_mul_inA) 1 => E - 6n :MSTORE(array_mul_inA + E) + 6n :MSTORE(array_mul_inA + E) - 11n :MSTORE(array_mul_inB) + 11n :MSTORE(array_mul_inB) 1 => E - 21n :MSTORE(array_mul_inB + E) + 21n :MSTORE(array_mul_inB + E) 2 => E - 16n :MSTORE(array_mul_inB + E) - :CALL(array_mul) - 55n :MLOAD(array_mul_out) + 16n :MSTORE(array_mul_inB + E) + :CALL(array_mul) + 55n :MLOAD(array_mul_out) 1 => E - 171n :MLOAD(array_mul_out + E) + 171n :MLOAD(array_mul_out + E) 2 => E - 206n :MLOAD(array_mul_out + E) + 206n :MLOAD(array_mul_out + E) 3 => E - 96n :MLOAD(array_mul_out + E) - 4 :MLOAD(array_mul_len_out) + 96n :MLOAD(array_mul_out + E) + 4 :MLOAD(array_mul_len_out) ; --------------------------------------------------------------- ; ; WIP: array karatsuba mul @@ -439,137 +434,137 @@ start: ; 1] [a, a, a] * a 3 => C 1 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inB) - :CALL(array_mul) - 1n :MLOAD(array_mul_out) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inB) + :CALL(array_mul) + 1n :MLOAD(array_mul_out) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_mul_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_mul_out + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_mul_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_mul_out + E) 3 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_mul_out + E) - 4 :MLOAD(array_mul_len_out) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_mul_out + E) + 4 :MLOAD(array_mul_len_out) ; 2] [a, 100, a, 6] * 400 4 => C 1 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA) 1 => E - 100n :MSTORE(array_mul_inA + E) + 100n :MSTORE(array_mul_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_mul_inA + E) 3 => E - 6n :MSTORE(array_mul_inA + E) + 6n :MSTORE(array_mul_inA + E) - 400n :MSTORE(array_mul_inB) - :CALL(array_mul) - 115792089237316195423570985008687907853269984665640564039457584007913129639536n :MLOAD(array_mul_out) + 400n :MSTORE(array_mul_inB) + :CALL(array_mul) + 115792089237316195423570985008687907853269984665640564039457584007913129639536n :MLOAD(array_mul_out) 1 => E - 40399n :MLOAD(array_mul_out + E) + 40399n :MLOAD(array_mul_out + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639536n :MLOAD(array_mul_out + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639536n :MLOAD(array_mul_out + E) 3 => E - 2799n :MLOAD(array_mul_out + E) - 4 :MLOAD(array_mul_len_out) + 2799n :MLOAD(array_mul_out + E) + 4 :MLOAD(array_mul_len_out) ; --------------------------------------------------------------- ; array square ; --------------------------------------------------------------- ; 1] [4n, 4n, 4n, 3n, 2n, 4n] 6 => C - 4n :MSTORE(array_square_in) + 4n :MSTORE(array_square_in) 1 => E - 4n :MSTORE(array_square_in + E) + 4n :MSTORE(array_square_in + E) 2 => E - 4n :MSTORE(array_square_in + E) + 4n :MSTORE(array_square_in + E) 3 => E - 3n :MSTORE(array_square_in + E) + 3n :MSTORE(array_square_in + E) 4 => E - 2n :MSTORE(array_square_in + E) + 2n :MSTORE(array_square_in + E) 5 => E - 4n :MSTORE(array_square_in + E) - :CALL(array_square) - 16n :MLOAD(array_square_out) + 4n :MSTORE(array_square_in + E) + :CALL(array_square) + 16n :MLOAD(array_square_out) 1 => E - 32n :MLOAD(array_square_out + E) + 32n :MLOAD(array_square_out + E) 2 => E - 48n :MLOAD(array_square_out + E) + 48n :MLOAD(array_square_out + E) 3 => E - 56n :MLOAD(array_square_out + E) + 56n :MLOAD(array_square_out + E) 4 => E - 56n :MLOAD(array_square_out + E) + 56n :MLOAD(array_square_out + E) 5 => E - 72n :MLOAD(array_square_out + E) + 72n :MLOAD(array_square_out + E) 6 => E - 57n :MLOAD(array_square_out + E) + 57n :MLOAD(array_square_out + E) 7 => E - 44n :MLOAD(array_square_out + E) + 44n :MLOAD(array_square_out + E) 8 => E - 28n :MLOAD(array_square_out + E) + 28n :MLOAD(array_square_out + E) 9 => E - 16n :MLOAD(array_square_out + E) + 16n :MLOAD(array_square_out + E) 10 => E - 16n :MLOAD(array_square_out + E) - 11 :MLOAD(array_square_len_out) + 16n :MLOAD(array_square_out + E) + 11 :MLOAD(array_square_len_out) ; 2] [49625181101706940895816136432294817651401421999560241731196107431962769845690n, 16541727033902313631938712144098272550467140666520080577065369143987589948564n, 2n] 3 => C - 49625181101706940895816136432294817651401421999560241731196107431962769845690n :MSTORE(array_square_in) + 49625181101706940895816136432294817651401421999560241731196107431962769845690n :MSTORE(array_square_in) 1 => E - 16541727033902313631938712144098272550467140666520080577065369143987589948564n :MSTORE(array_square_in + E) + 16541727033902313631938712144098272550467140666520080577065369143987589948564n :MSTORE(array_square_in + E) 2 => E - 2n :MSTORE(array_square_in + E) - :CALL(array_square) - 73256219721567388941442868066720921294925908666017499698432349066230755486500n :MLOAD(array_square_out) + 2n :MSTORE(array_square_in + E) + :CALL(array_square) + 73256219721567388941442868066720921294925908666017499698432349066230755486500n :MLOAD(array_square_out) 1 => E - 59077596549651120114066829086065259108811216666143144918090604085669964102021n :MLOAD(array_square_out + E) + 59077596549651120114066829086065259108811216666143144918090604085669964102021n :MLOAD(array_square_out + E) 2 => E - 75619323583553433746005541230163531659278357332663225495155973229657554050588n :MLOAD(array_square_out + E) + 75619323583553433746005541230163531659278357332663225495155973229657554050588n :MLOAD(array_square_out + E) 3 => E - 68530011997595299332317521739835700566221011332726048104985100739377158358338n :MLOAD(array_square_out + E) + 68530011997595299332317521739835700566221011332726048104985100739377158358338n :MLOAD(array_square_out + E) 4 => E - 4n :MLOAD(array_square_out + E) - 5 :MLOAD(array_square_len_out) + 4n :MLOAD(array_square_out + E) + 5 :MLOAD(array_square_len_out) ; 3] [108509871213644914495224788117262720812102234692915980461799068728781566717980n, 97610657482852136417037764955262109743864410230427530868747251158690618238750n, 3n] 3 => C - 108509871213644914495224788117262720812102234692915980461799068728781566717980n :MSTORE(array_square_in) + 108509871213644914495224788117262720812102234692915980461799068728781566717980n :MSTORE(array_square_in) 1 => E - 97610657482852136417037764955262109743864410230427530868747251158690618238750n :MSTORE(array_square_in + E) + 97610657482852136417037764955262109743864410230427530868747251158690618238750n :MSTORE(array_square_in + E) 2 => E - 3n :MSTORE(array_square_in + E) - :CALL(array_square) - 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MLOAD(array_square_out) + 3n :MSTORE(array_square_in + E) + :CALL(array_square) + 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MLOAD(array_square_out) 1 => E - 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MLOAD(array_square_out + E) + 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MLOAD(array_square_out + E) 2 => E - 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MLOAD(array_square_out + E) + 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MLOAD(array_square_out + E) 3 => E - 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MLOAD(array_square_out + E) + 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MLOAD(array_square_out + E) 4 => E - 14n :MLOAD(array_square_out + E) - 5 :MLOAD(array_square_len_out) + 14n :MLOAD(array_square_out + E) + 5 :MLOAD(array_square_len_out) ; 4] [94296684984090328915786319894647341212298256830891608529662243544763352873524n,85801804490443701075961240310880668636621463408258506144468684495763969931231n] 2 => C - 94296684984090328915786319894647341212298256830891608529662243544763352873524n :MSTORE(array_square_in) + 94296684984090328915786319894647341212298256830891608529662243544763352873524n :MSTORE(array_square_in) 1 => E - 85801804490443701075961240310880668636621463408258506144468684495763969931231n :MSTORE(array_square_in + E) - :CALL(array_square) - 56476742620324943499420425449441725188859143808665910845865775685761970051728n :MLOAD(array_square_out) + 85801804490443701075961240310880668636621463408258506144468684495763969931231n :MSTORE(array_square_in + E) + :CALL(array_square) + 56476742620324943499420425449441725188859143808665910845865775685761970051728n :MLOAD(array_square_out) 1 => E - 15939360972613038527243286761436595585964755988147232278935003110685006573864n :MLOAD(array_square_out + E) + 15939360972613038527243286761436595585964755988147232278935003110685006573864n :MLOAD(array_square_out + E) 2 => E - 71885101902860809166787972884705167254384530826288829047389464757277834814455n :MLOAD(array_square_out + E) + 71885101902860809166787972884705167254384530826288829047389464757277834814455n :MLOAD(array_square_out + E) 3 => E - 63579038104476977130956937454941822659502127575865339775268690127769381598323n :MLOAD(array_square_out + E) - 4 :MLOAD(array_square_len_out) + 63579038104476977130956937454941822659502127575865339775268690127769381598323n :MLOAD(array_square_out + E) + 4 :MLOAD(array_square_len_out) ; --------------------------------------------------------------- ; array short mod div @@ -577,126 +572,126 @@ start: ; 1] [9n, 8n, 7n, 6n] / 8n 4 => C 1 => D - 9n :MSTORE(array_div_mod_inA) + 9n :MSTORE(array_div_mod_inA) 1 => E - 8n :MSTORE(array_div_mod_inA + E) + 8n :MSTORE(array_div_mod_inA + E) 2 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_mod_inA + E) 3 => E - 6n :MSTORE(array_div_mod_inA + E) + 6n :MSTORE(array_div_mod_inA + E) - 8n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 1n :MLOAD(array_div_mod_quo) + 8n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 1n :MLOAD(array_div_mod_quo) 1 => E - 101318078082651670995624611882601919371611236582435493534525386006923988434945n :MLOAD(array_div_mod_quo + E) + 101318078082651670995624611882601919371611236582435493534525386006923988434945n :MLOAD(array_div_mod_quo + E) 2 => E - 86844066927987146567678238756515930889952488499230423029593188005934847229952n :MLOAD(array_div_mod_quo + E) - 1n :MLOAD(array_div_mod_rem) - 3 :MLOAD(array_div_mod_len_quo) + 86844066927987146567678238756515930889952488499230423029593188005934847229952n :MLOAD(array_div_mod_quo + E) + 1n :MLOAD(array_div_mod_rem) + 3 :MLOAD(array_div_mod_len_quo) ; 2] [a, 7n, a, 12n, a, 20n, a, 80n] / a 8 => C 1 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) 1 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_mod_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) 3 => E - 12n :MSTORE(array_div_mod_inA + E) + 12n :MSTORE(array_div_mod_inA + E) 4 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) 5 => E - 20n :MSTORE(array_div_mod_inA + E) + 20n :MSTORE(array_div_mod_inA + E) 6 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) 7 => E - 80n :MSTORE(array_div_mod_inA + E) + 80n :MSTORE(array_div_mod_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 120n :MLOAD(array_div_mod_quo) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 120n :MLOAD(array_div_mod_quo) 1 => E - 112n :MLOAD(array_div_mod_quo + E) + 112n :MLOAD(array_div_mod_quo + E) 2 => E - 113n :MLOAD(array_div_mod_quo + E) + 113n :MLOAD(array_div_mod_quo + E) 3 => E - 100n :MLOAD(array_div_mod_quo + E) + 100n :MLOAD(array_div_mod_quo + E) 4 => E - 101n :MLOAD(array_div_mod_quo + E) + 101n :MLOAD(array_div_mod_quo + E) 5 => E - 80n :MLOAD(array_div_mod_quo + E) + 80n :MLOAD(array_div_mod_quo + E) 6 => E - 81n :MLOAD(array_div_mod_quo + E) - 119n :MLOAD(array_div_mod_rem) - 7 :MLOAD(array_div_mod_len_quo) + 81n :MLOAD(array_div_mod_quo + E) + 119n :MLOAD(array_div_mod_rem) + 7 :MLOAD(array_div_mod_len_quo) ; 3] inA == 0, inB != 0 1 => C 1 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_mod_inA) - 8n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) + 8n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) ; 4] inA != 0, inB == 0 -> error 2 => C 1 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_mod_inA) 1 => E - 30n :MSTORE(array_div_mod_inA + E) + 30n :MSTORE(array_div_mod_inA + E) - 0n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) + 0n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) 1 => A - B :ASSERT + B :ASSERT ; 5] inA == inB 1 => C 1 => D - 10n :MSTORE(array_div_mod_inA) + 10n :MSTORE(array_div_mod_inA) - 10n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 1n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) + 10n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 1n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) ; 6] inA < inB 1 => C 1 => D - 10n :MSTORE(array_div_mod_inA) + 10n :MSTORE(array_div_mod_inA) - 11n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 10n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) + 11n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 10n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) ; 7] [28948022309329048855892746252171976963317496166410141009864396001978282409984n, 1n] / 2 2 => C 1 => D - 28948022309329048855892746252171976963317496166410141009864396001978282409984n :MSTORE(array_div_mod_inA) + 28948022309329048855892746252171976963317496166410141009864396001978282409984n :MSTORE(array_div_mod_inA) 1 => E - 1n :MSTORE(array_div_mod_inA + E) + 1n :MSTORE(array_div_mod_inA + E) - 2n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MLOAD(array_div_mod_quo) - 1 :MLOAD(array_div_mod_len_quo) + 2n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MLOAD(array_div_mod_quo) + 1 :MLOAD(array_div_mod_len_quo) ; 8] [72370055773322622139731865630429942408293740416025352524660990004945706024960n] / 2 1 => C 1 => D - 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MSTORE(array_div_mod_inA) - 2n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 36185027886661311069865932815214971204146870208012676262330495002472853012480n :MLOAD(array_div_mod_quo) - 1 :MLOAD(array_div_mod_len_quo) + 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MSTORE(array_div_mod_inA) + 2n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) + 36185027886661311069865932815214971204146870208012676262330495002472853012480n :MLOAD(array_div_mod_quo) + 1 :MLOAD(array_div_mod_len_quo) ; --------------------------------------------------------------- ; array long mod div @@ -704,240 +699,240 @@ start: ; 1] len(inB) = len(inA) and inB > inA 4 => C 2 => D - 9n :MSTORE(array_div_mod_inA) + 9n :MSTORE(array_div_mod_inA) 1 => E - 8n :MSTORE(array_div_mod_inA + E) + 8n :MSTORE(array_div_mod_inA + E) 2 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_mod_inA + E) 3 => E - 6n :MSTORE(array_div_mod_inA + E) + 6n :MSTORE(array_div_mod_inA + E) - 8n :MSTORE(array_div_mod_inB) + 8n :MSTORE(array_div_mod_inB) 1 => E - 1n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 335n :MLOAD(array_div_mod_quo) + 1n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 335n :MLOAD(array_div_mod_quo) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639895n :MLOAD(array_div_mod_quo + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639895n :MLOAD(array_div_mod_quo + E) 2 => E - 5n :MLOAD(array_div_mod_quo + E) - 115792089237316195423570985008687907853269984665640564039457584007913129637265n :MLOAD(array_div_mod_rem) + 5n :MLOAD(array_div_mod_quo + E) + 115792089237316195423570985008687907853269984665640564039457584007913129637265n :MLOAD(array_div_mod_rem) ; 2] [a, 7n, a, 12n, a, 20n, a, 80n] / [a, a, a, a, 100n] 8 => C 5 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) 1 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_mod_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) 3 => E - 12n :MSTORE(array_div_mod_inA + E) + 12n :MSTORE(array_div_mod_inA + E) 4 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) 5 => E - 20n :MSTORE(array_div_mod_inA + E) + 20n :MSTORE(array_div_mod_inA + E) 6 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) 7 => E - 80n :MSTORE(array_div_mod_inA + E) + 80n :MSTORE(array_div_mod_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) 3 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) 4 => E - 100n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 87130681010257731209815790699606742543054641926620622445532439451498988639951n :MLOAD(array_div_mod_quo) + 100n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 87130681010257731209815790699606742543054641926620622445532439451498988639951n :MLOAD(array_div_mod_quo) 1 => E - 76812574048516684092863920748337523031377118540573443471719387411189897879957n :MLOAD(array_div_mod_quo + E) + 76812574048516684092863920748337523031377118540573443471719387411189897879957n :MLOAD(array_div_mod_quo + E) 2 => E - 92862962655669424052566829561422975605097710474424610764317468362781816839948n :MLOAD(array_div_mod_quo + E) - 87130681010257731209815790699606742543054641926620622445532439451498988639950n :MLOAD(array_div_mod_rem) + 92862962655669424052566829561422975605097710474424610764317468362781816839948n :MLOAD(array_div_mod_quo + E) + 87130681010257731209815790699606742543054641926620622445532439451498988639950n :MLOAD(array_div_mod_rem) 1 => E - 76812574048516684092863920748337523031377118540573443471719387411189897879965n :MLOAD(array_div_mod_rem + E) + 76812574048516684092863920748337523031377118540573443471719387411189897879965n :MLOAD(array_div_mod_rem + E) 2 => E - 92862962655669424052566829561422975605097710474424610764317468362781816839947n :MLOAD(array_div_mod_rem + E) + 92862962655669424052566829561422975605097710474424610764317468362781816839947n :MLOAD(array_div_mod_rem + E) 3 => E - 13n :MLOAD(array_div_mod_rem + E) + 13n :MLOAD(array_div_mod_rem + E) 4 => E - 84n :MLOAD(array_div_mod_rem + E) + 84n :MLOAD(array_div_mod_rem + E) ; 3] inA == 0, inB != 0 1 => C 2 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_mod_inA) - 8n :MSTORE(array_div_mod_inB) + 8n :MSTORE(array_div_mod_inB) 1 => E - 1n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) + 1n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) ; 4] inA != 0, inB == 0 -> error 2 => C 1 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_mod_inA) 1 => E - 30n :MSTORE(array_div_mod_inA + E) + 30n :MSTORE(array_div_mod_inA + E) - 0n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) + 0n :MSTORE(array_div_mod_inB) + :CALL(array_div_mod) 1 => A - B :ASSERT + B :ASSERT ; 5] inA == inB 2 => C 2 => D - 10n :MSTORE(array_div_mod_inA) + 10n :MSTORE(array_div_mod_inA) 1 => E - 30n :MSTORE(array_div_mod_inA + E) + 30n :MSTORE(array_div_mod_inA + E) - 10n :MSTORE(array_div_mod_inB) + 10n :MSTORE(array_div_mod_inB) 1 => E - 30n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 1n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) + 30n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 1n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) ; 6] inA < inB 2 => C 3 => D - 10n :MSTORE(array_div_mod_inA) + 10n :MSTORE(array_div_mod_inA) 1 => E - 30n :MSTORE(array_div_mod_inA + E) + 30n :MSTORE(array_div_mod_inA + E) - 6n :MSTORE(array_div_mod_inB) + 6n :MSTORE(array_div_mod_inB) 1 => E - 7n :MSTORE(array_div_mod_inB + E) + 7n :MSTORE(array_div_mod_inB + E) 2 => E - 8n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 10n :MLOAD(array_div_mod_rem) + 8n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 10n :MLOAD(array_div_mod_rem) 1 => E - 30n :MSTORE(array_div_mod_rem + E) + 30n :MSTORE(array_div_mod_rem + E) ; 7] [82987931714326364316120253427931880709278140571418487333162713377057429160720n,4257238595720679277571917967782652353394431698489248379634099239588181418140n,15209178211456919413336795740141505754388379695813905932093982440742677791802n,88987534839350135473536361176867192550264928852523682165693061442019881855583n,14n], [4n, 6n, 7n] 5 => C 3 => D - 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MSTORE(array_div_mod_inA) + 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MSTORE(array_div_mod_inA) 1 => E - 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MSTORE(array_div_mod_inA + E) + 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MSTORE(array_div_mod_inA + E) 2 => E - 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MSTORE(array_div_mod_inA + E) + 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MSTORE(array_div_mod_inA + E) 3 => E - 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MSTORE(array_div_mod_inA + E) + 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MSTORE(array_div_mod_inA + E) 4 => E - 14n :MSTORE(array_div_mod_inA + E) + 14n :MSTORE(array_div_mod_inA + E) - 4n :MSTORE(array_div_mod_inB) + 4n :MSTORE(array_div_mod_inB) 1 => E - 6n :MSTORE(array_div_mod_inB + E) + 6n :MSTORE(array_div_mod_inB + E) 2 => E - 7n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 90526669110436282262084097418054683975846294708417529350769755852355732618090n :MLOAD(array_div_mod_quo) + 7n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 90526669110436282262084097418054683975846294708417529350769755852355732618090n :MLOAD(array_div_mod_quo) 1 => E - 12712504977050019353362337310981027507180704121789097452241865920288554550795n :MLOAD(array_div_mod_quo + E) + 12712504977050019353362337310981027507180704121789097452241865920288554550795n :MLOAD(array_div_mod_quo + E) 2 => E - 2n :MLOAD(array_div_mod_quo + E) - 68257522984529821538496818781776868365702915734670062048456441991373887608168n :MLOAD(array_div_mod_rem) + 2n :MLOAD(array_div_mod_quo + E) + 68257522984529821538496818781776868365702915734670062048456441991373887608168n :MLOAD(array_div_mod_rem) 1 => E - 104999739448800080833043894267657885589213754954671066702793604491778345346033n :MSTORE(array_div_mod_rem + E) + 104999739448800080833043894267657885589213754954671066702793604491778345346033n :MSTORE(array_div_mod_rem + E) 2 => E - 4n :MSTORE(array_div_mod_rem + E) - 3 :MLOAD(array_div_mod_len_quo) - 3 :MLOAD(array_div_mod_len_rem) + 4n :MSTORE(array_div_mod_rem + E) + 3 :MLOAD(array_div_mod_len_quo) + 3 :MLOAD(array_div_mod_len_rem) ; 8] [0n,0n,0n,0n,87552057494100699607633960453116574392480272162273084008350826812719088235449n,29405388739667337424543497575767709934732594998639086405406332616399343873602n,370491411790392985199n], [0n, 0n, 8238129386n, 23102318237n] 7 => C 4 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_mod_inA) 1 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_mod_inA + E) 2 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_mod_inA + E) 3 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_mod_inA + E) 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MSTORE(array_div_mod_inA + E) + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MSTORE(array_div_mod_inA + E) 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_div_mod_inA + E) + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_div_mod_inA + E) 6 => E - 370491411790392985199n :MSTORE(array_div_mod_inA + E) + 370491411790392985199n :MSTORE(array_div_mod_inA + E) - 0n :MSTORE(array_div_mod_inB) + 0n :MSTORE(array_div_mod_inB) 1 => E - 0n :MSTORE(array_div_mod_inB + E) + 0n :MSTORE(array_div_mod_inB + E) 2 => E - 8238129386n :MSTORE(array_div_mod_inB + E) + 8238129386n :MSTORE(array_div_mod_inB + E) 3 => E - 23102318237n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 10624890954144362706283399919870985530330343554129711486796784890935496833177n :MLOAD(array_div_mod_quo) + 23102318237n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 10624890954144362706283399919870985530330343554129711486796784890935496833177n :MLOAD(array_div_mod_quo) 1 => E - 12699239907746414269759600684072701206520647567004427767570235373004025148518n :MLOAD(array_div_mod_quo + E) + 12699239907746414269759600684072701206520647567004427767570235373004025148518n :MLOAD(array_div_mod_quo + E) 2 => E - 62973947849727744055941265906651873030488901951864462234513788026171769471385n :MLOAD(array_div_mod_quo + E) + 62973947849727744055941265906651873030488901951864462234513788026171769471385n :MLOAD(array_div_mod_quo + E) 3 => E - 16036979838n :MLOAD(array_div_mod_quo + E) - 0n :MLOAD(array_div_mod_rem) + 16036979838n :MLOAD(array_div_mod_quo + E) + 0n :MLOAD(array_div_mod_rem) 1 => E - 0n :MSTORE(array_div_mod_rem + E) + 0n :MSTORE(array_div_mod_rem + E) 2 => E - 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_div_mod_rem + E) + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_div_mod_rem + E) 3 => E - 6019321230n :MSTORE(array_div_mod_rem + E) - 4 :MLOAD(array_div_mod_len_quo) - 4 :MLOAD(array_div_mod_len_rem) + 6019321230n :MSTORE(array_div_mod_rem + E) + 4 :MLOAD(array_div_mod_len_quo) + 4 :MLOAD(array_div_mod_len_rem) ; 9] [7n], [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] 1 => C 2 => D - 7n :MSTORE(array_div_mod_inA) - 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(array_div_mod_inB) + 7n :MSTORE(array_div_mod_inA) + 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(array_div_mod_inB) 1 => E - 17n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 7n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) - 1 :MLOAD(array_div_mod_len_rem) + 17n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 7n :MLOAD(array_div_mod_rem) + 1 :MLOAD(array_div_mod_len_quo) + 1 :MLOAD(array_div_mod_len_rem) ; 10] [9,12,16,2,0,2**256-4], [2**256-1,2**256-1] 6 => C 2 => D - 9n :MSTORE(array_div_mod_inA) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + 9n :MSTORE(array_div_mod_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) 1 => E - 12n :MSTORE(array_div_mod_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 12n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) 2 => E - 16n :MSTORE(array_div_mod_inA + E) + 16n :MSTORE(array_div_mod_inA + E) 3 => E - 2n :MSTORE(array_div_mod_inA + E) + 2n :MSTORE(array_div_mod_inA + E) 4 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_mod_inA + E) 5 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MSTORE(array_div_mod_inA + E) - :CALL(array_div_mod) - 4 :MLOAD(array_div_mod_len_quo) - 2 :MLOAD(array_div_mod_len_rem) - 17n :MLOAD(array_div_mod_quo) - 26n :MLOAD(array_div_mod_rem) + 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MSTORE(array_div_mod_inA + E) + :CALL(array_div_mod) + 4 :MLOAD(array_div_mod_len_quo) + 2 :MLOAD(array_div_mod_len_rem) + 17n :MLOAD(array_div_mod_quo) + 26n :MLOAD(array_div_mod_rem) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_div_mod_quo + E) - 10n :MLOAD(array_div_mod_rem + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_div_mod_quo + E) + 10n :MLOAD(array_div_mod_rem + E) 2 => E - 0n :MLOAD(array_div_mod_quo + E) + 0n :MLOAD(array_div_mod_quo + E) 3 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_div_mod_quo + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_div_mod_quo + E) ; --------------------------------------------------------------- :JMP(end) diff --git a/test/testArrayUtils.zkasm b/test/testArrayUtils.zkasm index ec858436..90fd0a82 100644 --- a/test/testArrayUtils.zkasm +++ b/test/testArrayUtils.zkasm @@ -237,7 +237,7 @@ array_compare_test_5_compare: ; --------------------------------------------------------------- 0 => C 5n => D - 3n :MSTORE(array_unshift_in) + 3n :MSTORE(array_unshift_in) :CALL(array_unshift) 5 :MLOAD(array_unshift_in) 1 :MLOAD(array_unshift_len) From b115099748863e17254fb89614e620ff8bc15b0a Mon Sep 17 00:00:00 2001 From: krlosMata Date: Mon, 4 Dec 2023 17:39:02 +0100 Subject: [PATCH 054/121] comments & spaces --- main/block-info.zkasm | 22 +-- main/constants.zkasm | 2 +- main/load-tx-rlp-utils.zkasm | 12 +- main/load-tx-rlp.zkasm | 4 +- main/main.zkasm | 116 ++++++------- main/opcodes/arithmetic.zkasm | 2 +- .../CYCLOFP12BN254/decompressFp12BN254.zkasm | 4 +- main/precompiled/identity.zkasm | 4 +- main/precompiled/pre-ecAdd.zkasm | 2 +- main/precompiled/pre-ecMul.zkasm | 9 +- main/precompiled/pre-ecPairing.zkasm | 2 +- main/precompiled/pre-ecrecover.zkasm | 2 +- main/precompiled/pre-modexp.zkasm | 2 +- main/precompiled/pre-sha2-256.zkasm | 2 +- main/precompiled/selector.zkasm | 4 +- main/process-change-l2-block.zkasm | 50 +++--- main/process-tx.zkasm | 40 ++--- main/touched.zkasm | 10 +- main/utils.zkasm | 162 +++++++++--------- 19 files changed, 221 insertions(+), 230 deletions(-) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index fc8cd16e..daa25583 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -21,7 +21,7 @@ revertBlockInfoTree: ; @info Fill Block Info tree with initial block values setupNewBlockInfoTree: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*7 :JMPN(outOfCountersPoseidon) ; save current state root & load block info root SR :MSTORE(tmpSR) @@ -97,7 +97,7 @@ setupNewBlockInfoTree: ; @info Fill Block Info tree with tx receipt values fillBlockInfoTreeWithTxReceipt: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon) ; save current state root & load block info root SR :MSTORE(tmpSR) @@ -142,7 +142,7 @@ fillBlockInfoTreeWithTxReceipt: ; @info Fill Block Info tree with block gas used at the end of block processing and Store block Info Root in storage consolidateBlock: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) ; save current state root & load block info root SR :MSTORE(tmpSR) @@ -158,8 +158,8 @@ consolidateBlock: $ => SR :SSTORE ; Restore current SR - SR :MSTORE(blockInfoSR) - $ => SR :MLOAD(tmpSR) + SR :MSTORE(blockInfoSR) + $ => SR :MLOAD(tmpSR) finalConsolidateBlockInfoTree: ; Store block Info Root in storage @@ -167,22 +167,22 @@ finalConsolidateBlockInfoTree: %SMT_KEY_SC_STORAGE => B %BLOCK_INFO_ROOT_STORAGE_POS => C writeBlockInfoRoot: - $ => D :MLOAD(blockInfoSR) - $ => SR :SSTORE, RETURN + $ => D :MLOAD(blockInfoSR) + $ => SR :SSTORE, RETURN ; @info add new log hash to block info tree ; @in D => Value to store (linearPoseidon(log_data + log_topics)) fillBlockInfoTreeWithLog: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) - %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE :JMPN(outOfCountersPoseidon) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE :JMPN(outOfCountersPoseidon) ; save current state root & load block info root SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) ; Retrieve and update currentLogIndex - $ => C :MLOAD(currentLogIndex) - C + 1 :MSTORE(currentLogIndex) + $ => C :MLOAD(currentLogIndex) + C + 1 :MSTORE(currentLogIndex) ; Insert new log to block info tree ; key: H([logIndexKey[0:4], logIndexKey[4:8], logIndexKey[8:12], logIndexKey[12:16], logIndexKey[16:20], 0, SMT_KEY_BLOCK_HEADER_LOGS, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) diff --git a/main/constants.zkasm b/main/constants.zkasm index 73f913e1..c29c6cd4 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -135,7 +135,7 @@ CONST %CODE_SIZE_LIMIT = 0x6000 CONST %BYTECODE_STARTS_EF = 0xEF CONST %MAX_SIZE_MODEXP = 1024 CONST %MAX_GAS_WORD_MODEXP = 9487 -CONSTL %MAX_GAS_IT_MODEXP = 90000000 ; %TX_GAS_LIMIT*3 +CONSTL %MAX_GAS_IT_MODEXP = 90000000 ; %TX_GAS_LIMIT * 3 ; CONSTANTS TX CHANGEL2BLOCK CONST %CHANGE_L2_BLOCK_TX_TYPE = 0x0b diff --git a/main/load-tx-rlp-utils.zkasm b/main/load-tx-rlp-utils.zkasm index f5046940..7ec5500d 100644 --- a/main/load-tx-rlp-utils.zkasm +++ b/main/load-tx-rlp-utils.zkasm @@ -72,11 +72,11 @@ skipCheckShortData: VAR GLOBAL tmpVarAcheckNonLeadingZeros VAR GLOBAL tmpVarZkPCcheckNonLeadingZeros checkNonLeadingZeros: - RR :MSTORE(tmpVarZkPCcheckNonLeadingZeros) - A :MSTORE(tmpVarAcheckNonLeadingZeros) + RR :MSTORE(tmpVarZkPCcheckNonLeadingZeros) + A :MSTORE(tmpVarAcheckNonLeadingZeros) ; set value to B and get its - A => B :CALL(getLenBytes) ; in: [B: number] out: [A: byte length of B] + A => B :CALL(getLenBytes) ; in: [B: number] out: [A: byte length of B] ; check (bytes length - encoded length) are not equal - D - A :JMPNZ(invalidTxRLP) - $ => RR :MLOAD(tmpVarZkPCcheckNonLeadingZeros) - $ => A :MLOAD(tmpVarAcheckNonLeadingZeros), RETURN \ No newline at end of file + D - A :JMPNZ(invalidTxRLP) + $ => RR :MLOAD(tmpVarZkPCcheckNonLeadingZeros) + $ => A :MLOAD(tmpVarAcheckNonLeadingZeros), RETURN \ No newline at end of file diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index c568bdb3..28ac3e42 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -76,7 +76,7 @@ endList: 136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => B :MLOAD(arithRes1) $ => D :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1:JMPN(outOfCountersKeccak) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1 :JMPN(outOfCountersKeccak) ;; Read RLP 'nonce' ; 64 bits max @@ -88,7 +88,7 @@ nonceREAD: A - 0x89 :JMPN(shortNonce, invalidTxRLP) nonce0: - 0 => A :MSTORE(lengthNonce), JMP(endNonce) + 0 => A :MSTORE(lengthNonce), JMP(endNonce) shortNonce: A - 0x80 => D diff --git a/main/main.zkasm b/main/main.zkasm index f85b9feb..9412d2ef 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -14,36 +14,36 @@ start: ; main zkROM entry point ;; A - Load input variables ;;;;;;;;;;;;;;;;;; STEP => A - 0 :ASSERT ; Ensure it is the beginning of the execution + 0 :ASSERT ; Ensure it is the beginning of the execution - CTX :MSTORE(forkID) - CTX - %FORK_ID :JMPNZ(failAssert) + CTX :MSTORE(forkID) + CTX - %FORK_ID :JMPNZ(failAssert) - B => A :MSTORE(oldStateRoot) + B => A :MSTORE(oldStateRoot) ; safety check that the input root is indeed inside the range limit of 4 goldilocks fields elements %FOUR_GOLDILOCKS => B - 1 :LT4 + 1 :LT4 - C :MSTORE(oldAccInputHash) - SP :MSTORE(oldNumBatch) - GAS :MSTORE(chainID) ; assumed to be less than 32 bits + C :MSTORE(oldAccInputHash) + SP :MSTORE(oldNumBatch) + GAS :MSTORE(chainID) ; assumed to be less than 32 bits - ${getL1InfoRoot()} :MSTORE(l1InfoRoot) - ${getSequencerAddr()} :MSTORE(sequencerAddr) - ${getTimestampLimit()} :MSTORE(timestampLimit) - ${getTxsLen()} :MSTORE(batchL2DataLength) ; less than 300.000 bytes. Enforced by the smart contract - ${getForcedBlockHashL1()} => A :MSTORE(forcedBlockHashL1) + ${getL1InfoRoot()} :MSTORE(l1InfoRoot) + ${getSequencerAddr()} :MSTORE(sequencerAddr) + ${getTimestampLimit()} :MSTORE(timestampLimit) + ${getTxsLen()} :MSTORE(batchL2DataLength) ; less than 300.000 bytes. Enforced by the smart contract + ${getForcedBlockHashL1()} => A :MSTORE(forcedBlockHashL1) ;set initial state root - $ => SR :MLOAD(oldStateRoot) - SR :MSTORE(batchSR) + $ => SR :MLOAD(oldStateRoot) + SR :MSTORE(batchSR) ; Increase batch number - SP + 1 :MSTORE(newNumBatch) + SP + 1 :MSTORE(newNumBatch) ; compute isForced flag 0 => B - $ :EQ, JMPC(computeKeccaks) - 1 :MSTORE(isForced) + $ :EQ, JMPC(computeKeccaks) + 1 :MSTORE(isForced) ;;;;;;;;;;;;;;;;;; ;; B - Compute keccaks needed to finish the batch @@ -68,27 +68,27 @@ computeKeccaks: ;; - If an error is found in any transaction, the batch will not process any transaction ;;;;;;;;;;;;;;;;;; - 1 => E :MSTORE(lastHashKIdUsed) - 0 :MSTORE(batchHashPos) - E :MSTORE(batchHashDataId) - $ => A :MLOAD(lastCtxUsed) - A + %CALLDATA_RESERVED_CTX => A :MSTORE(ctxTxToUse) ; Points at first context to be used when processing transactions. We reserve ctx = 1 for calldata - A :MSTORE(lastCtxUsed) + 1 => E :MSTORE(lastHashKIdUsed) + 0 :MSTORE(batchHashPos) + E :MSTORE(batchHashDataId) + $ => A :MLOAD(lastCtxUsed) + A + %CALLDATA_RESERVED_CTX => A :MSTORE(ctxTxToUse) ; Points at first context to be used when processing transactions. We reserve ctx = 1 for calldata + A :MSTORE(lastCtxUsed) $${var p = 0} ; set flag isLoadingRLP to 1 - 1 :MSTORE(isLoadingRLP) + 1 :MSTORE(isLoadingRLP) txLoopRLP: - $ => A :MLOAD(lastCtxUsed) - A+1 => CTX :MSTORE(lastCtxUsed) + $ => A :MLOAD(lastCtxUsed) + A+1 => CTX :MSTORE(lastCtxUsed) - $ => A :MLOAD(batchL2DataLength) - $ => C :MLOAD(batchL2DataParsed) - C - A :JMPN(loadTx_rlp, endCheckRLP) + $ => A :MLOAD(batchL2DataLength) + $ => C :MLOAD(batchL2DataParsed) + C - A :JMPN(loadTx_rlp, endCheckRLP) endCheckRLP: ; set flag isLoadingRLP to 0 - 0 :MSTORE(isLoadingRLP) + 0 :MSTORE(isLoadingRLP) ;;;;;;;;;;;;;;;;;; ;; D - Load blockNum variable @@ -100,42 +100,42 @@ setBlockNum: %LAST_BLOCK_STORAGE_POS => C %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B - $ :SLOAD,MSTORE(blockNum) + $ :SLOAD,MSTORE(blockNum) ; If forced batch ==> process a forced changeL2BlockTx - $ :MLOAD(isForced), JMPZ(txLoop, handleForcedBatch) + $ :MLOAD(isForced), JMPZ(txLoop, handleForcedBatch) handleForcedBatch: - 1 :MSTORE(currentTx), JMP(processChangeL2Block) + 1 :MSTORE(currentTx), JMP(processChangeL2Block) txLoop: - $ => A :MLOAD(pendingTxs) - A - 1 :MSTORE(pendingTxs), JMPN(processTxsEnd) - $ => A :MLOAD(currentTx) - A + 1 :MSTORE(currentTx) - $ => A :MLOAD(ctxTxToUse) ; Load first context used by transaction - A + 1 => CTX :MSTORE(ctxTxToUse) + $ => A :MLOAD(pendingTxs) + A - 1 :MSTORE(pendingTxs), JMPN(processTxsEnd) + $ => A :MLOAD(currentTx) + A + 1 :MSTORE(currentTx) + $ => A :MLOAD(ctxTxToUse) ; Load first context used by transaction + A + 1 => CTX :MSTORE(ctxTxToUse) ; Detect if transaction is a change L2 block tx ; Store initial state at the beginning of the transaction - SR :MSTORE(originSR) - $ => A :MLOAD(isChangeL2BlockTx) - A - 1 :JMPZ(processChangeL2Block, processTx) + SR :MSTORE(originSR) + $ => A :MLOAD(isChangeL2BlockTx) + A - 1 :JMPZ(processChangeL2Block, processTx) processTxFinished: ; Increase cumulativeGasUsed - $ => A :MLOAD(txGasLimit) + $ => A :MLOAD(txGasLimit) A - GAS => A - $ => B :MLOAD(cumulativeGasUsed) + $ => B :MLOAD(cumulativeGasUsed) ; Fill block info tree with tx receipt - A + B :MSTORE(cumulativeGasUsed), CALL(fillBlockInfoTreeWithTxReceipt) + A + B :MSTORE(cumulativeGasUsed), CALL(fillBlockInfoTreeWithTxReceipt) ; Increase txIndex - $ => A :MLOAD(txIndex) - A + 1 :MSTORE(txIndex) + $ => A :MLOAD(txIndex) + A + 1 :MSTORE(txIndex) processIntrinsicTxFinished: - $${eventLog(onFinishTx)} :JMP(txLoop) + $${eventLog(onFinishTx)} :JMP(txLoop) processTxsEnd: ; Write values at storage at the end of block processing - :CALL(consolidateBlock) + :CALL(consolidateBlock) finalizeBatch: ;;;;;;;;;;;;;;;;;; @@ -152,22 +152,22 @@ finalizeBatch: %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A %SMT_KEY_SC_STORAGE => B %LOCAL_EXIT_ROOT_STORAGE_POS => C - $ => A :SLOAD - A :MSTORE(newLocalExitRoot) + $ => A :SLOAD + A :MSTORE(newLocalExitRoot) ;; Transactions size verification ; Ensure bytes added to compute the 'batchHashData' matches the number of bytes loaded from input - $ => A :MLOAD(batchHashPos) - $ :MLOAD(batchL2DataLength), ASSERT + $ => A :MLOAD(batchHashPos) + $ :MLOAD(batchL2DataLength), ASSERT ;; Compute 'batchHashData' A => HASHPOS - $ => E :MLOAD(batchHashDataId) + $ => E :MLOAD(batchHashDataId) - HASHPOS :HASHKLEN(E) - $ => A :HASHKDIGEST(E) + HASHPOS :HASHKLEN(E) + $ => A :HASHKDIGEST(E) - A :MSTORE(batchHashData) + A :MSTORE(batchHashData) ;; Compute 'newAccInputHash' 0 => HASHPOS diff --git a/main/opcodes/arithmetic.zkasm b/main/opcodes/arithmetic.zkasm index 6656350d..97652330 100644 --- a/main/opcodes/arithmetic.zkasm +++ b/main/opcodes/arithmetic.zkasm @@ -1,6 +1,6 @@ /** - * @link [Link EVM behavior --> evm.codes?] + * @link [https://www.evm.codes/#01?fork=berlin] * @zk-counters * - 20 steps * - 1 binary diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm index cb030b5f..25b70da4 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm @@ -226,6 +226,4 @@ decompressFp12BN254_Ca2_is_not_zero: decompressFp12BN254_end: $ => RR :MLOAD(decompressFp12BN254_RR) - :RETURN - - \ No newline at end of file + :RETURN \ No newline at end of file diff --git a/main/precompiled/identity.zkasm b/main/precompiled/identity.zkasm index bffbe04a..5a177028 100644 --- a/main/precompiled/identity.zkasm +++ b/main/precompiled/identity.zkasm @@ -1,5 +1,5 @@ /** - * @link [https://www.evm.codes/precompiled#0x04?fork=shanghai] + * @link [https://www.evm.codes/precompiled#0x04?fork=berlin] * @zk-counters * - dynamic steps: 100 * - dynamic binary: 1 @@ -9,7 +9,7 @@ */ IDENTITY: %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; Move balances if value > 0 just before executing the contract CALL $ => B :MLOAD(txValue) 0 => A diff --git a/main/precompiled/pre-ecAdd.zkasm b/main/precompiled/pre-ecAdd.zkasm index 522944d1..54bf9722 100644 --- a/main/precompiled/pre-ecAdd.zkasm +++ b/main/precompiled/pre-ecAdd.zkasm @@ -1,5 +1,5 @@ /** - * @link [https://www.evm.codes/precompiled#0x06?fork=shanghai] + * @link [https://www.evm.codes/precompiled#0x06?fork=berlin] * @zk-counters * - dynamic steps: 500 * - dynamic arith: 50 diff --git a/main/precompiled/pre-ecMul.zkasm b/main/precompiled/pre-ecMul.zkasm index 8948fa04..a6b144aa 100644 --- a/main/precompiled/pre-ecMul.zkasm +++ b/main/precompiled/pre-ecMul.zkasm @@ -1,5 +1,5 @@ /** - * @link [https://www.evm.codes/precompiled#0x07?fork=shanghai] + * @link [https://www.evm.codes/precompiled#0x07?fork=berlin] * @zk-counters * - dynamic steps: 130000 * - dynamic arith: 20000 @@ -75,13 +75,6 @@ continueEcMul: :CALL(MSTOREX); in: [bytesToStore, E: offset] out: [E: new offset] :JMP(endECMUL) -;endECMULFail: -; $ => A :MLOAD(originCTX), JMPZ(handleGas) -; 0 => GAS -; A => CTX -; 0 :MSTORE(retDataCTX) -; CTX :MSTORE(currentCTX), JMP(preEndFail) - preEndECMUL: $ => CTX :MLOAD(originCTX) diff --git a/main/precompiled/pre-ecPairing.zkasm b/main/precompiled/pre-ecPairing.zkasm index 299f450b..fb592c6d 100644 --- a/main/precompiled/pre-ecPairing.zkasm +++ b/main/precompiled/pre-ecPairing.zkasm @@ -1,5 +1,5 @@ /** - * @link [https://www.evm.codes/precompiled#0x08?fork=shanghai] + * @link [https://www.evm.codes/precompiled#0x08?fork=berlin] * @zk-counters * - dynamic steps: 50000, 550000, 700000,... * - dynamic arith: 4000, 43000, 56000,... diff --git a/main/precompiled/pre-ecrecover.zkasm b/main/precompiled/pre-ecrecover.zkasm index e989fd25..ba2eb694 100644 --- a/main/precompiled/pre-ecrecover.zkasm +++ b/main/precompiled/pre-ecrecover.zkasm @@ -1,5 +1,5 @@ /** - * @link [https://www.evm.codes/precompiled#0x01?fork=shanghai] + * @link [https://www.evm.codes/precompiled#0x01?fork=berlin] * @zk-counters * - dynamic steps: * - dynamic arith: diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 513a6e8e..887ae1ee 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -1,5 +1,5 @@ /** - * @link [https://www.evm.codes/precompiled#0x05?fork=shanghai] + * @link [https://www.evm.codes/precompiled#0x05?fork=berlin] * @zk-counters * - dynamic steps: * - dynamic arith: diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 3425c257..eb7eeac4 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -1,5 +1,5 @@ /** - * @link [https://www.evm.codes/precompiled#0x02?fork=shanghai] + * @link [https://www.evm.codes/precompiled#0x02?fork=berlin] * @zk-counters * - dynamic steps: * - dynamic binary: diff --git a/main/precompiled/selector.zkasm b/main/precompiled/selector.zkasm index 3aedd8d9..c81a55e0 100644 --- a/main/precompiled/selector.zkasm +++ b/main/precompiled/selector.zkasm @@ -59,7 +59,7 @@ INCLUDE "end.zkasm" /** * Selector precompiled contract to run - * Current precompiled supported: ECRECOVER, IDENTITY, MODEXP, ECADD, ECMUL, ECPAIRING + * Current precompiled supported: ECRECOVER, SHA2-256, IDENTITY, MODEXP, ECADD, ECMUL, ECPAIRING * @param {A} - Precompiled address * @dev Any call to an unsupported precompiled will result in a revert * - All gas is refunded @@ -67,7 +67,7 @@ INCLUDE "end.zkasm" */ selectorPrecompiled: A - 2 :JMPN(funcECRECOVER) - A - 3 :JMPN(funcSHA256) ;:JMPN(SHA256) + A - 3 :JMPN(funcSHA256) A - 4 :JMPN(revertPrecompiled) ;:JMPN(RIPEMD160) A - 5 :JMPN(IDENTITY) A - 6 :JMPN(funcModexp) diff --git a/main/process-change-l2-block.zkasm b/main/process-change-l2-block.zkasm index b55d7fc4..3a94e253 100644 --- a/main/process-change-l2-block.zkasm +++ b/main/process-change-l2-block.zkasm @@ -9,9 +9,9 @@ processChangeL2Block: %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) ; If it is not the first transaction, we must consolidate previous block - $ => A :MLOAD(currentTx) - A - 1 :JMPZ(continueProcessChangeL2Block) - :CALL(consolidateBlock) + $ => A :MLOAD(currentTx) + A - 1 :JMPZ(continueProcessChangeL2Block) + :CALL(consolidateBlock) continueProcessChangeL2Block: ; Reset tx index, logIndex and cumulative gas used @@ -51,52 +51,52 @@ continueProcessChangeL2Block: %TIMESTAMP_STORAGE_POS => C %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B - $ => A :SLOAD ; currentTimestamp => A + $ => A :SLOAD ; currentTimestamp => A - $ => B :MLOAD(timestampLimit) ; timestampLimit => B + $ => B :MLOAD(timestampLimit) ; timestampLimit => B ; If it is NOT a forced tx ==> verify Timestamp & L1InfoRoot - $ :MLOAD(isForced), JMPZ(verifyTimestampAndL1InfoRoot) + $ :MLOAD(isForced), JMPZ(verifyTimestampAndL1InfoRoot) ; forced batch ; - update timestamp only if currentTimestamp < limitTimestamp ; - set blockHash to default - $ => C :MLOAD(forcedBlockHashL1) - C :MSTORE(blockHashL1InfoTree) - A :MSTORE(timestamp) - $ :LT, JMPNC(initSetGERL1InfoTree) + $ => C :MLOAD(forcedBlockHashL1) + C :MSTORE(blockHashL1InfoTree) + A :MSTORE(timestamp) + $ :LT, JMPNC(initSetGERL1InfoTree) newForcedTimestamp: - B :MSTORE(timestamp), JMP(setNewTimestamp) + B :MSTORE(timestamp), JMP(setNewTimestamp) verifyTimestampAndL1InfoRoot: - $ => B :MLOAD(deltaTimestamp) + $ => B :MLOAD(deltaTimestamp) ; Addition of two values of 8 bytes [B: currentTimestamp(A) + deltaTimestamp(B)] - $ => B :ADD, MSTORE(timestamp) + $ => B :ADD, MSTORE(timestamp) ; Verify (currentTimestamp + deltaTimestamp) <= limitTimestamp - $ => A :MLOAD(timestampLimit) - $ :LT, JMPC(invalidChangeL2Block) + $ => A :MLOAD(timestampLimit) + $ :LT, JMPC(invalidChangeL2Block) ; Set new timestamp %TIMESTAMP_STORAGE_POS => C %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B - $ => D :MLOAD(timestamp) - $ => SR :SSTORE + $ => D :MLOAD(timestamp) + $ => SR :SSTORE ; check indexL1InfoTree != 0 to verify data L1InfoTree - $ :MLOAD(indexL1InfoTree), JMPZ(skipSetGERL1InfoTree) + $ :MLOAD(indexL1InfoTree), JMPZ(skipSetGERL1InfoTree) - ${getL1InfoGER(mem.indexL1InfoTree)} => A :MSTORE(gerL1InfoTree) - ${getL1InfoBlockHash(mem.indexL1InfoTree)} => B :MSTORE(blockHashL1InfoTree) - ${getL1InfoTimestamp(mem.indexL1InfoTree)} => C :MSTORE(timestampL1InfoTree) - :CALL(verifyMerkleProof) +${getL1InfoGER(mem.indexL1InfoTree)} => A :MSTORE(gerL1InfoTree) +${getL1InfoBlockHash(mem.indexL1InfoTree)} => B :MSTORE(blockHashL1InfoTree) +${getL1InfoTimestamp(mem.indexL1InfoTree)} => C :MSTORE(timestampL1InfoTree) + :CALL(verifyMerkleProof) ; Verify (currentTimestamp + deltaTimestamp) >= l1InfoRoot.timestamp - $ => A :MLOAD(timestamp) - $ => B :MLOAD(timestampL1InfoTree) - $ :LT, JMPC(invalidChangeL2Block, initSetGERL1InfoTree) + $ => A :MLOAD(timestamp) + $ => B :MLOAD(timestampL1InfoTree) + $ :LT, JMPC(invalidChangeL2Block, initSetGERL1InfoTree) setNewTimestamp: ; Set new timestamp diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index 3ec43eab..b9fc3eda 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -30,9 +30,9 @@ processTx: CTX :MSTORE(currentCTX) ; Minimum of 100000 steps left to process a tx - %MAX_CNT_STEPS - STEP - 100000 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 100 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 100000 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 100 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) ; Check the signature 0 => B @@ -79,12 +79,12 @@ endCheckChainId: ; get value above 256 bits ${_effGasPriceShifted >> 256} => D ; compute ARITH - ${_effGasPriceShifted} => E :ARITH + ${_effGasPriceShifted} => E :ARITH ; txGasPrice = _effGasPriceShifted / 256 256 => B ; (_effGasPriceShifted / 256)(A) * 256(B) + (_effGasPriceShifted % 256)(C) = D * 2**256 + op(E) - ${_effGasPriceShifted / 256} => A :MSTORE(txGasPrice) + ${_effGasPriceShifted / 256} => A :MSTORE(txGasPrice) ${_effGasPriceShifted % 256} => C ; compute ARITH E :ARITH @@ -137,7 +137,7 @@ addGas: 0 => C :JMP(loopBytes) loopBytes: - %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) A - C - 1 :JMPN(endCalldataIntrinsicGas) E => B $ => E :MLOAD(batchHashDataId) @@ -327,10 +327,10 @@ endContractAddress: ;; deploy contract in state-tree deploy: - %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon) - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) - :CALL(isColdAddress) ; add address to touched addresses + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + :CALL(isColdAddress) ; add address to touched addresses ; check if address is deployable ( nonce == bytecode == 0) A => E @@ -458,7 +458,7 @@ readCode: ;; Compute and save hash bytecode and bytecode length in the state-tree endDeploy: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) ; called from `opRETURNDeploy` which has: C --> length, E --> offset @@ -496,7 +496,7 @@ handleGasFromError: 0 :MSTORE(txStatus) ;; compute maximum gas to refund handleGas: - %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*4 :JMPN(outOfCountersPoseidon) 0 => A $ => B :MLOAD(gasRefund), JMPZ(refundGas) @@ -557,30 +557,30 @@ sendGasSeq: ;; handle invalid transaction due to intrinsic checks invalidIntrinsicTxSignature: - $${eventLog(onError, intrinsic_invalid_signature)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_signature)} :JMP(handleIntrinsicError) invalidIntrinsicTxChainId: - $${eventLog(onError, intrinsic_invalid_chain_id)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_chain_id)} :JMP(handleIntrinsicError) invalidIntrinsicTxNonce: - $${eventLog(onError, intrinsic_invalid_nonce)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_nonce)} :JMP(handleIntrinsicError) invalidIntrinsicTxGasLimit: - $${eventLog(onError, intrinsic_invalid_gas_limit)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_gas_limit)} :JMP(handleIntrinsicError) invalidIntrinsicTxGasOverflow: - $${eventLog(onError, intrinsic_invalid_gas_overflow)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_gas_overflow)} :JMP(handleIntrinsicError) invalidIntrinsicTxBalance: - $${eventLog(onError, intrinsic_invalid_balance)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_balance)} :JMP(handleIntrinsicError) invalidIntrinsicBatchGasLimit: - $${eventLog(onError, intrinsic_invalid_batch_gas_limit)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_batch_gas_limit)}:JMP(handleIntrinsicError) invalidIntrinsicTxSenderCode: - $${eventLog(onError, intrinsic_invalid_sender_code)} :JMP(handleIntrinsicError) + $${eventLog(onError, intrinsic_invalid_sender_code)} :JMP(handleIntrinsicError) handleIntrinsicError: - $ => SR :MLOAD(originSR), JMP(processIntrinsicTxFinished) + $ => SR :MLOAD(originSR), JMP(processIntrinsicTxFinished) ;; handle error no more bytecode to read defaultOpCode: diff --git a/main/touched.zkasm b/main/touched.zkasm index 6ca50e67..9cd3f222 100644 --- a/main/touched.zkasm +++ b/main/touched.zkasm @@ -22,8 +22,8 @@ revertTouched: ; @out D => if the address is cold [0 if warm, 1 if cold] isColdAddress: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) ; store previous registers values temporary B :MSTORE(tmpB) @@ -80,7 +80,7 @@ finishColdPrecompiled: ; @out A => if the storage slot is cold [0 if warm, 1 if cold] isColdSlot: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) ; store previous registers values temporary B :MSTORE(tmpB) @@ -94,10 +94,10 @@ isColdSlot: ; read from touched tree if slot is warm ; A register already set %SMT_KEY_TOUCHED_SLOTS => B - $ => D :SLOAD, JMPZ(markWarmSlot) + $ => D :SLOAD, JMPZ(markWarmSlot) ; slot is warm. A = 0 - 0 => A :JMP(finishColdSlot) + 0 => A :JMP(finishColdSlot) ; set address to warm and return 0 markWarmSlot: diff --git a/main/utils.zkasm b/main/utils.zkasm index 59cee4ee..71cf04a6 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -39,8 +39,8 @@ getLenBytes: getLenBytesLoop: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) 0 => B ; if A is zero, finish counter @@ -77,8 +77,8 @@ getLenBits: getLenBitsLoop: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) 0 => B ; if B is zero, finish counter $ :EQ,JMPC(getLenBitsEnd) @@ -126,9 +126,9 @@ MSTOREX: ; @out E => new offset MSTORE32: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 1 :JMPN(outOfCountersMemalign) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 1 :JMPN(outOfCountersMemalign) ; store current registries RR :MSTORE(tmpZkPCmstore) A :MSTORE(tmpVarAmstore) @@ -270,9 +270,9 @@ VAR GLOBAL isMLOADX ; @out E => new offset MLOADX: ; check zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) - %MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 1 :JMPN(outOfCountersMemalign) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 1 :JMPN(outOfCountersMemalign) 32 - C :JMPN(errorMLOADMSTORE) 32 - C - 1 :JMPN(MLOAD32) @@ -284,9 +284,9 @@ MLOADX: ; @out E => new offset MLOAD32: ; check zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) - %MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 1 :JMPN(outOfCountersMemalign) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 1 :JMPN(outOfCountersMemalign) ; store current registries RR :MSTORE(tmpZkPCmload) B :MSTORE(tmpVarBmload) @@ -348,8 +348,8 @@ VAR GLOBAL tmpVarDemptyAcc ; @out E => isEmpty => 1 = true, 0 = false isEmptyAccount: ; check zk-counters - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon) ; store current registries @@ -457,7 +457,7 @@ VAR GLOBAL tmpZkPCsaveMem ; @in: lastMemLength: size of the bytes to copy saveMem: ; check zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 5 :JMPN(outOfCountersBinary) RR :MSTORE(tmpZkPCsaveMem) A :MSTORE(tmpVarAsaveMem) @@ -660,18 +660,18 @@ divisorSmallerDiv: :RETURN loadTmp: - $ => A :MLOAD(tmpVarAArith) - $ => B :MLOAD(tmpVarBArith) - $ => C :MLOAD(tmpVarCArith) - $ => D :MLOAD(tmpVarDArith) - $ => E :MLOAD(tmpVarEArith), RETURN + $ => A :MLOAD(tmpVarAArith) + $ => B :MLOAD(tmpVarBArith) + $ => C :MLOAD(tmpVarCArith) + $ => D :MLOAD(tmpVarDArith) + $ => E :MLOAD(tmpVarEArith), RETURN storeTmp: - A :MSTORE(tmpVarAArith) - B :MSTORE(tmpVarBArith) - C :MSTORE(tmpVarCArith) - D :MSTORE(tmpVarDArith) - E :MSTORE(tmpVarEArith), RETURN + A :MSTORE(tmpVarAArith) + B :MSTORE(tmpVarBArith) + C :MSTORE(tmpVarCArith) + D :MSTORE(tmpVarDArith) + E :MSTORE(tmpVarEArith), RETURN VAR GLOBAL tmpSHXZkPC VAR GLOBAL tmpSHXZkPC2 @@ -756,9 +756,9 @@ SHRarithfinal: ;@out A - A << D => A SHLarith: ; check zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) RR :MSTORE(tmpSHXZkPC2) B :MSTORE(tmpVarBSHX) C :MSTORE(tmpVarCSHX) @@ -777,9 +777,9 @@ SHLarith: :JMP(SHLarithinit) SHLarithBit: ; check zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) RR :MSTORE(tmpSHXZkPC2) B :MSTORE(tmpVarBSHX) C :MSTORE(tmpVarCSHX) @@ -826,45 +826,45 @@ SHLarithfinal: ; out of counters full tracer event trigger outOfCountersStep: - $${eventLog(onError, OOCS)} :JMP(handleBatchError) + $${eventLog(onError, OOCS)} :JMP(handleBatchError) outOfCountersKeccak: - $${eventLog(onError, OOCK)} :JMP(handleBatchError) + $${eventLog(onError, OOCK)} :JMP(handleBatchError) outOfCountersBinary: - $${eventLog(onError, OOCB)} :JMP(handleBatchError) + $${eventLog(onError, OOCB)} :JMP(handleBatchError) outOfCountersMemalign: - $${eventLog(onError, OOCM)} :JMP(handleBatchError) + $${eventLog(onError, OOCM)} :JMP(handleBatchError) outOfCountersArith: - $${eventLog(onError, OOCA)} :JMP(handleBatchError) + $${eventLog(onError, OOCA)} :JMP(handleBatchError) outOfCountersPadding: - $${eventLog(onError, OOCPA)} :JMP(handleBatchError) + $${eventLog(onError, OOCPA)} :JMP(handleBatchError) outOfCountersPoseidon: - $${eventLog(onError, OOCPO)} :JMP(handleBatchError) + $${eventLog(onError, OOCPO)} :JMP(handleBatchError) outOfCountersSha256: - $${eventLog(onError, OOCSH)} :JMP(handleBatchError) + $${eventLog(onError, OOCSH)} :JMP(handleBatchError) invalidChangeL2Block: - $${eventLog(onError, invalid_change_l2_block)} :JMP(handleBatchError) + $${eventLog(onError, invalid_change_l2_block)} :JMP(handleBatchError) outOfGas: - $${eventLog(onError, OOG)} :JMP(handleError) + $${eventLog(onError, OOG)} :JMP(handleError) invalidJump: - $${eventLog(onError, invalidJump)} :JMP(handleError) + $${eventLog(onError, invalidJump)} :JMP(handleError) invalidOpcode: - $${eventLog(onError, invalidOpcode)} :JMP(handleError) + $${eventLog(onError, invalidOpcode)} :JMP(handleError) stackUnderflow: - $${eventLog(onError, underflow)} :JMP(handleError) + $${eventLog(onError, underflow)} :JMP(handleError) stackOverflow: - $${eventLog(onError, overflow)} :JMP(handleError) + $${eventLog(onError, overflow)} :JMP(handleError) deployAddressCollision: - $${eventLog(onError, invalidAddressCollision)} :JMP(handleError) + $${eventLog(onError, invalidAddressCollision)} :JMP(handleError) invalidStaticTx: - $${eventLog(onError, invalidStaticTx)} :JMP(handleError) + $${eventLog(onError, invalidStaticTx)} :JMP(handleError) invalidCodeSize: - $${eventLog(onError, invalidCodeSize)} :JMP(handleError) + $${eventLog(onError, invalidCodeSize)} :JMP(handleError) invalidCodeStartsEF: - $${eventLog(onError, invalidCodeStartsEF)} :JMP(handleError) + $${eventLog(onError, invalidCodeStartsEF)} :JMP(handleError) handleError: - %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) ;revert all state changes $ => SR :MLOAD(initSR), CALL(revertTouched) :CALL(revertBlockInfoTree) @@ -882,7 +882,7 @@ handleError: handleBatchError: ; restore init state root and finish batch - $ => SR :MLOAD(batchSR) + $ => SR :MLOAD(batchSR) ; if batch error is triggered while parsing the RLP, it jumps to 'appendTxsInit' ; to fill the missing bytes to complete 'batchDataHash' $ :MLOAD(isLoadingRLP),JMPNZ(appendTxsInit) @@ -932,8 +932,8 @@ moveBalances: ;;;;;;;; ; evmCALL (Move Balances) ;;;;;;;; - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*4 :JMPN(outOfCountersPoseidon) ;Check if is a delegate call $ => A :MLOAD(isDelegateCall), JMPNZ(endMoveBalances) @@ -997,8 +997,8 @@ VAR GLOBAL accumulator ; @in D => bytes to read ; @out E => value read readPush: - %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) D :MSTORE(pushBytes) D => A 0 :MSTORE(accumulator) @@ -1022,8 +1022,8 @@ readPush: 0 => B readPushBlock: - %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; load hash contract identifier $ => E :MLOAD(contractHashId) $ => A :MLOAD(numBlocks) @@ -1060,13 +1060,13 @@ endRotate: B + 1 => B :JMP(readPushBlock) endPushInit: - $ => A :MLOAD(leftBytes), JMPZ(finalPush) + $ => A :MLOAD(leftBytes), JMPZ(finalPush) 0 => C - 0 => B :JMP(endPushLoop) + 0 => B :JMP(endPushLoop) endPushLoop: - %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) $ => A :MLOAD(leftBytes) $ :EQ, JMPC(endPushFinal) @@ -1076,7 +1076,7 @@ endPushLoop: B - 1 => A :JMP(computeFactorLoop) computeFactorLoop: - %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) A :JMPN(computeFactorEnd) 256*D => D A - 1 => A :JMP(computeFactorLoop) @@ -1123,8 +1123,8 @@ addBatchHashByteByByte: 1 => D utilsAddBatchHashBytebyByteLoop: - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) 32 - D => D $ => A :MLOAD(auxBytes), CALL(SHRarith); in: [A: value, D: #bytes to right shift] out: [A: shifted result] ; get last byte in A @@ -1154,7 +1154,7 @@ VAR GLOBAL tmpZkPCEF ; @internalParam {memOffset} memory offset to read bytes from ; @internalParam {startsWithEF} flag to indicate if first deployed byte on the bytecode is 0xEF checkBytecodeStartsEF: - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) ; save temporary registers A :MSTORE(tmpVarAEF) B :MSTORE(tmpVarBEF) @@ -1201,8 +1201,8 @@ VAR GLOBAL memSizeLinearPoseidon ; @internalParam {memSize} memory size to read bytes from ; @out D => resulting linear poseidon hashPoseidonLinearFromMemory: - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) A :MSTORE(tmpVarAhashP) B :MSTORE(tmpVarBhashP) C :MSTORE(tmpVarChashP) @@ -1264,8 +1264,8 @@ VAR GLOBAL tmpVarBmask ; @in A => address not masked ; @out A => masked address maskAddress: - %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) B :MSTORE(tmpVarBmask) 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn => B $ => A :AND @@ -1283,7 +1283,7 @@ VAR GLOBAL tmpZkPCmulmod ; @out C utilMULMOD: ; checks zk-counters - %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) @@ -1429,8 +1429,8 @@ expAD: ; - 3 ARITH: 1 in divARITH + 1 in 2*mulARITH ; - 5 BINARIES: 5 in divARITH ; - 100 steps (rounded up): 37 in divARITH + 11 in 2*mulARITH + 18 self - %MAX_CNT_BINARY - CNT_BINARY - 2*A :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 50*A :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2*A :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50*A :JMPN(outOfCountersStep) expADloop: ;A exp @@ -1502,24 +1502,24 @@ verifyMerkleProof: ;;;;;;;;;;;;;;;;;;;;; ; new keccak address - $ => E :MLOAD(lastHashKIdUsed) - E + 1 => E :MSTORE(lastHashKIdUsed) + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) ; add gerL1InfoTree (32 bytes) 0 => HASHPOS 32 => D - A :HASHK(E) + A :HASHK(E) ; add blockHashL1 (32 bytes) - B :HASHK(E) + B :HASHK(E) ; add timestamp (8 bytes) 8 => D - C :HASHK(E) + C :HASHK(E) ; compute l1InfoTree Leaf value - HASHPOS :HASHKLEN(E) - $ => C :HASHKDIGEST(E) ; initial value + HASHPOS :HASHKLEN(E) + $ => C :HASHKDIGEST(E) ; initial value ; initialization registers for smt verify 0 => D From 2cacb208f571d43ff171ea54648bf95144dcc538 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Mon, 4 Dec 2023 23:35:21 +0100 Subject: [PATCH 055/121] update sample invalid-batch --- package.json | 2 +- tools/parallel-tests-sample/sample.test.js | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/package.json b/package.json index a4bea130..2b96ba0a 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/add-gen-ooc", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", diff --git a/tools/parallel-tests-sample/sample.test.js b/tools/parallel-tests-sample/sample.test.js index c9e87c4b..178750b4 100644 --- a/tools/parallel-tests-sample/sample.test.js +++ b/tools/parallel-tests-sample/sample.test.js @@ -56,12 +56,6 @@ async function runTest(cmPols, steps) { await smMain.execute(cmPols.Main, input, rom, config); } catch (err) { - // If fails for ooc, retry increasing stepsN up to three times - if (inputPath.includes('invalid-batch')) { - expect(input.oldStateRoot).to.be.equal(input.newStateRoot); - - return; - } fs.writeFileSync(checkerDir, `Failed test ${inputPath} - ${err}}`); throw err; } From 4944971d83584a433603adb25a912efff004f7b9 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Tue, 5 Dec 2023 11:11:59 +0100 Subject: [PATCH 056/121] update package json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b96ba0a..a4bea130 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/add-gen-ooc", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 7371c37e1df7c7c7a14ba1b24a0e3ee2fe055f49 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Tue, 5 Dec 2023 16:07:29 +0100 Subject: [PATCH 057/121] update packages --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3c939c4d..1ffe14f3 100644 --- a/package.json +++ b/package.json @@ -37,13 +37,13 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#v2.0.0-rc.1-fork.7", "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/zkasmtest-stats", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.1-fork.7", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#b066730fb04b31da192d58eb52953b82fc87314e", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.1-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 067ea9a77d308fae51570a361fdadf7469c172b6 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Thu, 7 Dec 2023 11:31:08 +0100 Subject: [PATCH 058/121] Add on step for unsigned transactions --- main/load-tx-rlp.zkasm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 28ac3e42..61432789 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -358,8 +358,9 @@ finishLoadRLP: $ => C :MLOAD(txS) $ => D :MLOAD(txV), CALL(ecrecover_tx) checkAndSaveFrom: - A :MSTORE(txSrcAddr) + ; warning: we need to insert one transition step between label `checkAndSafeFrom` and `MSTORE(txSrcAddr)` to allow unsigned transactions from executor 20 => D + A :MSTORE(txSrcAddr) $ => E :MLOAD(l2TxHashPointer) $ => HASHPOS :MLOAD(l2HASHP) A :HASHP(E) From fa8464222ce81231be2644f34ee69a03b71c8bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 11 Dec 2023 19:25:18 +0100 Subject: [PATCH 059/121] Fixing a bug in modexp --- main/modexp/array_lib/array_square.zkasm | 105 ++++++++++++----------- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 9162d44e..d553cce7 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -12,7 +12,7 @@ ; function array_square(a: bigint[], B: bigint): bigint[] { ; let len = a.length; -; let result = new Array(len).fill(0n); +; let out = new Array(len).fill(0n); ; let product: bigint; ; let carry: bigint; ; let a_i: bigint; @@ -22,15 +22,15 @@ ; carry = 0n - a_i * a_i; ; for (var j = i; j < len; j++) { ; a_j = a[j]; -; product = 2n * (a_i * a_j) + result[i + j] + carry; +; product = 2n * (a_i * a_j) + out[i + j] + carry; ; carry = product / B; -; result[i + j] = product - carry * B; +; out[i + j] = product - carry * B; ; } -; result[i + len] = carry; +; out[i + len] = carry; ; } -; trim(result); -; return result; +; trim(out); +; return out; ; } VAR GLOBAL array_square_in[%ARRAY_MAX_LEN] @@ -86,61 +86,72 @@ array_square_clean_out: RR :JMPZ(array_square_loopZero2inA, array_square_clean_out) ; Begin of branching -array_square_add_carry_1: - D + 1 => D :JMP(return_array_square_add_carry_1) +array_square_add_low_carry_1: + ; Since here high ∈ [0, 2²⁵⁶ - 2], there cannot be carry in the following addition + D => A + 1 => B + $ => D :ADD, JMP(return_array_square_add_low_carry_1) -array_square_add_carry_2: +array_square_add_low_carry_2: + ; Since here high ∈ [0, 2²⁵⁶ - 1], there can be carry in the following addition D => A 1 => B - $ => D :ADD, JMPC(array_square_add_carry_carry_2, return_array_square_add_carry_2) + $ => D :ADD, JMPC(array_square_add_high_carry_2, return_array_square_add_low_carry_2) -array_square_add_carry_3: +array_square_add_low_carry_3: + ; Since here high ∈ [0, 2²⁵⁶ - 1], there can be carry in the following addition D => A 1 => B - $ => D :ADD, JMPC(array_square_add_carry_carry_4, return_array_square_add_carry_3) + $ => D :ADD, JMPC(array_square_add_high_carry_4, return_array_square_add_low_carry_3) -array_square_add_carry_carry_1: +; In the add_high_carry_X branches, since highest = 0, there cannot be carry in the additions +; Moreover, we can perform "plain" addition +array_square_add_high_carry_1: $ => A :MLOAD(array_square_highest_carry) A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_carry_carry_1) + :JMP(return_array_square_add_high_carry_1) -array_square_add_carry_carry_2: +array_square_add_high_carry_2: $ => A :MLOAD(array_square_highest_carry) A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_carry_2) + :JMP(return_array_square_add_low_carry_2) -array_square_add_carry_carry_3: +array_square_add_high_carry_3: $ => A :MLOAD(array_square_highest_carry) A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_carry_carry_3) + :JMP(return_array_square_add_high_carry_3) -array_square_add_carry_carry_4: +array_square_add_high_carry_4: $ => A :MLOAD(array_square_highest_carry) A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_carry_3) + :JMP(return_array_square_add_low_carry_3) -array_square_add_carry_carry_5: +array_square_add_high_carry_5: $ => A :MLOAD(array_square_highest_carry) A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_carry_carry_5) + :JMP(return_array_square_add_high_carry_5) +; In the is_negative_X branches, we perform subtraction of a value with three chunks +; Therefore, the subtraction can produce carry until the highest chunk array_square_is_negative_1: - $ => C :SUB, JMPC(array_square_sub_carry_2, return_array_square_is_negative_1) + $ => C :SUB, JMPC(array_square_sub_low_carry_2, return_array_square_is_negative_1) array_square_is_negative_2: - $ => D :SUB, JMPC(array_square_sub_carry_carry_2, return_array_square_is_negative_2) + $ => D :SUB, JMPC(array_square_sub_high_carry_2, return_array_square_is_negative_2) -array_square_sub_carry_2: +array_square_sub_low_carry_2: D => A 1 => B - $ => D :SUB, JMPC(array_square_sub_carry_carry_1, return_array_square_is_negative_1) + $ => D :SUB, JMPC(array_square_sub_high_carry_1, return_array_square_is_negative_1) -array_square_sub_carry_carry_1: +; Similarly, in the sub_high_carry_X branches, since highest = 1, there cannot be carry in the subtraction +; Moreover, we can perform "plain" subtraction +array_square_sub_high_carry_1: $ => A :MLOAD(array_square_highest_carry) A - 1 :MSTORE(array_square_highest_carry) :JMP(return_array_square_is_negative_1) -array_square_sub_carry_carry_2: +array_square_sub_high_carry_2: $ => A :MLOAD(array_square_highest_carry) A - 1 :MSTORE(array_square_highest_carry) :JMP(return_array_square_is_negative_2) @@ -180,7 +191,8 @@ array_square_loop_index_check: array_square_loopZero2inA: RCX => E - ; product = 2·(a_i·a_j) + out[i + j] + carry + ; product = 2·(a_i·a_j) + out[i + j] + carry. + ; The result will be stored as array_square_highest_carry·base² + D·base + C ; 1] a_i·a_j: This number cannot be GT (base - 2)·base + 1, two chunks $ => A :MLOAD(array_square_in + E) @@ -193,47 +205,44 @@ array_square_loopZero2inA: ; 2] 2·a_i·a_j: This number cannot be GT base² + (base - 4)·base + 2, three chunks E => A,B - $ => C :ADD, JMPC(array_square_add_carry_1) - return_array_square_add_carry_1: + $ => C :ADD, JMPC(array_square_add_low_carry_1) + return_array_square_add_low_carry_1: $ => A :MLOAD(array_square_aiaj_high) D => B - $ => D :ADD, JMPC(array_square_add_carry_carry_1) - return_array_square_add_carry_carry_1: - - ; The result is stored as array_square_highest_carry·base² + D·base + C - + $ => D :ADD, JMPC(array_square_add_high_carry_1) + return_array_square_add_high_carry_1: ; 3] 2·a_i·a_j + out[i + j]: ; a) j != len: This number cannot be GT base² + (base - 3)·base + 1, as out[i + j] < B - ; b) j == len: This number cannot be GT base² + (base - 3)·base + base - 1, as out[i + j] <= B + (B - 3) + ; b) j == len: This number cannot be GT base² + (base - 3)·base + base - 1, as out[i + len] <= B + (B - 3) ; In both cases, three chunks RR + RCX => E $ => A :MLOAD(array_square_out + E) C => B - $ => C :ADD, JMPC(array_square_add_carry_2) - return_array_square_add_carry_2: + $ => C :ADD, JMPC(array_square_add_low_carry_2) + return_array_square_add_low_carry_2: $ => A :MLOAD(array_square_out_carry) D => B - $ => D :ADD, JMPC(array_square_add_carry_carry_3) - return_array_square_add_carry_carry_3: + $ => D :ADD, JMPC(array_square_add_high_carry_3) + return_array_square_add_high_carry_3: - ; 4] 2·a_i·a_j + out[i + j] + carry: This number cannot be GT (base - 2)·base + 1, two chunks + ; 4] 2·a_i·a_j + out[i + j] + carry: This number cannot be GT base² + (base - 2)·base, three chunks C => A $ => B :MLOAD(array_square_carry_low) $ :MLOAD(array_square_carry_sign), JMPZ(array_square_is_negative_1) - $ => C :ADD, JMPC(array_square_add_carry_3) - return_array_square_add_carry_3: + $ => C :ADD, JMPC(array_square_add_low_carry_3) + return_array_square_add_low_carry_3: return_array_square_is_negative_1: D => A $ => B :MLOAD(array_square_carry_high) $ :MLOAD(array_square_carry_sign), JMPZ(array_square_is_negative_2) - $ => D :ADD, JMPC(array_square_add_carry_carry_5) - return_array_square_add_carry_carry_5: + $ => D :ADD, JMPC(array_square_add_high_carry_5) + return_array_square_add_high_carry_5: return_array_square_is_negative_2: - ; carry = product / B; This number cannot be greater than base + (base - 3) + ; carry = product / B; This number cannot be greater than base + (base - 2) D :MSTORE(array_square_carry_low) $ => A :MLOAD(array_square_highest_carry) A :MSTORE(array_square_carry_high) @@ -247,7 +256,7 @@ array_square_loopZero2inA: 0 :MSTORE(array_square_highest_carry) RR => A $ => B :MLOAD(array_square_len_in) - $ :EQ, JMPC(array_square_loop_index_check) ; [Steps: 61] + $ :EQ, JMPC(array_square_loop_index_check) return_array_square_loop_index_check: :JMP(array_square_loopZero2inA) From 934c82f1efd0069c4573b7854a8d0e3287ee7f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 11 Dec 2023 19:26:04 +0100 Subject: [PATCH 060/121] Removing redundancy on array utils --- test/testArrayUtils.zkasm | 340 +++++++++++--------------------------- 1 file changed, 96 insertions(+), 244 deletions(-) diff --git a/test/testArrayUtils.zkasm b/test/testArrayUtils.zkasm index 90fd0a82..2cc3dc13 100644 --- a/test/testArrayUtils.zkasm +++ b/test/testArrayUtils.zkasm @@ -18,10 +18,6 @@ VAR GLOBAL initial_RR VAR GLOBAL initial_HASHPOS VAR GLOBAL initial_RCX -VAR GLOBAL inA[300] -VAR GLOBAL inB[300] -VAR GLOBAL out[300] - ; Fix better notation for the above start: @@ -49,232 +45,121 @@ start: ; array_compare ; --------------------------------------------------------------- -; 1] len(inA) > len(inB) should return 2 +; 1] inA = [5,6,7], inB = [2,3]. len(inA) > len(inB) should return 2 array_compare_test_1: - 5n :MSTORE(inA) + 3 => C + 2 => D + 5n :MSTORE(array_compare_inA) 1 => E - 6n :MSTORE(inA + E) + 6n :MSTORE(array_compare_inA + E) 2 => E - 7n :MSTORE(inA + E) - - 2n :MSTORE(inB) + 7n :MSTORE(array_compare_inA + E) + 2n :MSTORE(array_compare_inB) 1 => E - 3n :MSTORE(inB + E) - - 3 => C - 2 => D - 0 => E,RR -array_compare_test_1_memory_copy_inA_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_compare_inA + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_compare_test_1_memory_copy_inB_loop, array_compare_test_1_memory_copy_inA_loop) - -array_compare_test_1_memory_copy_inB_loop: - $ => A :MLOAD(inB + RR) - A :MSTORE(array_compare_inB + RR) - RR + 1 => RR - RR => A - D => B - $ :EQ, JMPC(array_compare_test_1_compare, array_compare_test_1_memory_copy_inB_loop) - -array_compare_test_1_compare: + 3n :MSTORE(array_compare_inB + E) :CALL(array_compare) 2 :MLOAD(array_compare_result) -; 2] len(inA) < len(inB) should return 0 +; 2] inA = [5,6], inB = [2,3,4]. len(inA) < len(inB) should return 0 array_compare_test_2: - 5n :MSTORE(inA) + 2 => C + 3 => D + 5n :MSTORE(array_compare_inA) 1 => E - 6n :MSTORE(inA + E) - - 2n :MSTORE(inB) + 6n :MSTORE(array_compare_inA + E) + 2n :MSTORE(array_compare_inB) 1 => E - 3n :MSTORE(inB + E) + 3n :MSTORE(array_compare_inB + E) 2 => E - 4n :MSTORE(inB + E) - - 2 => C - 3 => D - 0 => E,RR -array_compare_test_2_memory_copy_inA_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_compare_inA + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_compare_test_2_memory_copy_inB_loop, array_compare_test_2_memory_copy_inA_loop) - -array_compare_test_2_memory_copy_inB_loop: - $ => A :MLOAD(inB + RR) - A :MSTORE(array_compare_inB + RR) - RR + 1 => RR - RR => A - D => B - $ :EQ, JMPC(array_compare_test_2_compare, array_compare_test_2_memory_copy_inB_loop) - -array_compare_test_2_compare: + 4n :MSTORE(array_compare_inB + E) :CALL(array_compare) 0 :MLOAD(array_compare_result) -; 3] len(inA) = len(inB) but inA > inB should return 2 +; 3] inA = [5,6,7], inB = [5,6,6]. len(inA) = len(inB) but inA > inB should return 2 array_compare_test_3: - 5n :MSTORE(inA) + 3 => C + 3 => D + 5n :MSTORE(array_compare_inA) 1 => E - 6n :MSTORE(inA + E) + 6n :MSTORE(array_compare_inA + E) 2 => E - 7n :MSTORE(inA + E) - - 5n :MSTORE(inB) + 7n :MSTORE(array_compare_inA + E) + 5n :MSTORE(array_compare_inB) 1 => E - 6n :MSTORE(inB + E) + 6n :MSTORE(array_compare_inB + E) 2 => E - 6n :MSTORE(inB + E) - - 3 => C - 3 => D - 0 => E,RR -array_compare_test_3_memory_copy_inA_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_compare_inA + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_compare_test_3_memory_copy_inB_loop, array_compare_test_3_memory_copy_inA_loop) - -array_compare_test_3_memory_copy_inB_loop: - $ => A :MLOAD(inB + RR) - A :MSTORE(array_compare_inB + RR) - RR + 1 => RR - RR => A - D => B - $ :EQ, JMPC(array_compare_test_3_compare, array_compare_test_3_memory_copy_inB_loop) - -array_compare_test_3_compare: + 6n :MSTORE(array_compare_inB + E) :CALL(array_compare) 2 :MLOAD(array_compare_result) -; 4] len(inA) = len(inB) but inA < inB should return 0 +; 4] inA = [5,6,6], inB = [5,6,7]. len(inA) = len(inB) but inA < inB should return 0 array_compare_test_4: - 5n :MSTORE(inA) + 3 => C + 3 => D + 5n :MSTORE(array_compare_inA) 1 => E - 6n :MSTORE(inA + E) + 6n :MSTORE(array_compare_inA + E) 2 => E - 6n :MSTORE(inA + E) + 6n :MSTORE(array_compare_inA + E) - 5n :MSTORE(inB) + 5n :MSTORE(array_compare_inB) 1 => E - 6n :MSTORE(inB + E) + 6n :MSTORE(array_compare_inB + E) 2 => E - 7n :MSTORE(inB + E) - - 3 => C - 3 => D - 0 => E,RR -array_compare_test_4_memory_copy_inA_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_compare_inA + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_compare_test_4_memory_copy_inB_loop, array_compare_test_4_memory_copy_inA_loop) - -array_compare_test_4_memory_copy_inB_loop: - $ => A :MLOAD(inB + RR) - A :MSTORE(array_compare_inB + RR) - RR + 1 => RR - RR => A - D => B - $ :EQ, JMPC(array_compare_test_4_compare, array_compare_test_4_memory_copy_inB_loop) - -array_compare_test_4_compare: + 7n :MSTORE(array_compare_inB + E) :CALL(array_compare) 0 :MLOAD(array_compare_result) -; 5] inA = inB should return 1 +; 5] inA = [5,6,6], inB = [5,6,6]. inA = inB should return 1 array_compare_test_5: - 5n :MSTORE(inA) + 3 => C + 3 => D + 5n :MSTORE(array_compare_inA) 1 => E - 6n :MSTORE(inA + E) + 6n :MSTORE(array_compare_inA + E) 2 => E - 6n :MSTORE(inA + E) - - 5n :MSTORE(inB) + 6n :MSTORE(array_compare_inA + E) + 5n :MSTORE(array_compare_inB) 1 => E - 6n :MSTORE(inB + E) + 6n :MSTORE(array_compare_inB + E) 2 => E - 6n :MSTORE(inB + E) - - 3 => C - 3 => D - 0 => E,RR -array_compare_test_5_memory_copy_inA_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_compare_inA + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_compare_test_5_memory_copy_inB_loop, array_compare_test_5_memory_copy_inA_loop) - -array_compare_test_5_memory_copy_inB_loop: - $ => A :MLOAD(inB + RR) - A :MSTORE(array_compare_inB + RR) - RR + 1 => RR - RR => A - D => B - $ :EQ, JMPC(array_compare_test_5_compare, array_compare_test_5_memory_copy_inB_loop) - -array_compare_test_5_compare: + 6n :MSTORE(array_compare_inB + E) :CALL(array_compare) 1 :MLOAD(array_compare_result) ; --------------------------------------------------------------- ; array unshift ; --------------------------------------------------------------- - 0 => C - 5n => D +; 1] in = [3] and D = 5 => in = [5,3] +array_unshift_test_1: + 1 => C 3n :MSTORE(array_unshift_in) + 5 => D :CALL(array_unshift) - 5 :MLOAD(array_unshift_in) - 1 :MLOAD(array_unshift_len) - -array_unshift_test_1: - 2n :MSTORE(inA) + 5n :MLOAD(array_unshift_in) 1 => E - 1n :MSTORE(inA + E) - 2 => E - 1n :MSTORE(inA + E) - 5n => D + 3n :MLOAD(array_unshift_in + E) + 2 :MLOAD(array_unshift_len) +; 2] in = [2,1,1] and D = 5 => in = [5,2,1,1] +array_unshift_test_2: 3 => C - 0 => E -array_unshift_test_1_memory_copy_in_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_unshift_in + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_unshift_test_1_unshift, array_unshift_test_1_memory_copy_in_loop) - -array_unshift_test_1_unshift: + 5 => D + 2n :MSTORE(array_unshift_in) + 1 => E + 1n :MSTORE(array_unshift_in + E) + 2 => E + 1n :MSTORE(array_unshift_in + E) :CALL(array_unshift) - 4 :MLOAD(array_unshift_len) - 3 => C ; reset the len back to 3 - 0 => E ; reset the loop counter - -array_unshift_test_1_memory_copy_out_loop: - $ => A :MLOAD(array_unshift_in + E) - A :MSTORE(out + E) - E + 1 => E - E => A - C + 1 => B - $ :EQ, JMPC(array_unshift_test_1_dump, array_unshift_test_1_memory_copy_out_loop) - -array_unshift_test_1_dump: + 5n :MLOAD(array_unshift_in) + 1 => E + 2n :MLOAD(array_unshift_in + E) + 2 => E + 1n :MLOAD(array_unshift_in + E) + 3 => E + 1n :MLOAD(array_unshift_in + E) 4 :MLOAD(array_unshift_len) ; --------------------------------------------------------------- @@ -282,77 +167,44 @@ array_unshift_test_1_dump: ; --------------------------------------------------------------- ; 1] [2,1,0] should return 2 array_trim_test_1: - 2n :MSTORE(inA) + 3 => C + 2n :MSTORE(array_trim_in) 1 => E - 1n :MSTORE(inA + E) + 1n :MSTORE(array_trim_in + E) 2 => E - 0n :MSTORE(inA + E) - -3 => C -0 => E -array_trim_test_1_memory_copy_in_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_trim_in + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_trim_test_1_trim, array_trim_test_1_memory_copy_in_loop) - -array_trim_test_1_trim: + 0n :MSTORE(array_trim_in + E) :CALL(array_trim) 2 => A C :ASSERT ; 2] [2,1,0,2] should return 4 array_trim_test_2: - 2n :MSTORE(inA) + 4 => C + 2n :MSTORE(array_trim_in) 1 => E - 1n :MSTORE(inA + E) + 1n :MSTORE(array_trim_in + E) 2 => E - 0n :MSTORE(inA + E) + 0n :MSTORE(array_trim_in + E) 3 => E - 2n :MSTORE(inA + E) - -4 => C -0 => E -array_trim_test_2_memory_copy_in_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_trim_in + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_trim_test_2_trim, array_trim_test_2_memory_copy_in_loop) - -array_trim_test_2_trim: + 2n :MSTORE(array_trim_in + E) :CALL(array_trim) 4 => A C :ASSERT ; 3] [0,0,0,0,0,0] should return 1 array_trim_test_3: - 0n :MSTORE(inA) + 6 => C + 0n :MSTORE(array_trim_in) 1 => E - 0n :MSTORE(inA + E) + 0n :MSTORE(array_trim_in + E) 2 => E - 0n :MSTORE(inA + E) + 0n :MSTORE(array_trim_in + E) 3 => E - 0n :MSTORE(inA + E) + 0n :MSTORE(array_trim_in + E) 4 => E - 0n :MSTORE(inA + E) + 0n :MSTORE(array_trim_in + E) 5 => E - 0n :MSTORE(inA + E) - -6 => C -0 => E -array_trim_test_3_memory_copy_in_loop: - $ => A :MLOAD(inA + E) - A :MSTORE(array_trim_in + E) - E + 1 => E - E => A - C => B - $ :EQ, JMPC(array_trim_test_3_trim, array_trim_test_3_memory_copy_in_loop) - -array_trim_test_3_trim: + 0n :MSTORE(array_trim_in + E) :CALL(array_trim) 1 => A C :ASSERT @@ -448,25 +300,25 @@ outOfCountersStep: end: - $ => A :MLOAD(initial_A) - $ => B :MLOAD(initial_B) - $ => C :MLOAD(initial_C) - $ => D :MLOAD(initial_D) - $ => E :MLOAD(initial_E) - $ => CTX :MLOAD(initial_CTX) - $ => SP :MLOAD(initial_SP) - $ => PC :MLOAD(initial_PC) - $ => GAS :MLOAD(initial_GAS) - $ => SR :MLOAD(initial_SR) - $ => RR :MLOAD(initial_RR) - $ => HASHPOS :MLOAD(initial_HASHPOS) - $ => RCX :MLOAD(initial_RCX) + $ => A :MLOAD(initial_A) + $ => B :MLOAD(initial_B) + $ => C :MLOAD(initial_C) + $ => D :MLOAD(initial_D) + $ => E :MLOAD(initial_E) + $ => CTX :MLOAD(initial_CTX) + $ => SP :MLOAD(initial_SP) + $ => PC :MLOAD(initial_PC) + $ => GAS :MLOAD(initial_GAS) + $ => SR :MLOAD(initial_SR) + $ => RR :MLOAD(initial_RR) + $ => HASHPOS :MLOAD(initial_HASHPOS) + $ => RCX :MLOAD(initial_RCX) ; label finalizeExecution needed by executor C++ finalizeExecution: - ${beforeLast()} : JMPN(finalizeExecution) + ${beforeLast()} :JMPN(finalizeExecution) - : JMP(start) + :JMP(start) opINVALID: ; label checkAndSaveFrom needed by executor C++ checkAndSaveFrom: From 6963fc9369b6ddbc9ab5ae921b19a907dee91530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 12 Dec 2023 15:56:36 +0100 Subject: [PATCH 061/121] Array arith coverage completed --- main/modexp/array_lib/array_square.zkasm | 4 +- test/testArrayArith.zkasm | 749 ++++++++++++----------- 2 files changed, 379 insertions(+), 374 deletions(-) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index d553cce7..02751990 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -12,7 +12,7 @@ ; function array_square(a: bigint[], B: bigint): bigint[] { ; let len = a.length; -; let out = new Array(len).fill(0n); +; let out = new Array(2*len).fill(0n); ; let product: bigint; ; let carry: bigint; ; let a_i: bigint; @@ -33,6 +33,8 @@ ; return out; ; } +; Matrix visualization: https://hackmd.io/C9KQPGoaSICStIQQFweBlw?view + VAR GLOBAL array_square_in[%ARRAY_MAX_LEN] VAR GLOBAL array_square_out[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_square_len_in diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index a8881997..43c4e84b 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -41,136 +41,7 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; array_add - ; --------------------------------------------------------------- - ; 1] len(inA) = len(inB) - 3 => C - 3 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - :CALL(array_add) - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) - 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) - 3 => E - 1n :MLOAD(array_add_out + E) - 4 :MLOAD(array_add_len_out) - - ; 2] len(inA) = len(inB) + 1 - 3 => C - 2 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - :CALL(array_add) - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) - 2 => E - 0n :MLOAD(array_add_out + E) - 3 => E - 1n :MLOAD(array_add_out + E) - 4 :MLOAD(array_add_len_out) - - ; 3] len(inA) = len(inB) + 3 - 7 => C - 4 => D - 0n :MSTORE(array_add_inA) - 1 => E - 0n :MSTORE(array_add_inA + E) - 2 => E - 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inA + E) - 3 => E - 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inA + E) - 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inA + E) - 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inA + E) - 6 => E - 370491411790392985199n :MSTORE(array_add_inA + E) - - 0n :MSTORE(array_add_inB) - 1 => E - 0n :MSTORE(array_add_inB + E) - 2 => E - 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inB + E) - 3 => E - 6019321230n :MSTORE(array_add_inB + E) - :CALL(array_add) - 0n :MLOAD(array_add_out) - 1 => E - 0n :MLOAD(array_add_out + E) - 2 => E - 0n :MLOAD(array_add_out + E) - 3 => E - 0n :MLOAD(array_add_out + E) - 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) - 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) - 6 => E - 370491411790392985199n :MLOAD(array_add_out + E) - 7 :MLOAD(array_add_len_out) - - ; 4] len(inA) = len(inB) - 3 - 4 => C - 7 => D - 0n :MSTORE(array_add_inA) - 1 => E - 0n :MSTORE(array_add_inA + E) - 2 => E - 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inA + E) - 3 => E - 6019321230n :MSTORE(array_add_inA + E) - - 0n :MSTORE(array_add_inB) - 1 => E - 0n :MSTORE(array_add_inB + E) - 2 => E - 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inB + E) - 3 => E - 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inB + E) - 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inB + E) - 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inB + E) - 6 => E - 370491411790392985199n :MSTORE(array_add_inB + E) - :CALL(array_add) - 0n :MLOAD(array_add_out) - 1 => E - 0n :MLOAD(array_add_out + E) - 2 => E - 0n :MLOAD(array_add_out + E) - 3 => E - 0n :MLOAD(array_add_out + E) - 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) - 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) - 6 => E - 370491411790392985199n :MLOAD(array_add_out + E) - 7 :MLOAD(array_add_len_out) - ; --------------------------------------------------------------- - - ; array_add AGTB + ; addition with len(inA) >= len(inB) ; --------------------------------------------------------------- ; 1] [2**256-1,2**256-1,2**256-1] + [2**256-1,2**256-1] 3 => C @@ -180,7 +51,6 @@ start: 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) 2 => E 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB) 1 => E 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_AGTB_inB + E) @@ -195,7 +65,7 @@ start: 4 :MLOAD(array_add_AGTB_len_out) ; --------------------------------------------------------------- - ; array_add small + ; short addition ; --------------------------------------------------------------- ; 1] [2**256-1,2**256-1,2**256-1] + [2**256-1] 3 => C @@ -204,7 +74,6 @@ start: 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) 2 => E 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_short_inB) :CALL(array_add_short) 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_short_out) @@ -217,107 +86,7 @@ start: 4 :MLOAD(array_add_short_len_out) ; --------------------------------------------------------------- - ; array_sub - ; --------------------------------------------------------------- - ; 1] len(inA) > len(inB) and inA_i >= inb_i for all i - 3 => C - 2 => D - 5n :MSTORE(array_sub_AGTB_inA) - 1 => E - 6n :MSTORE(array_sub_AGTB_inA + E) - 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) - - 2n :MSTORE(array_sub_AGTB_inB) - 1 => E - 3n :MSTORE(array_sub_AGTB_inB + E) - :CALL(array_sub_AGTB) - 3n :MLOAD(array_sub_AGTB_out) - 1 => E - 3n :MLOAD(array_sub_AGTB_out + E) - 2 => E - 7n :MLOAD(array_sub_AGTB_out + E) - - ; 2] len(inA) > len(inB) and inA_i < inb_i for some i - 3 => C - 2 => D - 5n :MSTORE(array_sub_AGTB_inA) - 1 => E - 6n :MSTORE(array_sub_AGTB_inA + E) - 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) - - 6n :MSTORE(array_sub_AGTB_inB) - 1 => E - 3n :MSTORE(array_sub_AGTB_inB + E) - :CALL(array_sub_AGTB) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) - 1 => E - 2n :MLOAD(array_sub_AGTB_out + E) - 2 => E - 7n :MLOAD(array_sub_AGTB_out + E) - - ; 3] len(inA) > len(inB) and inA_i < inB_i for all i lower than len(inA) - 3 => C - 2 => D - 5n :MSTORE(array_sub_AGTB_inA) - 1 => E - 1n :MSTORE(array_sub_AGTB_inA + E) - 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) - - 6n :MSTORE(array_sub_AGTB_inB) - 1 => E - 8n :MSTORE(array_sub_AGTB_inB + E) - :CALL(array_sub_AGTB) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) - 2 => E - 6n :MLOAD(array_sub_AGTB_out + E) - - ; 4] len(inB) > len(inA) and inB_i < inA_i for all i lower than len(inB) - 3 => C - 2 => D - 6n :MSTORE(array_sub_AGTB_inB) - 1 => E - 8n :MSTORE(array_sub_AGTB_inB + E) - - 5n :MSTORE(array_sub_AGTB_inA) - 1 => E - 1n :MSTORE(array_sub_AGTB_inA + E) - 2 => E - 7n :MSTORE(array_sub_AGTB_inA + E) - :CALL(array_sub_AGTB) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) - 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) - 2 => E - 6n :MLOAD(array_sub_AGTB_out + E) - - ; 5] len(inB) = len(inA) and inB > inA - 3 => C - 3 => D - 6n :MSTORE(array_sub_AGTB_inB) - 1 => E - 8n :MSTORE(array_sub_AGTB_inB + E) - 2 => E - 8n :MSTORE(array_sub_AGTB_inB + E) - - 7n :MSTORE(array_sub_AGTB_inA) - 1 => E - 8n :MSTORE(array_sub_AGTB_inA + E) - 2 => E - 8n :MSTORE(array_sub_AGTB_inA + E) - :CALL(array_sub_AGTB) - 1n :MLOAD(array_sub_AGTB_out) - 1 => E - 0n :MLOAD(array_sub_AGTB_out + E) - 2 => E - 0n :MLOAD(array_sub_AGTB_out + E) - ; --------------------------------------------------------------- - - ; array long mul + ; multiplication ; --------------------------------------------------------------- ; 1] len(inB) = len(inA) and inB > inA 3 => C @@ -368,68 +137,7 @@ start: 4 :MLOAD(array_mul_len_out) ; --------------------------------------------------------------- - ; ; WIP: array karatsuba mul - ; ; --------------------------------------------------------------- - ; ; 1] len(inA) > len(inB) - ; 2 => C - ; 1 => D - ; 2n :MSTORE(array_mul_karatsuba_inA) - ; 1 => E - ; 6n :MSTORE(array_mul_karatsuba_inA + E) - - ; 8n :MSTORE(array_mul_karatsuba_inB) - ; :CALL(array_mul_karatsuba) - ; 16n :MLOAD(array_mul_karatsuba_out) - ; 1 => E - ; 48n :MLOAD(array_mul_karatsuba_out + E) - ; 2 :MLOAD(array_mul_karatsuba_len_out) - - ; ; 2] len(inA) = len(inB) - ; 2 => C - ; 2 => D - ; 10n :MSTORE(array_mul_karatsuba_inA) - ; 1 => E - ; 50n :MSTORE(array_mul_karatsuba_inA + E) - - ; 98n :MSTORE(array_mul_karatsuba_inB) - ; 1 => E - ; 1000n :MSTORE(array_mul_karatsuba_inB + E) - ; :CALL(array_mul_karatsuba) - ; 980n :MLOAD(array_mul_karatsuba_out) - ; 1 => E - ; 14900n :MLOAD(array_mul_karatsuba_out + E) - ; 2 => E - ; 50000n :MLOAD(array_mul_karatsuba_out + E) - ; 3 :MLOAD(array_mul_karatsuba_len_out) - - ; ; 3] - ; 3 => C - ; 3 => D - ; 10n :MSTORE(array_mul_karatsuba_inA) - ; 1 => E - ; 6n :MSTORE(array_mul_karatsuba_inA + E) - ; 2 => E - ; 2n :MSTORE(array_mul_karatsuba_inA + E) - - ; 8n :MSTORE(array_mul_karatsuba_inB) - ; 1 => E - ; 3n :MSTORE(array_mul_karatsuba_inB + E) - ; 2 => E - ; 5n :MSTORE(array_mul_karatsuba_inB + E) - ; :CALL(array_mul_karatsuba) - ; 16n :MLOAD(array_mul_karatsuba_out) - ; 1 => E - ; 54n :MLOAD(array_mul_karatsuba_out + E) - ; 2 => E - ; 40n :MLOAD(array_mul_karatsuba_out + E) - ; 3 => E - ; 24n :MLOAD(array_mul_karatsuba_out + E) - ; 4 => E - ; 6n :MLOAD(array_mul_karatsuba_out + E) - ; 5 :MLOAD(array_mul_karatsuba_len_out) - ; ; --------------------------------------------------------------- - - ; array short mult + ; short multiplication ; --------------------------------------------------------------- ; 1] [a, a, a] * a 3 => C @@ -474,7 +182,7 @@ start: 4 :MLOAD(array_mul_len_out) ; --------------------------------------------------------------- - ; array square + ; squaring ; --------------------------------------------------------------- ; 1] [4n, 4n, 4n, 3n, 2n, 4n] 6 => C @@ -567,7 +275,7 @@ start: 4 :MLOAD(array_square_len_out) ; --------------------------------------------------------------- - ; array short mod div + ; division ; --------------------------------------------------------------- ; 1] [9n, 8n, 7n, 6n] / 8n 4 => C @@ -627,7 +335,7 @@ start: 119n :MLOAD(array_div_mod_rem) 7 :MLOAD(array_div_mod_len_quo) - ; 3] inA == 0, inB != 0 + ; 3] inA == 0, inB != 0, len(inB) == 1 1 => C 1 => D 0n :MSTORE(array_div_mod_inA) @@ -638,7 +346,47 @@ start: 0n :MLOAD(array_div_mod_rem) 1 :MLOAD(array_div_mod_len_quo) - ; 4] inA != 0, inB == 0 -> error + 1 => C + 1 => D + 0n :MSTORE(array_div_mod_short_inA) + 8n :MSTORE(array_div_mod_short_inB) + :CALL(array_div_mod_short) + 0n :MLOAD(array_div_mod_short_quo) + 0n :MLOAD(array_div_mod_short_rem) + 1 :MLOAD(array_div_mod_short_len_quo) + + ; 4] inA == 0, inB != 0, len(inB) > 1 + 1 => C + 2 => D + 0n :MSTORE(array_div_mod_inA) + + 8n :MSTORE(array_div_mod_inB) + 1 => E + 1n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + + 1 => C + 2 => D + 0n :MSTORE(array_div_mod_long_inA) + 8n :MSTORE(array_div_mod_long_inB) + 1 => E + 8n :MSTORE(array_div_mod_long_inB + E) + :CALL(array_div_mod_long) + 0n :MLOAD(array_div_mod_long_quo) + 0n :MLOAD(array_div_mod_long_rem) + 1 :MLOAD(array_div_mod_long_len_quo) + + ; 5] inA != 0, inB == 0 -> error + 1 => C + 1 => D + 8n :MSTORE(array_div_mod_long_inA) + 0n :MSTORE(array_div_mod_long_inB) + :CALL(array_div_mod_long) + 1 => A + B :ASSERT + 2 => C 1 => D 0n :MSTORE(array_div_mod_inA) @@ -650,29 +398,110 @@ start: 1 => A B :ASSERT - ; 5] inA == inB + ; 6] inA == inB == 0 -> error 1 => C 1 => D - 10n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_mod_long_inA) + 0n :MSTORE(array_div_mod_long_inB) + :CALL(array_div_mod_long) + 1 => A + B :ASSERT + + 1 => C + 1 => D + 0n :MSTORE(array_div_mod_short_inA) + 0n :MSTORE(array_div_mod_short_inB) + :CALL(array_div_mod_short) + 1 => A + B :ASSERT + ; 7] inA == inB + 1 => C + 1 => D + 10n :MSTORE(array_div_mod_inA) 10n :MSTORE(array_div_mod_inB) :CALL(array_div_mod) 1n :MLOAD(array_div_mod_quo) 0n :MLOAD(array_div_mod_rem) 1 :MLOAD(array_div_mod_len_quo) - ; 6] inA < inB + 2 => C + 2 => D + 10n :MSTORE(array_div_mod_inA) + 1 => E + 30n :MSTORE(array_div_mod_inA + E) + + 10n :MSTORE(array_div_mod_inB) + 1 => E + 30n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 1n :MLOAD(array_div_mod_quo) + 0n :MLOAD(array_div_mod_rem) + 1 => C 1 => D - 10n :MSTORE(array_div_mod_inA) + 10n :MSTORE(array_div_mod_long_inA) + 10n :MSTORE(array_div_mod_long_inB) + :CALL(array_div_mod_long) + 1n :MLOAD(array_div_mod_long_quo) + 0n :MLOAD(array_div_mod_long_rem) + 1 :MLOAD(array_div_mod_long_len_quo) + 1 => C + 1 => D + 10n :MSTORE(array_div_mod_short_inA) + 10n :MSTORE(array_div_mod_short_inB) + :CALL(array_div_mod_short) + 1n :MLOAD(array_div_mod_short_quo) + 0n :MLOAD(array_div_mod_short_rem) + 1 :MLOAD(array_div_mod_short_len_quo) + + ; 8] inA < inB + 1 => C + 1 => D + 10n :MSTORE(array_div_mod_inA) 11n :MSTORE(array_div_mod_inB) :CALL(array_div_mod) 0n :MLOAD(array_div_mod_quo) 10n :MLOAD(array_div_mod_rem) 1 :MLOAD(array_div_mod_len_quo) - ; 7] [28948022309329048855892746252171976963317496166410141009864396001978282409984n, 1n] / 2 + 2 => C + 3 => D + 10n :MSTORE(array_div_mod_inA) + 1 => E + 30n :MSTORE(array_div_mod_inA + E) + + 6n :MSTORE(array_div_mod_inB) + 1 => E + 7n :MSTORE(array_div_mod_inB + E) + 2 => E + 8n :MSTORE(array_div_mod_inB + E) + :CALL(array_div_mod) + 0n :MLOAD(array_div_mod_quo) + 10n :MLOAD(array_div_mod_rem) + 1 => E + 30n :MSTORE(array_div_mod_rem + E) + + 1 => C + 1 => D + 10n :MSTORE(array_div_mod_long_inA) + 11n :MSTORE(array_div_mod_long_inB) + :CALL(array_div_mod_long) + 0n :MLOAD(array_div_mod_long_quo) + 10n :MLOAD(array_div_mod_long_rem) + 1 :MLOAD(array_div_mod_long_len_quo) + + 1 => C + 1 => D + 10n :MSTORE(array_div_mod_short_inA) + 11n :MSTORE(array_div_mod_short_inB) + :CALL(array_div_mod_short) + 0n :MLOAD(array_div_mod_short_quo) + 10n :MLOAD(array_div_mod_short_rem) + 1 :MLOAD(array_div_mod_short_len_quo) + + ; 9] [28948022309329048855892746252171976963317496166410141009864396001978282409984n, 1n] / 2 2 => C 1 => D 28948022309329048855892746252171976963317496166410141009864396001978282409984n :MSTORE(array_div_mod_inA) @@ -684,7 +513,7 @@ start: 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MLOAD(array_div_mod_quo) 1 :MLOAD(array_div_mod_len_quo) - ; 8] [72370055773322622139731865630429942408293740416025352524660990004945706024960n] / 2 + ; 10] [72370055773322622139731865630429942408293740416025352524660990004945706024960n] / 2 1 => C 1 => D 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MSTORE(array_div_mod_inA) @@ -692,11 +521,8 @@ start: :CALL(array_div_mod) 36185027886661311069865932815214971204146870208012676262330495002472853012480n :MLOAD(array_div_mod_quo) 1 :MLOAD(array_div_mod_len_quo) - ; --------------------------------------------------------------- - ; array long mod div - ; --------------------------------------------------------------- - ; 1] len(inB) = len(inA) and inB > inA + ; 11] len(inB) = len(inA) and inB > inA 4 => C 2 => D 9n :MSTORE(array_div_mod_inA) @@ -718,7 +544,7 @@ start: 5n :MLOAD(array_div_mod_quo + E) 115792089237316195423570985008687907853269984665640564039457584007913129637265n :MLOAD(array_div_mod_rem) - ; 2] [a, 7n, a, 12n, a, 20n, a, 80n] / [a, a, a, a, 100n] + ; 12] [a, 7n, a, 12n, a, 20n, a, 80n] / [a, a, a, a, 100n] 8 => C 5 => D 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) @@ -762,63 +588,7 @@ start: 4 => E 84n :MLOAD(array_div_mod_rem + E) - ; 3] inA == 0, inB != 0 - 1 => C - 2 => D - 0n :MSTORE(array_div_mod_inA) - - 8n :MSTORE(array_div_mod_inB) - 1 => E - 1n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) - - ; 4] inA != 0, inB == 0 -> error - 2 => C - 1 => D - 0n :MSTORE(array_div_mod_inA) - 1 => E - 30n :MSTORE(array_div_mod_inA + E) - - 0n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 1 => A - B :ASSERT - - ; 5] inA == inB - 2 => C - 2 => D - 10n :MSTORE(array_div_mod_inA) - 1 => E - 30n :MSTORE(array_div_mod_inA + E) - - 10n :MSTORE(array_div_mod_inB) - 1 => E - 30n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 1n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) - - ; 6] inA < inB - 2 => C - 3 => D - 10n :MSTORE(array_div_mod_inA) - 1 => E - 30n :MSTORE(array_div_mod_inA + E) - - 6n :MSTORE(array_div_mod_inB) - 1 => E - 7n :MSTORE(array_div_mod_inB + E) - 2 => E - 8n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 10n :MLOAD(array_div_mod_rem) - 1 => E - 30n :MSTORE(array_div_mod_rem + E) - - ; 7] [82987931714326364316120253427931880709278140571418487333162713377057429160720n,4257238595720679277571917967782652353394431698489248379634099239588181418140n,15209178211456919413336795740141505754388379695813905932093982440742677791802n,88987534839350135473536361176867192550264928852523682165693061442019881855583n,14n], [4n, 6n, 7n] + ; 13] [82987931714326364316120253427931880709278140571418487333162713377057429160720n,4257238595720679277571917967782652353394431698489248379634099239588181418140n,15209178211456919413336795740141505754388379695813905932093982440742677791802n,88987534839350135473536361176867192550264928852523682165693061442019881855583n,14n], [4n, 6n, 7n] 5 => C 3 => D 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MSTORE(array_div_mod_inA) @@ -850,7 +620,7 @@ start: 3 :MLOAD(array_div_mod_len_quo) 3 :MLOAD(array_div_mod_len_rem) - ; 8] [0n,0n,0n,0n,87552057494100699607633960453116574392480272162273084008350826812719088235449n,29405388739667337424543497575767709934732594998639086405406332616399343873602n,370491411790392985199n], [0n, 0n, 8238129386n, 23102318237n] + ; 14] [0n,0n,0n,0n,87552057494100699607633960453116574392480272162273084008350826812719088235449n,29405388739667337424543497575767709934732594998639086405406332616399343873602n,370491411790392985199n], [0n, 0n, 8238129386n, 23102318237n] 7 => C 4 => D 0n :MSTORE(array_div_mod_inA) @@ -892,7 +662,7 @@ start: 4 :MLOAD(array_div_mod_len_quo) 4 :MLOAD(array_div_mod_len_rem) - ; 9] [7n], [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] + ; 15] [7n], [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] 1 => C 2 => D 7n :MSTORE(array_div_mod_inA) @@ -905,7 +675,7 @@ start: 1 :MLOAD(array_div_mod_len_quo) 1 :MLOAD(array_div_mod_len_rem) - ; 10] [9,12,16,2,0,2**256-4], [2**256-1,2**256-1] + ; 16] [9,12,16,2,0,2**256-4], [2**256-1,2**256-1] 6 => C 2 => D 9n :MSTORE(array_div_mod_inA) @@ -935,6 +705,239 @@ start: 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_div_mod_quo + E) ; --------------------------------------------------------------- + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; UNUSED + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ; ; addition + ; ; --------------------------------------------------------------- + ; ; 1] len(inA) = len(inB) + ; 3 => C + ; 3 => D + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + ; 2 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + ; 2 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + ; :CALL(array_add) + ; 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + ; 2 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + ; 3 => E + ; 1n :MLOAD(array_add_out + E) + ; 4 :MLOAD(array_add_len_out) + + ; ; 2] len(inA) = len(inB) + 1 + ; 3 => C + ; 2 => D + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + ; 2 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + ; :CALL(array_add) + ; 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + ; 2 => E + ; 0n :MLOAD(array_add_out + E) + ; 3 => E + ; 1n :MLOAD(array_add_out + E) + ; 4 :MLOAD(array_add_len_out) + + ; ; 3] len(inA) = len(inB) + 3 + ; 7 => C + ; 4 => D + ; 0n :MSTORE(array_add_inA) + ; 1 => E + ; 0n :MSTORE(array_add_inA + E) + ; 2 => E + ; 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inA + E) + ; 3 => E + ; 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inA + E) + ; 4 => E + ; 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inA + E) + ; 5 => E + ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inA + E) + ; 6 => E + ; 370491411790392985199n :MSTORE(array_add_inA + E) + + ; 0n :MSTORE(array_add_inB) + ; 1 => E + ; 0n :MSTORE(array_add_inB + E) + ; 2 => E + ; 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inB + E) + ; 3 => E + ; 6019321230n :MSTORE(array_add_inB + E) + ; :CALL(array_add) + ; 0n :MLOAD(array_add_out) + ; 1 => E + ; 0n :MLOAD(array_add_out + E) + ; 2 => E + ; 0n :MLOAD(array_add_out + E) + ; 3 => E + ; 0n :MLOAD(array_add_out + E) + ; 4 => E + ; 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + ; 5 => E + ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + ; 6 => E + ; 370491411790392985199n :MLOAD(array_add_out + E) + ; 7 :MLOAD(array_add_len_out) + + ; ; 4] len(inA) = len(inB) - 3 + ; 4 => C + ; 7 => D + ; 0n :MSTORE(array_add_inA) + ; 1 => E + ; 0n :MSTORE(array_add_inA + E) + ; 2 => E + ; 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inA + E) + ; 3 => E + ; 6019321230n :MSTORE(array_add_inA + E) + + ; 0n :MSTORE(array_add_inB) + ; 1 => E + ; 0n :MSTORE(array_add_inB + E) + ; 2 => E + ; 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inB + E) + ; 3 => E + ; 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inB + E) + ; 4 => E + ; 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inB + E) + ; 5 => E + ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inB + E) + ; 6 => E + ; 370491411790392985199n :MSTORE(array_add_inB + E) + ; :CALL(array_add) + ; 0n :MLOAD(array_add_out) + ; 1 => E + ; 0n :MLOAD(array_add_out + E) + ; 2 => E + ; 0n :MLOAD(array_add_out + E) + ; 3 => E + ; 0n :MLOAD(array_add_out + E) + ; 4 => E + ; 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + ; 5 => E + ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + ; 6 => E + ; 370491411790392985199n :MLOAD(array_add_out + E) + ; 7 :MLOAD(array_add_len_out) + ; ; --------------------------------------------------------------- + + ; ; subtraction with len(inA) >= len(inB) + ; ; --------------------------------------------------------------- + ; ; 1] len(inA) > len(inB) and inA_i >= inb_i for all i + ; 3 => C + ; 2 => D + ; 5n :MSTORE(array_sub_AGTB_inA) + ; 1 => E + ; 6n :MSTORE(array_sub_AGTB_inA + E) + ; 2 => E + ; 7n :MSTORE(array_sub_AGTB_inA + E) + + ; 2n :MSTORE(array_sub_AGTB_inB) + ; 1 => E + ; 3n :MSTORE(array_sub_AGTB_inB + E) + ; :CALL(array_sub_AGTB) + ; 3n :MLOAD(array_sub_AGTB_out) + ; 1 => E + ; 3n :MLOAD(array_sub_AGTB_out + E) + ; 2 => E + ; 7n :MLOAD(array_sub_AGTB_out + E) + + ; ; 2] len(inA) > len(inB) and inA_i < inb_i for some i + ; 3 => C + ; 2 => D + ; 5n :MSTORE(array_sub_AGTB_inA) + ; 1 => E + ; 6n :MSTORE(array_sub_AGTB_inA + E) + ; 2 => E + ; 7n :MSTORE(array_sub_AGTB_inA + E) + + ; 6n :MSTORE(array_sub_AGTB_inB) + ; 1 => E + ; 3n :MSTORE(array_sub_AGTB_inB + E) + ; :CALL(array_sub_AGTB) + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + ; 1 => E + ; 2n :MLOAD(array_sub_AGTB_out + E) + ; 2 => E + ; 7n :MLOAD(array_sub_AGTB_out + E) + + ; ; 3] len(inA) > len(inB) and inA_i < inB_i for all i lower than len(inA) + ; 3 => C + ; 2 => D + ; 5n :MSTORE(array_sub_AGTB_inA) + ; 1 => E + ; 1n :MSTORE(array_sub_AGTB_inA + E) + ; 2 => E + ; 7n :MSTORE(array_sub_AGTB_inA + E) + + ; 6n :MSTORE(array_sub_AGTB_inB) + ; 1 => E + ; 8n :MSTORE(array_sub_AGTB_inB + E) + ; :CALL(array_sub_AGTB) + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + ; 2 => E + ; 6n :MLOAD(array_sub_AGTB_out + E) + + ; ; 4] len(inB) > len(inA) and inB_i < inA_i for all i lower than len(inB) + ; 3 => C + ; 2 => D + ; 6n :MSTORE(array_sub_AGTB_inB) + ; 1 => E + ; 8n :MSTORE(array_sub_AGTB_inB + E) + + ; 5n :MSTORE(array_sub_AGTB_inA) + ; 1 => E + ; 1n :MSTORE(array_sub_AGTB_inA + E) + ; 2 => E + ; 7n :MSTORE(array_sub_AGTB_inA + E) + ; :CALL(array_sub_AGTB) + ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + ; 1 => E + ; 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + ; 2 => E + ; 6n :MLOAD(array_sub_AGTB_out + E) + + ; ; 5] len(inB) = len(inA) and inB > inA + ; 3 => C + ; 3 => D + ; 6n :MSTORE(array_sub_AGTB_inB) + ; 1 => E + ; 8n :MSTORE(array_sub_AGTB_inB + E) + ; 2 => E + ; 8n :MSTORE(array_sub_AGTB_inB + E) + + ; 7n :MSTORE(array_sub_AGTB_inA) + ; 1 => E + ; 8n :MSTORE(array_sub_AGTB_inA + E) + ; 2 => E + ; 8n :MSTORE(array_sub_AGTB_inA + E) + ; :CALL(array_sub_AGTB) + ; 1n :MLOAD(array_sub_AGTB_out) + ; 1 => E + ; 0n :MLOAD(array_sub_AGTB_out + E) + ; 2 => E + ; 0n :MLOAD(array_sub_AGTB_out + E) + ; ; --------------------------------------------------------------- + :JMP(end) outOfCountersBinary: @@ -990,5 +993,5 @@ INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" -INCLUDE "../main/modexp/array_lib/unused/array_sub_AGTB.zkasm" -INCLUDE "../main/modexp/array_lib/unused/array_add.zkasm" \ No newline at end of file +; INCLUDE "../main/modexp/array_lib/unused/array_sub_AGTB.zkasm" +; INCLUDE "../main/modexp/array_lib/unused/array_add.zkasm" \ No newline at end of file From ad40b95c2052ff526bb0ac7517bf0dd20cfe69e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 13 Dec 2023 12:02:48 +0100 Subject: [PATCH 062/121] ecAdd, ecMul and ecPairing coverage completed --- test/testArrayArith.zkasm | 460 ++++++++++----------- test/testCycloFp12ArithBN254.zkasm | 27 ++ test/testFp12ArithBN254.zkasm | 339 ++++++++------- test/testFp2ArithBN254.zkasm | 16 + test/testFpArithBN254.zkasm | 9 + test/testHalfPairingBN254.zkasm | 156 ++++++- test/testModExp.zkasm | 37 +- test/testPairingBN254.zkasm | 640 +++++++++++++++-------------- 8 files changed, 988 insertions(+), 696 deletions(-) diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index 43c4e84b..bb780787 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -709,234 +709,234 @@ start: ;; UNUSED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; ; addition - ; ; --------------------------------------------------------------- - ; ; 1] len(inA) = len(inB) - ; 3 => C - ; 3 => D - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - ; 2 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - ; 2 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - ; :CALL(array_add) - ; 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) - ; 2 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) - ; 3 => E - ; 1n :MLOAD(array_add_out + E) - ; 4 :MLOAD(array_add_len_out) - - ; ; 2] len(inA) = len(inB) + 1 - ; 3 => C - ; 2 => D - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - ; 2 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) - - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) - ; :CALL(array_add) - ; 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) - ; 2 => E - ; 0n :MLOAD(array_add_out + E) - ; 3 => E - ; 1n :MLOAD(array_add_out + E) - ; 4 :MLOAD(array_add_len_out) - - ; ; 3] len(inA) = len(inB) + 3 - ; 7 => C - ; 4 => D - ; 0n :MSTORE(array_add_inA) - ; 1 => E - ; 0n :MSTORE(array_add_inA + E) - ; 2 => E - ; 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inA + E) - ; 3 => E - ; 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inA + E) - ; 4 => E - ; 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inA + E) - ; 5 => E - ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inA + E) - ; 6 => E - ; 370491411790392985199n :MSTORE(array_add_inA + E) - - ; 0n :MSTORE(array_add_inB) - ; 1 => E - ; 0n :MSTORE(array_add_inB + E) - ; 2 => E - ; 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inB + E) - ; 3 => E - ; 6019321230n :MSTORE(array_add_inB + E) - ; :CALL(array_add) - ; 0n :MLOAD(array_add_out) - ; 1 => E - ; 0n :MLOAD(array_add_out + E) - ; 2 => E - ; 0n :MLOAD(array_add_out + E) - ; 3 => E - ; 0n :MLOAD(array_add_out + E) - ; 4 => E - ; 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) - ; 5 => E - ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) - ; 6 => E - ; 370491411790392985199n :MLOAD(array_add_out + E) - ; 7 :MLOAD(array_add_len_out) - - ; ; 4] len(inA) = len(inB) - 3 - ; 4 => C - ; 7 => D - ; 0n :MSTORE(array_add_inA) - ; 1 => E - ; 0n :MSTORE(array_add_inA + E) - ; 2 => E - ; 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inA + E) - ; 3 => E - ; 6019321230n :MSTORE(array_add_inA + E) - - ; 0n :MSTORE(array_add_inB) - ; 1 => E - ; 0n :MSTORE(array_add_inB + E) - ; 2 => E - ; 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inB + E) - ; 3 => E - ; 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inB + E) - ; 4 => E - ; 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inB + E) - ; 5 => E - ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inB + E) - ; 6 => E - ; 370491411790392985199n :MSTORE(array_add_inB + E) - ; :CALL(array_add) - ; 0n :MLOAD(array_add_out) - ; 1 => E - ; 0n :MLOAD(array_add_out + E) - ; 2 => E - ; 0n :MLOAD(array_add_out + E) - ; 3 => E - ; 0n :MLOAD(array_add_out + E) - ; 4 => E - ; 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) - ; 5 => E - ; 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) - ; 6 => E - ; 370491411790392985199n :MLOAD(array_add_out + E) - ; 7 :MLOAD(array_add_len_out) - ; ; --------------------------------------------------------------- - - ; ; subtraction with len(inA) >= len(inB) - ; ; --------------------------------------------------------------- - ; ; 1] len(inA) > len(inB) and inA_i >= inb_i for all i - ; 3 => C - ; 2 => D - ; 5n :MSTORE(array_sub_AGTB_inA) - ; 1 => E - ; 6n :MSTORE(array_sub_AGTB_inA + E) - ; 2 => E - ; 7n :MSTORE(array_sub_AGTB_inA + E) - - ; 2n :MSTORE(array_sub_AGTB_inB) - ; 1 => E - ; 3n :MSTORE(array_sub_AGTB_inB + E) - ; :CALL(array_sub_AGTB) - ; 3n :MLOAD(array_sub_AGTB_out) - ; 1 => E - ; 3n :MLOAD(array_sub_AGTB_out + E) - ; 2 => E - ; 7n :MLOAD(array_sub_AGTB_out + E) - - ; ; 2] len(inA) > len(inB) and inA_i < inb_i for some i - ; 3 => C - ; 2 => D - ; 5n :MSTORE(array_sub_AGTB_inA) - ; 1 => E - ; 6n :MSTORE(array_sub_AGTB_inA + E) - ; 2 => E - ; 7n :MSTORE(array_sub_AGTB_inA + E) - - ; 6n :MSTORE(array_sub_AGTB_inB) - ; 1 => E - ; 3n :MSTORE(array_sub_AGTB_inB + E) - ; :CALL(array_sub_AGTB) - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) - ; 1 => E - ; 2n :MLOAD(array_sub_AGTB_out + E) - ; 2 => E - ; 7n :MLOAD(array_sub_AGTB_out + E) - - ; ; 3] len(inA) > len(inB) and inA_i < inB_i for all i lower than len(inA) - ; 3 => C - ; 2 => D - ; 5n :MSTORE(array_sub_AGTB_inA) - ; 1 => E - ; 1n :MSTORE(array_sub_AGTB_inA + E) - ; 2 => E - ; 7n :MSTORE(array_sub_AGTB_inA + E) - - ; 6n :MSTORE(array_sub_AGTB_inB) - ; 1 => E - ; 8n :MSTORE(array_sub_AGTB_inB + E) - ; :CALL(array_sub_AGTB) - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) - ; 2 => E - ; 6n :MLOAD(array_sub_AGTB_out + E) - - ; ; 4] len(inB) > len(inA) and inB_i < inA_i for all i lower than len(inB) - ; 3 => C - ; 2 => D - ; 6n :MSTORE(array_sub_AGTB_inB) - ; 1 => E - ; 8n :MSTORE(array_sub_AGTB_inB + E) - - ; 5n :MSTORE(array_sub_AGTB_inA) - ; 1 => E - ; 1n :MSTORE(array_sub_AGTB_inA + E) - ; 2 => E - ; 7n :MSTORE(array_sub_AGTB_inA + E) - ; :CALL(array_sub_AGTB) - ; 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) - ; 1 => E - ; 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) - ; 2 => E - ; 6n :MLOAD(array_sub_AGTB_out + E) - - ; ; 5] len(inB) = len(inA) and inB > inA - ; 3 => C - ; 3 => D - ; 6n :MSTORE(array_sub_AGTB_inB) - ; 1 => E - ; 8n :MSTORE(array_sub_AGTB_inB + E) - ; 2 => E - ; 8n :MSTORE(array_sub_AGTB_inB + E) - - ; 7n :MSTORE(array_sub_AGTB_inA) - ; 1 => E - ; 8n :MSTORE(array_sub_AGTB_inA + E) - ; 2 => E - ; 8n :MSTORE(array_sub_AGTB_inA + E) - ; :CALL(array_sub_AGTB) - ; 1n :MLOAD(array_sub_AGTB_out) - ; 1 => E - ; 0n :MLOAD(array_sub_AGTB_out + E) - ; 2 => E - ; 0n :MLOAD(array_sub_AGTB_out + E) - ; ; --------------------------------------------------------------- + ; addition + ; --------------------------------------------------------------- + ; 1] len(inA) = len(inB) + 3 => C + 3 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + :CALL(array_add) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 3 => E + 1n :MLOAD(array_add_out + E) + 4 :MLOAD(array_add_len_out) + + ; 2] len(inA) = len(inB) + 1 + 3 => C + 2 => D + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inA + E) + + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_add_inB + E) + :CALL(array_add) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_add_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_add_out + E) + 2 => E + 0n :MLOAD(array_add_out + E) + 3 => E + 1n :MLOAD(array_add_out + E) + 4 :MLOAD(array_add_len_out) + + ; 3] len(inA) = len(inB) + 3 + 7 => C + 4 => D + 0n :MSTORE(array_add_inA) + 1 => E + 0n :MSTORE(array_add_inA + E) + 2 => E + 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inA + E) + 3 => E + 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inA + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inA + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inA + E) + 6 => E + 370491411790392985199n :MSTORE(array_add_inA + E) + + 0n :MSTORE(array_add_inB) + 1 => E + 0n :MSTORE(array_add_inB + E) + 2 => E + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inB + E) + 3 => E + 6019321230n :MSTORE(array_add_inB + E) + :CALL(array_add) + 0n :MLOAD(array_add_out) + 1 => E + 0n :MLOAD(array_add_out + E) + 2 => E + 0n :MLOAD(array_add_out + E) + 3 => E + 0n :MLOAD(array_add_out + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + 6 => E + 370491411790392985199n :MLOAD(array_add_out + E) + 7 :MLOAD(array_add_len_out) + + ; 4] len(inA) = len(inB) - 3 + 4 => C + 7 => D + 0n :MSTORE(array_add_inA) + 1 => E + 0n :MSTORE(array_add_inA + E) + 2 => E + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_add_inA + E) + 3 => E + 6019321230n :MSTORE(array_add_inA + E) + + 0n :MSTORE(array_add_inB) + 1 => E + 0n :MSTORE(array_add_inB + E) + 2 => E + 71980342328814551066277152664912916825216970430701952092274083071078176857050n :MSTORE(array_add_inB + E) + 3 => E + 115792089237316195423570985008687907853269984665640564039457584007907110318705n :MSTORE(array_add_inB + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235448n :MSTORE(array_add_inB + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_add_inB + E) + 6 => E + 370491411790392985199n :MSTORE(array_add_inB + E) + :CALL(array_add) + 0n :MLOAD(array_add_out) + 1 => E + 0n :MLOAD(array_add_out + E) + 2 => E + 0n :MLOAD(array_add_out + E) + 3 => E + 0n :MLOAD(array_add_out + E) + 4 => E + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MLOAD(array_add_out + E) + 5 => E + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MLOAD(array_add_out + E) + 6 => E + 370491411790392985199n :MLOAD(array_add_out + E) + 7 :MLOAD(array_add_len_out) + ; --------------------------------------------------------------- + + ; subtraction with len(inA) >= len(inB) + ; --------------------------------------------------------------- + ; 1] len(inA) > len(inB) and inA_i >= inb_i for all i + 3 => C + 2 => D + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 6n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + + 2n :MSTORE(array_sub_AGTB_inB) + 1 => E + 3n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + 3n :MLOAD(array_sub_AGTB_out) + 1 => E + 3n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 7n :MLOAD(array_sub_AGTB_out + E) + + ; 2] len(inA) > len(inB) and inA_i < inb_i for some i + 3 => C + 2 => D + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 6n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 3n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 1 => E + 2n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 7n :MLOAD(array_sub_AGTB_out + E) + + ; 3] len(inA) > len(inB) and inA_i < inB_i for all i lower than len(inA) + 3 => C + 2 => D + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 1n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + :CALL(array_sub_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 6n :MLOAD(array_sub_AGTB_out + E) + + ; 4] len(inB) > len(inA) and inB_i < inA_i for all i lower than len(inB) + 3 => C + 2 => D + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + + 5n :MSTORE(array_sub_AGTB_inA) + 1 => E + 1n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 7n :MSTORE(array_sub_AGTB_inA + E) + :CALL(array_sub_AGTB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MLOAD(array_sub_AGTB_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639928n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 6n :MLOAD(array_sub_AGTB_out + E) + + ; 5] len(inB) = len(inA) and inB > inA + 3 => C + 3 => D + 6n :MSTORE(array_sub_AGTB_inB) + 1 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + 2 => E + 8n :MSTORE(array_sub_AGTB_inB + E) + + 7n :MSTORE(array_sub_AGTB_inA) + 1 => E + 8n :MSTORE(array_sub_AGTB_inA + E) + 2 => E + 8n :MSTORE(array_sub_AGTB_inA + E) + :CALL(array_sub_AGTB) + 1n :MLOAD(array_sub_AGTB_out) + 1 => E + 0n :MLOAD(array_sub_AGTB_out + E) + 2 => E + 0n :MLOAD(array_sub_AGTB_out + E) + ; --------------------------------------------------------------- :JMP(end) @@ -993,5 +993,5 @@ INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" -; INCLUDE "../main/modexp/array_lib/unused/array_sub_AGTB.zkasm" -; INCLUDE "../main/modexp/array_lib/unused/array_add.zkasm" \ No newline at end of file +INCLUDE "../main/modexp/array_lib/unused/array_sub_AGTB.zkasm" +INCLUDE "../main/modexp/array_lib/unused/array_add.zkasm" \ No newline at end of file diff --git a/test/testCycloFp12ArithBN254.zkasm b/test/testCycloFp12ArithBN254.zkasm index d4574f82..63872930 100644 --- a/test/testCycloFp12ArithBN254.zkasm +++ b/test/testCycloFp12ArithBN254.zkasm @@ -277,6 +277,33 @@ start: 0n :MLOAD(expCycloFp12BN254_c23_x) 0n :MLOAD(expCycloFp12BN254_c23_y) + 0n :MSTORE(expCycloFp12BN254_e) + 2n :MSTORE(expCycloFp12BN254_a11_x) + 0n :MSTORE(expCycloFp12BN254_a11_y) + 0n :MSTORE(expCycloFp12BN254_a12_x) + 0n :MSTORE(expCycloFp12BN254_a12_y) + 0n :MSTORE(expCycloFp12BN254_a13_x) + 0n :MSTORE(expCycloFp12BN254_a13_y) + 0n :MSTORE(expCycloFp12BN254_a21_x) + 0n :MSTORE(expCycloFp12BN254_a21_y) + 0n :MSTORE(expCycloFp12BN254_a22_x) + 0n :MSTORE(expCycloFp12BN254_a22_y) + 0n :MSTORE(expCycloFp12BN254_a23_x) + 0n :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 1n :MLOAD(expCycloFp12BN254_c11_x) + 0n :MLOAD(expCycloFp12BN254_c11_y) + 0n :MLOAD(expCycloFp12BN254_c12_x) + 0n :MLOAD(expCycloFp12BN254_c12_y) + 0n :MLOAD(expCycloFp12BN254_c13_x) + 0n :MLOAD(expCycloFp12BN254_c13_y) + 0n :MLOAD(expCycloFp12BN254_c21_x) + 0n :MLOAD(expCycloFp12BN254_c21_y) + 0n :MLOAD(expCycloFp12BN254_c22_x) + 0n :MLOAD(expCycloFp12BN254_c22_y) + 0n :MLOAD(expCycloFp12BN254_c23_x) + 0n :MLOAD(expCycloFp12BN254_c23_y) + 4965661367192848881n :MSTORE(expCycloFp12BN254_e) 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expCycloFp12BN254_a11_x) 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expCycloFp12BN254_a11_y) diff --git a/test/testFp12ArithBN254.zkasm b/test/testFp12ArithBN254.zkasm index 894dfa09..f387ba2b 100644 --- a/test/testFp12ArithBN254.zkasm +++ b/test/testFp12ArithBN254.zkasm @@ -53,85 +53,7 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; 1] Addition - 10n :MSTORE(addFp12BN254_a11_x) - 2n :MSTORE(addFp12BN254_a11_y) - 5n :MSTORE(addFp12BN254_a12_x) - 13n :MSTORE(addFp12BN254_a12_y) - 7n :MSTORE(addFp12BN254_a13_x) - 5n :MSTORE(addFp12BN254_a13_y) - 10n :MSTORE(addFp12BN254_a21_x) - 2n :MSTORE(addFp12BN254_a21_y) - 5n :MSTORE(addFp12BN254_a22_x) - 13n :MSTORE(addFp12BN254_a22_y) - 7n :MSTORE(addFp12BN254_a23_x) - 5n :MSTORE(addFp12BN254_a23_y) - 78n :MSTORE(addFp12BN254_b11_x) - 5n :MSTORE(addFp12BN254_b11_y) - 3n :MSTORE(addFp12BN254_b12_x) - 193n :MSTORE(addFp12BN254_b12_y) - 20n :MSTORE(addFp12BN254_b13_x) - 2n :MSTORE(addFp12BN254_b13_y) - 1n :MSTORE(addFp12BN254_b21_x) - 0n :MSTORE(addFp12BN254_b21_y) - 0n :MSTORE(addFp12BN254_b22_x) - 3n :MSTORE(addFp12BN254_b22_y) - 69n :MSTORE(addFp12BN254_b23_x) - 27n :MSTORE(addFp12BN254_b23_y) - :CALL(addFp12BN254) - 88n :MLOAD(addFp12BN254_c11_x) - 7n :MLOAD(addFp12BN254_c11_y) - 8n :MLOAD(addFp12BN254_c12_x) - 206n :MLOAD(addFp12BN254_c12_y) - 27n :MLOAD(addFp12BN254_c13_x) - 7n :MLOAD(addFp12BN254_c13_y) - 11n :MLOAD(addFp12BN254_c21_x) - 2n :MLOAD(addFp12BN254_c21_y) - 5n :MLOAD(addFp12BN254_c22_x) - 16n :MLOAD(addFp12BN254_c22_y) - 76n :MLOAD(addFp12BN254_c23_x) - 32n :MLOAD(addFp12BN254_c23_y) - - ; 2] Subtraction - 10n :MSTORE(subFp12BN254_a11_x) - 2n :MSTORE(subFp12BN254_a11_y) - 5n :MSTORE(subFp12BN254_a12_x) - 13n :MSTORE(subFp12BN254_a12_y) - 7n :MSTORE(subFp12BN254_a13_x) - 5n :MSTORE(subFp12BN254_a13_y) - 10n :MSTORE(subFp12BN254_a21_x) - 2n :MSTORE(subFp12BN254_a21_y) - 5n :MSTORE(subFp12BN254_a22_x) - 13n :MSTORE(subFp12BN254_a22_y) - 7n :MSTORE(subFp12BN254_a23_x) - 5n :MSTORE(subFp12BN254_a23_y) - 78n :MSTORE(subFp12BN254_b11_x) - 5n :MSTORE(subFp12BN254_b11_y) - 3n :MSTORE(subFp12BN254_b12_x) - 193n :MSTORE(subFp12BN254_b12_y) - 20n :MSTORE(subFp12BN254_b13_x) - 2n :MSTORE(subFp12BN254_b13_y) - 1n :MSTORE(subFp12BN254_b21_x) - 0n :MSTORE(subFp12BN254_b21_y) - 0n :MSTORE(subFp12BN254_b22_x) - 3n :MSTORE(subFp12BN254_b22_y) - 69n :MSTORE(subFp12BN254_b23_x) - 27n :MSTORE(subFp12BN254_b23_y) - :CALL(subFp12BN254) - 21888242871839275222246405745257275088696311157297823662689037894645226208515n :MLOAD(subFp12BN254_c11_x) - 21888242871839275222246405745257275088696311157297823662689037894645226208580n :MLOAD(subFp12BN254_c11_y) - 2n :MLOAD(subFp12BN254_c12_x) - 21888242871839275222246405745257275088696311157297823662689037894645226208403n :MLOAD(subFp12BN254_c12_y) - 21888242871839275222246405745257275088696311157297823662689037894645226208570n :MLOAD(subFp12BN254_c13_x) - 3n :MLOAD(subFp12BN254_c13_y) - 9n :MLOAD(subFp12BN254_c21_x) - 2n :MLOAD(subFp12BN254_c21_y) - 5n :MLOAD(subFp12BN254_c22_x) - 10n :MLOAD(subFp12BN254_c22_y) - 21888242871839275222246405745257275088696311157297823662689037894645226208521n :MLOAD(subFp12BN254_c23_x) - 21888242871839275222246405745257275088696311157297823662689037894645226208561n :MLOAD(subFp12BN254_c23_y) - - ; 3] Multiplication + ; 1] Multiplication 10n :MSTORE(mulFp12BN254_a11_x) 2n :MSTORE(mulFp12BN254_a11_y) 5n :MSTORE(mulFp12BN254_a12_x) @@ -208,7 +130,7 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226207620n :MLOAD(mulFp12BN254_c23_x) 6214n :MLOAD(mulFp12BN254_c23_y) - ; 4] Squaring + ; 2] Squaring 2n :MSTORE(squareFp12BN254_a11_x) 4n :MSTORE(squareFp12BN254_a11_y) 0n :MSTORE(squareFp12BN254_a12_x) @@ -261,7 +183,7 @@ start: 18987338659195924269172748027172054817706283508452795151531146694958273165690n :MLOAD(squareFp12BN254_c23_x) 8860539994207234999664733841364243523346939192669625740842082601247122017n :MLOAD(squareFp12BN254_c23_y) - ; 5] Inversion + ; 3] Inversion 0n :MSTORE(inverseFp12BN254_a11_x) 0n :MSTORE(inverseFp12BN254_a11_y) 0n :MSTORE(inverseFp12BN254_a12_x) @@ -314,7 +236,7 @@ start: 8570196145412438361611057965650768730501569553533068267820731323855389368346n :MLOAD(inverseFp12BN254_c23_x) 7491118698937156772874143978394611345783939114329232646099076078308797709778n :MLOAD(inverseFp12BN254_c23_y) - ; 6] Frobenius 1 + ; 4] Frobenius 1 2n :MSTORE(frobFp12BN254_a11_x) 4n :MSTORE(frobFp12BN254_a11_y) 0n :MSTORE(frobFp12BN254_a12_x) @@ -341,7 +263,7 @@ start: 18558562840876269057841639761243305870292532112761084078231157243871160309578n :MLOAD(frobFp12BN254_c23_x) 11857974535903257516183381046246360366676403947472414230254839754001932999778n :MLOAD(frobFp12BN254_c23_y) - ; 7] Frobenius 2 + ; 5] Frobenius 2 2n :MSTORE(frob2Fp12BN254_a11_x) 4n :MSTORE(frob2Fp12BN254_a11_y) 0n :MSTORE(frob2Fp12BN254_a12_x) @@ -368,7 +290,7 @@ start: 15427723396036853449930226199780334146819954812161439563769n :MLOAD(frob2Fp12BN254_c23_x) 152073273475220412577883658254977579447225268862734189985723n :MLOAD(frob2Fp12BN254_c23_y) - ; 8] Frobenius 3 + ; 6] Frobenius 3 2n :MSTORE(frob3Fp12BN254_a11_x) 4n :MSTORE(frob3Fp12BN254_a11_y) 0n :MSTORE(frob3Fp12BN254_a12_x) @@ -395,7 +317,156 @@ start: 9835836312269481659124129352040423254366959727421963915440501313066399824733n :MLOAD(frob3Fp12BN254_c23_x) 2627768430169233579625702931774614886811535516639531274999928953109345755919n :MLOAD(frob3Fp12BN254_c23_y) - ; 9] Exponentiation + ; 7] Sparse Multiplication A + 2n :MSTORE(sparseMulAFp12BN254_a11_x) + 4n :MSTORE(sparseMulAFp12BN254_a11_y) + 0n :MSTORE(sparseMulAFp12BN254_a12_x) + 0n :MSTORE(sparseMulAFp12BN254_a12_y) + 0n :MSTORE(sparseMulAFp12BN254_a13_x) + 5n :MSTORE(sparseMulAFp12BN254_a13_y) + 5n :MSTORE(sparseMulAFp12BN254_a21_x) + 10n :MSTORE(sparseMulAFp12BN254_a21_y) + 20n :MSTORE(sparseMulAFp12BN254_a22_x) + 30n :MSTORE(sparseMulAFp12BN254_a22_y) + 7n :MSTORE(sparseMulAFp12BN254_a23_x) + 69n :MSTORE(sparseMulAFp12BN254_a23_y) + 7n :MSTORE(sparseMulAFp12BN254_b12_x) + 6n :MSTORE(sparseMulAFp12BN254_b12_y) + 7n :MSTORE(sparseMulAFp12BN254_b22_x) + 83n :MSTORE(sparseMulAFp12BN254_b22_y) + 2n :MSTORE(sparseMulAFp12BN254_b23_x) + 29n :MSTORE(sparseMulAFp12BN254_b23_y) + :CALL(sparseMulAFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226182573n :MLOAD(sparseMulAFp12BN254_c11_x) + 15970n :MLOAD(sparseMulAFp12BN254_c11_y) + 21888242871839275222246405745257275088696311157297823662689037894645226148297n :MLOAD(sparseMulAFp12BN254_c12_x) + 8868n :MLOAD(sparseMulAFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226189564n :MLOAD(sparseMulAFp12BN254_c13_x) + 1567n :MLOAD(sparseMulAFp12BN254_c13_y) + 21888242871839275222246405745257275088696311157297823662689037894645226201003n :MLOAD(sparseMulAFp12BN254_c21_x) + 4260n :MLOAD(sparseMulAFp12BN254_c21_y) + 21888242871839275222246405745257275088696311157297823662689037894645226206925n :MLOAD(sparseMulAFp12BN254_c22_x) + 239n :MLOAD(sparseMulAFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208431n :MLOAD(sparseMulAFp12BN254_c23_x) + 396n :MLOAD(sparseMulAFp12BN254_c23_y) + + ; 8] Sparse Multiplication B + 2n :MSTORE(sparseMulBFp12BN254_a11_x) + 4n :MSTORE(sparseMulBFp12BN254_a11_y) + 0n :MSTORE(sparseMulBFp12BN254_a12_x) + 0n :MSTORE(sparseMulBFp12BN254_a12_y) + 0n :MSTORE(sparseMulBFp12BN254_a13_x) + 5n :MSTORE(sparseMulBFp12BN254_a13_y) + 5n :MSTORE(sparseMulBFp12BN254_a21_x) + 10n :MSTORE(sparseMulBFp12BN254_a21_y) + 20n :MSTORE(sparseMulBFp12BN254_a22_x) + 30n :MSTORE(sparseMulBFp12BN254_a22_y) + 7n :MSTORE(sparseMulBFp12BN254_a23_x) + 69n :MSTORE(sparseMulBFp12BN254_a23_y) + 7n :MSTORE(sparseMulBFp12BN254_b11_x) + 6n :MSTORE(sparseMulBFp12BN254_b11_y) + 7n :MSTORE(sparseMulBFp12BN254_b13_x) + 83n :MSTORE(sparseMulBFp12BN254_b13_y) + 2n :MSTORE(sparseMulBFp12BN254_b22_x) + 29n :MSTORE(sparseMulBFp12BN254_b22_y) + :CALL(sparseMulBFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226200463n :MLOAD(sparseMulBFp12BN254_c11_x) + 4970n :MLOAD(sparseMulBFp12BN254_c11_y) + 21888242871839275222246405745257275088696311157297823662689037894645226186589n :MLOAD(sparseMulBFp12BN254_c12_x) + 982n :MLOAD(sparseMulBFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207955n :MLOAD(sparseMulBFp12BN254_c13_x) + 394n :MLOAD(sparseMulBFp12BN254_c13_y) + 21888242871839275222246405745257275088696311157297823662689037894645226184223n :MLOAD(sparseMulBFp12BN254_c21_x) + 14525n :MLOAD(sparseMulBFp12BN254_c21_y) + 21888242871839275222246405745257275088696311157297823662689037894645226156265n :MLOAD(sparseMulBFp12BN254_c22_x) + 4294n :MLOAD(sparseMulBFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226207423n :MLOAD(sparseMulBFp12BN254_c23_x) + 1010n :MLOAD(sparseMulBFp12BN254_c23_y) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; UNUSED + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ; 1] Addition + 10n :MSTORE(addFp12BN254_a11_x) + 2n :MSTORE(addFp12BN254_a11_y) + 5n :MSTORE(addFp12BN254_a12_x) + 13n :MSTORE(addFp12BN254_a12_y) + 7n :MSTORE(addFp12BN254_a13_x) + 5n :MSTORE(addFp12BN254_a13_y) + 10n :MSTORE(addFp12BN254_a21_x) + 2n :MSTORE(addFp12BN254_a21_y) + 5n :MSTORE(addFp12BN254_a22_x) + 13n :MSTORE(addFp12BN254_a22_y) + 7n :MSTORE(addFp12BN254_a23_x) + 5n :MSTORE(addFp12BN254_a23_y) + 78n :MSTORE(addFp12BN254_b11_x) + 5n :MSTORE(addFp12BN254_b11_y) + 3n :MSTORE(addFp12BN254_b12_x) + 193n :MSTORE(addFp12BN254_b12_y) + 20n :MSTORE(addFp12BN254_b13_x) + 2n :MSTORE(addFp12BN254_b13_y) + 1n :MSTORE(addFp12BN254_b21_x) + 0n :MSTORE(addFp12BN254_b21_y) + 0n :MSTORE(addFp12BN254_b22_x) + 3n :MSTORE(addFp12BN254_b22_y) + 69n :MSTORE(addFp12BN254_b23_x) + 27n :MSTORE(addFp12BN254_b23_y) + :CALL(addFp12BN254) + 88n :MLOAD(addFp12BN254_c11_x) + 7n :MLOAD(addFp12BN254_c11_y) + 8n :MLOAD(addFp12BN254_c12_x) + 206n :MLOAD(addFp12BN254_c12_y) + 27n :MLOAD(addFp12BN254_c13_x) + 7n :MLOAD(addFp12BN254_c13_y) + 11n :MLOAD(addFp12BN254_c21_x) + 2n :MLOAD(addFp12BN254_c21_y) + 5n :MLOAD(addFp12BN254_c22_x) + 16n :MLOAD(addFp12BN254_c22_y) + 76n :MLOAD(addFp12BN254_c23_x) + 32n :MLOAD(addFp12BN254_c23_y) + + ; 2] Subtraction + 10n :MSTORE(subFp12BN254_a11_x) + 2n :MSTORE(subFp12BN254_a11_y) + 5n :MSTORE(subFp12BN254_a12_x) + 13n :MSTORE(subFp12BN254_a12_y) + 7n :MSTORE(subFp12BN254_a13_x) + 5n :MSTORE(subFp12BN254_a13_y) + 10n :MSTORE(subFp12BN254_a21_x) + 2n :MSTORE(subFp12BN254_a21_y) + 5n :MSTORE(subFp12BN254_a22_x) + 13n :MSTORE(subFp12BN254_a22_y) + 7n :MSTORE(subFp12BN254_a23_x) + 5n :MSTORE(subFp12BN254_a23_y) + 78n :MSTORE(subFp12BN254_b11_x) + 5n :MSTORE(subFp12BN254_b11_y) + 3n :MSTORE(subFp12BN254_b12_x) + 193n :MSTORE(subFp12BN254_b12_y) + 20n :MSTORE(subFp12BN254_b13_x) + 2n :MSTORE(subFp12BN254_b13_y) + 1n :MSTORE(subFp12BN254_b21_x) + 0n :MSTORE(subFp12BN254_b21_y) + 0n :MSTORE(subFp12BN254_b22_x) + 3n :MSTORE(subFp12BN254_b22_y) + 69n :MSTORE(subFp12BN254_b23_x) + 27n :MSTORE(subFp12BN254_b23_y) + :CALL(subFp12BN254) + 21888242871839275222246405745257275088696311157297823662689037894645226208515n :MLOAD(subFp12BN254_c11_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208580n :MLOAD(subFp12BN254_c11_y) + 2n :MLOAD(subFp12BN254_c12_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208403n :MLOAD(subFp12BN254_c12_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208570n :MLOAD(subFp12BN254_c13_x) + 3n :MLOAD(subFp12BN254_c13_y) + 9n :MLOAD(subFp12BN254_c21_x) + 2n :MLOAD(subFp12BN254_c21_y) + 5n :MLOAD(subFp12BN254_c22_x) + 10n :MLOAD(subFp12BN254_c22_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208521n :MLOAD(subFp12BN254_c23_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208561n :MLOAD(subFp12BN254_c23_y) + + ; 3] Exponentiation + ; 1) 0^0 = 0 0n :MSTORE(expFp12BN254_e) 0n :MSTORE(expFp12BN254_a11_x) 0n :MSTORE(expFp12BN254_a11_y) @@ -423,6 +494,7 @@ start: 0n :MLOAD(expFp12BN254_c23_x) 0n :MLOAD(expFp12BN254_c23_y) + ; 2) 0^e = 0 with e != 0 10n :MSTORE(expFp12BN254_e) 0n :MSTORE(expFp12BN254_a11_x) 0n :MSTORE(expFp12BN254_a11_y) @@ -450,6 +522,7 @@ start: 0n :MLOAD(expFp12BN254_c23_x) 0n :MLOAD(expFp12BN254_c23_y) + ; 3.1) 1^0 = 1 0n :MSTORE(expFp12BN254_e) 1n :MSTORE(expFp12BN254_a11_x) 0n :MSTORE(expFp12BN254_a11_y) @@ -477,6 +550,35 @@ start: 0n :MLOAD(expFp12BN254_c23_x) 0n :MLOAD(expFp12BN254_c23_y) + ; 3.2) a^0 = 1 with a > 1 + 0n :MSTORE(expFp12BN254_e) + 2n :MSTORE(expFp12BN254_a11_x) + 0n :MSTORE(expFp12BN254_a11_y) + 0n :MSTORE(expFp12BN254_a12_x) + 0n :MSTORE(expFp12BN254_a12_y) + 0n :MSTORE(expFp12BN254_a13_x) + 0n :MSTORE(expFp12BN254_a13_y) + 0n :MSTORE(expFp12BN254_a21_x) + 0n :MSTORE(expFp12BN254_a21_y) + 0n :MSTORE(expFp12BN254_a22_x) + 0n :MSTORE(expFp12BN254_a22_y) + 0n :MSTORE(expFp12BN254_a23_x) + 0n :MSTORE(expFp12BN254_a23_y) + :CALL(expFp12BN254) + 1n :MLOAD(expFp12BN254_c11_x) + 0n :MLOAD(expFp12BN254_c11_y) + 0n :MLOAD(expFp12BN254_c12_x) + 0n :MLOAD(expFp12BN254_c12_y) + 0n :MLOAD(expFp12BN254_c13_x) + 0n :MLOAD(expFp12BN254_c13_y) + 0n :MLOAD(expFp12BN254_c21_x) + 0n :MLOAD(expFp12BN254_c21_y) + 0n :MLOAD(expFp12BN254_c22_x) + 0n :MLOAD(expFp12BN254_c22_y) + 0n :MLOAD(expFp12BN254_c23_x) + 0n :MLOAD(expFp12BN254_c23_y) + + ; 4) Small example 167n :MSTORE(expFp12BN254_e) 2n :MSTORE(expFp12BN254_a11_x) 4n :MSTORE(expFp12BN254_a11_y) @@ -504,6 +606,7 @@ start: 4130369998871020954078407548456754295747138847271917082666014536095464174364n :MLOAD(expFp12BN254_c23_x) 1685641307692274787278258791922218462843126978449545532205987451962723928051n :MLOAD(expFp12BN254_c23_y) + ; 5) Big example 123456789n :MSTORE(expFp12BN254_e) 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expFp12BN254_a11_x) 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expFp12BN254_a11_y) @@ -531,72 +634,6 @@ start: 2894810207171007395751896130534905544170418813733418015224386592699923578372n :MLOAD(expFp12BN254_c23_x) 18124993142426825678658622810384924838784371007656354124172463271771994460493n :MLOAD(expFp12BN254_c23_y) - ; 10] Sparse Multiplication A - 2n :MSTORE(sparseMulAFp12BN254_a11_x) - 4n :MSTORE(sparseMulAFp12BN254_a11_y) - 0n :MSTORE(sparseMulAFp12BN254_a12_x) - 0n :MSTORE(sparseMulAFp12BN254_a12_y) - 0n :MSTORE(sparseMulAFp12BN254_a13_x) - 5n :MSTORE(sparseMulAFp12BN254_a13_y) - 5n :MSTORE(sparseMulAFp12BN254_a21_x) - 10n :MSTORE(sparseMulAFp12BN254_a21_y) - 20n :MSTORE(sparseMulAFp12BN254_a22_x) - 30n :MSTORE(sparseMulAFp12BN254_a22_y) - 7n :MSTORE(sparseMulAFp12BN254_a23_x) - 69n :MSTORE(sparseMulAFp12BN254_a23_y) - 7n :MSTORE(sparseMulAFp12BN254_b12_x) - 6n :MSTORE(sparseMulAFp12BN254_b12_y) - 7n :MSTORE(sparseMulAFp12BN254_b22_x) - 83n :MSTORE(sparseMulAFp12BN254_b22_y) - 2n :MSTORE(sparseMulAFp12BN254_b23_x) - 29n :MSTORE(sparseMulAFp12BN254_b23_y) - :CALL(sparseMulAFp12BN254) - 21888242871839275222246405745257275088696311157297823662689037894645226182573n :MLOAD(sparseMulAFp12BN254_c11_x) - 15970n :MLOAD(sparseMulAFp12BN254_c11_y) - 21888242871839275222246405745257275088696311157297823662689037894645226148297n :MLOAD(sparseMulAFp12BN254_c12_x) - 8868n :MLOAD(sparseMulAFp12BN254_c12_y) - 21888242871839275222246405745257275088696311157297823662689037894645226189564n :MLOAD(sparseMulAFp12BN254_c13_x) - 1567n :MLOAD(sparseMulAFp12BN254_c13_y) - 21888242871839275222246405745257275088696311157297823662689037894645226201003n :MLOAD(sparseMulAFp12BN254_c21_x) - 4260n :MLOAD(sparseMulAFp12BN254_c21_y) - 21888242871839275222246405745257275088696311157297823662689037894645226206925n :MLOAD(sparseMulAFp12BN254_c22_x) - 239n :MLOAD(sparseMulAFp12BN254_c22_y) - 21888242871839275222246405745257275088696311157297823662689037894645226208431n :MLOAD(sparseMulAFp12BN254_c23_x) - 396n :MLOAD(sparseMulAFp12BN254_c23_y) - - ; 11] Sparse Multiplication B - 2n :MSTORE(sparseMulBFp12BN254_a11_x) - 4n :MSTORE(sparseMulBFp12BN254_a11_y) - 0n :MSTORE(sparseMulBFp12BN254_a12_x) - 0n :MSTORE(sparseMulBFp12BN254_a12_y) - 0n :MSTORE(sparseMulBFp12BN254_a13_x) - 5n :MSTORE(sparseMulBFp12BN254_a13_y) - 5n :MSTORE(sparseMulBFp12BN254_a21_x) - 10n :MSTORE(sparseMulBFp12BN254_a21_y) - 20n :MSTORE(sparseMulBFp12BN254_a22_x) - 30n :MSTORE(sparseMulBFp12BN254_a22_y) - 7n :MSTORE(sparseMulBFp12BN254_a23_x) - 69n :MSTORE(sparseMulBFp12BN254_a23_y) - 7n :MSTORE(sparseMulBFp12BN254_b11_x) - 6n :MSTORE(sparseMulBFp12BN254_b11_y) - 7n :MSTORE(sparseMulBFp12BN254_b13_x) - 83n :MSTORE(sparseMulBFp12BN254_b13_y) - 2n :MSTORE(sparseMulBFp12BN254_b22_x) - 29n :MSTORE(sparseMulBFp12BN254_b22_y) - :CALL(sparseMulBFp12BN254) - 21888242871839275222246405745257275088696311157297823662689037894645226200463n :MLOAD(sparseMulBFp12BN254_c11_x) - 4970n :MLOAD(sparseMulBFp12BN254_c11_y) - 21888242871839275222246405745257275088696311157297823662689037894645226186589n :MLOAD(sparseMulBFp12BN254_c12_x) - 982n :MLOAD(sparseMulBFp12BN254_c12_y) - 21888242871839275222246405745257275088696311157297823662689037894645226207955n :MLOAD(sparseMulBFp12BN254_c13_x) - 394n :MLOAD(sparseMulBFp12BN254_c13_y) - 21888242871839275222246405745257275088696311157297823662689037894645226184223n :MLOAD(sparseMulBFp12BN254_c21_x) - 14525n :MLOAD(sparseMulBFp12BN254_c21_y) - 21888242871839275222246405745257275088696311157297823662689037894645226156265n :MLOAD(sparseMulBFp12BN254_c22_x) - 4294n :MLOAD(sparseMulBFp12BN254_c22_y) - 21888242871839275222246405745257275088696311157297823662689037894645226207423n :MLOAD(sparseMulBFp12BN254_c23_x) - 1010n :MLOAD(sparseMulBFp12BN254_c23_y) - $ => A :MLOAD(initial_A) $ => B :MLOAD(initial_B) diff --git a/test/testFp2ArithBN254.zkasm b/test/testFp2ArithBN254.zkasm index 5e5edca8..0c51cd3d 100644 --- a/test/testFp2ArithBN254.zkasm +++ b/test/testFp2ArithBN254.zkasm @@ -114,6 +114,22 @@ start: D => A 1287543698343486777779200337956310299335077126899871980158178699685013306387n :ASSERT + %BN254_P => A + 0n => B + :CALL(invFp2BN254) + C => A + 0 :ASSERT + D => A + 0 :ASSERT + + 0n => A + %BN254_P => B + :CALL(invFp2BN254) + C => A + 0 :ASSERT + D => A + 0 :ASSERT + ; 4] Squaring 1n => A 4n => B diff --git a/test/testFpArithBN254.zkasm b/test/testFpArithBN254.zkasm index d2364f18..3b2bc356 100644 --- a/test/testFpArithBN254.zkasm +++ b/test/testFpArithBN254.zkasm @@ -81,20 +81,29 @@ start: %BN254_P + %BN254_P => A :CALL(invFpBN254) + B => A 0n :ASSERT %BN254_P + %BN254_P + %BN254_P => A :CALL(invFpBN254) + B => A 0n :ASSERT %BN254_P + %BN254_P + %BN254_P + %BN254_P => A :CALL(invFpBN254) + B => A 0n :ASSERT %BN254_P + %BN254_P + %BN254_P + %BN254_P + %BN254_P => A :CALL(invFpBN254) + B => A 0n :ASSERT + 2n => A + :CALL(invFpBN254) + B => A + 10944121435919637611123202872628637544348155578648911831344518947322613104292n :ASSERT + ; 5] Reduction 0n => A :CALL(reduceFpBN254) diff --git a/test/testHalfPairingBN254.zkasm b/test/testHalfPairingBN254.zkasm index 059bf7c1..a37ef1f0 100644 --- a/test/testHalfPairingBN254.zkasm +++ b/test/testHalfPairingBN254.zkasm @@ -8,6 +8,8 @@ CONST %MAX_CNT_KECCAK_F_LIMIT = %N CONST %MAX_CNT_PADDING_PG_LIMIT = %N CONST %MAX_CNT_POSEIDON_G_LIMIT = %N +INCLUDE "../main/pairings/constants.zkasm" + VAR GLOBAL lastHashKId VAR GLOBAL lastHashPId @@ -49,6 +51,158 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) + ; 1] P = Q = 0 + 0n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + 1n :MLOAD(halfPairingBN254_f11_x) + 0n :MLOAD(halfPairingBN254_f11_y) + 0n :MLOAD(halfPairingBN254_f12_x) + 0n :MLOAD(halfPairingBN254_f12_y) + 0n :MLOAD(halfPairingBN254_f13_x) + 0n :MLOAD(halfPairingBN254_f13_y) + 0n :MLOAD(halfPairingBN254_f21_x) + 0n :MLOAD(halfPairingBN254_f21_y) + 0n :MLOAD(halfPairingBN254_f22_x) + 0n :MLOAD(halfPairingBN254_f22_y) + 0n :MLOAD(halfPairingBN254_f23_x) + 0n :MLOAD(halfPairingBN254_f23_y) + + ; 2] P = 0, Q ∈ G2\{0} + 0n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(halfPairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(halfPairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(halfPairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + 1n :MLOAD(halfPairingBN254_f11_x) + 0n :MLOAD(halfPairingBN254_f11_y) + 0n :MLOAD(halfPairingBN254_f12_x) + 0n :MLOAD(halfPairingBN254_f12_y) + 0n :MLOAD(halfPairingBN254_f13_x) + 0n :MLOAD(halfPairingBN254_f13_y) + 0n :MLOAD(halfPairingBN254_f21_x) + 0n :MLOAD(halfPairingBN254_f21_y) + 0n :MLOAD(halfPairingBN254_f22_x) + 0n :MLOAD(halfPairingBN254_f22_y) + 0n :MLOAD(halfPairingBN254_f23_x) + 0n :MLOAD(halfPairingBN254_f23_y) + + ; 3] P ∈ G1\{0}, Q = 0 + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(halfPairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + 1n :MLOAD(halfPairingBN254_f11_x) + 0n :MLOAD(halfPairingBN254_f11_y) + 0n :MLOAD(halfPairingBN254_f12_x) + 0n :MLOAD(halfPairingBN254_f12_y) + 0n :MLOAD(halfPairingBN254_f13_x) + 0n :MLOAD(halfPairingBN254_f13_y) + 0n :MLOAD(halfPairingBN254_f21_x) + 0n :MLOAD(halfPairingBN254_f21_y) + 0n :MLOAD(halfPairingBN254_f22_x) + 0n :MLOAD(halfPairingBN254_f22_y) + 0n :MLOAD(halfPairingBN254_f23_x) + 0n :MLOAD(halfPairingBN254_f23_y) + + ; 3] Px too big + %BN254_P :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 1 :ASSERT + + ; 4] Py too big + 0n :MSTORE(halfPairingBN254_P_x) + %BN254_P :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 2 :ASSERT + + ; 5] Qx1 too big + 0n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + %BN254_P :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 3 :ASSERT + + ; 6] Qx2 too big + 0n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + %BN254_P :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 4 :ASSERT + + ; 7] Qy1 too big + 0n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + %BN254_P :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 5 :ASSERT + + ; 8] Qy2 too big + 0n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + %BN254_P :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 6 :ASSERT + + ; 9] P ∉ G1 + 1n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 0n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 7 :ASSERT + + ; 10] Q ∉ G2 + 0n :MSTORE(halfPairingBN254_P_x) + 0n :MSTORE(halfPairingBN254_P_y) + 1n :MSTORE(halfPairingBN254_Q_x1) + 0n :MSTORE(halfPairingBN254_Q_x2) + 0n :MSTORE(halfPairingBN254_Q_y1) + 0n :MSTORE(halfPairingBN254_Q_y2) + :CALL(halfPairingBN254) + B => A + 8 :ASSERT + + ; 11] Normal example 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(halfPairingBN254_P_x) 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(halfPairingBN254_P_y) 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(halfPairingBN254_Q_x1) @@ -95,8 +249,6 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) -INCLUDE "../main/pairings/constants.zkasm" - INCLUDE "../main/pairings/halfPairingBN254.zkasm" INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index 72567d80..12ada5db 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -255,7 +255,38 @@ start: ; 256 BITS EXPONENT TESTS ; --------------------------------------------------------------------------------------------- - ; 1] B = [100n, 2831023n, 0n, 73916234139162n], E = [2n**256n - 1n], M = [0n, 0n, 8238129386n, 23102318237n] + ; 1] B == k·M (at any point of the exponentiations) should return 0 + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + 4n :MSTORE(modexp_B) + 78n :MSTORE(modexp_E) + 4n :MSTORE(modexp_M) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + 8n :MSTORE(modexp_B) + 78n :MSTORE(modexp_E) + 4n :MSTORE(modexp_M) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + 1 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 1 :MSTORE(modexp_Mlen) + 2n :MSTORE(modexp_B) + 2n :MSTORE(modexp_E) + 4n :MSTORE(modexp_M) + :CALL(modexp) + 0n :MLOAD(modexp_out) + 1 :MLOAD(modexp_outlen) + + ; 2] B = [100n, 2831023n, 0n, 73916234139162n], E = [2n**256n - 1n], M = [0n, 0n, 8238129386n, 23102318237n] ; Hamming weight of E is 256 4 :MSTORE(modexp_Blen) 1 :MSTORE(modexp_Elen) @@ -286,7 +317,7 @@ start: 4679155145n :MLOAD(modexp_out + E) 4 :MLOAD(modexp_outlen) - ; 2] B = [100n, 2831023n, 0n, 73916234139162n, 100n, 2831023n, 0n, 73916234139162n,100n, 2831023n, 0n, 73916234139162n], E = [903741926349715234612309461283471234n], M = [0n, 0n, 8238129386n, 23102318237n, 1892397612351n, 7246598123051n, 8238129386n, 1264591241237897123126n] + ; 3] B = [100n, 2831023n, 0n, 73916234139162n, 100n, 2831023n, 0n, 73916234139162n,100n, 2831023n, 0n, 73916234139162n], E = [903741926349715234612309461283471234n], M = [0n, 0n, 8238129386n, 23102318237n, 1892397612351n, 7246598123051n, 8238129386n, 1264591241237897123126n] ; Hamming weight of E is 120 12 :MSTORE(modexp_Blen) 1 :MSTORE(modexp_Elen) @@ -349,7 +380,7 @@ start: 511131288598502431475n :MLOAD(modexp_out + E) 8 :MLOAD(modexp_outlen) - ; 3] B = [7n], E = [110n], M = [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] + ; 4] B = [7n], E = [110n], M = [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] ; Hamming weight of E is 5 1 :MSTORE(modexp_Blen) 1 :MSTORE(modexp_Elen) diff --git a/test/testPairingBN254.zkasm b/test/testPairingBN254.zkasm index 57fce84e..3a2ed975 100644 --- a/test/testPairingBN254.zkasm +++ b/test/testPairingBN254.zkasm @@ -49,316 +49,336 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; Generators P,Q - - ; 1] Degenerate tests: e(0,Q) = 1 and e(P,0) = 1 - 0n :MSTORE(pairingBN254_P_x) - 0n :MSTORE(pairingBN254_P_y) - 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) - 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) - 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) - 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 1n :MLOAD(pairingBN254_f11_x) - 0n :MLOAD(pairingBN254_f11_y) - 0n :MLOAD(pairingBN254_f12_x) - 0n :MLOAD(pairingBN254_f12_y) - 0n :MLOAD(pairingBN254_f13_x) - 0n :MLOAD(pairingBN254_f13_y) - 0n :MLOAD(pairingBN254_f21_x) - 0n :MLOAD(pairingBN254_f21_y) - 0n :MLOAD(pairingBN254_f22_x) - 0n :MLOAD(pairingBN254_f22_y) - 0n :MLOAD(pairingBN254_f23_x) - 0n :MLOAD(pairingBN254_f23_y) - - 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) - 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) - 0n :MSTORE(pairingBN254_Q_x1) - 0n :MSTORE(pairingBN254_Q_x2) - 0n :MSTORE(pairingBN254_Q_y1) - 0n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 1n :MLOAD(pairingBN254_f11_x) - 0n :MLOAD(pairingBN254_f11_y) - 0n :MLOAD(pairingBN254_f12_x) - 0n :MLOAD(pairingBN254_f12_y) - 0n :MLOAD(pairingBN254_f13_x) - 0n :MLOAD(pairingBN254_f13_y) - 0n :MLOAD(pairingBN254_f21_x) - 0n :MLOAD(pairingBN254_f21_y) - 0n :MLOAD(pairingBN254_f22_x) - 0n :MLOAD(pairingBN254_f22_y) - 0n :MLOAD(pairingBN254_f23_x) - 0n :MLOAD(pairingBN254_f23_y) - - ; 2] P not in range - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_x) - 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 1 => A - 1 :EQ - - 0n :MSTORE(pairingBN254_P_x) - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 2 => A - 1 :EQ - - ; 3] Q not in range - 0n :MSTORE(pairingBN254_P_x) - 0n :MSTORE(pairingBN254_P_y) - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 3 => A - 1 :EQ - - 0n :MSTORE(pairingBN254_P_x) - 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 4 => A - 1 :EQ - - 0n :MSTORE(pairingBN254_P_x) - 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y1) - 4n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 5 => A - 1 :EQ - - 0n :MSTORE(pairingBN254_P_x) - 0n :MSTORE(pairingBN254_P_y) - 1n :MSTORE(pairingBN254_Q_x1) - 2n :MSTORE(pairingBN254_Q_x2) - 3n :MSTORE(pairingBN254_Q_y1) - 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 6 => A - 1 :EQ - - ; 4] P not in G1 - 1n :MSTORE(pairingBN254_P_x) - 1n :MSTORE(pairingBN254_P_y) - 0n :MSTORE(pairingBN254_Q_x1) - 0n :MSTORE(pairingBN254_Q_x2) - 0n :MSTORE(pairingBN254_Q_y1) - 0n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 7 => A - 1 :EQ - - ; 5] Q not in G2 - 0n :MSTORE(pairingBN254_P_x) - 0n :MSTORE(pairingBN254_P_y) - 13952973379259391431794065814946995996741015657664522404741834284791195202656n :MSTORE(pairingBN254_Q_x1) - 10904417650644905372723866879625669404817699819926286815323845522270190436451n :MSTORE(pairingBN254_Q_x2) - 12292403207927938194042684085166933223459250332097452603928615449631462314854n :MSTORE(pairingBN254_Q_y1) - 3535501093699632689489376651381121898720279562088698464643486166587401099479n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 8 => A - 1 :EQ - - ; 6] Bilinearity test: e(2P,12Q) = e(P,12Q)² = e(2P,Q)¹² = e(P,Q)²⁴ = e(12P,2Q) - ; e(2P,12Q) - 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) - 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) - 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) - 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) - 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) - 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(pairingBN254_f11_x) - 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(pairingBN254_f11_y) - 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(pairingBN254_f12_x) - 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(pairingBN254_f12_y) - 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(pairingBN254_f13_x) - 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(pairingBN254_f13_y) - 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(pairingBN254_f21_x) - 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(pairingBN254_f21_y) - 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(pairingBN254_f22_x) - 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(pairingBN254_f22_y) - 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(pairingBN254_f23_x) - 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(pairingBN254_f23_y) - - ; e(P,12Q)² - 1n :MSTORE(pairingBN254_P_x) - 2n :MSTORE(pairingBN254_P_y) - 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) - 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) - 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) - 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 2n :MSTORE(expCycloFp12BN254_e) - $ => A :MLOAD(pairingBN254_f11_x) - $ => B :MLOAD(pairingBN254_f11_y) - A :MSTORE(expCycloFp12BN254_a11_x) - B :MSTORE(expCycloFp12BN254_a11_y) - $ => A :MLOAD(pairingBN254_f12_x) - $ => B :MLOAD(pairingBN254_f12_y) - A :MSTORE(expCycloFp12BN254_a12_x) - B :MSTORE(expCycloFp12BN254_a12_y) - $ => A :MLOAD(pairingBN254_f13_x) - $ => B :MLOAD(pairingBN254_f13_y) - A :MSTORE(expCycloFp12BN254_a13_x) - B :MSTORE(expCycloFp12BN254_a13_y) - $ => A :MLOAD(pairingBN254_f21_x) - $ => B :MLOAD(pairingBN254_f21_y) - A :MSTORE(expCycloFp12BN254_a21_x) - B :MSTORE(expCycloFp12BN254_a21_y) - $ => A :MLOAD(pairingBN254_f22_x) - $ => B :MLOAD(pairingBN254_f22_y) - A :MSTORE(expCycloFp12BN254_a22_x) - B :MSTORE(expCycloFp12BN254_a22_y) - $ => A :MLOAD(pairingBN254_f23_x) - $ => B :MLOAD(pairingBN254_f23_y) - A :MSTORE(expCycloFp12BN254_a23_x) - B :MSTORE(expCycloFp12BN254_a23_y) - :CALL(expCycloFp12BN254) - 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) - 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) - 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) - 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) - 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) - 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) - 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) - 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) - 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) - 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) - 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) - 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) - - ; e(2P,Q)¹² - 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) - 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(pairingBN254_Q_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 12n :MSTORE(expCycloFp12BN254_e) - $ => A :MLOAD(pairingBN254_f11_x) - $ => B :MLOAD(pairingBN254_f11_y) - A :MSTORE(expCycloFp12BN254_a11_x) - B :MSTORE(expCycloFp12BN254_a11_y) - $ => A :MLOAD(pairingBN254_f12_x) - $ => B :MLOAD(pairingBN254_f12_y) - A :MSTORE(expCycloFp12BN254_a12_x) - B :MSTORE(expCycloFp12BN254_a12_y) - $ => A :MLOAD(pairingBN254_f13_x) - $ => B :MLOAD(pairingBN254_f13_y) - A :MSTORE(expCycloFp12BN254_a13_x) - B :MSTORE(expCycloFp12BN254_a13_y) - $ => A :MLOAD(pairingBN254_f21_x) - $ => B :MLOAD(pairingBN254_f21_y) - A :MSTORE(expCycloFp12BN254_a21_x) - B :MSTORE(expCycloFp12BN254_a21_y) - $ => A :MLOAD(pairingBN254_f22_x) - $ => B :MLOAD(pairingBN254_f22_y) - A :MSTORE(expCycloFp12BN254_a22_x) - B :MSTORE(expCycloFp12BN254_a22_y) - $ => A :MLOAD(pairingBN254_f23_x) - $ => B :MLOAD(pairingBN254_f23_y) - A :MSTORE(expCycloFp12BN254_a23_x) - B :MSTORE(expCycloFp12BN254_a23_y) - :CALL(expCycloFp12BN254) - 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) - 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) - 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) - 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) - 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) - 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) - 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) - 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) - 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) - 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) - 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) - 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) - - ; e(P,Q)²⁴ - 1n :MSTORE(pairingBN254_P_x) - 2n :MSTORE(pairingBN254_P_y) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(pairingBN254_Q_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 24n :MSTORE(expCycloFp12BN254_e) - $ => A :MLOAD(pairingBN254_f11_x) - $ => B :MLOAD(pairingBN254_f11_y) - A :MSTORE(expCycloFp12BN254_a11_x) - B :MSTORE(expCycloFp12BN254_a11_y) - $ => A :MLOAD(pairingBN254_f12_x) - $ => B :MLOAD(pairingBN254_f12_y) - A :MSTORE(expCycloFp12BN254_a12_x) - B :MSTORE(expCycloFp12BN254_a12_y) - $ => A :MLOAD(pairingBN254_f13_x) - $ => B :MLOAD(pairingBN254_f13_y) - A :MSTORE(expCycloFp12BN254_a13_x) - B :MSTORE(expCycloFp12BN254_a13_y) - $ => A :MLOAD(pairingBN254_f21_x) - $ => B :MLOAD(pairingBN254_f21_y) - A :MSTORE(expCycloFp12BN254_a21_x) - B :MSTORE(expCycloFp12BN254_a21_y) - $ => A :MLOAD(pairingBN254_f22_x) - $ => B :MLOAD(pairingBN254_f22_y) - A :MSTORE(expCycloFp12BN254_a22_x) - B :MSTORE(expCycloFp12BN254_a22_y) - $ => A :MLOAD(pairingBN254_f23_x) - $ => B :MLOAD(pairingBN254_f23_y) - A :MSTORE(expCycloFp12BN254_a23_x) - B :MSTORE(expCycloFp12BN254_a23_y) - :CALL(expCycloFp12BN254) - 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) - 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) - 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) - 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) - 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) - 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) - 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) - 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) - 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) - 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) - 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) - 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) - - ; e(12P,2Q) - 17108685722251241369314020928988529881027530433467445791267465866135602972753n :MSTORE(pairingBN254_P_x) - 20666112440056908034039013737427066139426903072479162670940363761207457724060n :MSTORE(pairingBN254_P_y) - 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(pairingBN254_Q_x1) - 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(pairingBN254_Q_x2) - 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(pairingBN254_Q_y1) - 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(pairingBN254_Q_y2) - :CALL(pairingBN254) - 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) - 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) - 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) - 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) - 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) - 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) - 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) - 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) - 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) - 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) - 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) - 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + ; Generators P,Q + + ; 1] Degenerate tests: e(0,Q) = e(P,0) = e(0,0) = 1 + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 1n :MLOAD(pairingBN254_f11_x) + 0n :MLOAD(pairingBN254_f11_y) + 0n :MLOAD(pairingBN254_f12_x) + 0n :MLOAD(pairingBN254_f12_y) + 0n :MLOAD(pairingBN254_f13_x) + 0n :MLOAD(pairingBN254_f13_y) + 0n :MLOAD(pairingBN254_f21_x) + 0n :MLOAD(pairingBN254_f21_y) + 0n :MLOAD(pairingBN254_f22_x) + 0n :MLOAD(pairingBN254_f22_y) + 0n :MLOAD(pairingBN254_f23_x) + 0n :MLOAD(pairingBN254_f23_y) + + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) + 0n :MSTORE(pairingBN254_Q_x1) + 0n :MSTORE(pairingBN254_Q_x2) + 0n :MSTORE(pairingBN254_Q_y1) + 0n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 1n :MLOAD(pairingBN254_f11_x) + 0n :MLOAD(pairingBN254_f11_y) + 0n :MLOAD(pairingBN254_f12_x) + 0n :MLOAD(pairingBN254_f12_y) + 0n :MLOAD(pairingBN254_f13_x) + 0n :MLOAD(pairingBN254_f13_y) + 0n :MLOAD(pairingBN254_f21_x) + 0n :MLOAD(pairingBN254_f21_y) + 0n :MLOAD(pairingBN254_f22_x) + 0n :MLOAD(pairingBN254_f22_y) + 0n :MLOAD(pairingBN254_f23_x) + 0n :MLOAD(pairingBN254_f23_y) + + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 0n :MSTORE(pairingBN254_Q_x1) + 0n :MSTORE(pairingBN254_Q_x2) + 0n :MSTORE(pairingBN254_Q_y1) + 0n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 1n :MLOAD(pairingBN254_f11_x) + 0n :MLOAD(pairingBN254_f11_y) + 0n :MLOAD(pairingBN254_f12_x) + 0n :MLOAD(pairingBN254_f12_y) + 0n :MLOAD(pairingBN254_f13_x) + 0n :MLOAD(pairingBN254_f13_y) + 0n :MLOAD(pairingBN254_f21_x) + 0n :MLOAD(pairingBN254_f21_y) + 0n :MLOAD(pairingBN254_f22_x) + 0n :MLOAD(pairingBN254_f22_y) + 0n :MLOAD(pairingBN254_f23_x) + 0n :MLOAD(pairingBN254_f23_y) + + ; 2] P not in range + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 1 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 2 => A + 1 :EQ + + ; 3] Q not in range + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 3 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 4 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y1) + 4n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 5 => A + 1 :EQ + + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 1n :MSTORE(pairingBN254_Q_x1) + 2n :MSTORE(pairingBN254_Q_x2) + 3n :MSTORE(pairingBN254_Q_y1) + 21888242871839275222246405745257275088696311157297823662689037894645226208583n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 6 => A + 1 :EQ + + ; 4] P not in G1 + 1n :MSTORE(pairingBN254_P_x) + 1n :MSTORE(pairingBN254_P_y) + 0n :MSTORE(pairingBN254_Q_x1) + 0n :MSTORE(pairingBN254_Q_x2) + 0n :MSTORE(pairingBN254_Q_y1) + 0n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 7 => A + 1 :EQ + + ; 5] Q not in G2 + 0n :MSTORE(pairingBN254_P_x) + 0n :MSTORE(pairingBN254_P_y) + 13952973379259391431794065814946995996741015657664522404741834284791195202656n :MSTORE(pairingBN254_Q_x1) + 10904417650644905372723866879625669404817699819926286815323845522270190436451n :MSTORE(pairingBN254_Q_x2) + 12292403207927938194042684085166933223459250332097452603928615449631462314854n :MSTORE(pairingBN254_Q_y1) + 3535501093699632689489376651381121898720279562088698464643486166587401099479n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 8 => A + 1 :EQ + + ; 6] Bilinearity test: e(2P,12Q) = e(P,12Q)² = e(2P,Q)¹² = e(P,Q)²⁴ = e(12P,2Q) + ; e(2P,12Q) + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(pairingBN254_f11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(pairingBN254_f11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(pairingBN254_f12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(pairingBN254_f12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(pairingBN254_f13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(pairingBN254_f13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(pairingBN254_f21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(pairingBN254_f21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(pairingBN254_f22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(pairingBN254_f22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(pairingBN254_f23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(pairingBN254_f23_y) + + ; e(P,12Q)² + 1n :MSTORE(pairingBN254_P_x) + 2n :MSTORE(pairingBN254_P_y) + 4351401811647638138392695977895401859084096897123577305203754529537814663109n :MSTORE(pairingBN254_Q_x1) + 2046729899889901964437012741252570163462327955511008570480857952505584629957n :MSTORE(pairingBN254_Q_x2) + 322506915963699862059245473966830598387691259163658767351233132602858049743n :MSTORE(pairingBN254_Q_y1) + 14316075702276096164483565793667862351398527813470041574939773541551376891710n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 2n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + + ; e(2P,Q)¹² + 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MSTORE(pairingBN254_P_x) + 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MSTORE(pairingBN254_P_y) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(pairingBN254_Q_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 12n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + + ; e(P,Q)²⁴ + 1n :MSTORE(pairingBN254_P_x) + 2n :MSTORE(pairingBN254_P_y) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(pairingBN254_Q_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(pairingBN254_Q_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(pairingBN254_Q_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 24n :MSTORE(expCycloFp12BN254_e) + $ => A :MLOAD(pairingBN254_f11_x) + $ => B :MLOAD(pairingBN254_f11_y) + A :MSTORE(expCycloFp12BN254_a11_x) + B :MSTORE(expCycloFp12BN254_a11_y) + $ => A :MLOAD(pairingBN254_f12_x) + $ => B :MLOAD(pairingBN254_f12_y) + A :MSTORE(expCycloFp12BN254_a12_x) + B :MSTORE(expCycloFp12BN254_a12_y) + $ => A :MLOAD(pairingBN254_f13_x) + $ => B :MLOAD(pairingBN254_f13_y) + A :MSTORE(expCycloFp12BN254_a13_x) + B :MSTORE(expCycloFp12BN254_a13_y) + $ => A :MLOAD(pairingBN254_f21_x) + $ => B :MLOAD(pairingBN254_f21_y) + A :MSTORE(expCycloFp12BN254_a21_x) + B :MSTORE(expCycloFp12BN254_a21_y) + $ => A :MLOAD(pairingBN254_f22_x) + $ => B :MLOAD(pairingBN254_f22_y) + A :MSTORE(expCycloFp12BN254_a22_x) + B :MSTORE(expCycloFp12BN254_a22_y) + $ => A :MLOAD(pairingBN254_f23_x) + $ => B :MLOAD(pairingBN254_f23_y) + A :MSTORE(expCycloFp12BN254_a23_x) + B :MSTORE(expCycloFp12BN254_a23_y) + :CALL(expCycloFp12BN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + + ; e(12P,2Q) + 17108685722251241369314020928988529881027530433467445791267465866135602972753n :MSTORE(pairingBN254_P_x) + 20666112440056908034039013737427066139426903072479162670940363761207457724060n :MSTORE(pairingBN254_P_y) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(pairingBN254_Q_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(pairingBN254_Q_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(pairingBN254_Q_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(pairingBN254_Q_y2) + :CALL(pairingBN254) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) end: From cca8f6663ccdf1b2b41589b5d39c5587ab01aeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 13 Dec 2023 15:32:35 +0100 Subject: [PATCH 063/121] array_div_mod renamed to array_div for correctness --- main/modexp/array_lib/array_div.zkasm | 235 +++++++++ ...iv_mod_long.zkasm => array_div_long.zkasm} | 190 +++---- main/modexp/array_lib/array_div_mod.zkasm | 235 --------- ..._mod_short.zkasm => array_div_short.zkasm} | 144 +++--- main/modexp/modexp.zkasm | 106 ++-- main/precompiled/pre-modexp.zkasm | 6 +- test/testArrayArith.zkasm | 462 +++++++++--------- test/testModExp.zkasm | 6 +- tools/modexp-utils/README.md | 2 +- tools/modexp-utils/modexp-test-gen.js | 14 +- 10 files changed, 700 insertions(+), 700 deletions(-) create mode 100644 main/modexp/array_lib/array_div.zkasm rename main/modexp/array_lib/{array_div_mod_long.zkasm => array_div_long.zkasm} (53%) delete mode 100644 main/modexp/array_lib/array_div_mod.zkasm rename main/modexp/array_lib/{array_div_mod_short.zkasm => array_div_short.zkasm} (54%) diff --git a/main/modexp/array_lib/array_div.zkasm b/main/modexp/array_lib/array_div.zkasm new file mode 100644 index 00000000..2bada0d5 --- /dev/null +++ b/main/modexp/array_lib/array_div.zkasm @@ -0,0 +1,235 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: The input arrays have been trimmed; +;; POST: The quotient and remainder are trimmed. +;; +;; array_div: +;; in: +;; · C ∈ [1, 32], the len of inA +;; · D ∈ [1, 32], the len of inB +;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array +;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array +;; +;; output: +;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; function array_div(a: bigint[], b: bigint[], B: bigint): bigint[] { +; if (a === [0n]) { +; if (b === [0n]) { +; throw new Error("Division by zero"); +; } +; return [0n, 0n]; +; } else if (b === [0n]) { +; throw new Error("Division by zero"); +; } +; +; if (a === b) { +; return [1n, 0n]; +; } else if (a < b) { +; return [0n, a]; +; } +; +; if (b.length === 1) { +; return array_div_short(a, b, B); +; } +; return array_div_long(a, b, B); +; } + +VAR GLOBAL array_div_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_quo[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_rem[%ARRAY_MAX_LEN] + +VAR GLOBAL array_div_len_inA +VAR GLOBAL array_div_len_inB +VAR GLOBAL array_div_len_quo +VAR GLOBAL array_div_len_rem + +VAR GLOBAL array_div_RR + +; ERROR CODES (B) +; 0 - no error +; 1 - inB is zero + +array_div: + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + + RR :MSTORE(array_div_RR) + C :MSTORE(array_div_len_inA) + D :MSTORE(array_div_len_inB) + + ; Let's cover the edge cases + ; 1] Is C == 1 and inA == 0? + C => A + 1 => B + $ :EQ, JMPNC(array_div_inA_continue) + 0 => B + $ => A :MLOAD(array_div_inA) + $ :EQ, JMPC(array_div_inA_is_zero) + array_div_inA_continue: + + ; 2] Is D == 1 and inB == 0? + D => A + 1 => B + $ :EQ, JMPNC(array_div_inB_continue1) + 0 => B + $ => A :MLOAD(array_div_inB) + $ :EQ, JMPC(array_div_inB_is_zero) + array_div_inB_continue1: + + ; 3] Check if inA = inB or inA < inB + C => RR + D => E +array_div_compare_inA: + RR - 1 => RR + $ => A :MLOAD(array_div_inA + RR) + A :MSTORE(array_compare_inA + RR) + RR :JMPZ(array_div_compare_inB, array_div_compare_inA) + +array_div_compare_inB: + E - 1 => E + $ => A :MLOAD(array_div_inB + E) + A :MSTORE(array_compare_inB + E) + E :JMPZ(array_div_compare, array_div_compare_inB) + +array_div_compare: + :CALL(array_compare) + + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + + $ => A :MLOAD(array_compare_result), JMPZ(array_div_prep_inALTinB) + 1 => B + $ :EQ, JMPC(array_div_same_input) + ; From here, inA > inB + + C => RR + D => A,E + 1 => B + $ :EQ, JMPC(array_div_inA_to_div_short, array_div_inA_to_div_long); worst case is div long + +; Begin of edge cases +array_div_inA_is_zero: + ;Is D == 1 and inB == 0? 0/0 is undefined + D => A + 1 => B + $ :EQ, JMPNC(array_div_inB_continue2) + 0 => B + $ => A :MLOAD(array_div_inB) + $ :EQ, JMPC(array_div_inB_is_zero) + array_div_inB_continue2: + ; From here, inB != 0 + + ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 + 0 :MSTORE(array_div_quo) + 0 :MSTORE(array_div_rem) + 1 :MSTORE(array_div_len_quo) + 1 :MSTORE(array_div_len_rem) + 0 => B :JMP(array_div_end) + +array_div_inB_is_zero: + ; Error, you cannot divide by 0 + 1 => B :JMP(array_div_end) + +array_div_same_input: + 1 :MSTORE(array_div_quo) + 0 :MSTORE(array_div_rem) + 1 :MSTORE(array_div_len_quo) + 1 :MSTORE(array_div_len_rem) + 0 => B :JMP(array_div_end) + +array_div_prep_inALTinB: + C :MSTORE(array_div_len_rem) + 1 :MSTORE(array_div_len_quo) + + %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) + + 0 => RR + +array_div_inALTinB: + $ => A :MLOAD(array_div_inA + RR) + A :MSTORE(array_div_rem + RR) + RR + 1 => RR + C - 1 => C :JMPNZ(array_div_inALTinB) + +array_div_inALTinB_before_end: + 0 :MSTORE(array_div_quo) + 0 => B :JMP(array_div_end) +; End of edge cases + +; Long +array_div_inA_to_div_long: + RR - 1 => RR + $ => A :MLOAD(array_div_inA + RR) + A :MSTORE(array_div_long_inA + RR) + RR :JMPZ(array_div_inB_to_div_long, array_div_inA_to_div_long) + +array_div_inB_to_div_long: + E - 1 => E + $ => A :MLOAD(array_div_inB + E) + A :MSTORE(array_div_long_inB + E) + E :JMPZ(array_div_compute_long, array_div_inB_to_div_long) + +array_div_compute_long: + :CALL(array_div_long) + + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_long_len_quo) + $ => D :MLOAD(array_div_long_len_rem) + C :MSTORE(array_div_len_quo) + D :MSTORE(array_div_len_rem) + C => RR + D => E + + %MAX_CNT_STEPS - STEP - 4*C - 4*D - 2 :JMPN(outOfCountersStep) + +array_div_assign_long_quo: + RR - 1 => RR + $ => A :MLOAD(array_div_long_quo + RR) + A :MSTORE(array_div_quo + RR) + RR :JMPZ(array_div_assign_long_rem, array_div_assign_long_quo) + +array_div_assign_long_rem: + E - 1 => E + $ => A :MLOAD(array_div_long_rem + E) + A :MSTORE(array_div_rem + E) + E :JMPZ(array_div_end, array_div_assign_long_rem) + +; Short +array_div_inA_to_div_short: + RR - 1 => RR + $ => A :MLOAD(array_div_inA + RR) + A :MSTORE(array_div_short_inA + RR) + RR :JMPZ(array_div_inB_to_div_short, array_div_inA_to_div_short) + +array_div_inB_to_div_short: + $ => A :MLOAD(array_div_inB) + A :MSTORE(array_div_short_inB) + +array_div_compute_short: + :CALL(array_div_short) + + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) + + $ => C :MLOAD(array_div_short_len_quo) + C :MSTORE(array_div_len_quo) + 1 :MSTORE(array_div_len_rem) + C => RR + + %MAX_CNT_STEPS - STEP - 4*C - 4 :JMPN(outOfCountersStep) + +array_div_assign_short_quo: + RR - 1 => RR + $ => A :MLOAD(array_div_short_quo + RR) + A :MSTORE(array_div_quo + RR) + RR :JMPZ(array_div_assign_short_rem, array_div_assign_short_quo) + +array_div_assign_short_rem: + $ => A :MLOAD(array_div_short_rem) + A :MSTORE(array_div_rem) + +array_div_end: + $ => RR :MLOAD(array_div_RR) + :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_div_mod_long.zkasm b/main/modexp/array_lib/array_div_long.zkasm similarity index 53% rename from main/modexp/array_lib/array_div_mod_long.zkasm rename to main/modexp/array_lib/array_div_long.zkasm index ac0e98f6..c9792a7d 100644 --- a/main/modexp/array_lib/array_div_mod_long.zkasm +++ b/main/modexp/array_lib/array_div_long.zkasm @@ -2,7 +2,7 @@ ;; PRE: The input arrays have been trimmed. ;; POST: The quotient and remainder are trimmed. ;; -;; array_div_mod_long: +;; array_div_long: ;; in: ;; · C ∈ [1, 32], the len of inA ;; · D ∈ [1, 32], the len of inB @@ -13,7 +13,7 @@ ;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_div_mod_long(a: bigint[], b: bigint[], B: bigint): bigint[] { +; function array_div_long(a: bigint[], b: bigint[], B: bigint): bigint[] { ; if (a === [0n]) { ; if (b === [0n]) { ; throw new Error("Division by zero"); @@ -33,129 +33,129 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_long_inA[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_long_inB[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_long_quo[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_long_rem[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_long_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_long_inB[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_long_quo[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_long_rem[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_long_len_inA -VAR GLOBAL array_div_mod_long_len_inB -VAR GLOBAL array_div_mod_long_len_quo -VAR GLOBAL array_div_mod_long_len_rem +VAR GLOBAL array_div_long_len_inA +VAR GLOBAL array_div_long_len_inB +VAR GLOBAL array_div_long_len_quo +VAR GLOBAL array_div_long_len_rem -VAR GLOBAL array_div_mod_long_RR +VAR GLOBAL array_div_long_RR ; ERROR CODES (B) ; 0 - no error ; 1 - inB is zero -array_div_mod_long: +array_div_long: %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) - RR :MSTORE(array_div_mod_long_RR) - C :MSTORE(array_div_mod_long_len_inA) - D :MSTORE(array_div_mod_long_len_inB) + RR :MSTORE(array_div_long_RR) + C :MSTORE(array_div_long_len_inA) + D :MSTORE(array_div_long_len_inB) ; Let's cover the edge cases ; 1] Is C == 1 and inA == 0? C => A 1 => B - $ :EQ, JMPNC(array_div_mod_long_inA_continue) + $ :EQ, JMPNC(array_div_long_inA_continue) 0 => B - $ => A :MLOAD(array_div_mod_long_inA) - $ :EQ, JMPC(array_div_mod_long_inA_is_zero) - array_div_mod_long_inA_continue: + $ => A :MLOAD(array_div_long_inA) + $ :EQ, JMPC(array_div_long_inA_is_zero) + array_div_long_inA_continue: ; 2] Is D == 1 and inB == 0? D => A 1 => B - $ :EQ, JMPNC(array_div_mod_long_inB_continue1) + $ :EQ, JMPNC(array_div_long_inB_continue1) 0 => B - $ => A :MLOAD(array_div_mod_long_inB) - $ :EQ, JMPC(array_div_mod_long_inB_is_zero) - array_div_mod_long_inB_continue1: + $ => A :MLOAD(array_div_long_inB) + $ :EQ, JMPC(array_div_long_inB_is_zero) + array_div_long_inB_continue1: ; 3] Check if inA = inB or inA < inB C => RR D => E -array_div_mod_long_compare_inA1: +array_div_long_compare_inA1: RR - 1 => RR - $ => A :MLOAD(array_div_mod_long_inA + RR) + $ => A :MLOAD(array_div_long_inA + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_mod_long_compare_inB1, array_div_mod_long_compare_inA1) + RR :JMPZ(array_div_long_compare_inB1, array_div_long_compare_inA1) -array_div_mod_long_compare_inB1: +array_div_long_compare_inB1: E - 1 => E - $ => A :MLOAD(array_div_mod_long_inB + E) + $ => A :MLOAD(array_div_long_inB + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_mod_long_compare1, array_div_mod_long_compare_inB1) + E :JMPZ(array_div_long_compare1, array_div_long_compare_inB1) -array_div_mod_long_compare1: +array_div_long_compare1: :CALL(array_compare) %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) - $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_long_prep_inALTinB) + $ => A :MLOAD(array_compare_result), JMPZ(array_div_long_prep_inALTinB) 1 => B - $ :EQ, JMPC(array_div_mod_long_same_input) + $ :EQ, JMPC(array_div_long_same_input) ; From here, inA > inB - $${MPdiv(addr.array_div_mod_long_inA,mem.array_div_mod_long_len_inA,addr.array_div_mod_long_inB,mem.array_div_mod_long_len_inB)} + $${MPdiv(addr.array_div_long_inA,mem.array_div_long_len_inA,addr.array_div_long_inB,mem.array_div_long_len_inB)} - :JMP(array_div_mod_long_prepare_mul_quo_inB) + :JMP(array_div_long_prepare_mul_quo_inB) ; Begin of edge cases -array_div_mod_long_inA_is_zero: +array_div_long_inA_is_zero: ; Is D == 1 and inB == 0? 0/0 is undefined D => A 1 => B - $ :EQ, JMPNC(array_div_mod_long_inB_continue2) + $ :EQ, JMPNC(array_div_long_inB_continue2) 0 => B - $ => A :MLOAD(array_div_mod_long_inB) - $ :EQ, JMPC(array_div_mod_long_inB_is_zero) - array_div_mod_long_inB_continue2: + $ => A :MLOAD(array_div_long_inB) + $ :EQ, JMPC(array_div_long_inB_is_zero) + array_div_long_inB_continue2: ; From here, inB != 0 ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 - 0 :MSTORE(array_div_mod_long_quo) - 0 :MSTORE(array_div_mod_long_rem) - 1 :MSTORE(array_div_mod_long_len_quo) - 1 :MSTORE(array_div_mod_long_len_rem) - 0 => B :JMP(array_div_mod_long_end) + 0 :MSTORE(array_div_long_quo) + 0 :MSTORE(array_div_long_rem) + 1 :MSTORE(array_div_long_len_quo) + 1 :MSTORE(array_div_long_len_rem) + 0 => B :JMP(array_div_long_end) -array_div_mod_long_inB_is_zero: +array_div_long_inB_is_zero: ; Error, you cannot divide by 0 - 1 => B :JMP(array_div_mod_long_end) + 1 => B :JMP(array_div_long_end) -array_div_mod_long_same_input: - 1 :MSTORE(array_div_mod_long_quo) - 0 :MSTORE(array_div_mod_long_rem) - 1 :MSTORE(array_div_mod_long_len_quo) - 1 :MSTORE(array_div_mod_long_len_rem) - 0 => B :JMP(array_div_mod_long_end) +array_div_long_same_input: + 1 :MSTORE(array_div_long_quo) + 0 :MSTORE(array_div_long_rem) + 1 :MSTORE(array_div_long_len_quo) + 1 :MSTORE(array_div_long_len_rem) + 0 => B :JMP(array_div_long_end) -array_div_mod_long_prep_inALTinB: - C :MSTORE(array_div_mod_long_len_rem) - 1 :MSTORE(array_div_mod_long_len_quo) +array_div_long_prep_inALTinB: + C :MSTORE(array_div_long_len_rem) + 1 :MSTORE(array_div_long_len_quo) %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) 0 => RR -array_div_mod_long_inALTinB: - $ => A :MLOAD(array_div_mod_long_inA + RR) - A :MSTORE(array_div_mod_long_rem + RR) +array_div_long_inALTinB: + $ => A :MLOAD(array_div_long_inA + RR) + A :MSTORE(array_div_long_rem + RR) RR + 1 => RR - C - 1 => C :JMPNZ(array_div_mod_long_inALTinB) + C - 1 => C :JMPNZ(array_div_long_inALTinB) -array_div_mod_long_inALTinB_before_end: - 0 :MSTORE(array_div_mod_long_quo) - 0 => B :JMP(array_div_mod_long_end) +array_div_long_inALTinB_before_end: + 0 :MSTORE(array_div_long_quo) + 0 => B :JMP(array_div_long_end) ; End of edge cases -array_div_mod_long_prepare_mul_quo_inB: +array_div_long_prepare_mul_quo_inB: $0{receiveLenQuotient()} => C ; The received length must be between 1 and %ARRAY_MAX_LEN @@ -170,27 +170,27 @@ array_div_mod_long_prepare_mul_quo_inB: 0 :EQ ; From here, the quotient is trimmed - C :MSTORE(array_div_mod_long_len_quo) - $ => D :MLOAD(array_div_mod_long_len_inB) + C :MSTORE(array_div_long_len_quo) + $ => D :MLOAD(array_div_long_len_inB) C => RR D => E %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4*D - 1 :JMPN(outOfCountersStep) -array_div_mod_long_quo_to_mul: +array_div_long_quo_to_mul: RR - 1 => RR ${receiveQuotientChunk(RR)} => A - A :MSTORE(array_div_mod_long_quo + RR) + A :MSTORE(array_div_long_quo + RR) A :MSTORE(array_mul_inA + RR) - RR :JMPZ(array_div_mod_long_inB_to_mul, array_div_mod_long_quo_to_mul) + RR :JMPZ(array_div_long_inB_to_mul, array_div_long_quo_to_mul) -array_div_mod_long_inB_to_mul: +array_div_long_inB_to_mul: E - 1 => E - $ => A :MLOAD(array_div_mod_long_inB + E) + $ => A :MLOAD(array_div_long_inB + E) A :MSTORE(array_mul_inB + E) - E :JMPZ(array_div_mod_long_mul_quo_inB, array_div_mod_long_inB_to_mul) + E :JMPZ(array_div_long_mul_quo_inB, array_div_long_inB_to_mul) -array_div_mod_long_mul_quo_inB: +array_div_long_mul_quo_inB: :CALL(array_mul) %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) @@ -212,32 +212,32 @@ array_div_mod_long_mul_quo_inB: ; From here, the remainder is trimmed ; 3] Finally, we must ensure that the remainder is lower than inB - $ => C :MLOAD(array_div_mod_long_len_inB) + $ => C :MLOAD(array_div_long_len_inB) C => RR D => E %MAX_CNT_STEPS - STEP - 4*C - 4*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) -array_div_mod_long_compare_inB2: +array_div_long_compare_inB2: RR - 1 => RR - $ => A :MLOAD(array_div_mod_inB + RR) + $ => A :MLOAD(array_div_inB + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_mod_long_compare_rem, array_div_mod_long_compare_inB2) + RR :JMPZ(array_div_long_compare_rem, array_div_long_compare_inB2) -array_div_mod_long_compare_rem: +array_div_long_compare_rem: E - 1 => E ${receiveRemainderChunk(E)} => A A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_mod_long_compare2, array_div_mod_long_compare_rem) + E :JMPZ(array_div_long_compare2, array_div_long_compare_rem) -array_div_mod_long_compare2: +array_div_long_compare2: :CALL(array_compare) %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) 2 :MLOAD(array_compare_result) - D :MSTORE(array_div_mod_long_len_rem) + D :MSTORE(array_div_long_len_rem) ; prepare output and remainder to be added $ => C :MLOAD(array_mul_len_out) @@ -246,45 +246,45 @@ array_div_mod_long_compare2: %MAX_CNT_STEPS - STEP - 4*C - 5*D - 1 :JMPN(outOfCountersStep) -array_div_mod_long_res_to_add: +array_div_long_res_to_add: RR - 1 => RR $ => A :MLOAD(array_mul_out + RR) A :MSTORE(array_add_AGTB_inA + RR) - RR :JMPZ(array_div_mod_long_rem_to_add, array_div_mod_long_res_to_add) + RR :JMPZ(array_div_long_rem_to_add, array_div_long_res_to_add) -array_div_mod_long_rem_to_add: +array_div_long_rem_to_add: E - 1 => E ${receiveRemainderChunk(E)} => A - A :MSTORE(array_div_mod_long_rem + E) + A :MSTORE(array_div_long_rem + E) A :MSTORE(array_add_AGTB_inB + E) - E :JMPZ(array_div_mod_long_add_res_rem, array_div_mod_long_rem_to_add) + E :JMPZ(array_div_long_add_res_rem, array_div_long_rem_to_add) -array_div_mod_long_add_res_rem: +array_div_long_add_res_rem: :CALL(array_add_AGTB) %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) ; prepare next $ => C :MLOAD(array_add_AGTB_len_out) - $ => D :MLOAD(array_div_mod_long_len_inA) + $ => D :MLOAD(array_div_long_len_inA) C => RR D => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) -array_div_mod_long_compare_inA2: +array_div_long_compare_inA2: RR - 1 => RR $ => A :MLOAD(array_add_AGTB_out + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_mod_long_compare_inB3, array_div_mod_long_compare_inA2) + RR :JMPZ(array_div_long_compare_inB3, array_div_long_compare_inA2) -array_div_mod_long_compare_inB3: +array_div_long_compare_inB3: E - 1 => E - $ => A :MLOAD(array_div_mod_long_inA + E) + $ => A :MLOAD(array_div_long_inA + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_mod_long_compare3, array_div_mod_long_compare_inB3) + E :JMPZ(array_div_long_compare3, array_div_long_compare_inB3) -array_div_mod_long_compare3: +array_div_long_compare3: :CALL(array_compare) %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) @@ -292,6 +292,6 @@ array_div_mod_long_compare3: 1 :MLOAD(array_compare_result) 0 => B ; everything worked fine -array_div_mod_long_end: - $ => RR :MLOAD(array_div_mod_long_RR) +array_div_long_end: + $ => RR :MLOAD(array_div_long_RR) :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_div_mod.zkasm b/main/modexp/array_lib/array_div_mod.zkasm deleted file mode 100644 index 05b74585..00000000 --- a/main/modexp/array_lib/array_div_mod.zkasm +++ /dev/null @@ -1,235 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; PRE: The input arrays have been trimmed; -;; POST: The quotient and remainder are trimmed. -;; -;; array_div_mod: -;; in: -;; · C ∈ [1, 32], the len of inA -;; · D ∈ [1, 32], the len of inB -;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array -;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array -;; -;; output: -;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; function array_div_mod(a: bigint[], b: bigint[], B: bigint): bigint[] { -; if (a === [0n]) { -; if (b === [0n]) { -; throw new Error("Division by zero"); -; } -; return [0n, 0n]; -; } else if (b === [0n]) { -; throw new Error("Division by zero"); -; } -; -; if (a === b) { -; return [1n, 0n]; -; } else if (a < b) { -; return [0n, a]; -; } -; -; if (b.length === 1) { -; return array_div_mod_short(a, b, B); -; } -; return array_div_mod_long(a, b, B); -; } - -VAR GLOBAL array_div_mod_inA[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_inB[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_quo[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_rem[%ARRAY_MAX_LEN] - -VAR GLOBAL array_div_mod_len_inA -VAR GLOBAL array_div_mod_len_inB -VAR GLOBAL array_div_mod_len_quo -VAR GLOBAL array_div_mod_len_rem - -VAR GLOBAL array_div_mod_RR - -; ERROR CODES (B) -; 0 - no error -; 1 - inB is zero - -array_div_mod: - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) - - RR :MSTORE(array_div_mod_RR) - C :MSTORE(array_div_mod_len_inA) - D :MSTORE(array_div_mod_len_inB) - - ; Let's cover the edge cases - ; 1] Is C == 1 and inA == 0? - C => A - 1 => B - $ :EQ, JMPNC(array_div_mod_inA_continue) - 0 => B - $ => A :MLOAD(array_div_mod_inA) - $ :EQ, JMPC(array_div_mod_inA_is_zero) - array_div_mod_inA_continue: - - ; 2] Is D == 1 and inB == 0? - D => A - 1 => B - $ :EQ, JMPNC(array_div_mod_inB_continue1) - 0 => B - $ => A :MLOAD(array_div_mod_inB) - $ :EQ, JMPC(array_div_mod_inB_is_zero) - array_div_mod_inB_continue1: - - ; 3] Check if inA = inB or inA < inB - C => RR - D => E -array_div_mod_compare_inA: - RR - 1 => RR - $ => A :MLOAD(array_div_mod_inA + RR) - A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_mod_compare_inB, array_div_mod_compare_inA) - -array_div_mod_compare_inB: - E - 1 => E - $ => A :MLOAD(array_div_mod_inB + E) - A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_mod_compare, array_div_mod_compare_inB) - -array_div_mod_compare: - :CALL(array_compare) - - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) - - $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_prep_inALTinB) - 1 => B - $ :EQ, JMPC(array_div_mod_same_input) - ; From here, inA > inB - - C => RR - D => A,E - 1 => B - $ :EQ, JMPC(array_div_mod_inA_to_div_mod_short, array_div_mod_inA_to_div_mod_long); worst case is mod long - -; Begin of edge cases -array_div_mod_inA_is_zero: - ;Is D == 1 and inB == 0? 0/0 is undefined - D => A - 1 => B - $ :EQ, JMPNC(array_div_mod_inB_continue2) - 0 => B - $ => A :MLOAD(array_div_mod_inB) - $ :EQ, JMPC(array_div_mod_inB_is_zero) - array_div_mod_inB_continue2: - ; From here, inB != 0 - - ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 - 0 :MSTORE(array_div_mod_quo) - 0 :MSTORE(array_div_mod_rem) - 1 :MSTORE(array_div_mod_len_quo) - 1 :MSTORE(array_div_mod_len_rem) - 0 => B :JMP(array_div_mod_end) - -array_div_mod_inB_is_zero: - ; Error, you cannot divide by 0 - 1 => B :JMP(array_div_mod_end) - -array_div_mod_same_input: - 1 :MSTORE(array_div_mod_quo) - 0 :MSTORE(array_div_mod_rem) - 1 :MSTORE(array_div_mod_len_quo) - 1 :MSTORE(array_div_mod_len_rem) - 0 => B :JMP(array_div_mod_end) - -array_div_mod_prep_inALTinB: - C :MSTORE(array_div_mod_len_rem) - 1 :MSTORE(array_div_mod_len_quo) - - %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) - - 0 => RR - -array_div_mod_inALTinB: - $ => A :MLOAD(array_div_mod_inA + RR) - A :MSTORE(array_div_mod_rem + RR) - RR + 1 => RR - C - 1 => C :JMPNZ(array_div_mod_inALTinB) - -array_div_mod_inALTinB_before_end: - 0 :MSTORE(array_div_mod_quo) - 0 => B :JMP(array_div_mod_end) -; End of edge cases - -; Long -array_div_mod_inA_to_div_mod_long: - RR - 1 => RR - $ => A :MLOAD(array_div_mod_inA + RR) - A :MSTORE(array_div_mod_long_inA + RR) - RR :JMPZ(array_div_mod_inB_to_div_mod_long, array_div_mod_inA_to_div_mod_long) - -array_div_mod_inB_to_div_mod_long: - E - 1 => E - $ => A :MLOAD(array_div_mod_inB + E) - A :MSTORE(array_div_mod_long_inB + E) - E :JMPZ(array_div_mod_compute_long, array_div_mod_inB_to_div_mod_long) - -array_div_mod_compute_long: - :CALL(array_div_mod_long) - - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) - - $ => C :MLOAD(array_div_mod_long_len_quo) - $ => D :MLOAD(array_div_mod_long_len_rem) - C :MSTORE(array_div_mod_len_quo) - D :MSTORE(array_div_mod_len_rem) - C => RR - D => E - - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 2 :JMPN(outOfCountersStep) - -array_div_mod_assign_long_quo: - RR - 1 => RR - $ => A :MLOAD(array_div_mod_long_quo + RR) - A :MSTORE(array_div_mod_quo + RR) - RR :JMPZ(array_div_mod_assign_long_rem, array_div_mod_assign_long_quo) - -array_div_mod_assign_long_rem: - E - 1 => E - $ => A :MLOAD(array_div_mod_long_rem + E) - A :MSTORE(array_div_mod_rem + E) - E :JMPZ(array_div_mod_end, array_div_mod_assign_long_rem) - -; Short -array_div_mod_inA_to_div_mod_short: - RR - 1 => RR - $ => A :MLOAD(array_div_mod_inA + RR) - A :MSTORE(array_div_mod_short_inA + RR) - RR :JMPZ(array_div_mod_inB_to_div_mod_short, array_div_mod_inA_to_div_mod_short) - -array_div_mod_inB_to_div_mod_short: - $ => A :MLOAD(array_div_mod_inB) - A :MSTORE(array_div_mod_short_inB) - -array_div_mod_compute_short: - :CALL(array_div_mod_short) - - %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) - - $ => C :MLOAD(array_div_mod_short_len_quo) - C :MSTORE(array_div_mod_len_quo) - 1 :MSTORE(array_div_mod_len_rem) - C => RR - - %MAX_CNT_STEPS - STEP - 4*C - 4 :JMPN(outOfCountersStep) - -array_div_mod_assign_short_quo: - RR - 1 => RR - $ => A :MLOAD(array_div_mod_short_quo + RR) - A :MSTORE(array_div_mod_quo + RR) - RR :JMPZ(array_div_mod_assign_short_rem, array_div_mod_assign_short_quo) - -array_div_mod_assign_short_rem: - $ => A :MLOAD(array_div_mod_short_rem) - A :MSTORE(array_div_mod_rem) - -array_div_mod_end: - $ => RR :MLOAD(array_div_mod_RR) - :RETURN \ No newline at end of file diff --git a/main/modexp/array_lib/array_div_mod_short.zkasm b/main/modexp/array_lib/array_div_short.zkasm similarity index 54% rename from main/modexp/array_lib/array_div_mod_short.zkasm rename to main/modexp/array_lib/array_div_short.zkasm index f2f37e43..27fe5e63 100644 --- a/main/modexp/array_lib/array_div_mod_short.zkasm +++ b/main/modexp/array_lib/array_div_short.zkasm @@ -2,7 +2,7 @@ ;; PRE: The input arrays have been trimmed. ;; POST: The quotient is trimmed. ;; -;; array_div_mod_short: +;; array_div_short: ;; in: ;; · C ∈ [1, 32], the len of inA ;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array @@ -12,7 +12,7 @@ ;; · [quo,rem] = [inA / inB[0], inA % inB[0]], with len(quo) <= C, len(rem) = 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_div_mod_short(a: bigint[], b: bigint, B: bigint): bigint[] { +; function array_div_short(a: bigint[], b: bigint, B: bigint): bigint[] { ; if (a === [0n]) { ; if (b === 0n) { ; throw new Error("Division by zero"); @@ -32,108 +32,108 @@ ; NOTE: This function receives the actual result from the helper (avoiding the need of computing divisions); ; checks the correctness of the result and returns the result to the caller -VAR GLOBAL array_div_mod_short_inA[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_short_inB -VAR GLOBAL array_div_mod_short_quo[%ARRAY_MAX_LEN] -VAR GLOBAL array_div_mod_short_rem +VAR GLOBAL array_div_short_inA[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_short_inB +VAR GLOBAL array_div_short_quo[%ARRAY_MAX_LEN] +VAR GLOBAL array_div_short_rem -VAR GLOBAL array_div_mod_short_len_inA -VAR GLOBAL array_div_mod_short_len_quo +VAR GLOBAL array_div_short_len_inA +VAR GLOBAL array_div_short_len_quo -VAR GLOBAL array_div_mod_short_RR +VAR GLOBAL array_div_short_RR ; ERROR CODES (B) ; 0 - no error ; 1 - inB is zero -array_div_mod_short: +array_div_short: %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 15 - 4*C - 3 :JMPN(outOfCountersStep) - RR :MSTORE(array_div_mod_short_RR) - C :MSTORE(array_div_mod_short_len_inA) - C :MSTORE(array_div_mod_short_len_quo) + RR :MSTORE(array_div_short_RR) + C :MSTORE(array_div_short_len_inA) + C :MSTORE(array_div_short_len_quo) ; Let's cover the edge cases ; 1] Is inA == 0? C => A 1 => B - $ :EQ, JMPNC(array_div_mod_short_inA_continue) + $ :EQ, JMPNC(array_div_short_inA_continue) 0 => B - $ => A :MLOAD(array_div_mod_short_inA) - $ :EQ, JMPC(array_div_mod_short_inA_is_zero) - array_div_mod_short_inA_continue: + $ => A :MLOAD(array_div_short_inA) + $ :EQ, JMPC(array_div_short_inA_is_zero) + array_div_short_inA_continue: ; 2] Is inB == 0? 0 => B - $ => A :MLOAD(array_div_mod_short_inB) - $ :EQ, JMPC(array_div_mod_short_inB_is_zero) + $ => A :MLOAD(array_div_short_inB) + $ :EQ, JMPC(array_div_short_inB_is_zero) ; Check whether inA = inB or inA < inB C => RR 1 => D -array_div_mod_short_inA_to_compare1: +array_div_short_inA_to_compare1: RR - 1 => RR - $ => A :MLOAD(array_div_mod_short_inA + RR) + $ => A :MLOAD(array_div_short_inA + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_mod_short_inB_to_compare, array_div_mod_short_inA_to_compare1) + RR :JMPZ(array_div_short_inB_to_compare, array_div_short_inA_to_compare1) -array_div_mod_short_inB_to_compare: - $ => A :MLOAD(array_div_mod_short_inB) +array_div_short_inB_to_compare: + $ => A :MLOAD(array_div_short_inB) A :MSTORE(array_compare_inB) -array_div_mod_short_compare_inA_inB: +array_div_short_compare_inA_inB: :CALL(array_compare) %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 18 :JMPN(outOfCountersStep) - $ => A :MLOAD(array_compare_result), JMPZ(array_div_mod_short_inALTinB) + $ => A :MLOAD(array_compare_result), JMPZ(array_div_short_inALTinB) 1 => B - $ :EQ, JMPC(array_div_mod_short_same_input) + $ :EQ, JMPC(array_div_short_same_input) ; From here, it is known that inA > inB ; Strategy: Divide outside and check the result inside - $${MPdiv_short(addr.array_div_mod_short_inA,mem.array_div_mod_short_len_inA,mem.array_div_mod_short_inB)} + $${MPdiv_short(addr.array_div_short_inA,mem.array_div_short_len_inA,mem.array_div_short_inB)} - :JMP(array_div_mod_short_prepare_mul_quo_inB) + :JMP(array_div_short_prepare_mul_quo_inB) ; Begin of edge cases -array_div_mod_short_inA_is_zero: +array_div_short_inA_is_zero: ; Is inB == 0? 0/0 is undefined - $ => A :MLOAD(array_div_mod_short_inB) - $ :EQ, JMPC(array_div_mod_short_inB_is_zero) + $ => A :MLOAD(array_div_short_inB) + $ :EQ, JMPC(array_div_short_inB_is_zero) ; From here, inB != 0 ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 - 0 :MSTORE(array_div_mod_short_quo) - 0 :MSTORE(array_div_mod_short_rem) - 1 :MSTORE(array_div_mod_short_len_quo) - 0 => B :JMP(array_div_mod_short_end) + 0 :MSTORE(array_div_short_quo) + 0 :MSTORE(array_div_short_rem) + 1 :MSTORE(array_div_short_len_quo) + 0 => B :JMP(array_div_short_end) -array_div_mod_short_inB_is_zero: +array_div_short_inB_is_zero: ; Error, you cannot divide by 0 - 1 => B :JMP(array_div_mod_short_end) + 1 => B :JMP(array_div_short_end) -array_div_mod_short_same_input: +array_div_short_same_input: ; If inA = inB, then the result is [1,0] since inA = 1·inB + 0 - 1 :MSTORE(array_div_mod_short_quo) - 1 :MSTORE(array_div_mod_short_len_quo) - 0 :MSTORE(array_div_mod_short_rem) - 0 => B :JMP(array_div_mod_short_end) + 1 :MSTORE(array_div_short_quo) + 1 :MSTORE(array_div_short_len_quo) + 0 :MSTORE(array_div_short_rem) + 0 => B :JMP(array_div_short_end) -array_div_mod_short_inALTinB: +array_div_short_inALTinB: ; If inA < inB, then the result is [0, inA] since inA = 0·inB + inA - 0 :MSTORE(array_div_mod_short_quo) - 1 :MSTORE(array_div_mod_short_len_quo) - $ => A :MLOAD(array_div_mod_short_inA) - A :MSTORE(array_div_mod_short_rem) - 0 => B :JMP(array_div_mod_short_end) + 0 :MSTORE(array_div_short_quo) + 1 :MSTORE(array_div_short_len_quo) + $ => A :MLOAD(array_div_short_inA) + A :MSTORE(array_div_short_rem) + 0 => B :JMP(array_div_short_end) ; End of edge cases -array_div_mod_short_prepare_mul_quo_inB: +array_div_short_prepare_mul_quo_inB: $0{receiveLenQuotient_short()} => C ; The received length must be between 1 and %ARRAY_MAX_LEN @@ -148,23 +148,23 @@ array_div_mod_short_prepare_mul_quo_inB: 0 :EQ ; From here, the quotient is trimmed - C :MSTORE(array_div_mod_short_len_quo) + C :MSTORE(array_div_short_len_quo) C => RR %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4 :JMPN(outOfCountersStep) -array_div_mod_short_quo_to_mul: +array_div_short_quo_to_mul: RR - 1 => RR ${receiveQuotientChunk_short(RR)} => A - A :MSTORE(array_div_mod_short_quo + RR) + A :MSTORE(array_div_short_quo + RR) A :MSTORE(array_mul_short_inA + RR) - RR :JMPZ(array_div_mod_short_inB_to_mul, array_div_mod_short_quo_to_mul) + RR :JMPZ(array_div_short_inB_to_mul, array_div_short_quo_to_mul) -array_div_mod_short_inB_to_mul: - $ => A :MLOAD(array_div_mod_short_inB) +array_div_short_inB_to_mul: + $ => A :MLOAD(array_div_short_inB) A :MSTORE(array_mul_short_inB) -array_div_mod_short_mul_quo_inB: +array_div_short_mul_quo_inB: :CALL(array_mul_short) %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) @@ -176,48 +176,48 @@ array_div_mod_short_mul_quo_inB: %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 4*C - 6 :JMPN(outOfCountersStep) -array_div_mod_short_result_to_add: +array_div_short_result_to_add: RR - 1 => RR $ => A :MLOAD(array_mul_short_out + RR) A :MSTORE(array_add_short_inA + RR) - RR :JMPZ(array_div_mod_short_rem_to_add, array_div_mod_short_result_to_add) + RR :JMPZ(array_div_short_rem_to_add, array_div_short_result_to_add) -array_div_mod_short_rem_to_add: +array_div_short_rem_to_add: ${receiveRemainderChunk_short()} => A ; We must ensure the the remaider is lower than inB - $ => B :MLOAD(array_div_mod_short_inB) + $ => B :MLOAD(array_div_short_inB) 1 :LT - A :MSTORE(array_div_mod_short_rem) + A :MSTORE(array_div_short_rem) A :MSTORE(array_add_short_inB) -array_div_mod_short_add_result_rem: +array_div_short_add_result_rem: :CALL(array_add_short) %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) ; prepare next $ => C :MLOAD(array_add_short_len_out) - $ => D :MLOAD(array_div_mod_short_len_inA) + $ => D :MLOAD(array_div_short_len_inA) C => RR D => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) -array_div_mod_short_result_to_compare: +array_div_short_result_to_compare: RR - 1 => RR $ => A :MLOAD(array_add_short_out + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_mod_short_inA_to_compare2, array_div_mod_short_result_to_compare) + RR :JMPZ(array_div_short_inA_to_compare2, array_div_short_result_to_compare) -array_div_mod_short_inA_to_compare2: +array_div_short_inA_to_compare2: E - 1 => E - $ => A :MLOAD(array_div_mod_short_inA + E) + $ => A :MLOAD(array_div_short_inA + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_mod_short_compare_result_inA, array_div_mod_short_inA_to_compare2) + E :JMPZ(array_div_short_compare_result_inA, array_div_short_inA_to_compare2) -array_div_mod_short_compare_result_inA: +array_div_short_compare_result_inA: :CALL(array_compare) %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) @@ -225,6 +225,6 @@ array_div_mod_short_compare_result_inA: 1 :MLOAD(array_compare_result) 0 => B -array_div_mod_short_end: - $ => RR :MLOAD(array_div_mod_short_RR) +array_div_short_end: + $ => RR :MLOAD(array_div_short_RR) :RETURN \ No newline at end of file diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index cb71c30d..77b50cc1 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -24,26 +24,26 @@ ;; if (array_is_zero(e)) return [1n]; ;; ;; let r = [1n]; -;; let base = array_div_mod(b, mod, B)[1]; +;; let base = array_div(b, mod, B)[1]; ;; while (!array_is_zero(exp)) { ;; if (array_is_zero(base)) return [0n]; ;; if (isOdd(exp)) { -;; r = array_div_mod(array_mul(r, base, B),mod,B)[1]; +;; r = array_div(array_mul(r, base, B),mod,B)[1]; ;; } -;; exp = array_div_mod_short(exp, 2n, B)[0]; -;; base = array_div_mod(array_square(base, B),mod,B)[1]; +;; exp = array_div_short(exp, 2n, B)[0]; +;; base = array_div(array_square(base, B),mod,B)[1]; ;; } ;; return r; ;; }; ;; RESOURCES (assuming a worst case scenario): ;; ------------------------------------------- -;; cost(pre_loop) = 3·cost(isZero) + 2·cost(isOne) + cost(array_div_mod) +;; cost(pre_loop) = 3·cost(isZero) + 2·cost(isOne) + cost(array_div) ;; nIterations = ⌊log₂(E)⌋ + 1 ;; nTimesEIsOdd = HammingWeight(E) (i.e., number of 1s in the binary representation of E) ;; nTimesEIsEven = nIterations - nTimesEIsOdd -;; cost(iteration1) (if E is odd) = cost(isZero) + cost(isOdd) + 2·cost(array_div_mod) + cost(array_mul) + cost(array_div_mod_short) + cost(array_square) -;; cost(iteration2) (if E is even) = cost(isZero) + cost(isOdd) + cost(array_div_mod) + cost(array_div_mod_short) + cost(array_square) +;; cost(iteration1) (if E is odd) = cost(isZero) + cost(isOdd) + 2·cost(array_div) + cost(array_mul) + cost(array_div_short) + cost(array_square) +;; cost(iteration2) (if E is even) = cost(isZero) + cost(isOdd) + cost(array_div) + cost(array_div_short) + cost(array_square) ;; ------------ ;; cost(total) = cost(pre_loop) + nTimesEIsOdd·cost(iteration1) + nTimesEIsEven·cost(iteration2) ;; ------------ @@ -82,34 +82,34 @@ modexp: ; Compute B = B % M ; ------------------- -modexp_B_to_divmod: +modexp_B_to_div: RR - 1 => RR $ => A :MLOAD(modexp_B + RR) - A :MSTORE(array_div_mod_inA + RR) - RR :JMPZ(modexp_M_to_divmod1, modexp_B_to_divmod) + A :MSTORE(array_div_inA + RR) + RR :JMPZ(modexp_M_to_div1, modexp_B_to_div) -modexp_M_to_divmod1: +modexp_M_to_div1: E - 1 => E $ => A :MLOAD(modexp_M + E) - A :MSTORE(array_div_mod_inB + E) - E :JMPZ(modexp_divmod_B_and_M, modexp_M_to_divmod1) + A :MSTORE(array_div_inB + E) + E :JMPZ(modexp_div_B_and_M, modexp_M_to_div1) -modexp_divmod_B_and_M: - :CALL(array_div_mod) +modexp_div_B_and_M: + :CALL(array_div) %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) - $ => C :MLOAD(array_div_mod_len_rem) + $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_Blen) C => RR %MAX_CNT_STEPS - STEP - 4*C :JMPN(outOfCountersStep) -modexp_rem_from_divmod1: +modexp_rem_from_div1: RR - 1 => RR - $ => A :MLOAD(array_div_mod_rem + RR) + $ => A :MLOAD(array_div_rem + RR) A :MSTORE(modexp_B + RR) - RR :JMPZ(modexp_pre_loop, modexp_rem_from_divmod1) + RR :JMPZ(modexp_pre_loop, modexp_rem_from_div1) ; ------------------- ; Begin of edge cases @@ -155,34 +155,34 @@ modexp_mul_long_out_and_B: %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) ; Compute out = (out * B) % M -modexp_out_to_divmod1: +modexp_out_to_div1: RR - 1 => RR $ => A :MLOAD(array_mul_out + RR) - A :MSTORE(array_div_mod_inA + RR) - RR :JMPZ(modexp_M_to_divmod, modexp_out_to_divmod1) + A :MSTORE(array_div_inA + RR) + RR :JMPZ(modexp_M_to_div, modexp_out_to_div1) -modexp_M_to_divmod: +modexp_M_to_div: E - 1 => E $ => A :MLOAD(modexp_M + E) - A :MSTORE(array_div_mod_inB + E) - E :JMPZ(modexp_divmod_out_and_M2, modexp_M_to_divmod) + A :MSTORE(array_div_inB + E) + E :JMPZ(modexp_div_out_and_M2, modexp_M_to_div) -modexp_divmod_out_and_M2: - :CALL(array_div_mod) +modexp_div_out_and_M2: + :CALL(array_div) %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) - $ => C :MLOAD(array_div_mod_len_rem) + $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_outlen) C => RR %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) -modexp_rem_from_divmod2: +modexp_rem_from_div2: RR - 1 => RR - $ => A :MLOAD(array_div_mod_rem + RR) + $ => A :MLOAD(array_div_rem + RR) A :MSTORE(modexp_out + RR) - RR :JMPZ(return_modexp_loop_multiply, modexp_rem_from_divmod2) + RR :JMPZ(return_modexp_loop_multiply, modexp_rem_from_div2) ; ------------------- ; End of branching @@ -220,35 +220,35 @@ modexp_loop: %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) $ => C :MLOAD(modexp_Elen) - 2 :MSTORE(array_div_mod_short_inB) + 2 :MSTORE(array_div_short_inB) C => RR %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) ; Compute E = E // 2 ; ------------------- -modexp_E_to_divmod_short: +modexp_E_to_div_short: RR - 1 => RR $ => A :MLOAD(modexp_E + RR) - A :MSTORE(array_div_mod_short_inA + RR) - RR :JMPZ(modexp_divmod_E_and_2, modexp_E_to_divmod_short) + A :MSTORE(array_div_short_inA + RR) + RR :JMPZ(modexp_div_E_and_2, modexp_E_to_div_short) -modexp_divmod_E_and_2: - :CALL(array_div_mod_short) +modexp_div_E_and_2: + :CALL(array_div_short) %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) - $ => C :MLOAD(array_div_mod_short_len_quo) + $ => C :MLOAD(array_div_short_len_quo) C :MSTORE(modexp_Elen) C => RR %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) -modexp_quo_from_divmod_short: +modexp_quo_from_div_short: RR - 1 => RR - $ => A :MLOAD(array_div_mod_short_quo + RR) + $ => A :MLOAD(array_div_short_quo + RR) A :MSTORE(modexp_E + RR) - RR :JMPZ(modexp_pre_B_square, modexp_quo_from_divmod_short) + RR :JMPZ(modexp_pre_B_square, modexp_quo_from_div_short) ; ------------------- ; Compute B^2 @@ -278,34 +278,34 @@ modexp_square_B: %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) ; Compute B = (B^2) % M -modexp_out_to_divmod2: +modexp_out_to_div2: RR - 1 => RR $ => A :MLOAD(array_square_out + RR) - A :MSTORE(array_div_mod_inA + RR) - RR :JMPZ(modexp_M_to_divmod2, modexp_out_to_divmod2) + A :MSTORE(array_div_inA + RR) + RR :JMPZ(modexp_M_to_div2, modexp_out_to_div2) -modexp_M_to_divmod2: +modexp_M_to_div2: E - 1 => E $ => A :MLOAD(modexp_M + E) - A :MSTORE(array_div_mod_inB + E) - E :JMPZ(modexp_divmod_out_and_M1, modexp_M_to_divmod2) + A :MSTORE(array_div_inB + E) + E :JMPZ(modexp_div_out_and_M1, modexp_M_to_div2) -modexp_divmod_out_and_M1: - :CALL(array_div_mod) +modexp_div_out_and_M1: + :CALL(array_div) %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) - $ => C :MLOAD(array_div_mod_len_rem) + $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_Blen) C => RR %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) -modexp_rem_from_divmod3: +modexp_rem_from_div3: RR - 1 => RR - $ => A :MLOAD(array_div_mod_rem + RR) + $ => A :MLOAD(array_div_rem + RR) A :MSTORE(modexp_B + RR) - RR :JMPZ(modexp_pre_loop, modexp_rem_from_divmod3) + RR :JMPZ(modexp_pre_loop, modexp_rem_from_div3) ; ------------------- modexp_end: diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 887ae1ee..1b92df61 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -25,9 +25,9 @@ INCLUDE "../modexp/array_lib/array_mul_long.zkasm" INCLUDE "../modexp/array_lib/array_mul_short.zkasm" INCLUDE "../modexp/array_lib/array_mul.zkasm" INCLUDE "../modexp/array_lib/array_square.zkasm" -INCLUDE "../modexp/array_lib/array_div_mod_short.zkasm" -INCLUDE "../modexp/array_lib/array_div_mod_long.zkasm" -INCLUDE "../modexp/array_lib/array_div_mod.zkasm" +INCLUDE "../modexp/array_lib/array_div_short.zkasm" +INCLUDE "../modexp/array_lib/array_div_long.zkasm" +INCLUDE "../modexp/array_lib/array_div.zkasm" VAR GLOBAL multiplication_complexity diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index bb780787..5990c953 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -280,429 +280,429 @@ start: ; 1] [9n, 8n, 7n, 6n] / 8n 4 => C 1 => D - 9n :MSTORE(array_div_mod_inA) + 9n :MSTORE(array_div_inA) 1 => E - 8n :MSTORE(array_div_mod_inA + E) + 8n :MSTORE(array_div_inA + E) 2 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_inA + E) 3 => E - 6n :MSTORE(array_div_mod_inA + E) + 6n :MSTORE(array_div_inA + E) - 8n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 1n :MLOAD(array_div_mod_quo) + 8n :MSTORE(array_div_inB) + :CALL(array_div) + 1n :MLOAD(array_div_quo) 1 => E - 101318078082651670995624611882601919371611236582435493534525386006923988434945n :MLOAD(array_div_mod_quo + E) + 101318078082651670995624611882601919371611236582435493534525386006923988434945n :MLOAD(array_div_quo + E) 2 => E - 86844066927987146567678238756515930889952488499230423029593188005934847229952n :MLOAD(array_div_mod_quo + E) - 1n :MLOAD(array_div_mod_rem) - 3 :MLOAD(array_div_mod_len_quo) + 86844066927987146567678238756515930889952488499230423029593188005934847229952n :MLOAD(array_div_quo + E) + 1n :MLOAD(array_div_rem) + 3 :MLOAD(array_div_len_quo) ; 2] [a, 7n, a, 12n, a, 20n, a, 80n] / a 8 => C 1 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA) 1 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA + E) 3 => E - 12n :MSTORE(array_div_mod_inA + E) + 12n :MSTORE(array_div_inA + E) 4 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA + E) 5 => E - 20n :MSTORE(array_div_mod_inA + E) + 20n :MSTORE(array_div_inA + E) 6 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA + E) 7 => E - 80n :MSTORE(array_div_mod_inA + E) + 80n :MSTORE(array_div_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 120n :MLOAD(array_div_mod_quo) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB) + :CALL(array_div) + 120n :MLOAD(array_div_quo) 1 => E - 112n :MLOAD(array_div_mod_quo + E) + 112n :MLOAD(array_div_quo + E) 2 => E - 113n :MLOAD(array_div_mod_quo + E) + 113n :MLOAD(array_div_quo + E) 3 => E - 100n :MLOAD(array_div_mod_quo + E) + 100n :MLOAD(array_div_quo + E) 4 => E - 101n :MLOAD(array_div_mod_quo + E) + 101n :MLOAD(array_div_quo + E) 5 => E - 80n :MLOAD(array_div_mod_quo + E) + 80n :MLOAD(array_div_quo + E) 6 => E - 81n :MLOAD(array_div_mod_quo + E) - 119n :MLOAD(array_div_mod_rem) - 7 :MLOAD(array_div_mod_len_quo) + 81n :MLOAD(array_div_quo + E) + 119n :MLOAD(array_div_rem) + 7 :MLOAD(array_div_len_quo) ; 3] inA == 0, inB != 0, len(inB) == 1 1 => C 1 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_inA) - 8n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) + 8n :MSTORE(array_div_inB) + :CALL(array_div) + 0n :MLOAD(array_div_quo) + 0n :MLOAD(array_div_rem) + 1 :MLOAD(array_div_len_quo) 1 => C 1 => D - 0n :MSTORE(array_div_mod_short_inA) - 8n :MSTORE(array_div_mod_short_inB) - :CALL(array_div_mod_short) - 0n :MLOAD(array_div_mod_short_quo) - 0n :MLOAD(array_div_mod_short_rem) - 1 :MLOAD(array_div_mod_short_len_quo) + 0n :MSTORE(array_div_short_inA) + 8n :MSTORE(array_div_short_inB) + :CALL(array_div_short) + 0n :MLOAD(array_div_short_quo) + 0n :MLOAD(array_div_short_rem) + 1 :MLOAD(array_div_short_len_quo) ; 4] inA == 0, inB != 0, len(inB) > 1 1 => C 2 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_inA) - 8n :MSTORE(array_div_mod_inB) + 8n :MSTORE(array_div_inB) 1 => E - 1n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) + 1n :MSTORE(array_div_inB + E) + :CALL(array_div) + 0n :MLOAD(array_div_quo) + 0n :MLOAD(array_div_rem) 1 => C 2 => D - 0n :MSTORE(array_div_mod_long_inA) - 8n :MSTORE(array_div_mod_long_inB) + 0n :MSTORE(array_div_long_inA) + 8n :MSTORE(array_div_long_inB) 1 => E - 8n :MSTORE(array_div_mod_long_inB + E) - :CALL(array_div_mod_long) - 0n :MLOAD(array_div_mod_long_quo) - 0n :MLOAD(array_div_mod_long_rem) - 1 :MLOAD(array_div_mod_long_len_quo) + 8n :MSTORE(array_div_long_inB + E) + :CALL(array_div_long) + 0n :MLOAD(array_div_long_quo) + 0n :MLOAD(array_div_long_rem) + 1 :MLOAD(array_div_long_len_quo) ; 5] inA != 0, inB == 0 -> error 1 => C 1 => D - 8n :MSTORE(array_div_mod_long_inA) - 0n :MSTORE(array_div_mod_long_inB) - :CALL(array_div_mod_long) + 8n :MSTORE(array_div_long_inA) + 0n :MSTORE(array_div_long_inB) + :CALL(array_div_long) 1 => A B :ASSERT 2 => C 1 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_inA) 1 => E - 30n :MSTORE(array_div_mod_inA + E) + 30n :MSTORE(array_div_inA + E) - 0n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) + 0n :MSTORE(array_div_inB) + :CALL(array_div) 1 => A B :ASSERT ; 6] inA == inB == 0 -> error 1 => C 1 => D - 0n :MSTORE(array_div_mod_long_inA) - 0n :MSTORE(array_div_mod_long_inB) - :CALL(array_div_mod_long) + 0n :MSTORE(array_div_long_inA) + 0n :MSTORE(array_div_long_inB) + :CALL(array_div_long) 1 => A B :ASSERT 1 => C 1 => D - 0n :MSTORE(array_div_mod_short_inA) - 0n :MSTORE(array_div_mod_short_inB) - :CALL(array_div_mod_short) + 0n :MSTORE(array_div_short_inA) + 0n :MSTORE(array_div_short_inB) + :CALL(array_div_short) 1 => A B :ASSERT ; 7] inA == inB 1 => C 1 => D - 10n :MSTORE(array_div_mod_inA) - 10n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 1n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) + 10n :MSTORE(array_div_inA) + 10n :MSTORE(array_div_inB) + :CALL(array_div) + 1n :MLOAD(array_div_quo) + 0n :MLOAD(array_div_rem) + 1 :MLOAD(array_div_len_quo) 2 => C 2 => D - 10n :MSTORE(array_div_mod_inA) + 10n :MSTORE(array_div_inA) 1 => E - 30n :MSTORE(array_div_mod_inA + E) + 30n :MSTORE(array_div_inA + E) - 10n :MSTORE(array_div_mod_inB) + 10n :MSTORE(array_div_inB) 1 => E - 30n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 1n :MLOAD(array_div_mod_quo) - 0n :MLOAD(array_div_mod_rem) + 30n :MSTORE(array_div_inB + E) + :CALL(array_div) + 1n :MLOAD(array_div_quo) + 0n :MLOAD(array_div_rem) 1 => C 1 => D - 10n :MSTORE(array_div_mod_long_inA) - 10n :MSTORE(array_div_mod_long_inB) - :CALL(array_div_mod_long) - 1n :MLOAD(array_div_mod_long_quo) - 0n :MLOAD(array_div_mod_long_rem) - 1 :MLOAD(array_div_mod_long_len_quo) + 10n :MSTORE(array_div_long_inA) + 10n :MSTORE(array_div_long_inB) + :CALL(array_div_long) + 1n :MLOAD(array_div_long_quo) + 0n :MLOAD(array_div_long_rem) + 1 :MLOAD(array_div_long_len_quo) 1 => C 1 => D - 10n :MSTORE(array_div_mod_short_inA) - 10n :MSTORE(array_div_mod_short_inB) - :CALL(array_div_mod_short) - 1n :MLOAD(array_div_mod_short_quo) - 0n :MLOAD(array_div_mod_short_rem) - 1 :MLOAD(array_div_mod_short_len_quo) + 10n :MSTORE(array_div_short_inA) + 10n :MSTORE(array_div_short_inB) + :CALL(array_div_short) + 1n :MLOAD(array_div_short_quo) + 0n :MLOAD(array_div_short_rem) + 1 :MLOAD(array_div_short_len_quo) ; 8] inA < inB 1 => C 1 => D - 10n :MSTORE(array_div_mod_inA) - 11n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 10n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) + 10n :MSTORE(array_div_inA) + 11n :MSTORE(array_div_inB) + :CALL(array_div) + 0n :MLOAD(array_div_quo) + 10n :MLOAD(array_div_rem) + 1 :MLOAD(array_div_len_quo) 2 => C 3 => D - 10n :MSTORE(array_div_mod_inA) + 10n :MSTORE(array_div_inA) 1 => E - 30n :MSTORE(array_div_mod_inA + E) + 30n :MSTORE(array_div_inA + E) - 6n :MSTORE(array_div_mod_inB) + 6n :MSTORE(array_div_inB) 1 => E - 7n :MSTORE(array_div_mod_inB + E) + 7n :MSTORE(array_div_inB + E) 2 => E - 8n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 10n :MLOAD(array_div_mod_rem) + 8n :MSTORE(array_div_inB + E) + :CALL(array_div) + 0n :MLOAD(array_div_quo) + 10n :MLOAD(array_div_rem) 1 => E - 30n :MSTORE(array_div_mod_rem + E) + 30n :MSTORE(array_div_rem + E) 1 => C 1 => D - 10n :MSTORE(array_div_mod_long_inA) - 11n :MSTORE(array_div_mod_long_inB) - :CALL(array_div_mod_long) - 0n :MLOAD(array_div_mod_long_quo) - 10n :MLOAD(array_div_mod_long_rem) - 1 :MLOAD(array_div_mod_long_len_quo) + 10n :MSTORE(array_div_long_inA) + 11n :MSTORE(array_div_long_inB) + :CALL(array_div_long) + 0n :MLOAD(array_div_long_quo) + 10n :MLOAD(array_div_long_rem) + 1 :MLOAD(array_div_long_len_quo) 1 => C 1 => D - 10n :MSTORE(array_div_mod_short_inA) - 11n :MSTORE(array_div_mod_short_inB) - :CALL(array_div_mod_short) - 0n :MLOAD(array_div_mod_short_quo) - 10n :MLOAD(array_div_mod_short_rem) - 1 :MLOAD(array_div_mod_short_len_quo) + 10n :MSTORE(array_div_short_inA) + 11n :MSTORE(array_div_short_inB) + :CALL(array_div_short) + 0n :MLOAD(array_div_short_quo) + 10n :MLOAD(array_div_short_rem) + 1 :MLOAD(array_div_short_len_quo) ; 9] [28948022309329048855892746252171976963317496166410141009864396001978282409984n, 1n] / 2 2 => C 1 => D - 28948022309329048855892746252171976963317496166410141009864396001978282409984n :MSTORE(array_div_mod_inA) + 28948022309329048855892746252171976963317496166410141009864396001978282409984n :MSTORE(array_div_inA) 1 => E - 1n :MSTORE(array_div_mod_inA + E) + 1n :MSTORE(array_div_inA + E) - 2n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MLOAD(array_div_mod_quo) - 1 :MLOAD(array_div_mod_len_quo) + 2n :MSTORE(array_div_inB) + :CALL(array_div) + 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MLOAD(array_div_quo) + 1 :MLOAD(array_div_len_quo) ; 10] [72370055773322622139731865630429942408293740416025352524660990004945706024960n] / 2 1 => C 1 => D - 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MSTORE(array_div_mod_inA) - 2n :MSTORE(array_div_mod_inB) - :CALL(array_div_mod) - 36185027886661311069865932815214971204146870208012676262330495002472853012480n :MLOAD(array_div_mod_quo) - 1 :MLOAD(array_div_mod_len_quo) + 72370055773322622139731865630429942408293740416025352524660990004945706024960n :MSTORE(array_div_inA) + 2n :MSTORE(array_div_inB) + :CALL(array_div) + 36185027886661311069865932815214971204146870208012676262330495002472853012480n :MLOAD(array_div_quo) + 1 :MLOAD(array_div_len_quo) ; 11] len(inB) = len(inA) and inB > inA 4 => C 2 => D - 9n :MSTORE(array_div_mod_inA) + 9n :MSTORE(array_div_inA) 1 => E - 8n :MSTORE(array_div_mod_inA + E) + 8n :MSTORE(array_div_inA + E) 2 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_inA + E) 3 => E - 6n :MSTORE(array_div_mod_inA + E) + 6n :MSTORE(array_div_inA + E) - 8n :MSTORE(array_div_mod_inB) + 8n :MSTORE(array_div_inB) 1 => E - 1n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 335n :MLOAD(array_div_mod_quo) + 1n :MSTORE(array_div_inB + E) + :CALL(array_div) + 335n :MLOAD(array_div_quo) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639895n :MLOAD(array_div_mod_quo + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639895n :MLOAD(array_div_quo + E) 2 => E - 5n :MLOAD(array_div_mod_quo + E) - 115792089237316195423570985008687907853269984665640564039457584007913129637265n :MLOAD(array_div_mod_rem) + 5n :MLOAD(array_div_quo + E) + 115792089237316195423570985008687907853269984665640564039457584007913129637265n :MLOAD(array_div_rem) ; 12] [a, 7n, a, 12n, a, 20n, a, 80n] / [a, a, a, a, 100n] 8 => C 5 => D - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA) 1 => E - 7n :MSTORE(array_div_mod_inA + E) + 7n :MSTORE(array_div_inA + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA + E) 3 => E - 12n :MSTORE(array_div_mod_inA + E) + 12n :MSTORE(array_div_inA + E) 4 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA + E) 5 => E - 20n :MSTORE(array_div_mod_inA + E) + 20n :MSTORE(array_div_inA + E) 6 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inA + E) 7 => E - 80n :MSTORE(array_div_mod_inA + E) + 80n :MSTORE(array_div_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB + E) 2 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB + E) 3 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB + E) 4 => E - 100n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 87130681010257731209815790699606742543054641926620622445532439451498988639951n :MLOAD(array_div_mod_quo) + 100n :MSTORE(array_div_inB + E) + :CALL(array_div) + 87130681010257731209815790699606742543054641926620622445532439451498988639951n :MLOAD(array_div_quo) 1 => E - 76812574048516684092863920748337523031377118540573443471719387411189897879957n :MLOAD(array_div_mod_quo + E) + 76812574048516684092863920748337523031377118540573443471719387411189897879957n :MLOAD(array_div_quo + E) 2 => E - 92862962655669424052566829561422975605097710474424610764317468362781816839948n :MLOAD(array_div_mod_quo + E) - 87130681010257731209815790699606742543054641926620622445532439451498988639950n :MLOAD(array_div_mod_rem) + 92862962655669424052566829561422975605097710474424610764317468362781816839948n :MLOAD(array_div_quo + E) + 87130681010257731209815790699606742543054641926620622445532439451498988639950n :MLOAD(array_div_rem) 1 => E - 76812574048516684092863920748337523031377118540573443471719387411189897879965n :MLOAD(array_div_mod_rem + E) + 76812574048516684092863920748337523031377118540573443471719387411189897879965n :MLOAD(array_div_rem + E) 2 => E - 92862962655669424052566829561422975605097710474424610764317468362781816839947n :MLOAD(array_div_mod_rem + E) + 92862962655669424052566829561422975605097710474424610764317468362781816839947n :MLOAD(array_div_rem + E) 3 => E - 13n :MLOAD(array_div_mod_rem + E) + 13n :MLOAD(array_div_rem + E) 4 => E - 84n :MLOAD(array_div_mod_rem + E) + 84n :MLOAD(array_div_rem + E) ; 13] [82987931714326364316120253427931880709278140571418487333162713377057429160720n,4257238595720679277571917967782652353394431698489248379634099239588181418140n,15209178211456919413336795740141505754388379695813905932093982440742677791802n,88987534839350135473536361176867192550264928852523682165693061442019881855583n,14n], [4n, 6n, 7n] 5 => C 3 => D - 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MSTORE(array_div_mod_inA) + 82987931714326364316120253427931880709278140571418487333162713377057429160720n :MSTORE(array_div_inA) 1 => E - 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MSTORE(array_div_mod_inA + E) + 4257238595720679277571917967782652353394431698489248379634099239588181418140n :MSTORE(array_div_inA + E) 2 => E - 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MSTORE(array_div_mod_inA + E) + 15209178211456919413336795740141505754388379695813905932093982440742677791802n :MSTORE(array_div_inA + E) 3 => E - 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MSTORE(array_div_mod_inA + E) + 88987534839350135473536361176867192550264928852523682165693061442019881855583n :MSTORE(array_div_inA + E) 4 => E - 14n :MSTORE(array_div_mod_inA + E) + 14n :MSTORE(array_div_inA + E) - 4n :MSTORE(array_div_mod_inB) + 4n :MSTORE(array_div_inB) 1 => E - 6n :MSTORE(array_div_mod_inB + E) + 6n :MSTORE(array_div_inB + E) 2 => E - 7n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 90526669110436282262084097418054683975846294708417529350769755852355732618090n :MLOAD(array_div_mod_quo) + 7n :MSTORE(array_div_inB + E) + :CALL(array_div) + 90526669110436282262084097418054683975846294708417529350769755852355732618090n :MLOAD(array_div_quo) 1 => E - 12712504977050019353362337310981027507180704121789097452241865920288554550795n :MLOAD(array_div_mod_quo + E) + 12712504977050019353362337310981027507180704121789097452241865920288554550795n :MLOAD(array_div_quo + E) 2 => E - 2n :MLOAD(array_div_mod_quo + E) - 68257522984529821538496818781776868365702915734670062048456441991373887608168n :MLOAD(array_div_mod_rem) + 2n :MLOAD(array_div_quo + E) + 68257522984529821538496818781776868365702915734670062048456441991373887608168n :MLOAD(array_div_rem) 1 => E - 104999739448800080833043894267657885589213754954671066702793604491778345346033n :MSTORE(array_div_mod_rem + E) + 104999739448800080833043894267657885589213754954671066702793604491778345346033n :MSTORE(array_div_rem + E) 2 => E - 4n :MSTORE(array_div_mod_rem + E) - 3 :MLOAD(array_div_mod_len_quo) - 3 :MLOAD(array_div_mod_len_rem) + 4n :MSTORE(array_div_rem + E) + 3 :MLOAD(array_div_len_quo) + 3 :MLOAD(array_div_len_rem) ; 14] [0n,0n,0n,0n,87552057494100699607633960453116574392480272162273084008350826812719088235449n,29405388739667337424543497575767709934732594998639086405406332616399343873602n,370491411790392985199n], [0n, 0n, 8238129386n, 23102318237n] 7 => C 4 => D - 0n :MSTORE(array_div_mod_inA) + 0n :MSTORE(array_div_inA) 1 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_inA + E) 2 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_inA + E) 3 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_inA + E) 4 => E - 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MSTORE(array_div_mod_inA + E) + 87552057494100699607633960453116574392480272162273084008350826812719088235449n :MSTORE(array_div_inA + E) 5 => E - 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_div_mod_inA + E) + 29405388739667337424543497575767709934732594998639086405406332616399343873602n :MSTORE(array_div_inA + E) 6 => E - 370491411790392985199n :MSTORE(array_div_mod_inA + E) + 370491411790392985199n :MSTORE(array_div_inA + E) - 0n :MSTORE(array_div_mod_inB) + 0n :MSTORE(array_div_inB) 1 => E - 0n :MSTORE(array_div_mod_inB + E) + 0n :MSTORE(array_div_inB + E) 2 => E - 8238129386n :MSTORE(array_div_mod_inB + E) + 8238129386n :MSTORE(array_div_inB + E) 3 => E - 23102318237n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 10624890954144362706283399919870985530330343554129711486796784890935496833177n :MLOAD(array_div_mod_quo) + 23102318237n :MSTORE(array_div_inB + E) + :CALL(array_div) + 10624890954144362706283399919870985530330343554129711486796784890935496833177n :MLOAD(array_div_quo) 1 => E - 12699239907746414269759600684072701206520647567004427767570235373004025148518n :MLOAD(array_div_mod_quo + E) + 12699239907746414269759600684072701206520647567004427767570235373004025148518n :MLOAD(array_div_quo + E) 2 => E - 62973947849727744055941265906651873030488901951864462234513788026171769471385n :MLOAD(array_div_mod_quo + E) + 62973947849727744055941265906651873030488901951864462234513788026171769471385n :MLOAD(array_div_quo + E) 3 => E - 16036979838n :MLOAD(array_div_mod_quo + E) - 0n :MLOAD(array_div_mod_rem) + 16036979838n :MLOAD(array_div_quo + E) + 0n :MLOAD(array_div_rem) 1 => E - 0n :MSTORE(array_div_mod_rem + E) + 0n :MSTORE(array_div_rem + E) 2 => E - 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_div_mod_rem + E) + 43811746908501644357293832343774991028053014234938611947183500936834952782886n :MSTORE(array_div_rem + E) 3 => E - 6019321230n :MSTORE(array_div_mod_rem + E) - 4 :MLOAD(array_div_mod_len_quo) - 4 :MLOAD(array_div_mod_len_rem) + 6019321230n :MSTORE(array_div_rem + E) + 4 :MLOAD(array_div_len_quo) + 4 :MLOAD(array_div_len_rem) ; 15] [7n], [7719472615821079694904732333912527190217998977709370935963838933860875309329n, 17n] 1 => C 2 => D - 7n :MSTORE(array_div_mod_inA) - 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(array_div_mod_inB) + 7n :MSTORE(array_div_inA) + 7719472615821079694904732333912527190217998977709370935963838933860875309329n :MSTORE(array_div_inB) 1 => E - 17n :MSTORE(array_div_mod_inB + E) - :CALL(array_div_mod) - 0n :MLOAD(array_div_mod_quo) - 7n :MLOAD(array_div_mod_rem) - 1 :MLOAD(array_div_mod_len_quo) - 1 :MLOAD(array_div_mod_len_rem) + 17n :MSTORE(array_div_inB + E) + :CALL(array_div) + 0n :MLOAD(array_div_quo) + 7n :MLOAD(array_div_rem) + 1 :MLOAD(array_div_len_quo) + 1 :MLOAD(array_div_len_rem) ; 16] [9,12,16,2,0,2**256-4], [2**256-1,2**256-1] 6 => C 2 => D - 9n :MSTORE(array_div_mod_inA) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB) + 9n :MSTORE(array_div_inA) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB) 1 => E - 12n :MSTORE(array_div_mod_inA + E) - 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E) + 12n :MSTORE(array_div_inA + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB + E) 2 => E - 16n :MSTORE(array_div_mod_inA + E) + 16n :MSTORE(array_div_inA + E) 3 => E - 2n :MSTORE(array_div_mod_inA + E) + 2n :MSTORE(array_div_inA + E) 4 => E - 0n :MSTORE(array_div_mod_inA + E) + 0n :MSTORE(array_div_inA + E) 5 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MSTORE(array_div_mod_inA + E) - :CALL(array_div_mod) - 4 :MLOAD(array_div_mod_len_quo) - 2 :MLOAD(array_div_mod_len_rem) - 17n :MLOAD(array_div_mod_quo) - 26n :MLOAD(array_div_mod_rem) + 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MSTORE(array_div_inA + E) + :CALL(array_div) + 4 :MLOAD(array_div_len_quo) + 2 :MLOAD(array_div_len_rem) + 17n :MLOAD(array_div_quo) + 26n :MLOAD(array_div_rem) 1 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_div_mod_quo + E) - 10n :MLOAD(array_div_mod_rem + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_div_quo + E) + 10n :MLOAD(array_div_rem + E) 2 => E - 0n :MLOAD(array_div_mod_quo + E) + 0n :MLOAD(array_div_quo + E) 3 => E - 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_div_mod_quo + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_div_quo + E) ; --------------------------------------------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -989,9 +989,9 @@ INCLUDE "../main/modexp/array_lib/array_mul_long.zkasm" INCLUDE "../main/modexp/array_lib/array_mul_short.zkasm" INCLUDE "../main/modexp/array_lib/array_mul.zkasm" INCLUDE "../main/modexp/array_lib/array_square.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_div.zkasm" INCLUDE "../main/modexp/array_lib/unused/array_sub_AGTB.zkasm" INCLUDE "../main/modexp/array_lib/unused/array_add.zkasm" \ No newline at end of file diff --git a/test/testModExp.zkasm b/test/testModExp.zkasm index 12ada5db..1b3c6095 100644 --- a/test/testModExp.zkasm +++ b/test/testModExp.zkasm @@ -579,8 +579,8 @@ INCLUDE "../main/modexp/array_lib/array_mul_long.zkasm" INCLUDE "../main/modexp/array_lib/array_mul_short.zkasm" INCLUDE "../main/modexp/array_lib/array_mul.zkasm" INCLUDE "../main/modexp/array_lib/array_square.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_div.zkasm" INCLUDE "../main/modexp/modexp.zkasm" \ No newline at end of file diff --git a/tools/modexp-utils/README.md b/tools/modexp-utils/README.md index f87bd4fe..37bd479b 100644 --- a/tools/modexp-utils/README.md +++ b/tools/modexp-utils/README.md @@ -1,5 +1,5 @@ ## Notes -The file `modexp-test-gen.js` automatically geneates a zkasm file, executes it some specified number of times and outputs a json file containing the record of the counters. At this moment, it is hardcoded to work for the operation `array_div_mod(array_mul(a, b),c)`, where `a` and `b` was chosen to be $2^{256} - 3$, while `c` was chosen to be $2^{256} - 1$ to achieve the maximum complexity in the operation. +The file `modexp-test-gen.js` automatically geneates a zkasm file, executes it some specified number of times and outputs a json file containing the record of the counters. At this moment, it is hardcoded to work for the operation `array_div(array_mul(a, b),c)`, where `a` and `b` was chosen to be $2^{256} - 3$, while `c` was chosen to be $2^{256} - 1$ to achieve the maximum complexity in the operation. The `modexp-test-init.sage` takes the counters in the json file and, for each different counter, interpolates the multivariate polynomial (having as evaluation points the lenght of the inputs in the previous file) that evaluates to the counters. \ No newline at end of file diff --git a/tools/modexp-utils/modexp-test-gen.js b/tools/modexp-utils/modexp-test-gen.js index b6126d12..8079d415 100644 --- a/tools/modexp-utils/modexp-test-gen.js +++ b/tools/modexp-utils/modexp-test-gen.js @@ -91,9 +91,9 @@ INCLUDE "../main/modexp/array_lib/array_add_short.zkasm" INCLUDE "../main/modexp/array_lib/array_mul.zkasm" INCLUDE "../main/modexp/array_lib/array_mul_long.zkasm" INCLUDE "../main/modexp/array_lib/array_mul_short.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod_long.zkasm" -INCLUDE "../main/modexp/array_lib/array_div_mod_short.zkasm" +INCLUDE "../main/modexp/array_lib/array_div.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_long.zkasm" +INCLUDE "../main/modexp/array_lib/array_div_short.zkasm" `; const counters = []; @@ -117,17 +117,17 @@ for (let i = 1; i <= 5; i++) { const fileTest2 = `\t\t:CALL(array_mul)\n\t${i+j} => C\n\t${k} => D\n\t` - let fileTest3 =`$ => A :MLOAD(array_mul_out)\n\tA :MSTORE(array_div_mod_inA)\n\t115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB)\n\t` + let fileTest3 =`$ => A :MLOAD(array_mul_out)\n\tA :MSTORE(array_div_inA)\n\t115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB)\n\t` for (let l = 1; l < k; l++) { - fileTest3 += `${l} => E\n\t$ => A :MLOAD(array_mul_out + E)\n\tA :MSTORE(array_div_mod_inA + E)\n\t115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_mod_inB + E)\n\t` + fileTest3 += `${l} => E\n\t$ => A :MLOAD(array_mul_out + E)\n\tA :MSTORE(array_div_inA + E)\n\t115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_div_inB + E)\n\t` } for (let l = k; l < i + j; l++) { - fileTest3 += `${l} => E\n\t$ => A :MLOAD(array_mul_out + E)\n\tA :MSTORE(array_div_mod_inA + E)\n\t` + fileTest3 += `${l} => E\n\t$ => A :MLOAD(array_mul_out + E)\n\tA :MSTORE(array_div_inA + E)\n\t` } - fileTest3 += `:CALL(array_div_mod)\n`; + fileTest3 += `:CALL(array_div)\n`; const fileTest = fileTest1 + fileTest2 + fileTest3; From 4c1965faf4f6b4d6e03130ef1d6eb292a16eec62 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 15 Dec 2023 10:01:58 +0100 Subject: [PATCH 064/121] improve error and events --- main/block-info.zkasm | 6 ++++-- main/process-change-l2-block.zkasm | 6 +++--- main/utils.zkasm | 6 ++++-- package.json | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index daa25583..8fa8940a 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -167,8 +167,10 @@ finalConsolidateBlockInfoTree: %SMT_KEY_SC_STORAGE => B %BLOCK_INFO_ROOT_STORAGE_POS => C writeBlockInfoRoot: - $ => D :MLOAD(blockInfoSR) - $ => SR :SSTORE, RETURN + $ => D :MLOAD(blockInfoSR) + $ => SR :SSTORE + $${eventLog(onFinishBlock)} + :RETURN ; @info add new log hash to block info tree ; @in D => Value to store (linearPoseidon(log_data + log_topics)) diff --git a/main/process-change-l2-block.zkasm b/main/process-change-l2-block.zkasm index 3a94e253..bed79ed1 100644 --- a/main/process-change-l2-block.zkasm +++ b/main/process-change-l2-block.zkasm @@ -1,5 +1,4 @@ processChangeL2Block: - $${eventLog(onProcessTx)} ; checks zk-counters %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*6 :JMPN(outOfCountersPoseidon) @@ -14,6 +13,7 @@ processChangeL2Block: :CALL(consolidateBlock) continueProcessChangeL2Block: + $${eventLog(onStartBlock)} ; Reset tx index, logIndex and cumulative gas used 0 :MSTORE(txIndex) 0 :MSTORE(cumulativeGasUsed) @@ -76,7 +76,7 @@ verifyTimestampAndL1InfoRoot: ; Verify (currentTimestamp + deltaTimestamp) <= limitTimestamp $ => A :MLOAD(timestampLimit) - $ :LT, JMPC(invalidChangeL2Block) + $ :LT, JMPC(invalidChangeL2BlockLimitTimestamp) ; Set new timestamp %TIMESTAMP_STORAGE_POS => C @@ -96,7 +96,7 @@ ${getL1InfoTimestamp(mem.indexL1InfoTree)} => C :MSTORE(timestampL1InfoTree) ; Verify (currentTimestamp + deltaTimestamp) >= l1InfoRoot.timestamp $ => A :MLOAD(timestamp) $ => B :MLOAD(timestampL1InfoTree) - $ :LT, JMPC(invalidChangeL2Block, initSetGERL1InfoTree) + $ :LT, JMPC(invalidChangeL2BlockMinTimestamp, initSetGERL1InfoTree) setNewTimestamp: ; Set new timestamp diff --git a/main/utils.zkasm b/main/utils.zkasm index 71cf04a6..5ae7129c 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -841,8 +841,10 @@ outOfCountersPoseidon: $${eventLog(onError, OOCPO)} :JMP(handleBatchError) outOfCountersSha256: $${eventLog(onError, OOCSH)} :JMP(handleBatchError) -invalidChangeL2Block: - $${eventLog(onError, invalid_change_l2_block)} :JMP(handleBatchError) +invalidChangeL2BlockLimitTimestamp: + $${eventLog(onError, invalid_change_l2_block_limit_timestamp)} :JMP(handleBatchError) +invalidChangeL2BlockMinTimestamp: + $${eventLog(onError, invalid_change_l2_block_min_timestamp)} :JMP(handleBatchError) outOfGas: $${eventLog(onError, OOG)} :JMP(handleError) invalidJump: diff --git a/package.json b/package.json index 1ffe14f3..ea2719fb 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.1-fork.7", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#b066730fb04b31da192d58eb52953b82fc87314e", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/improve-errors-and-events", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.1-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", From 9f68f48584439865dd003c427e3d92a82c8f36a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Fri, 15 Dec 2023 10:31:19 +0100 Subject: [PATCH 065/121] array_square minor bug fixed --- main/modexp/array_lib/array_square.zkasm | 249 ++++++++++------------- test/testArrayArith.zkasm | 70 +++++++ 2 files changed, 175 insertions(+), 144 deletions(-) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 02751990..ad93fd93 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -4,13 +4,13 @@ ;; array_square: ;; in: ;; · C ∈ [1, 32], the len of in -;; · in ∈ [0, 2²⁵ ⁶- 1]^C, the input array +;; · in ∈ [0, 2²⁵⁶- 1]^C, the input array ;; ;; output: ;; · out = in², with len(out) <= 2·C ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_square(a: bigint[], B: bigint): bigint[] { +; function array_square(a: bigint[], base: bigint): bigint[] { ; let len = a.length; ; let out = new Array(2*len).fill(0n); ; let product: bigint; @@ -23,9 +23,9 @@ ; for (var j = i; j < len; j++) { ; a_j = a[j]; ; product = 2n * (a_i * a_j) + out[i + j] + carry; -; carry = product / B; +; carry = product / base; -; out[i + j] = product - carry * B; +; out[i + j] = product - carry * base; ; } ; out[i + len] = carry; ; } @@ -40,12 +40,12 @@ VAR GLOBAL array_square_out[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_square_len_in VAR GLOBAL array_square_len_out -VAR GLOBAL array_square_carry_high -VAR GLOBAL array_square_carry_low -VAR GLOBAL array_square_carry_sign; 0 if negative, 1 if positive -VAR GLOBAL array_square_aiaj_high -VAR GLOBAL array_square_highest_carry -VAR GLOBAL array_square_out_carry +VAR GLOBAL array_square_carry_chunk_1 +VAR GLOBAL array_square_carry_chunk_2 +VAR GLOBAL array_square_carry_sign ; 0 if negative, 1 if positive +VAR GLOBAL array_square_chunk_3 +VAR GLOBAL array_square_aiaj_chunk_2 +VAR GLOBAL array_square_out_chunk_2 VAR GLOBAL array_square_RR @@ -69,198 +69,159 @@ array_square: 0 => RCX ; first index in loops C + C => RR ; second index in loops - - ; 1] carry = 0 - a_0²: The (unsigned) number cannot be GT (base - 2)·base + 1, two chunks - $ => A :MLOAD(array_square_in) - A => B - 0 => C - $${var _arraySquare_a02 = A*B} - ${_arraySquare_a02 >> 256} => D - ${_arraySquare_a02} => E :ARITH - D :MSTORE(array_square_carry_high) - E :MSTORE(array_square_carry_low) - 0 :MSTORE(array_square_carry_sign) - 0 :MSTORE(array_square_highest_carry) - array_square_clean_out: RR - 1 => RR 0 :MSTORE(array_square_out + RR) - RR :JMPZ(array_square_loopZero2inA, array_square_clean_out) + RR :JMPZ(array_square_ai_times_ai, array_square_clean_out) ; Begin of branching -array_square_add_low_carry_1: - ; Since here high ∈ [0, 2²⁵⁶ - 2], there cannot be carry in the following addition - D => A - 1 => B - $ => D :ADD, JMP(return_array_square_add_low_carry_1) - -array_square_add_low_carry_2: - ; Since here high ∈ [0, 2²⁵⁶ - 1], there can be carry in the following addition - D => A - 1 => B - $ => D :ADD, JMPC(array_square_add_high_carry_2, return_array_square_add_low_carry_2) - -array_square_add_low_carry_3: - ; Since here high ∈ [0, 2²⁵⁶ - 1], there can be carry in the following addition - D => A - 1 => B - $ => D :ADD, JMPC(array_square_add_high_carry_4, return_array_square_add_low_carry_3) - -; In the add_high_carry_X branches, since highest = 0, there cannot be carry in the additions -; Moreover, we can perform "plain" addition -array_square_add_high_carry_1: - $ => A :MLOAD(array_square_highest_carry) - A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_high_carry_1) - -array_square_add_high_carry_2: - $ => A :MLOAD(array_square_highest_carry) - A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_low_carry_2) - -array_square_add_high_carry_3: - $ => A :MLOAD(array_square_highest_carry) - A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_high_carry_3) - -array_square_add_high_carry_4: - $ => A :MLOAD(array_square_highest_carry) - A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_low_carry_3) - -array_square_add_high_carry_5: - $ => A :MLOAD(array_square_highest_carry) - A + 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_add_high_carry_5) - ; In the is_negative_X branches, we perform subtraction of a value with three chunks ; Therefore, the subtraction can produce carry until the highest chunk array_square_is_negative_1: - $ => C :SUB, JMPC(array_square_sub_low_carry_2, return_array_square_is_negative_1) - -array_square_is_negative_2: - $ => D :SUB, JMPC(array_square_sub_high_carry_2, return_array_square_is_negative_2) - -array_square_sub_low_carry_2: + $ => C :SUB, JMPNC(__return_array_square_is_negative_1) + ;----------------- D => A 1 => B - $ => D :SUB, JMPC(array_square_sub_high_carry_1, return_array_square_is_negative_1) + $ => D :SUB, JMPNC(__return_array_square_is_negative_1) + 0 :MSTORE(array_square_chunk_3) + :JMP(__return_array_square_is_negative_1) + ;----------------- -; Similarly, in the sub_high_carry_X branches, since highest = 1, there cannot be carry in the subtraction -; Moreover, we can perform "plain" subtraction -array_square_sub_high_carry_1: - $ => A :MLOAD(array_square_highest_carry) - A - 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_is_negative_1) -array_square_sub_high_carry_2: - $ => A :MLOAD(array_square_highest_carry) - A - 1 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_is_negative_2) +array_square_is_negative_2: + $ => D :SUB, JMPNC(__return_array_square_is_negative_2) + ;----------------- + 0 :MSTORE(array_square_chunk_3) + :JMP(__return_array_square_is_negative_2) + ;----------------- array_square_loop_index_check: - ; out[i + len] = carry; - $ => A :MLOAD(array_square_carry_low) - $ => B :MLOAD(array_square_len_in) + ; out[i + len] = carry + $ => A :MLOAD(array_square_carry_chunk_1) RCX + B => E A :MSTORE(array_square_out + E) - $ => A :MLOAD(array_square_carry_high) - A :MSTORE(array_square_out_carry) + $ => A :MLOAD(array_square_carry_chunk_2) + A :MSTORE(array_square_out_chunk_2) ; update indices - RCX + 1 => RCX - RCX => RR - - RCX => A - $ :EQ, JMPC(array_square_prep_trim_in) + RCX + 1 => RCX,RR,A + B - A :JMPZ(array_square_prep_trim_in) ; This subtraction is safe +; End of branching +array_square_ai_times_ai: ; carry = 0 - a_i·a_i - ; a_i·a_i: This number cannot be GT (base - 2)·base + 1, two chunks - $ => A :MLOAD(array_square_in + RR) - A => B + ; a_i·a_i, where a_i ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks + $ => A,B :MLOAD(array_square_in + RR) 0 => C $${var _arraySquare_aiai = A*B} ${_arraySquare_aiai >> 256} => D ${_arraySquare_aiai} => E :ARITH - D :MSTORE(array_square_carry_high) - E :MSTORE(array_square_carry_low) + E :MSTORE(array_square_carry_chunk_1) + D :MSTORE(array_square_carry_chunk_2) 0 :MSTORE(array_square_carry_sign) - 0 :MSTORE(array_square_highest_carry) - :JMP(return_array_square_loop_index_check) -; End of branching +array_square_loopRR2len: + ; product = 2·(a_i·a_j) + out[i + j] + carry (in the worst case, this is a 3-chunk number) + ; The result will be stored as array_square_chunk_3·base² + D·base + C -array_square_loopZero2inA: + ; 1] a_i·a_j, where a_i,a_j ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks RCX => E - ; product = 2·(a_i·a_j) + out[i + j] + carry. - ; The result will be stored as array_square_highest_carry·base² + D·base + C - - ; 1] a_i·a_j: This number cannot be GT (base - 2)·base + 1, two chunks $ => A :MLOAD(array_square_in + E) $ => B :MLOAD(array_square_in + RR) 0 => C $${var _arraySquare_aiaj = A*B} ${_arraySquare_aiaj >> 256} => D ${_arraySquare_aiaj} => E :ARITH - D :MSTORE(array_square_aiaj_high) + D :MSTORE(array_square_aiaj_chunk_2) ; 2] 2·a_i·a_j: This number cannot be GT base² + (base - 4)·base + 2, three chunks E => A,B - $ => C :ADD, JMPC(array_square_add_low_carry_1) - return_array_square_add_low_carry_1: - $ => A :MLOAD(array_square_aiaj_high) + $ => C :ADD, JMPNC(__array_square_no_carry_continue_1) + ;----------------- + ; Since here D ∈ [0, base - 2], there cannot be carry in the following addition + D => A + 1 => B + $ => D :ADD + ;----------------- + __array_square_no_carry_continue_1: + $ => A :MLOAD(array_square_aiaj_chunk_2) D => B - $ => D :ADD, JMPC(array_square_add_high_carry_1) - return_array_square_add_high_carry_1: + $ => D :ADD, JMPNC(__array_square_no_carry_continue_2) + ;----------------- + 1 :MSTORE(array_square_chunk_3) + ;----------------- + __array_square_no_carry_continue_2: ; 3] 2·a_i·a_j + out[i + j]: - ; a) j != len: This number cannot be GT base² + (base - 3)·base + 1, as out[i + j] < B - ; b) j == len: This number cannot be GT base² + (base - 3)·base + base - 1, as out[i + len] <= B + (B - 3) + ; a) j < len-1: This number cannot be GT base² + (base - 3)·base + 1, as out[i + j] < base + ; b) j == len-1: This number cannot be GT base² + (base - 3)·base + base - 1, as out[i + len] <= base + (base - 3) ; In both cases, three chunks - RR + RCX => E + RCX + RR => E $ => A :MLOAD(array_square_out + E) C => B - $ => C :ADD, JMPC(array_square_add_low_carry_2) - return_array_square_add_low_carry_2: + $ => C :ADD, JMPNC(__array_square_no_carry_continue_3) + ;----------------- + ; Since here D ∈ [0, base - 1], there can be carry in the following addition + D => A + 1 => B + $ => D :ADD, JMPNC(__array_square_no_carry_continue_3) + 1 :MSTORE(array_square_chunk_3) + ;----------------- + __array_square_no_carry_continue_3: - $ => A :MLOAD(array_square_out_carry) + ; The output can have two chunks only if j == len-1, so we must jump the following block of code if j < len-1 + RR + 1 => A + $ => B :MLOAD(array_square_len_in) + B - A :JMPNZ(__array_square_no_carry_continue_4) ; This subtraction is safe + ; Add the second output chunk + $ => A :MLOAD(array_square_out_chunk_2) D => B - $ => D :ADD, JMPC(array_square_add_high_carry_3) - return_array_square_add_high_carry_3: + $ => D :ADD, JMPNC(__array_square_no_carry_continue_4) + ;----------------- + 1 :MSTORE(array_square_chunk_3) + ;----------------- + __array_square_no_carry_continue_4: - ; 4] 2·a_i·a_j + out[i + j] + carry: This number cannot be GT base² + (base - 2)·base, three chunks + ; 4] product = 2·a_i·a_j + out[i + j] + carry: This number cannot be GT base² + (base - 2)·base, three chunks C => A - $ => B :MLOAD(array_square_carry_low) + $ => B :MLOAD(array_square_carry_chunk_1) $ :MLOAD(array_square_carry_sign), JMPZ(array_square_is_negative_1) - $ => C :ADD, JMPC(array_square_add_low_carry_3) - return_array_square_add_low_carry_3: - return_array_square_is_negative_1: + $ => C :ADD, JMPNC(__array_square_no_carry_continue_5) + ;----------------- + ; Since here D ∈ [0, base - 1], there can be carry in the following addition + D => A + 1 => B + $ => D :ADD, JMPNC(__array_square_no_carry_continue_5) + 1 :MSTORE(array_square_chunk_3) + ;----------------- + __array_square_no_carry_continue_5: + __return_array_square_is_negative_1: D => A - $ => B :MLOAD(array_square_carry_high) + $ => B :MLOAD(array_square_carry_chunk_2) $ :MLOAD(array_square_carry_sign), JMPZ(array_square_is_negative_2) - $ => D :ADD, JMPC(array_square_add_high_carry_5) - return_array_square_add_high_carry_5: - return_array_square_is_negative_2: - - ; carry = product / B; This number cannot be greater than base + (base - 2) - D :MSTORE(array_square_carry_low) - $ => A :MLOAD(array_square_highest_carry) - A :MSTORE(array_square_carry_high) + $ => D :ADD, JMPNC(__array_square_no_carry_continue_6) + ;----------------- + 1 :MSTORE(array_square_chunk_3) + ;----------------- + __array_square_no_carry_continue_6: + __return_array_square_is_negative_2: + + ; carry = product / base; This number cannot be greater than base + (base - 2) + D :MSTORE(array_square_carry_chunk_1) + $ => A :MLOAD(array_square_chunk_3) + A :MSTORE(array_square_carry_chunk_2) 1 :MSTORE(array_square_carry_sign) - ; out[i + j] = product - carry·B; + ; out[i + j] = product - carry·base; RCX + RR => E C :MSTORE(array_square_out + E) + 0 :MSTORE(array_square_chunk_3) ; reset the third chunk - RR + 1 => RR - 0 :MSTORE(array_square_highest_carry) - RR => A + RR + 1 => RR,A $ => B :MLOAD(array_square_len_in) - $ :EQ, JMPC(array_square_loop_index_check) - return_array_square_loop_index_check: - :JMP(array_square_loopZero2inA) + B - A :JMPZ(array_square_loop_index_check, array_square_loopRR2len) ; This subtraction is safe array_square_prep_trim_in: $ => C :MLOAD(array_square_len_out) diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index 5990c953..c14251ac 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -1,6 +1,8 @@ ; constants needed by executor C++ INCLUDE "../main/constants.zkasm" +CONSTL %ARRAY_BASE_MINUS_ONE = 115792089237316195423570985008687907853269984665640564039457584007913129639935n ; 2^256 + VAR GLOBAL lastHashKId VAR GLOBAL lastHashPId @@ -273,6 +275,74 @@ start: 3 => E 63579038104476977130956937454941822659502127575865339775268690127769381598323n :MLOAD(array_square_out + E) 4 :MLOAD(array_square_len_out) + + ; 5] [ARRAY_BASE-1,ARRAY_BASE/2+1,ARRAY_BASE-2] + ; this covers the edge case where the addition 2·a_i·a_j + out[i + j] produces a third chunk carry + 3 => C + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_square_in) + 1 => E + 57896044618658097711785492504343953926634992332820282019728792003956564819969n :MSTORE(array_square_in + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MSTORE(array_square_in + E) + :CALL(array_square) + 1n :MLOAD(array_square_out) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639932n :MLOAD(array_square_out + E) + 2 => E + 6n :MLOAD(array_square_out + E) + 3 => E + 28948022309329048855892746252171976963317496166410141009864396001978282409976n :MLOAD(array_square_out + E) + 4 => E + 6n :MLOAD(array_square_out + E) + 5 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639933n :MLOAD(array_square_out + E) + 6 :MLOAD(array_square_len_out) + + ; 6] [ARRAY_BASE/2+1,ARRAY_BASE/2+1,ARRAY_BASE-2] + ; this covers the edge case where out[i + j] has a non-zero second chunk (i.e., when j == len -1) + ; and it produces carry when added to the second chunk of 2·a_i·a_j + 3 => C + 57896044618658097711785492504343953926634992332820282019728792003956564819969n :MSTORE(array_square_in) + 1 => E + 57896044618658097711785492504343953926634992332820282019728792003956564819969n :MSTORE(array_square_in + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MSTORE(array_square_in + E) + :CALL(array_square) + 1n :MLOAD(array_square_out) + 1 => E + 28948022309329048855892746252171976963317496166410141009864396001978282409987n :MLOAD(array_square_out + E) + 2 => E + 57896044618658097711785492504343953926634992332820282019728792003956564819967n :MLOAD(array_square_out + E) + 3 => E + 28948022309329048855892746252171976963317496166410141009864396001978282409981n :MLOAD(array_square_out + E) + 4 => E + 5n :MLOAD(array_square_out + E) + 5 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639933n :MLOAD(array_square_out + E) + 6 :MLOAD(array_square_len_out) + + ; 7] [ARRAY_BASE/2+1,ARRAY_BASE-1,ARRAY_BASE-2] + ; this covers the edge case where carry has a non-zero second chunk + ; and it produces carry when added to the second chunk of 2·a_i·a_j + out[i + j] + 3 => C + 57896044618658097711785492504343953926634992332820282019728792003956564819969n :MSTORE(array_square_in) + 1 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(array_square_in + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MSTORE(array_square_in + E) + :CALL(array_square) + 1n :MLOAD(array_square_out) + 1 => E + 28948022309329048855892746252171976963317496166410141009864396001978282409983n :MLOAD(array_square_out + E) + 2 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_square_out + E) + 3 => E + 2n :MLOAD(array_square_out + E) + 4 => E + 0n :MLOAD(array_square_out + E) + 5 => E + 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_square_out + E) + 6 :MLOAD(array_square_len_out) ; --------------------------------------------------------------- ; division From 1dfb815666d28bd11ebeebe6d84724ef254746d6 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Wed, 13 Dec 2023 13:55:18 +0100 Subject: [PATCH 066/121] optimization for verifyMerkleProof --- main/utils.zkasm | 896 +++++++++++++++++++++++++++++++++++++++++++++-- package.json | 2 +- 2 files changed, 859 insertions(+), 39 deletions(-) diff --git a/main/utils.zkasm b/main/utils.zkasm index 5ae7129c..e3f0815b 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -1494,8 +1494,7 @@ verifyMerkleProof: ; 1 keccak for the leaf and 32 for the L1InfoTree %MAX_CNT_KECCAK_F - CNT_KECCAK_F - E - 33 :JMPN(outOfCountersKeccak) - %MAX_CNT_BINARY - CNT_BINARY - 32 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 20 * 32 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 10 * 32 :JMPN(outOfCountersStep) ; 301 steps RR :MSTORE(tmpZkPCVerifyMerkleProof) @@ -1504,66 +1503,553 @@ verifyMerkleProof: ;;;;;;;;;;;;;;;;;;;;; ; new keccak address - $ => E :MLOAD(lastHashKIdUsed) - E + 1 => E :MSTORE(lastHashKIdUsed) + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) ; add gerL1InfoTree (32 bytes) 0 => HASHPOS 32 => D - A :HASHK(E) + A :HASHK(E) ; add blockHashL1 (32 bytes) - B :HASHK(E) + B :HASHK(E) ; add timestamp (8 bytes) 8 => D - C :HASHK(E) + C :HASHK(E) ; compute l1InfoTree Leaf value - HASHPOS :HASHKLEN(E) - $ => C :HASHKDIGEST(E) ; initial value + HASHPOS :HASHKLEN(E) + $ => C :HASHKDIGEST(E) ; initial value ; initialization registers for smt verify 0 => D -verifyMerkleProofLoop: - %L1INFO_TREE_LEVELS - D :JMPZ(verifyMerkleProofEnd) + $ => A :MLOAD(indexL1InfoTree) + :CALL(u32ToBits) + ; prepare new hash + $ => E :MLOAD(lastHashKIdUsed) + E + 1 => E :MSTORE(lastHashKIdUsed) + 32 => D - ; get left/right branch - $ => A :MLOAD(indexL1InfoTree) - D => RR - :CALL(@exp_num + RR); out:[B: 2**RR] - ; A: index, B: SMTLevel (index maximum value is 4 bytes, SMTLevel maximum value is is 2**32) - $ => B :AND + ;;;;;;;;;;;;;;;;;;;;; + ;; loop unrolling + ;;;;;;;;;;;;;;;;;;;;; + ; BIT 0 + 0 => HASHPOS + $ :JMPZ(hashLeft0), MLOAD(u32bits[0]) - ; get leaf value - ${getSmtProof(mem.indexL1InfoTree, D)} => A +hashRight0: + ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E) + C :HASHK(E), JMP(hashBranchEnd0) - ; prepare new hash - $ => E :MLOAD(lastHashKIdUsed) - E + 1 => E :MSTORE(lastHashKIdUsed) +hashLeft0: + C :HASHK(E) + ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E) + +hashBranchEnd0: + HASHPOS :HASHKLEN(E) + $ => C :HASHKDIGEST(E) + + ; BIT 1 0 => HASHPOS + $ :JMPZ(hashLeft1), MLOAD(u32bits[1]) - ; decide left/right branch - B :JMPZ(hashLeft) +hashRight1: + ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) + C :HASHK(E+1), JMP(hashBranchEnd1) - ;hashRight: - D => B ; save D in B for the next loop - 32 => D - A :HASHK(E) - C :HASHK(E), JMP(hashBranchEnd) +hashLeft1: + C :HASHK(E+1) + ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) -hashLeft: - D => B ; save D in B for the next loop - 32 => D - C :HASHK(E) - A :HASHK(E) +hashBranchEnd1: + HASHPOS :HASHKLEN(E+1) + $ => C :HASHKDIGEST(E+1) + + ; BIT 2 + 0 => HASHPOS + $ :JMPZ(hashLeft2), MLOAD(u32bits[2]) + +hashRight2: + ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) + C :HASHK(E+2), JMP(hashBranchEnd2) + +hashLeft2: + C :HASHK(E+2) + ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) + +hashBranchEnd2: + HASHPOS :HASHKLEN(E+2) + $ => C :HASHKDIGEST(E+2) + + ; BIT 3 + 0 => HASHPOS + $ :JMPZ(hashLeft3), MLOAD(u32bits[3]) + +hashRight3: + ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) + C :HASHK(E+3), JMP(hashBranchEnd3) + +hashLeft3: + C :HASHK(E+3) + ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) + +hashBranchEnd3: + HASHPOS :HASHKLEN(E+3) + $ => C :HASHKDIGEST(E+3) + + ; BIT 4 + 0 => HASHPOS + $ :JMPZ(hashLeft4), MLOAD(u32bits[4]) + +hashRight4: + ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) + C :HASHK(E+4), JMP(hashBranchEnd4) + +hashLeft4: + C :HASHK(E+4) + ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) + +hashBranchEnd4: + HASHPOS :HASHKLEN(E+4) + $ => C :HASHKDIGEST(E+4) + + ; BIT 5 + 0 => HASHPOS + $ :JMPZ(hashLeft5), MLOAD(u32bits[5]) + +hashRight5: + ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) + C :HASHK(E+5), JMP(hashBranchEnd5) + +hashLeft5: + C :HASHK(E+5) + ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) + +hashBranchEnd5: + HASHPOS :HASHKLEN(E+5) + $ => C :HASHKDIGEST(E+5) + + ; BIT 6 + 0 => HASHPOS + $ :JMPZ(hashLeft6), MLOAD(u32bits[6]) + +hashRight6: + ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) + C :HASHK(E+6), JMP(hashBranchEnd6) + +hashLeft6: + C :HASHK(E+6) + ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) + +hashBranchEnd6: + HASHPOS :HASHKLEN(E+6) + $ => C :HASHKDIGEST(E+6) + + ; BIT 7 + 0 => HASHPOS + $ :JMPZ(hashLeft7), MLOAD(u32bits[7]) + +hashRight7: + ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) + C :HASHK(E+7), JMP(hashBranchEnd7) + +hashLeft7: + C :HASHK(E+7) + ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) + +hashBranchEnd7: + HASHPOS :HASHKLEN(E+7) + $ => C :HASHKDIGEST(E+7) + + ; BIT 8 + 0 => HASHPOS + $ :JMPZ(hashLeft8), MLOAD(u32bits[8]) + +hashRight8: + ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) + C :HASHK(E+8), JMP(hashBranchEnd8) + +hashLeft8: + C :HASHK(E+8) + ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) + +hashBranchEnd8: + HASHPOS :HASHKLEN(E+8) + $ => C :HASHKDIGEST(E+8) + + ; BIT 9 + 0 => HASHPOS + $ :JMPZ(hashLeft9), MLOAD(u32bits[9]) + +hashRight9: + ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) + C :HASHK(E+9), JMP(hashBranchEnd9) + +hashLeft9: + C :HASHK(E+9) + ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) + +hashBranchEnd9: + HASHPOS :HASHKLEN(E+9) + $ => C :HASHKDIGEST(E+9) + + ; BIT 10 + 0 => HASHPOS + $ :JMPZ(hashLeft10), MLOAD(u32bits[10]) + +hashRight10: + ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) + C :HASHK(E+10), JMP(hashBranchEnd10) + +hashLeft10: + C :HASHK(E+10) + ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) + +hashBranchEnd10: + HASHPOS :HASHKLEN(E+10) + $ => C :HASHKDIGEST(E+10) + + ; BIT 11 + 0 => HASHPOS + $ :JMPZ(hashLeft11), MLOAD(u32bits[11]) + +hashRight11: + ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) + C :HASHK(E+11), JMP(hashBranchEnd11) + +hashLeft11: + C :HASHK(E+11) + ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) + +hashBranchEnd11: + HASHPOS :HASHKLEN(E+11) + $ => C :HASHKDIGEST(E+11) + + ; BIT 12 + 0 => HASHPOS + $ :JMPZ(hashLeft12), MLOAD(u32bits[12]) + +hashRight12: + ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) + C :HASHK(E+12), JMP(hashBranchEnd12) + +hashLeft12: + C :HASHK(E+12) + ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) + +hashBranchEnd12: + HASHPOS :HASHKLEN(E+12) + $ => C :HASHKDIGEST(E+12) + + ; BIT 13 + 0 => HASHPOS + $ :JMPZ(hashLeft13), MLOAD(u32bits[13]) + +hashRight13: + ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) + C :HASHK(E+13), JMP(hashBranchEnd13) + +hashLeft13: + C :HASHK(E+13) + ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) + +hashBranchEnd13: + HASHPOS :HASHKLEN(E+13) + $ => C :HASHKDIGEST(E+13) + + ; BIT 14 + 0 => HASHPOS + $ :JMPZ(hashLeft14), MLOAD(u32bits[14]) + +hashRight14: + ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) + C :HASHK(E+14), JMP(hashBranchEnd14) + +hashLeft14: + C :HASHK(E+14) + ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) + +hashBranchEnd14: + HASHPOS :HASHKLEN(E+14) + $ => C :HASHKDIGEST(E+14) + + ; BIT 15 + 0 => HASHPOS + $ :JMPZ(hashLeft15), MLOAD(u32bits[15]) + +hashRight15: + ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) + C :HASHK(E+15), JMP(hashBranchEnd15) + +hashLeft15: + C :HASHK(E+15) + ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) + +hashBranchEnd15: + HASHPOS :HASHKLEN(E+15) + $ => C :HASHKDIGEST(E+15) + + ; BIT 16 + 0 => HASHPOS + $ :JMPZ(hashLeft16), MLOAD(u32bits[16]) + +hashRight16: + ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) + C :HASHK(E+16), JMP(hashBranchEnd16) + +hashLeft16: + C :HASHK(E+16) + ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) + +hashBranchEnd16: + HASHPOS :HASHKLEN(E+16) + $ => C :HASHKDIGEST(E+16) + + ; BIT 17 + 0 => HASHPOS + $ :JMPZ(hashLeft17), MLOAD(u32bits[17]) + +hashRight17: + ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) + C :HASHK(E+17), JMP(hashBranchEnd17) + +hashLeft17: + C :HASHK(E+17) + ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) + +hashBranchEnd17: + HASHPOS :HASHKLEN(E+17) + $ => C :HASHKDIGEST(E+17) + + ; BIT 18 + 0 => HASHPOS + $ :JMPZ(hashLeft18), MLOAD(u32bits[18]) + +hashRight18: + ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) + C :HASHK(E+18), JMP(hashBranchEnd18) + +hashLeft18: + C :HASHK(E+18) + ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) + +hashBranchEnd18: + HASHPOS :HASHKLEN(E+18) + $ => C :HASHKDIGEST(E+18) + + ; BIT 19 + 0 => HASHPOS + $ :JMPZ(hashLeft19), MLOAD(u32bits[19]) + +hashRight19: + ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) + C :HASHK(E+19), JMP(hashBranchEnd19) + +hashLeft19: + C :HASHK(E+19) + ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) + +hashBranchEnd19: + HASHPOS :HASHKLEN(E+19) + $ => C :HASHKDIGEST(E+19) + + ; BIT 20 + 0 => HASHPOS + $ :JMPZ(hashLeft20), MLOAD(u32bits[20]) + +hashRight20: + ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) + C :HASHK(E+20), JMP(hashBranchEnd20) + +hashLeft20: + C :HASHK(E+20) + ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) + +hashBranchEnd20: + HASHPOS :HASHKLEN(E+20) + $ => C :HASHKDIGEST(E+20) + + ; BIT 21 + 0 => HASHPOS + $ :JMPZ(hashLeft21), MLOAD(u32bits[21]) + +hashRight21: + ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) + C :HASHK(E+21), JMP(hashBranchEnd21) + +hashLeft21: + C :HASHK(E+21) + ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) + +hashBranchEnd21: + HASHPOS :HASHKLEN(E+21) + $ => C :HASHKDIGEST(E+21) + + ; BIT 22 + 0 => HASHPOS + $ :JMPZ(hashLeft22), MLOAD(u32bits[22]) + +hashRight22: + ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) + C :HASHK(E+22), JMP(hashBranchEnd22) + +hashLeft22: + C :HASHK(E+22) + ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) + +hashBranchEnd22: + HASHPOS :HASHKLEN(E+22) + $ => C :HASHKDIGEST(E+22) + + ; BIT 23 + 0 => HASHPOS + $ :JMPZ(hashLeft23), MLOAD(u32bits[23]) + +hashRight23: + ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) + C :HASHK(E+23), JMP(hashBranchEnd23) + +hashLeft23: + C :HASHK(E+23) + ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) + +hashBranchEnd23: + HASHPOS :HASHKLEN(E+23) + $ => C :HASHKDIGEST(E+23) + + ; BIT 24 + 0 => HASHPOS + $ :JMPZ(hashLeft24), MLOAD(u32bits[24]) + +hashRight24: + ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) + C :HASHK(E+24), JMP(hashBranchEnd24) + +hashLeft24: + C :HASHK(E+24) + ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) + +hashBranchEnd24: + HASHPOS :HASHKLEN(E+24) + $ => C :HASHKDIGEST(E+24) + + ; BIT 25 + 0 => HASHPOS + $ :JMPZ(hashLeft25), MLOAD(u32bits[25]) + +hashRight25: + ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) + C :HASHK(E+25), JMP(hashBranchEnd25) + +hashLeft25: + C :HASHK(E+25) + ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) + +hashBranchEnd25: + HASHPOS :HASHKLEN(E+25) + $ => C :HASHKDIGEST(E+25) + + ; BIT 26 + 0 => HASHPOS + $ :JMPZ(hashLeft26), MLOAD(u32bits[26]) + +hashRight26: + ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) + C :HASHK(E+26), JMP(hashBranchEnd26) + +hashLeft26: + C :HASHK(E+26) + ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) + +hashBranchEnd26: + HASHPOS :HASHKLEN(E+26) + $ => C :HASHKDIGEST(E+26) + + ; BIT 27 + 0 => HASHPOS + $ :JMPZ(hashLeft27), MLOAD(u32bits[27]) + +hashRight27: + ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) + C :HASHK(E+27), JMP(hashBranchEnd27) + +hashLeft27: + C :HASHK(E+27) + ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) + +hashBranchEnd27: + HASHPOS :HASHKLEN(E+27) + $ => C :HASHKDIGEST(E+27) + + ; BIT 28 + 0 => HASHPOS + $ :JMPZ(hashLeft28), MLOAD(u32bits[28]) + +hashRight28: + ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) + C :HASHK(E+28), JMP(hashBranchEnd28) + +hashLeft28: + C :HASHK(E+28) + ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) + +hashBranchEnd28: + HASHPOS :HASHKLEN(E+28) + $ => C :HASHKDIGEST(E+28) + + ; BIT 29 + 0 => HASHPOS + $ :JMPZ(hashLeft29), MLOAD(u32bits[29]) + +hashRight29: + ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) + C :HASHK(E+29), JMP(hashBranchEnd29) + +hashLeft29: + C :HASHK(E+29) + ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) + +hashBranchEnd29: + HASHPOS :HASHKLEN(E+29) + $ => C :HASHKDIGEST(E+29) + + ; BIT 30 + 0 => HASHPOS + $ :JMPZ(hashLeft30), MLOAD(u32bits[30]) + +hashRight30: + ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) + C :HASHK(E+30), JMP(hashBranchEnd30) + +hashLeft30: + C :HASHK(E+30) + ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) + +hashBranchEnd30: + HASHPOS :HASHKLEN(E+30) + $ => C :HASHKDIGEST(E+30) + + ; BIT 31 + 0 => HASHPOS + $ :JMPZ(hashLeft31), MLOAD(u32bits[31]) + +hashRight31: + ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) + C :HASHK(E+31), JMP(hashBranchEnd31) + +hashLeft31: + C :HASHK(E+31) + ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) + +hashBranchEnd31: + HASHPOS :HASHKLEN(E+31) + $ => C :HASHKDIGEST(E+31) + + E + 31 => E :MSTORE(lastHashKIdUsed) -hashBranchEnd: - HASHPOS :HASHKLEN(E) - $ => C :HASHKDIGEST(E) - B + 1 => D :JMP(verifyMerkleProofLoop) verifyMerkleProofEnd: $ => A :MLOAD(l1InfoRoot) @@ -1573,6 +2059,340 @@ verifyMerkleProofReturn: $ => RR :MLOAD(tmpZkPCVerifyMerkleProof) :RETURN + +;@info fill array u32bits with bits of A value, A must be a value of 32 bits. +;@in A: value +;@out u32bits[32]: bits + +VAR GLOBAL u32bits[32] +VAR GLOBAL u32bits_tmpA +VAR GLOBAL u32bits_tmpB + +u32ToBits: + + A :MSTORE(u32bits_tmpA) + B :MSTORE(u32bits_tmpB) + + ; bit 31 + +u32bits_31A: A - 0x80000000 => B :JMPN(u32bits_31A_0) +u32bits_31B_1: 1 :MSTORE(u32bits[31]), JMP(u32bits_30B) +u32bits_31A_0: 0 :MSTORE(u32bits[31]), JMP(u32bits_30A) + + ; bit 30 + +u32bits_30A: A - 0x40000000 => B :JMPN(u32bits_30A_0) +u32bits_30B_1: 1 :MSTORE(u32bits[30]), JMP(u32bits_29B) +u32bits_30A_0: 0 :MSTORE(u32bits[30]), JMP(u32bits_29A) + +u32bits_30B: B - 0x40000000 => A :JMPN(u32bits_30B_0) +u32bits_30A_1: 1 :MSTORE(u32bits[30]), JMP(u32bits_29A) +u32bits_30B_0: 0 :MSTORE(u32bits[30]), JMP(u32bits_29B) + + ; bit 29 + +u32bits_29A: A - 0x20000000 => B :JMPN(u32bits_29A_0) +u32bits_29B_1: 1 :MSTORE(u32bits[29]), JMP(u32bits_28B) +u32bits_29A_0: 0 :MSTORE(u32bits[29]), JMP(u32bits_28A) + +u32bits_29B: B - 0x20000000 => A :JMPN(u32bits_29B_0) +u32bits_29A_1: 1 :MSTORE(u32bits[29]), JMP(u32bits_28A) +u32bits_29B_0: 0 :MSTORE(u32bits[29]), JMP(u32bits_28B) + + ; bit 28 + +u32bits_28A: A - 0x10000000 => B :JMPN(u32bits_28A_0) +u32bits_28B_1: 1 :MSTORE(u32bits[28]), JMP(u32bits_27B) +u32bits_28A_0: 0 :MSTORE(u32bits[28]), JMP(u32bits_27A) + +u32bits_28B: B - 0x10000000 => A :JMPN(u32bits_28B_0) +u32bits_28A_1: 1 :MSTORE(u32bits[28]), JMP(u32bits_27A) +u32bits_28B_0: 0 :MSTORE(u32bits[28]), JMP(u32bits_27B) + + ; bit 27 + +u32bits_27A: A - 0x08000000 => B :JMPN(u32bits_27A_0) +u32bits_27B_1: 1 :MSTORE(u32bits[27]), JMP(u32bits_26B) +u32bits_27A_0: 0 :MSTORE(u32bits[27]), JMP(u32bits_26A) + +u32bits_27B: B - 0x08000000 => A :JMPN(u32bits_27B_0) +u32bits_27A_1: 1 :MSTORE(u32bits[27]), JMP(u32bits_26A) +u32bits_27B_0: 0 :MSTORE(u32bits[27]), JMP(u32bits_26B) + + ; bit 26 + +u32bits_26A: A - 0x04000000 => B :JMPN(u32bits_26A_0) +u32bits_26B_1: 1 :MSTORE(u32bits[26]), JMP(u32bits_25B) +u32bits_26A_0: 0 :MSTORE(u32bits[26]), JMP(u32bits_25A) + +u32bits_26B: B - 0x04000000 => A :JMPN(u32bits_26B_0) +u32bits_26A_1: 1 :MSTORE(u32bits[26]), JMP(u32bits_25A) +u32bits_26B_0: 0 :MSTORE(u32bits[26]), JMP(u32bits_25B) + + ; bit 25 + +u32bits_25A: A - 0x02000000 => B :JMPN(u32bits_25A_0) +u32bits_25B_1: 1 :MSTORE(u32bits[25]), JMP(u32bits_24B) +u32bits_25A_0: 0 :MSTORE(u32bits[25]), JMP(u32bits_24A) + +u32bits_25B: B - 0x02000000 => A :JMPN(u32bits_25B_0) +u32bits_25A_1: 1 :MSTORE(u32bits[25]), JMP(u32bits_24A) +u32bits_25B_0: 0 :MSTORE(u32bits[25]), JMP(u32bits_24B) + + ; bit 24 + +u32bits_24A: A - 0x01000000 => B :JMPN(u32bits_24A_0) +u32bits_24B_1: 1 :MSTORE(u32bits[24]), JMP(u32bits_23B) +u32bits_24A_0: 0 :MSTORE(u32bits[24]), JMP(u32bits_23A) + +u32bits_24B: B - 0x01000000 => A :JMPN(u32bits_24B_0) +u32bits_24A_1: 1 :MSTORE(u32bits[24]), JMP(u32bits_23A) +u32bits_24B_0: 0 :MSTORE(u32bits[24]), JMP(u32bits_23B) + + ; bit 23 + +u32bits_23A: A - 0x00800000 => B :JMPN(u32bits_23A_0) +u32bits_23B_1: 1 :MSTORE(u32bits[23]), JMP(u32bits_22B) +u32bits_23A_0: 0 :MSTORE(u32bits[23]), JMP(u32bits_22A) + +u32bits_23B: B - 0x00800000 => A :JMPN(u32bits_23B_0) +u32bits_23A_1: 1 :MSTORE(u32bits[23]), JMP(u32bits_22A) +u32bits_23B_0: 0 :MSTORE(u32bits[23]), JMP(u32bits_22B) + + ; bit 22 + +u32bits_22A: A - 0x00400000 => B :JMPN(u32bits_22A_0) +u32bits_22B_1: 1 :MSTORE(u32bits[22]), JMP(u32bits_21B) +u32bits_22A_0: 0 :MSTORE(u32bits[22]), JMP(u32bits_21A) + +u32bits_22B: B - 0x00400000 => A :JMPN(u32bits_22B_0) +u32bits_22A_1: 1 :MSTORE(u32bits[22]), JMP(u32bits_21A) +u32bits_22B_0: 0 :MSTORE(u32bits[22]), JMP(u32bits_21B) + + ; bit 21 + +u32bits_21A: A - 0x00200000 => B :JMPN(u32bits_21A_0) +u32bits_21B_1: 1 :MSTORE(u32bits[21]), JMP(u32bits_20B) +u32bits_21A_0: 0 :MSTORE(u32bits[21]), JMP(u32bits_20A) + +u32bits_21B: B - 0x00200000 => A :JMPN(u32bits_21B_0) +u32bits_21A_1: 1 :MSTORE(u32bits[21]), JMP(u32bits_20A) +u32bits_21B_0: 0 :MSTORE(u32bits[21]), JMP(u32bits_20B) + + ; bit 20 + +u32bits_20A: A - 0x00100000 => B :JMPN(u32bits_20A_0) +u32bits_20B_1: 1 :MSTORE(u32bits[20]), JMP(u32bits_19B) +u32bits_20A_0: 0 :MSTORE(u32bits[20]), JMP(u32bits_19A) + +u32bits_20B: B - 0x00100000 => A :JMPN(u32bits_20B_0) +u32bits_20A_1: 1 :MSTORE(u32bits[20]), JMP(u32bits_19A) +u32bits_20B_0: 0 :MSTORE(u32bits[20]), JMP(u32bits_19B) + + ; bit 19 + +u32bits_19A: A - 0x00080000 => B :JMPN(u32bits_19A_0) +u32bits_19B_1: 1 :MSTORE(u32bits[19]), JMP(u32bits_18B) +u32bits_19A_0: 0 :MSTORE(u32bits[19]), JMP(u32bits_18A) + +u32bits_19B: B - 0x00080000 => A :JMPN(u32bits_19B_0) +u32bits_19A_1: 1 :MSTORE(u32bits[19]), JMP(u32bits_18A) +u32bits_19B_0: 0 :MSTORE(u32bits[19]), JMP(u32bits_18B) + + ; bit 18 + +u32bits_18A: A - 0x00040000 => B :JMPN(u32bits_18A_0) +u32bits_18B_1: 1 :MSTORE(u32bits[18]), JMP(u32bits_17B) +u32bits_18A_0: 0 :MSTORE(u32bits[18]), JMP(u32bits_17A) + +u32bits_18B: B - 0x00040000 => A :JMPN(u32bits_18B_0) +u32bits_18A_1: 1 :MSTORE(u32bits[18]), JMP(u32bits_17A) +u32bits_18B_0: 0 :MSTORE(u32bits[18]), JMP(u32bits_17B) + + ; bit 17 + +u32bits_17A: A - 0x00020000 => B :JMPN(u32bits_17A_0) +u32bits_17B_1: 1 :MSTORE(u32bits[17]), JMP(u32bits_16B) +u32bits_17A_0: 0 :MSTORE(u32bits[17]), JMP(u32bits_16A) + +u32bits_17B: B - 0x00020000 => A :JMPN(u32bits_17B_0) +u32bits_17A_1: 1 :MSTORE(u32bits[17]), JMP(u32bits_16A) +u32bits_17B_0: 0 :MSTORE(u32bits[17]), JMP(u32bits_16B) + + ; bit 16 + +u32bits_16A: A - 0x00010000 => B :JMPN(u32bits_16A_0) +u32bits_16B_1: 1 :MSTORE(u32bits[16]), JMP(u32bits_15B) +u32bits_16A_0: 0 :MSTORE(u32bits[16]), JMP(u32bits_15A) + +u32bits_16B: B - 0x00010000 => A :JMPN(u32bits_16B_0) +u32bits_16A_1: 1 :MSTORE(u32bits[16]), JMP(u32bits_15A) +u32bits_16B_0: 0 :MSTORE(u32bits[16]), JMP(u32bits_15B) + + ; bit 15 + +u32bits_15A: A - 0x00008000 => B :JMPN(u32bits_15A_0) +u32bits_15B_1: 1 :MSTORE(u32bits[15]), JMP(u32bits_14B) +u32bits_15A_0: 0 :MSTORE(u32bits[15]), JMP(u32bits_14A) + +u32bits_15B: B - 0x00008000 => A :JMPN(u32bits_15B_0) +u32bits_15A_1: 1 :MSTORE(u32bits[15]), JMP(u32bits_14A) +u32bits_15B_0: 0 :MSTORE(u32bits[15]), JMP(u32bits_14B) + + ; bit 14 + +u32bits_14A: A - 0x00004000 => B :JMPN(u32bits_14A_0) +u32bits_14B_1: 1 :MSTORE(u32bits[14]), JMP(u32bits_13B) +u32bits_14A_0: 0 :MSTORE(u32bits[14]), JMP(u32bits_13A) + +u32bits_14B: B - 0x00004000 => A :JMPN(u32bits_14B_0) +u32bits_14A_1: 1 :MSTORE(u32bits[14]), JMP(u32bits_13A) +u32bits_14B_0: 0 :MSTORE(u32bits[14]), JMP(u32bits_13B) + + ; bit 13 + +u32bits_13A: A - 0x00002000 => B :JMPN(u32bits_13A_0) +u32bits_13B_1: 1 :MSTORE(u32bits[13]), JMP(u32bits_12B) +u32bits_13A_0: 0 :MSTORE(u32bits[13]), JMP(u32bits_12A) + +u32bits_13B: B - 0x00002000 => A :JMPN(u32bits_13B_0) +u32bits_13A_1: 1 :MSTORE(u32bits[13]), JMP(u32bits_12A) +u32bits_13B_0: 0 :MSTORE(u32bits[13]), JMP(u32bits_12B) + + ; bit 12 + +u32bits_12A: A - 0x00001000 => B :JMPN(u32bits_12A_0) +u32bits_12B_1: 1 :MSTORE(u32bits[12]), JMP(u32bits_11B) +u32bits_12A_0: 0 :MSTORE(u32bits[12]), JMP(u32bits_11A) + +u32bits_12B: B - 0x00001000 => A :JMPN(u32bits_12B_0) +u32bits_12A_1: 1 :MSTORE(u32bits[12]), JMP(u32bits_11A) +u32bits_12B_0: 0 :MSTORE(u32bits[12]), JMP(u32bits_11B) + + ; bit 11 + +u32bits_11A: A - 0x00000800 => B :JMPN(u32bits_11A_0) +u32bits_11B_1: 1 :MSTORE(u32bits[11]), JMP(u32bits_10B) +u32bits_11A_0: 0 :MSTORE(u32bits[11]), JMP(u32bits_10A) + +u32bits_11B: B - 0x00000800 => A :JMPN(u32bits_11B_0) +u32bits_11A_1: 1 :MSTORE(u32bits[11]), JMP(u32bits_10A) +u32bits_11B_0: 0 :MSTORE(u32bits[11]), JMP(u32bits_10B) + + ; bit 10 + +u32bits_10A: A - 0x00000400 => B :JMPN(u32bits_10A_0) +u32bits_10B_1: 1 :MSTORE(u32bits[10]), JMP(u32bits_9B) +u32bits_10A_0: 0 :MSTORE(u32bits[10]), JMP(u32bits_9A) + +u32bits_10B: B - 0x00000400 => A :JMPN(u32bits_10B_0) +u32bits_10A_1: 1 :MSTORE(u32bits[10]), JMP(u32bits_9A) +u32bits_10B_0: 0 :MSTORE(u32bits[10]), JMP(u32bits_9B) + + ; bit 9 + +u32bits_9A: A - 0x00000200 => B :JMPN(u32bits_9A_0) +u32bits_9B_1: 1 :MSTORE(u32bits[9]), JMP(u32bits_8B) +u32bits_9A_0: 0 :MSTORE(u32bits[9]), JMP(u32bits_8A) + +u32bits_9B: B - 0x00000200 => A :JMPN(u32bits_9B_0) +u32bits_9A_1: 1 :MSTORE(u32bits[9]), JMP(u32bits_8A) +u32bits_9B_0: 0 :MSTORE(u32bits[9]), JMP(u32bits_8B) + + ; bit 8 + +u32bits_8A: A - 0x00000100 => B :JMPN(u32bits_8A_0) +u32bits_8B_1: 1 :MSTORE(u32bits[8]), JMP(u32bits_7B) +u32bits_8A_0: 0 :MSTORE(u32bits[8]), JMP(u32bits_7A) + +u32bits_8B: B - 0x00000100 => A :JMPN(u32bits_8B_0) +u32bits_8A_1: 1 :MSTORE(u32bits[8]), JMP(u32bits_7A) +u32bits_8B_0: 0 :MSTORE(u32bits[8]), JMP(u32bits_7B) + + ; bit 7 + +u32bits_7A: A - 0x00000080 => B :JMPN(u32bits_7A_0) +u32bits_7B_1: 1 :MSTORE(u32bits[7]), JMP(u32bits_6B) +u32bits_7A_0: 0 :MSTORE(u32bits[7]), JMP(u32bits_6A) + +u32bits_7B: B - 0x00000080 => A :JMPN(u32bits_7B_0) +u32bits_7A_1: 1 :MSTORE(u32bits[7]), JMP(u32bits_6A) +u32bits_7B_0: 0 :MSTORE(u32bits[7]), JMP(u32bits_6B) + + ; bit 6 + +u32bits_6A: A - 0x00000040 => B :JMPN(u32bits_6A_0) +u32bits_6B_1: 1 :MSTORE(u32bits[6]), JMP(u32bits_5B) +u32bits_6A_0: 0 :MSTORE(u32bits[6]), JMP(u32bits_5A) + +u32bits_6B: B - 0x00000040 => A :JMPN(u32bits_6B_0) +u32bits_6A_1: 1 :MSTORE(u32bits[6]), JMP(u32bits_5A) +u32bits_6B_0: 0 :MSTORE(u32bits[6]), JMP(u32bits_5B) + + ; bit 5 + +u32bits_5A: A - 0x00000020 => B :JMPN(u32bits_5A_0) +u32bits_5B_1: 1 :MSTORE(u32bits[5]), JMP(u32bits_4B) +u32bits_5A_0: 0 :MSTORE(u32bits[5]), JMP(u32bits_4A) + +u32bits_5B: B - 0x00000020 => A :JMPN(u32bits_5B_0) +u32bits_5A_1: 1 :MSTORE(u32bits[5]), JMP(u32bits_4A) +u32bits_5B_0: 0 :MSTORE(u32bits[5]), JMP(u32bits_4B) + + ; bit 4 + +u32bits_4A: A - 0x00000010 => B :JMPN(u32bits_4A_0) +u32bits_4B_1: 1 :MSTORE(u32bits[4]), JMP(u32bits_3B) +u32bits_4A_0: 0 :MSTORE(u32bits[4]), JMP(u32bits_3A) + +u32bits_4B: B - 0x00000010 => A :JMPN(u32bits_4B_0) +u32bits_4A_1: 1 :MSTORE(u32bits[4]), JMP(u32bits_3A) +u32bits_4B_0: 0 :MSTORE(u32bits[4]), JMP(u32bits_3B) + + ; bit 3 + +u32bits_3A: A - 0x00000008 => B :JMPN(u32bits_3A_0) +u32bits_3B_1: 1 :MSTORE(u32bits[3]), JMP(u32bits_2B) +u32bits_3A_0: 0 :MSTORE(u32bits[3]), JMP(u32bits_2A) + +u32bits_3B: B - 0x00000008 => A :JMPN(u32bits_3B_0) +u32bits_3A_1: 1 :MSTORE(u32bits[3]), JMP(u32bits_2A) +u32bits_3B_0: 0 :MSTORE(u32bits[3]), JMP(u32bits_2B) + + ; bit 2 + +u32bits_2A: A - 0x00000004 => B :JMPN(u32bits_2A_0) +u32bits_2B_1: 1 :MSTORE(u32bits[2]), JMP(u32bits_1B) +u32bits_2A_0: 0 :MSTORE(u32bits[2]), JMP(u32bits_1A) + +u32bits_2B: B - 0x00000004 => A :JMPN(u32bits_2B_0) +u32bits_2A_1: 1 :MSTORE(u32bits[2]), JMP(u32bits_1A) +u32bits_2B_0: 0 :MSTORE(u32bits[2]), JMP(u32bits_1B) + + ; bit 1 + +u32bits_1A: A - 0x00000002 => B :JMPN(u32bits_1A_0) +u32bits_1B_1: 1 :MSTORE(u32bits[1]), JMP(u32bits_0B) +u32bits_1A_0: 0 :MSTORE(u32bits[1]), JMP(u32bits_0A) + +u32bits_1B: B - 0x00000002 => A :JMPN(u32bits_1B_0) +u32bits_1A_1: 1 :MSTORE(u32bits[1]), JMP(u32bits_0A) +u32bits_1B_0: 0 :MSTORE(u32bits[1]), JMP(u32bits_0B) + + ; bit 0 + +u32bits_0A: A - 0x00000001 => B :JMPN(u32bits_0A_0) +u32bits_0B_1: 1 :MSTORE(u32bits[0]), JMP(u32bits_end) +u32bits_0A_0: 0 :MSTORE(u32bits[0]), JMP(u32bits_end) + +u32bits_0B: B - 0x00000001 => A :JMPN(u32bits_0B_0) +u32bits_0A_1: 1 :MSTORE(u32bits[0]), JMP(u32bits_end) +u32bits_0B_0: 0 :MSTORE(u32bits[0]) + + $ => A :MLOAD(u32bits_tmpA) + $ => B :MLOAD(u32bits_tmpB), RETURN +u32bits_end: + VAR GLOBAL tmpZkPCreadXFromOffset VAR GLOBAL readXFromCalldataOffset VAR GLOBAL readXFromCalldataLength diff --git a/package.json b/package.json index ea2719fb..6530a6c6 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#v2.0.0-rc.1-fork.7", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/hash-id-offset", "yargs": "^17.5.1" }, "devDependencies": { From 4d08a4ed849cb91fe5a886f9ada1863d1a2878d0 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 15 Dec 2023 16:15:12 +0100 Subject: [PATCH 067/121] optimitzation verify merkle tree v2 --- main/utils.zkasm | 672 +++++++++++++---------------------------------- 1 file changed, 187 insertions(+), 485 deletions(-) diff --git a/main/utils.zkasm b/main/utils.zkasm index e3f0815b..db413c0b 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -1494,7 +1494,8 @@ verifyMerkleProof: ; 1 keccak for the leaf and 32 for the L1InfoTree %MAX_CNT_KECCAK_F - CNT_KECCAK_F - E - 33 :JMPN(outOfCountersKeccak) - %MAX_CNT_STEPS - STEP - 10 * 32 :JMPN(outOfCountersStep) ; 301 steps + ; 7 steps at most per bit + 21 statics + %MAX_CNT_STEPS - STEP - 7 * 32 - 21 :JMPN(outOfCountersStep) RR :MSTORE(tmpZkPCVerifyMerkleProof) @@ -1523,10 +1524,10 @@ verifyMerkleProof: $ => C :HASHKDIGEST(E) ; initial value ; initialization registers for smt verify - 0 => D + 0 => D, A - $ => A :MLOAD(indexL1InfoTree) - :CALL(u32ToBits) + $ => B :MLOAD(indexL1InfoTree) + ; :CALL(u32ToBits) ; prepare new hash $ => E :MLOAD(lastHashKIdUsed) E + 1 => E :MSTORE(lastHashKIdUsed) @@ -1538,30 +1539,32 @@ verifyMerkleProof: ; BIT 0 0 => HASHPOS - $ :JMPZ(hashLeft0), MLOAD(u32bits[0]) + ${B & 0x00000001} :JMPZ(hashLeft0) hashRight0: - ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E) - C :HASHK(E), JMP(hashBranchEnd0) + ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E+0) + C :HASHK(E+0) + A + 0x00000001 => A :JMP(hashBranchEnd0) hashLeft0: - C :HASHK(E) - ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E) + C :HASHK(E+0) + ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E+0) hashBranchEnd0: - HASHPOS :HASHKLEN(E) - $ => C :HASHKDIGEST(E) + HASHPOS :HASHKLEN(E+0) + $ => C :HASHKDIGEST(E+0) ; BIT 1 0 => HASHPOS - $ :JMPZ(hashLeft1), MLOAD(u32bits[1]) + ${B & 0x00000002} :JMPZ(hashLeft1) hashRight1: ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) - C :HASHK(E+1), JMP(hashBranchEnd1) + C :HASHK(E+1) + A + 0x00000002 => A :JMP(hashBranchEnd1) hashLeft1: - C :HASHK(E+1) + C :HASHK(E+1) ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) hashBranchEnd1: @@ -1570,14 +1573,15 @@ hashBranchEnd1: ; BIT 2 0 => HASHPOS - $ :JMPZ(hashLeft2), MLOAD(u32bits[2]) + ${B & 0x00000004} :JMPZ(hashLeft2) hashRight2: ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) - C :HASHK(E+2), JMP(hashBranchEnd2) + C :HASHK(E+2) + A + 0x00000004 => A :JMP(hashBranchEnd2) hashLeft2: - C :HASHK(E+2) + C :HASHK(E+2) ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) hashBranchEnd2: @@ -1586,14 +1590,15 @@ hashBranchEnd2: ; BIT 3 0 => HASHPOS - $ :JMPZ(hashLeft3), MLOAD(u32bits[3]) + ${B & 0x00000008} :JMPZ(hashLeft3) hashRight3: ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) - C :HASHK(E+3), JMP(hashBranchEnd3) + C :HASHK(E+3) + A + 0x00000008 => A :JMP(hashBranchEnd3) hashLeft3: - C :HASHK(E+3) + C :HASHK(E+3) ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) hashBranchEnd3: @@ -1602,14 +1607,15 @@ hashBranchEnd3: ; BIT 4 0 => HASHPOS - $ :JMPZ(hashLeft4), MLOAD(u32bits[4]) + ${B & 0x00000010} :JMPZ(hashLeft4) hashRight4: ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) - C :HASHK(E+4), JMP(hashBranchEnd4) + C :HASHK(E+4) + A + 0x00000010 => A :JMP(hashBranchEnd4) hashLeft4: - C :HASHK(E+4) + C :HASHK(E+4) ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) hashBranchEnd4: @@ -1618,14 +1624,15 @@ hashBranchEnd4: ; BIT 5 0 => HASHPOS - $ :JMPZ(hashLeft5), MLOAD(u32bits[5]) + ${B & 0x00000020} :JMPZ(hashLeft5) hashRight5: ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) - C :HASHK(E+5), JMP(hashBranchEnd5) + C :HASHK(E+5) + A + 0x00000020 => A :JMP(hashBranchEnd5) hashLeft5: - C :HASHK(E+5) + C :HASHK(E+5) ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) hashBranchEnd5: @@ -1634,15 +1641,16 @@ hashBranchEnd5: ; BIT 6 0 => HASHPOS - $ :JMPZ(hashLeft6), MLOAD(u32bits[6]) + ${B & 0x00000040} :JMPZ(hashLeft6) hashRight6: - ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) - C :HASHK(E+6), JMP(hashBranchEnd6) + ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) + C :HASHK(E+6) + A + 0x00000040 => A :JMP(hashBranchEnd6) hashLeft6: - C :HASHK(E+6) - ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) + C :HASHK(E+6) + ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) hashBranchEnd6: HASHPOS :HASHKLEN(E+6) @@ -1650,14 +1658,15 @@ hashBranchEnd6: ; BIT 7 0 => HASHPOS - $ :JMPZ(hashLeft7), MLOAD(u32bits[7]) + ${B & 0x00000080} :JMPZ(hashLeft7) hashRight7: - ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) - C :HASHK(E+7), JMP(hashBranchEnd7) + ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) + C :HASHK(E+7) + A + 0x00000080 => A :JMP(hashBranchEnd7) hashLeft7: - C :HASHK(E+7) + C :HASHK(E+7) ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) hashBranchEnd7: @@ -1666,14 +1675,15 @@ hashBranchEnd7: ; BIT 8 0 => HASHPOS - $ :JMPZ(hashLeft8), MLOAD(u32bits[8]) + ${B & 0x00000100} :JMPZ(hashLeft8) hashRight8: ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) - C :HASHK(E+8), JMP(hashBranchEnd8) + C :HASHK(E+8) + A + 0x00000100 => A :JMP(hashBranchEnd8) hashLeft8: - C :HASHK(E+8) + C :HASHK(E+8) ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) hashBranchEnd8: @@ -1682,14 +1692,15 @@ hashBranchEnd8: ; BIT 9 0 => HASHPOS - $ :JMPZ(hashLeft9), MLOAD(u32bits[9]) + ${B & 0x00000200} :JMPZ(hashLeft9) hashRight9: ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) - C :HASHK(E+9), JMP(hashBranchEnd9) + C :HASHK(E+9) + A + 0x00000200 => A :JMP(hashBranchEnd9) hashLeft9: - C :HASHK(E+9) + C :HASHK(E+9) ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) hashBranchEnd9: @@ -1698,15 +1709,16 @@ hashBranchEnd9: ; BIT 10 0 => HASHPOS - $ :JMPZ(hashLeft10), MLOAD(u32bits[10]) + ${B & 0x00000400} :JMPZ(hashLeft10) hashRight10: - ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) - C :HASHK(E+10), JMP(hashBranchEnd10) + ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) + C :HASHK(E+10) + A + 0x00000400 => A :JMP(hashBranchEnd10) hashLeft10: - C :HASHK(E+10) - ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) + C :HASHK(E+10) + ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) hashBranchEnd10: HASHPOS :HASHKLEN(E+10) @@ -1714,31 +1726,34 @@ hashBranchEnd10: ; BIT 11 0 => HASHPOS - $ :JMPZ(hashLeft11), MLOAD(u32bits[11]) + ${B & 0x00000800} :JMPZ(hashLeft11) hashRight11: - ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) - C :HASHK(E+11), JMP(hashBranchEnd11) + ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) + C :HASHK(E+11) + A + 0x00000800 => A :JMP(hashBranchEnd11) hashLeft11: - C :HASHK(E+11) - ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) + C :HASHK(E+11) + ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) hashBranchEnd11: HASHPOS :HASHKLEN(E+11) $ => C :HASHKDIGEST(E+11) + ; BIT 12 0 => HASHPOS - $ :JMPZ(hashLeft12), MLOAD(u32bits[12]) + ${B & 0x00001000} :JMPZ(hashLeft12) hashRight12: - ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) - C :HASHK(E+12), JMP(hashBranchEnd12) + ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) + C :HASHK(E+12) + A + 0x00001000 => A :JMP(hashBranchEnd12) hashLeft12: - C :HASHK(E+12) - ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) + C :HASHK(E+12) + ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) hashBranchEnd12: HASHPOS :HASHKLEN(E+12) @@ -1746,15 +1761,16 @@ hashBranchEnd12: ; BIT 13 0 => HASHPOS - $ :JMPZ(hashLeft13), MLOAD(u32bits[13]) + ${B & 0x00002000} :JMPZ(hashLeft13) hashRight13: - ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) - C :HASHK(E+13), JMP(hashBranchEnd13) + ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) + C :HASHK(E+13) + A + 0x00002000 => A :JMP(hashBranchEnd13) hashLeft13: - C :HASHK(E+13) - ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) + C :HASHK(E+13) + ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) hashBranchEnd13: HASHPOS :HASHKLEN(E+13) @@ -1762,15 +1778,16 @@ hashBranchEnd13: ; BIT 14 0 => HASHPOS - $ :JMPZ(hashLeft14), MLOAD(u32bits[14]) + ${B & 0x00004000} :JMPZ(hashLeft14) hashRight14: - ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) - C :HASHK(E+14), JMP(hashBranchEnd14) + ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) + C :HASHK(E+14) + A + 0x00004000 => A :JMP(hashBranchEnd14) hashLeft14: - C :HASHK(E+14) - ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) + C :HASHK(E+14) + ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) hashBranchEnd14: HASHPOS :HASHKLEN(E+14) @@ -1778,15 +1795,16 @@ hashBranchEnd14: ; BIT 15 0 => HASHPOS - $ :JMPZ(hashLeft15), MLOAD(u32bits[15]) + ${B & 0x00008000} :JMPZ(hashLeft15) hashRight15: - ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) - C :HASHK(E+15), JMP(hashBranchEnd15) + ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) + C :HASHK(E+15) + A + 0x00008000 => A :JMP(hashBranchEnd15) hashLeft15: - C :HASHK(E+15) - ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) + C :HASHK(E+15) + ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) hashBranchEnd15: HASHPOS :HASHKLEN(E+15) @@ -1794,15 +1812,16 @@ hashBranchEnd15: ; BIT 16 0 => HASHPOS - $ :JMPZ(hashLeft16), MLOAD(u32bits[16]) + ${B & 0x00010000} :JMPZ(hashLeft16) hashRight16: - ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) - C :HASHK(E+16), JMP(hashBranchEnd16) + ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) + C :HASHK(E+16) + A + 0x00010000 => A :JMP(hashBranchEnd16) hashLeft16: - C :HASHK(E+16) - ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) + C :HASHK(E+16) + ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) hashBranchEnd16: HASHPOS :HASHKLEN(E+16) @@ -1810,15 +1829,16 @@ hashBranchEnd16: ; BIT 17 0 => HASHPOS - $ :JMPZ(hashLeft17), MLOAD(u32bits[17]) + ${B & 0x00020000} :JMPZ(hashLeft17) hashRight17: - ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) - C :HASHK(E+17), JMP(hashBranchEnd17) + ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) + C :HASHK(E+17) + A + 0x00020000 => A :JMP(hashBranchEnd17) hashLeft17: - C :HASHK(E+17) - ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) + C :HASHK(E+17) + ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) hashBranchEnd17: HASHPOS :HASHKLEN(E+17) @@ -1826,15 +1846,16 @@ hashBranchEnd17: ; BIT 18 0 => HASHPOS - $ :JMPZ(hashLeft18), MLOAD(u32bits[18]) + ${B & 0x00040000} :JMPZ(hashLeft18) hashRight18: - ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) - C :HASHK(E+18), JMP(hashBranchEnd18) + ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) + C :HASHK(E+18) + A + 0x00040000 => A :JMP(hashBranchEnd18) hashLeft18: - C :HASHK(E+18) - ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) + C :HASHK(E+18) + ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) hashBranchEnd18: HASHPOS :HASHKLEN(E+18) @@ -1842,15 +1863,16 @@ hashBranchEnd18: ; BIT 19 0 => HASHPOS - $ :JMPZ(hashLeft19), MLOAD(u32bits[19]) + ${B & 0x00080000} :JMPZ(hashLeft19) hashRight19: - ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) - C :HASHK(E+19), JMP(hashBranchEnd19) + ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) + C :HASHK(E+19) + A + 0x00080000 => A :JMP(hashBranchEnd19) hashLeft19: - C :HASHK(E+19) - ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) + C :HASHK(E+19) + ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) hashBranchEnd19: HASHPOS :HASHKLEN(E+19) @@ -1858,15 +1880,16 @@ hashBranchEnd19: ; BIT 20 0 => HASHPOS - $ :JMPZ(hashLeft20), MLOAD(u32bits[20]) + ${B & 0x00100000} :JMPZ(hashLeft20) hashRight20: - ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) - C :HASHK(E+20), JMP(hashBranchEnd20) + ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) + C :HASHK(E+20) + A + 0x00100000 => A :JMP(hashBranchEnd20) hashLeft20: - C :HASHK(E+20) - ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) + C :HASHK(E+20) + ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) hashBranchEnd20: HASHPOS :HASHKLEN(E+20) @@ -1874,15 +1897,16 @@ hashBranchEnd20: ; BIT 21 0 => HASHPOS - $ :JMPZ(hashLeft21), MLOAD(u32bits[21]) + ${B & 0x00200000} :JMPZ(hashLeft21) hashRight21: - ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) - C :HASHK(E+21), JMP(hashBranchEnd21) + ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) + C :HASHK(E+21) + A + 0x00200000 => A :JMP(hashBranchEnd21) hashLeft21: - C :HASHK(E+21) - ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) + C :HASHK(E+21) + ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) hashBranchEnd21: HASHPOS :HASHKLEN(E+21) @@ -1890,15 +1914,16 @@ hashBranchEnd21: ; BIT 22 0 => HASHPOS - $ :JMPZ(hashLeft22), MLOAD(u32bits[22]) + ${B & 0x00400000} :JMPZ(hashLeft22) hashRight22: - ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) - C :HASHK(E+22), JMP(hashBranchEnd22) + ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) + C :HASHK(E+22) + A + 0x00400000 => A :JMP(hashBranchEnd22) hashLeft22: - C :HASHK(E+22) - ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) + C :HASHK(E+22) + ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) hashBranchEnd22: HASHPOS :HASHKLEN(E+22) @@ -1906,15 +1931,16 @@ hashBranchEnd22: ; BIT 23 0 => HASHPOS - $ :JMPZ(hashLeft23), MLOAD(u32bits[23]) + ${B & 0x00800000} :JMPZ(hashLeft23) hashRight23: - ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) - C :HASHK(E+23), JMP(hashBranchEnd23) + ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) + C :HASHK(E+23) + A + 0x00800000 => A :JMP(hashBranchEnd23) hashLeft23: - C :HASHK(E+23) - ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) + C :HASHK(E+23) + ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) hashBranchEnd23: HASHPOS :HASHKLEN(E+23) @@ -1922,15 +1948,16 @@ hashBranchEnd23: ; BIT 24 0 => HASHPOS - $ :JMPZ(hashLeft24), MLOAD(u32bits[24]) + ${B & 0x01000000} :JMPZ(hashLeft24) hashRight24: - ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) - C :HASHK(E+24), JMP(hashBranchEnd24) + ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) + C :HASHK(E+24) + A + 0x01000000 => A :JMP(hashBranchEnd24) hashLeft24: - C :HASHK(E+24) - ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) + C :HASHK(E+24) + ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) hashBranchEnd24: HASHPOS :HASHKLEN(E+24) @@ -1938,15 +1965,16 @@ hashBranchEnd24: ; BIT 25 0 => HASHPOS - $ :JMPZ(hashLeft25), MLOAD(u32bits[25]) + ${B & 0x02000000} :JMPZ(hashLeft25) hashRight25: - ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) - C :HASHK(E+25), JMP(hashBranchEnd25) + ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) + C :HASHK(E+25) + A + 0x02000000 => A :JMP(hashBranchEnd25) hashLeft25: - C :HASHK(E+25) - ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) + C :HASHK(E+25) + ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) hashBranchEnd25: HASHPOS :HASHKLEN(E+25) @@ -1954,15 +1982,16 @@ hashBranchEnd25: ; BIT 26 0 => HASHPOS - $ :JMPZ(hashLeft26), MLOAD(u32bits[26]) + ${B & 0x04000000} :JMPZ(hashLeft26) hashRight26: - ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) - C :HASHK(E+26), JMP(hashBranchEnd26) + ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) + C :HASHK(E+26) + A + 0x04000000 => A :JMP(hashBranchEnd26) hashLeft26: - C :HASHK(E+26) - ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) + C :HASHK(E+26) + ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) hashBranchEnd26: HASHPOS :HASHKLEN(E+26) @@ -1970,15 +1999,16 @@ hashBranchEnd26: ; BIT 27 0 => HASHPOS - $ :JMPZ(hashLeft27), MLOAD(u32bits[27]) + ${B & 0x08000000} :JMPZ(hashLeft27) hashRight27: - ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) - C :HASHK(E+27), JMP(hashBranchEnd27) + ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) + C :HASHK(E+27) + A + 0x08000000 => A :JMP(hashBranchEnd27) hashLeft27: - C :HASHK(E+27) - ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) + C :HASHK(E+27) + ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) hashBranchEnd27: HASHPOS :HASHKLEN(E+27) @@ -1986,15 +2016,16 @@ hashBranchEnd27: ; BIT 28 0 => HASHPOS - $ :JMPZ(hashLeft28), MLOAD(u32bits[28]) + ${B & 0x10000000} :JMPZ(hashLeft28) hashRight28: - ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) - C :HASHK(E+28), JMP(hashBranchEnd28) + ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) + C :HASHK(E+28) + A + 0x10000000 => A :JMP(hashBranchEnd28) hashLeft28: - C :HASHK(E+28) - ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) + C :HASHK(E+28) + ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) hashBranchEnd28: HASHPOS :HASHKLEN(E+28) @@ -2002,15 +2033,16 @@ hashBranchEnd28: ; BIT 29 0 => HASHPOS - $ :JMPZ(hashLeft29), MLOAD(u32bits[29]) + ${B & 0x20000000} :JMPZ(hashLeft29) hashRight29: - ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) - C :HASHK(E+29), JMP(hashBranchEnd29) + ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) + C :HASHK(E+29) + A + 0x20000000 => A :JMP(hashBranchEnd29) hashLeft29: - C :HASHK(E+29) - ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) + C :HASHK(E+29) + ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) hashBranchEnd29: HASHPOS :HASHKLEN(E+29) @@ -2018,15 +2050,16 @@ hashBranchEnd29: ; BIT 30 0 => HASHPOS - $ :JMPZ(hashLeft30), MLOAD(u32bits[30]) + ${B & 0x40000000} :JMPZ(hashLeft30) hashRight30: - ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) - C :HASHK(E+30), JMP(hashBranchEnd30) + ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) + C :HASHK(E+30) + A + 0x40000000 => A :JMP(hashBranchEnd30) hashLeft30: - C :HASHK(E+30) - ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) + C :HASHK(E+30) + ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) hashBranchEnd30: HASHPOS :HASHKLEN(E+30) @@ -2034,20 +2067,23 @@ hashBranchEnd30: ; BIT 31 0 => HASHPOS - $ :JMPZ(hashLeft31), MLOAD(u32bits[31]) + ${B & 0x80000000} :JMPZ(hashLeft31) hashRight31: - ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) - C :HASHK(E+31), JMP(hashBranchEnd31) + ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) + C :HASHK(E+31) + A + 0x80000000 => A :JMP(hashBranchEnd31) hashLeft31: - C :HASHK(E+31) - ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) + C :HASHK(E+31) + ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) hashBranchEnd31: HASHPOS :HASHKLEN(E+31) $ => C :HASHKDIGEST(E+31) + ; verify linear combination in A + B :ASSERT E + 31 => E :MSTORE(lastHashKIdUsed) @@ -2059,340 +2095,6 @@ verifyMerkleProofReturn: $ => RR :MLOAD(tmpZkPCVerifyMerkleProof) :RETURN - -;@info fill array u32bits with bits of A value, A must be a value of 32 bits. -;@in A: value -;@out u32bits[32]: bits - -VAR GLOBAL u32bits[32] -VAR GLOBAL u32bits_tmpA -VAR GLOBAL u32bits_tmpB - -u32ToBits: - - A :MSTORE(u32bits_tmpA) - B :MSTORE(u32bits_tmpB) - - ; bit 31 - -u32bits_31A: A - 0x80000000 => B :JMPN(u32bits_31A_0) -u32bits_31B_1: 1 :MSTORE(u32bits[31]), JMP(u32bits_30B) -u32bits_31A_0: 0 :MSTORE(u32bits[31]), JMP(u32bits_30A) - - ; bit 30 - -u32bits_30A: A - 0x40000000 => B :JMPN(u32bits_30A_0) -u32bits_30B_1: 1 :MSTORE(u32bits[30]), JMP(u32bits_29B) -u32bits_30A_0: 0 :MSTORE(u32bits[30]), JMP(u32bits_29A) - -u32bits_30B: B - 0x40000000 => A :JMPN(u32bits_30B_0) -u32bits_30A_1: 1 :MSTORE(u32bits[30]), JMP(u32bits_29A) -u32bits_30B_0: 0 :MSTORE(u32bits[30]), JMP(u32bits_29B) - - ; bit 29 - -u32bits_29A: A - 0x20000000 => B :JMPN(u32bits_29A_0) -u32bits_29B_1: 1 :MSTORE(u32bits[29]), JMP(u32bits_28B) -u32bits_29A_0: 0 :MSTORE(u32bits[29]), JMP(u32bits_28A) - -u32bits_29B: B - 0x20000000 => A :JMPN(u32bits_29B_0) -u32bits_29A_1: 1 :MSTORE(u32bits[29]), JMP(u32bits_28A) -u32bits_29B_0: 0 :MSTORE(u32bits[29]), JMP(u32bits_28B) - - ; bit 28 - -u32bits_28A: A - 0x10000000 => B :JMPN(u32bits_28A_0) -u32bits_28B_1: 1 :MSTORE(u32bits[28]), JMP(u32bits_27B) -u32bits_28A_0: 0 :MSTORE(u32bits[28]), JMP(u32bits_27A) - -u32bits_28B: B - 0x10000000 => A :JMPN(u32bits_28B_0) -u32bits_28A_1: 1 :MSTORE(u32bits[28]), JMP(u32bits_27A) -u32bits_28B_0: 0 :MSTORE(u32bits[28]), JMP(u32bits_27B) - - ; bit 27 - -u32bits_27A: A - 0x08000000 => B :JMPN(u32bits_27A_0) -u32bits_27B_1: 1 :MSTORE(u32bits[27]), JMP(u32bits_26B) -u32bits_27A_0: 0 :MSTORE(u32bits[27]), JMP(u32bits_26A) - -u32bits_27B: B - 0x08000000 => A :JMPN(u32bits_27B_0) -u32bits_27A_1: 1 :MSTORE(u32bits[27]), JMP(u32bits_26A) -u32bits_27B_0: 0 :MSTORE(u32bits[27]), JMP(u32bits_26B) - - ; bit 26 - -u32bits_26A: A - 0x04000000 => B :JMPN(u32bits_26A_0) -u32bits_26B_1: 1 :MSTORE(u32bits[26]), JMP(u32bits_25B) -u32bits_26A_0: 0 :MSTORE(u32bits[26]), JMP(u32bits_25A) - -u32bits_26B: B - 0x04000000 => A :JMPN(u32bits_26B_0) -u32bits_26A_1: 1 :MSTORE(u32bits[26]), JMP(u32bits_25A) -u32bits_26B_0: 0 :MSTORE(u32bits[26]), JMP(u32bits_25B) - - ; bit 25 - -u32bits_25A: A - 0x02000000 => B :JMPN(u32bits_25A_0) -u32bits_25B_1: 1 :MSTORE(u32bits[25]), JMP(u32bits_24B) -u32bits_25A_0: 0 :MSTORE(u32bits[25]), JMP(u32bits_24A) - -u32bits_25B: B - 0x02000000 => A :JMPN(u32bits_25B_0) -u32bits_25A_1: 1 :MSTORE(u32bits[25]), JMP(u32bits_24A) -u32bits_25B_0: 0 :MSTORE(u32bits[25]), JMP(u32bits_24B) - - ; bit 24 - -u32bits_24A: A - 0x01000000 => B :JMPN(u32bits_24A_0) -u32bits_24B_1: 1 :MSTORE(u32bits[24]), JMP(u32bits_23B) -u32bits_24A_0: 0 :MSTORE(u32bits[24]), JMP(u32bits_23A) - -u32bits_24B: B - 0x01000000 => A :JMPN(u32bits_24B_0) -u32bits_24A_1: 1 :MSTORE(u32bits[24]), JMP(u32bits_23A) -u32bits_24B_0: 0 :MSTORE(u32bits[24]), JMP(u32bits_23B) - - ; bit 23 - -u32bits_23A: A - 0x00800000 => B :JMPN(u32bits_23A_0) -u32bits_23B_1: 1 :MSTORE(u32bits[23]), JMP(u32bits_22B) -u32bits_23A_0: 0 :MSTORE(u32bits[23]), JMP(u32bits_22A) - -u32bits_23B: B - 0x00800000 => A :JMPN(u32bits_23B_0) -u32bits_23A_1: 1 :MSTORE(u32bits[23]), JMP(u32bits_22A) -u32bits_23B_0: 0 :MSTORE(u32bits[23]), JMP(u32bits_22B) - - ; bit 22 - -u32bits_22A: A - 0x00400000 => B :JMPN(u32bits_22A_0) -u32bits_22B_1: 1 :MSTORE(u32bits[22]), JMP(u32bits_21B) -u32bits_22A_0: 0 :MSTORE(u32bits[22]), JMP(u32bits_21A) - -u32bits_22B: B - 0x00400000 => A :JMPN(u32bits_22B_0) -u32bits_22A_1: 1 :MSTORE(u32bits[22]), JMP(u32bits_21A) -u32bits_22B_0: 0 :MSTORE(u32bits[22]), JMP(u32bits_21B) - - ; bit 21 - -u32bits_21A: A - 0x00200000 => B :JMPN(u32bits_21A_0) -u32bits_21B_1: 1 :MSTORE(u32bits[21]), JMP(u32bits_20B) -u32bits_21A_0: 0 :MSTORE(u32bits[21]), JMP(u32bits_20A) - -u32bits_21B: B - 0x00200000 => A :JMPN(u32bits_21B_0) -u32bits_21A_1: 1 :MSTORE(u32bits[21]), JMP(u32bits_20A) -u32bits_21B_0: 0 :MSTORE(u32bits[21]), JMP(u32bits_20B) - - ; bit 20 - -u32bits_20A: A - 0x00100000 => B :JMPN(u32bits_20A_0) -u32bits_20B_1: 1 :MSTORE(u32bits[20]), JMP(u32bits_19B) -u32bits_20A_0: 0 :MSTORE(u32bits[20]), JMP(u32bits_19A) - -u32bits_20B: B - 0x00100000 => A :JMPN(u32bits_20B_0) -u32bits_20A_1: 1 :MSTORE(u32bits[20]), JMP(u32bits_19A) -u32bits_20B_0: 0 :MSTORE(u32bits[20]), JMP(u32bits_19B) - - ; bit 19 - -u32bits_19A: A - 0x00080000 => B :JMPN(u32bits_19A_0) -u32bits_19B_1: 1 :MSTORE(u32bits[19]), JMP(u32bits_18B) -u32bits_19A_0: 0 :MSTORE(u32bits[19]), JMP(u32bits_18A) - -u32bits_19B: B - 0x00080000 => A :JMPN(u32bits_19B_0) -u32bits_19A_1: 1 :MSTORE(u32bits[19]), JMP(u32bits_18A) -u32bits_19B_0: 0 :MSTORE(u32bits[19]), JMP(u32bits_18B) - - ; bit 18 - -u32bits_18A: A - 0x00040000 => B :JMPN(u32bits_18A_0) -u32bits_18B_1: 1 :MSTORE(u32bits[18]), JMP(u32bits_17B) -u32bits_18A_0: 0 :MSTORE(u32bits[18]), JMP(u32bits_17A) - -u32bits_18B: B - 0x00040000 => A :JMPN(u32bits_18B_0) -u32bits_18A_1: 1 :MSTORE(u32bits[18]), JMP(u32bits_17A) -u32bits_18B_0: 0 :MSTORE(u32bits[18]), JMP(u32bits_17B) - - ; bit 17 - -u32bits_17A: A - 0x00020000 => B :JMPN(u32bits_17A_0) -u32bits_17B_1: 1 :MSTORE(u32bits[17]), JMP(u32bits_16B) -u32bits_17A_0: 0 :MSTORE(u32bits[17]), JMP(u32bits_16A) - -u32bits_17B: B - 0x00020000 => A :JMPN(u32bits_17B_0) -u32bits_17A_1: 1 :MSTORE(u32bits[17]), JMP(u32bits_16A) -u32bits_17B_0: 0 :MSTORE(u32bits[17]), JMP(u32bits_16B) - - ; bit 16 - -u32bits_16A: A - 0x00010000 => B :JMPN(u32bits_16A_0) -u32bits_16B_1: 1 :MSTORE(u32bits[16]), JMP(u32bits_15B) -u32bits_16A_0: 0 :MSTORE(u32bits[16]), JMP(u32bits_15A) - -u32bits_16B: B - 0x00010000 => A :JMPN(u32bits_16B_0) -u32bits_16A_1: 1 :MSTORE(u32bits[16]), JMP(u32bits_15A) -u32bits_16B_0: 0 :MSTORE(u32bits[16]), JMP(u32bits_15B) - - ; bit 15 - -u32bits_15A: A - 0x00008000 => B :JMPN(u32bits_15A_0) -u32bits_15B_1: 1 :MSTORE(u32bits[15]), JMP(u32bits_14B) -u32bits_15A_0: 0 :MSTORE(u32bits[15]), JMP(u32bits_14A) - -u32bits_15B: B - 0x00008000 => A :JMPN(u32bits_15B_0) -u32bits_15A_1: 1 :MSTORE(u32bits[15]), JMP(u32bits_14A) -u32bits_15B_0: 0 :MSTORE(u32bits[15]), JMP(u32bits_14B) - - ; bit 14 - -u32bits_14A: A - 0x00004000 => B :JMPN(u32bits_14A_0) -u32bits_14B_1: 1 :MSTORE(u32bits[14]), JMP(u32bits_13B) -u32bits_14A_0: 0 :MSTORE(u32bits[14]), JMP(u32bits_13A) - -u32bits_14B: B - 0x00004000 => A :JMPN(u32bits_14B_0) -u32bits_14A_1: 1 :MSTORE(u32bits[14]), JMP(u32bits_13A) -u32bits_14B_0: 0 :MSTORE(u32bits[14]), JMP(u32bits_13B) - - ; bit 13 - -u32bits_13A: A - 0x00002000 => B :JMPN(u32bits_13A_0) -u32bits_13B_1: 1 :MSTORE(u32bits[13]), JMP(u32bits_12B) -u32bits_13A_0: 0 :MSTORE(u32bits[13]), JMP(u32bits_12A) - -u32bits_13B: B - 0x00002000 => A :JMPN(u32bits_13B_0) -u32bits_13A_1: 1 :MSTORE(u32bits[13]), JMP(u32bits_12A) -u32bits_13B_0: 0 :MSTORE(u32bits[13]), JMP(u32bits_12B) - - ; bit 12 - -u32bits_12A: A - 0x00001000 => B :JMPN(u32bits_12A_0) -u32bits_12B_1: 1 :MSTORE(u32bits[12]), JMP(u32bits_11B) -u32bits_12A_0: 0 :MSTORE(u32bits[12]), JMP(u32bits_11A) - -u32bits_12B: B - 0x00001000 => A :JMPN(u32bits_12B_0) -u32bits_12A_1: 1 :MSTORE(u32bits[12]), JMP(u32bits_11A) -u32bits_12B_0: 0 :MSTORE(u32bits[12]), JMP(u32bits_11B) - - ; bit 11 - -u32bits_11A: A - 0x00000800 => B :JMPN(u32bits_11A_0) -u32bits_11B_1: 1 :MSTORE(u32bits[11]), JMP(u32bits_10B) -u32bits_11A_0: 0 :MSTORE(u32bits[11]), JMP(u32bits_10A) - -u32bits_11B: B - 0x00000800 => A :JMPN(u32bits_11B_0) -u32bits_11A_1: 1 :MSTORE(u32bits[11]), JMP(u32bits_10A) -u32bits_11B_0: 0 :MSTORE(u32bits[11]), JMP(u32bits_10B) - - ; bit 10 - -u32bits_10A: A - 0x00000400 => B :JMPN(u32bits_10A_0) -u32bits_10B_1: 1 :MSTORE(u32bits[10]), JMP(u32bits_9B) -u32bits_10A_0: 0 :MSTORE(u32bits[10]), JMP(u32bits_9A) - -u32bits_10B: B - 0x00000400 => A :JMPN(u32bits_10B_0) -u32bits_10A_1: 1 :MSTORE(u32bits[10]), JMP(u32bits_9A) -u32bits_10B_0: 0 :MSTORE(u32bits[10]), JMP(u32bits_9B) - - ; bit 9 - -u32bits_9A: A - 0x00000200 => B :JMPN(u32bits_9A_0) -u32bits_9B_1: 1 :MSTORE(u32bits[9]), JMP(u32bits_8B) -u32bits_9A_0: 0 :MSTORE(u32bits[9]), JMP(u32bits_8A) - -u32bits_9B: B - 0x00000200 => A :JMPN(u32bits_9B_0) -u32bits_9A_1: 1 :MSTORE(u32bits[9]), JMP(u32bits_8A) -u32bits_9B_0: 0 :MSTORE(u32bits[9]), JMP(u32bits_8B) - - ; bit 8 - -u32bits_8A: A - 0x00000100 => B :JMPN(u32bits_8A_0) -u32bits_8B_1: 1 :MSTORE(u32bits[8]), JMP(u32bits_7B) -u32bits_8A_0: 0 :MSTORE(u32bits[8]), JMP(u32bits_7A) - -u32bits_8B: B - 0x00000100 => A :JMPN(u32bits_8B_0) -u32bits_8A_1: 1 :MSTORE(u32bits[8]), JMP(u32bits_7A) -u32bits_8B_0: 0 :MSTORE(u32bits[8]), JMP(u32bits_7B) - - ; bit 7 - -u32bits_7A: A - 0x00000080 => B :JMPN(u32bits_7A_0) -u32bits_7B_1: 1 :MSTORE(u32bits[7]), JMP(u32bits_6B) -u32bits_7A_0: 0 :MSTORE(u32bits[7]), JMP(u32bits_6A) - -u32bits_7B: B - 0x00000080 => A :JMPN(u32bits_7B_0) -u32bits_7A_1: 1 :MSTORE(u32bits[7]), JMP(u32bits_6A) -u32bits_7B_0: 0 :MSTORE(u32bits[7]), JMP(u32bits_6B) - - ; bit 6 - -u32bits_6A: A - 0x00000040 => B :JMPN(u32bits_6A_0) -u32bits_6B_1: 1 :MSTORE(u32bits[6]), JMP(u32bits_5B) -u32bits_6A_0: 0 :MSTORE(u32bits[6]), JMP(u32bits_5A) - -u32bits_6B: B - 0x00000040 => A :JMPN(u32bits_6B_0) -u32bits_6A_1: 1 :MSTORE(u32bits[6]), JMP(u32bits_5A) -u32bits_6B_0: 0 :MSTORE(u32bits[6]), JMP(u32bits_5B) - - ; bit 5 - -u32bits_5A: A - 0x00000020 => B :JMPN(u32bits_5A_0) -u32bits_5B_1: 1 :MSTORE(u32bits[5]), JMP(u32bits_4B) -u32bits_5A_0: 0 :MSTORE(u32bits[5]), JMP(u32bits_4A) - -u32bits_5B: B - 0x00000020 => A :JMPN(u32bits_5B_0) -u32bits_5A_1: 1 :MSTORE(u32bits[5]), JMP(u32bits_4A) -u32bits_5B_0: 0 :MSTORE(u32bits[5]), JMP(u32bits_4B) - - ; bit 4 - -u32bits_4A: A - 0x00000010 => B :JMPN(u32bits_4A_0) -u32bits_4B_1: 1 :MSTORE(u32bits[4]), JMP(u32bits_3B) -u32bits_4A_0: 0 :MSTORE(u32bits[4]), JMP(u32bits_3A) - -u32bits_4B: B - 0x00000010 => A :JMPN(u32bits_4B_0) -u32bits_4A_1: 1 :MSTORE(u32bits[4]), JMP(u32bits_3A) -u32bits_4B_0: 0 :MSTORE(u32bits[4]), JMP(u32bits_3B) - - ; bit 3 - -u32bits_3A: A - 0x00000008 => B :JMPN(u32bits_3A_0) -u32bits_3B_1: 1 :MSTORE(u32bits[3]), JMP(u32bits_2B) -u32bits_3A_0: 0 :MSTORE(u32bits[3]), JMP(u32bits_2A) - -u32bits_3B: B - 0x00000008 => A :JMPN(u32bits_3B_0) -u32bits_3A_1: 1 :MSTORE(u32bits[3]), JMP(u32bits_2A) -u32bits_3B_0: 0 :MSTORE(u32bits[3]), JMP(u32bits_2B) - - ; bit 2 - -u32bits_2A: A - 0x00000004 => B :JMPN(u32bits_2A_0) -u32bits_2B_1: 1 :MSTORE(u32bits[2]), JMP(u32bits_1B) -u32bits_2A_0: 0 :MSTORE(u32bits[2]), JMP(u32bits_1A) - -u32bits_2B: B - 0x00000004 => A :JMPN(u32bits_2B_0) -u32bits_2A_1: 1 :MSTORE(u32bits[2]), JMP(u32bits_1A) -u32bits_2B_0: 0 :MSTORE(u32bits[2]), JMP(u32bits_1B) - - ; bit 1 - -u32bits_1A: A - 0x00000002 => B :JMPN(u32bits_1A_0) -u32bits_1B_1: 1 :MSTORE(u32bits[1]), JMP(u32bits_0B) -u32bits_1A_0: 0 :MSTORE(u32bits[1]), JMP(u32bits_0A) - -u32bits_1B: B - 0x00000002 => A :JMPN(u32bits_1B_0) -u32bits_1A_1: 1 :MSTORE(u32bits[1]), JMP(u32bits_0A) -u32bits_1B_0: 0 :MSTORE(u32bits[1]), JMP(u32bits_0B) - - ; bit 0 - -u32bits_0A: A - 0x00000001 => B :JMPN(u32bits_0A_0) -u32bits_0B_1: 1 :MSTORE(u32bits[0]), JMP(u32bits_end) -u32bits_0A_0: 0 :MSTORE(u32bits[0]), JMP(u32bits_end) - -u32bits_0B: B - 0x00000001 => A :JMPN(u32bits_0B_0) -u32bits_0A_1: 1 :MSTORE(u32bits[0]), JMP(u32bits_end) -u32bits_0B_0: 0 :MSTORE(u32bits[0]) - - $ => A :MLOAD(u32bits_tmpA) - $ => B :MLOAD(u32bits_tmpB), RETURN -u32bits_end: - VAR GLOBAL tmpZkPCreadXFromOffset VAR GLOBAL readXFromCalldataOffset VAR GLOBAL readXFromCalldataLength From 00c431ea9c6f23bb893b2ffc175e2a253117a948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Fri, 15 Dec 2023 18:16:16 +0100 Subject: [PATCH 068/121] array_square coverage completed --- main/modexp/array_lib/array_square.zkasm | 3 ++- test/testArrayArith.zkasm | 32 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index ad93fd93..897d85e4 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -75,8 +75,9 @@ array_square_clean_out: RR :JMPZ(array_square_ai_times_ai, array_square_clean_out) ; Begin of branching -; In the is_negative_X branches, we perform subtraction of a value with three chunks +; We perform subtraction of a value with three chunks ; Therefore, the subtraction can produce carry until the highest chunk +; e.g. (base² + y) - (y+1) = 0 array_square_is_negative_1: $ => C :SUB, JMPNC(__return_array_square_is_negative_1) ;----------------- diff --git a/test/testArrayArith.zkasm b/test/testArrayArith.zkasm index c14251ac..2374a8de 100644 --- a/test/testArrayArith.zkasm +++ b/test/testArrayArith.zkasm @@ -343,6 +343,38 @@ start: 5 => E 115792089237316195423570985008687907853269984665640564039457584007913129639934n :MLOAD(array_square_out + E) 6 :MLOAD(array_square_len_out) + + ; 8] [272043482145244634591109928786079352n,81877371507464127617551201542979628307507432471243237061821853600756754782485n,176318528146701254200802196825427983451687n] + ; this covers the edge case where carry is of the form -a_i·a_i + ; and it produces carry when added to the second chunk of 2·a_i·a_i + out[i + i] + ; e.g., when the subtraction is of the form (base² + y) - (y+1) = 0 + ;---------------------- + ; I obtained a (3-chunk) input by solving the system of inequalities: + ; 2·x² + z = base² + y + ; x² > y + ; 0 < x,y,z < base + ; (x,y ∈ ℕ and z ∈ 2ℕ) + ; where x = a_1 and z = out[2]. The solution ensures that 2·a_1·a_1 + out[2] > base², while 2·a_1·a_1 + out[2] - a_1·a_1 < base² + ; Then I simply found an appropriate pair of a_0,a_2 such that 2·a_0·a_2 = out[2] + 3 => C + 272043482145244634591109928786079352n :MSTORE(array_square_in) + 1 => E + 81877371507464127617551201542979628307507432471243237061821853600756754782485n :MSTORE(array_square_in + E) + 2 => E + 176318528146701254200802196825427983451687n :MSTORE(array_square_in + E) + :CALL(array_square) + 74007656177710036293062386420979166962778595461878138943934059640739904n :MLOAD(array_square_out) + 1 => E + 107309681785116775741345228420276669267595434811710002878660662063722468151216n :MLOAD(array_square_out + E) + 2 => E + 47966306363752936198863311407838158502039511278988772633471074046272807492009n :MLOAD(array_square_out + E) + 3 => E + 109177356221965282998310125805498648173787805805410017775027543248980737204326n :MLOAD(array_square_out + E) + 4 => E + 15873116718318493168742852298661062116740566009918431601066595319216311981693n :MLOAD(array_square_out + E) + 5 => E + 268483n :MLOAD(array_square_out + E) + 6 :MLOAD(array_square_len_out) ; --------------------------------------------------------------- ; division From d98a85855d9236f378d08c32c14ee1a6379400d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 18 Dec 2023 10:09:34 +0100 Subject: [PATCH 069/121] Starting the refactor with array add --- main/modexp/array_lib/array_add_AGTB.zkasm | 64 +++++++++------------ main/modexp/array_lib/array_add_short.zkasm | 33 +++++------ 2 files changed, 42 insertions(+), 55 deletions(-) diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index 3982aa5f..8e28339c 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -36,7 +36,7 @@ ; return result; ; } -; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead if possible. +; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead. VAR GLOBAL array_add_AGTB_inA[%ARRAY_MAX_LEN] VAR GLOBAL array_add_AGTB_inB[%ARRAY_MAX_LEN] @@ -60,71 +60,61 @@ array_add_AGTB: 0 => E ; index in loops 0 :MSTORE(array_add_AGTB_carry) - :JMP(array_add_AGTB_loopZero2inB) - -; Begin of branching -array_add_AGTB_add_carry1: - D + 1 => D :JMP(return_array_add_AGTB_add_carry1) - -array_add_AGTB_add_carry2: - D + 1 => D :JMP(return_array_add_AGTB_add_carry2) - -array_add_AGTB_add_carry3: - D + 1 => D :JMP(return_array_add_AGTB_add_carry3) -; End of branching array_add_AGTB_loopZero2inB: - 0 => D ; for the carry + ; The result will be stored as D·base + C + + 0 => D ; reset the carry chunk - ; a[i] + b[i] + ; a[i] + b[i], where a[i],b[i] ∈ [0,base-1]: This number cannot be GT base + (base - 2), two chunks $ => A :MLOAD(array_add_AGTB_inA + E) $ => B :MLOAD(array_add_AGTB_inB + E) - $ => C :ADD, JMPC(array_add_AGTB_add_carry1) - return_array_add_AGTB_add_carry1: + $ => C :ADD, JMPNC(__array_add_AGTB_continue_1) + 1 => D + __array_add_AGTB_continue_1: - ; sum = (a[i] + b[i]) + carry + ; sum = (a[i] + b[i]) + carry: This number cannot be GT base + (base - 1), two chunks $ => A :MLOAD(array_add_AGTB_carry) C => B - $ => C :ADD, JMPC(array_add_AGTB_add_carry2) - return_array_add_AGTB_add_carry2: + $ => C :ADD, JMPNC(__array_add_AGTB_continue_2) + 1 => D + __array_add_AGTB_continue_2: C :MSTORE(array_add_AGTB_out + E) D :MSTORE(array_add_AGTB_carry) - E + 1 => E - E => A + E + 1 => E,A $ => B :MLOAD(array_add_AGTB_len_inB) - $ :EQ, JMPC(array_add_AGTB_loop_index_check1, array_add_AGTB_loopZero2inB) + B - A :JMPZ(array_add_AGTB_loop_index_check, array_add_AGTB_loopZero2inB) -array_add_AGTB_loop_index_check1: - E => A +array_add_AGTB_loop_index_check: $ => B :MLOAD(array_add_AGTB_len_inA) - $ :EQ, JMPC(array_add_AGTB_check_carry) + B - A :JMPZ(array_add_AGTB_check_carry) + 0 => D array_add_AGTB_loopInB2InA: - ; sum = a[i] + carry + ; sum = a[i] + carry: This number cannot be GT base, two chunks $ => A :MLOAD(array_add_AGTB_inA + E) $ => B :MLOAD(array_add_AGTB_carry) - $ => C :ADD, JMPC(array_add_AGTB_add_carry3) - return_array_add_AGTB_add_carry3: + $ => C :ADD, JMPNC(__array_add_AGTB_continue_3) + 1 => D + __array_add_AGTB_continue_3: C :MSTORE(array_add_AGTB_out + E) D :MSTORE(array_add_AGTB_carry) - E + 1 => E - E => A + E + 1 => E,A $ => B :MLOAD(array_add_AGTB_len_inA) - $ :EQ, JMPC(array_add_AGTB_check_carry, array_add_AGTB_loopInB2InA) + B - A :JMPZ(array_add_AGTB_check_carry, array_add_AGTB_loopInB2InA) array_add_AGTB_check_carry: - $ => A :MLOAD(array_add_AGTB_carry) - 1 => B - $ :EQ, JMPNC(array_add_AGTB_len_out) + D => A + A :JMPZ(__array_add_AGTB_continue_4) + ; In this case, the carry = 1 and we should append it to the result 1 :MSTORE(array_add_AGTB_out + E) E + 1 :MSTORE(array_add_AGTB_len_out) :JMP(array_add_AGTB_end) - -array_add_AGTB_len_out: + __array_add_AGTB_continue_4: E :MSTORE(array_add_AGTB_len_out) array_add_AGTB_end: diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index 04d2bd42..cbb05c66 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -48,40 +48,37 @@ array_add_short: 0 => E ; index in loops $ => A :MLOAD(array_add_short_inB) A :MSTORE(array_add_short_carry) - :JMP(array_add_short_loopZero2inA) - -; Begin of branching -array_add_short_add_carry: - D + 1 => D :JMP(return_array_add_short_add_carry) -; End of branching array_add_short_loopZero2inA: - 0 => D ; for the carry + ; The result will be stored as D·base + C + + 0 => D ; reset the carry chunk - ; a[i] + carry. If i = 0, then carry = inB. + ; a[i] + carry, where a[i] ∈ [0,base-1]: + ; · If i = 0, then carry = inB and then the number cannot be GT base + (base - 2), two chunks + ; · Otherwise, the number cannot be GT base, two chunks $ => A :MLOAD(array_add_short_inA + E) $ => B :MLOAD(array_add_short_carry) - $ => C :ADD, JMPC(array_add_short_add_carry) - return_array_add_short_add_carry: + $ => C :ADD, JMPNC(__array_add_short_continue1) + 1 => D + __array_add_short_continue1: C :MSTORE(array_add_short_out + E) D :MSTORE(array_add_short_carry) - E + 1 => E - E => A + E + 1 => E,A $ => B :MLOAD(array_add_short_len_inA) - $ :EQ, JMPC(array_add_short_check_carry, array_add_short_loopZero2inA) + B - A :JMPZ(array_add_short_check_carry, array_add_short_loopZero2inA) array_add_short_check_carry: D => A - 1 => B - $ :EQ, JMPNC(array_add_short_len_out) + A :JMPZ(__array_add_short_continue2) + ; In this case, the carry = 1 and we should append it to the result 1 :MSTORE(array_add_short_out + E) E + 1 :MSTORE(array_add_short_len_out) :JMP(array_add_short_end) - -array_add_short_len_out: - E :MSTORE(array_add_short_len_out) + __array_add_short_continue2: + E :MSTORE(array_add_short_len_out) array_add_short_end: $ => RR :MLOAD(array_add_short_RR) From 9d1ab724bdf375a22aeae9efc05dd2716713965f Mon Sep 17 00:00:00 2001 From: laisolizq Date: Mon, 18 Dec 2023 15:22:45 +0100 Subject: [PATCH 070/121] fix sha256 retcalllength > 32 --- main/precompiled/pre-sha2-256.zkasm | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index eb7eeac4..5b5b00dc 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -9,7 +9,6 @@ */ VAR GLOBAL sha256DataOffset VAR GLOBAL sha256DataId -VAR GLOBAL sha256HashPos VAR GLOBAL sha256Hash VAR GLOBAL tmpZkSHA256 @@ -57,7 +56,7 @@ funcSHA256: $ => E :MLOAD(sha256DataId) E + 1 :MSTORE(sha256DataId) - ; copy sha256 to retData (hash 32 bytes) + ; copy sha256 to memory (hash 32 bytes) 0 => E A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset] @@ -69,15 +68,17 @@ SHA256dataReturn: A => CTX B :MSTORE(retDataCTX) B => CTX - ; Copy from memory current CTX to memory origin CTX - 0 => E + ; copy sha256 to retData (hash 32 bytes) $ => C :MLOAD(retCallLength) - ; MLOAD memory current CTX - :CALL(MLOADX) $ => E :MLOAD(retCallOffset) $ => CTX :MLOAD(originCTX) + C - 32 :JMPN(continueSHA256dataReturn) + 32 => C + +continueSHA256dataReturn: + $ => A :MLOAD(sha256Hash) ; MSTORE memory origin CTX - A :MSTORE(bytesToStore), CALL(MSTOREX) + A :MSTORE(bytesToStore), CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset] ; set currentCTX CTX :MSTORE(currentCTX), JMP(preEnd) @@ -108,8 +109,7 @@ SHA256dataFinal: C :MSTORE(readXFromCalldataLength) E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] $ => A :MLOAD(readXFromCalldataResult) - 32 - C => D - zkPC+1 => RR :JMP(SHRarith) + 32 - C => D :CALL(SHRarith) $ => E :MLOAD(sha256DataId) C => D A :HASHS(E) From 4e22a2d00d0ade46f3dcbe9f0788c29e1c152528 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Thu, 14 Dec 2023 13:58:42 +0100 Subject: [PATCH 071/121] fix pre-modexp memory --- main/precompiled/pre-ecAdd.zkasm | 2 +- main/precompiled/pre-ecMul.zkasm | 2 +- main/precompiled/pre-ecPairing.zkasm | 4 -- main/precompiled/pre-modexp.zkasm | 73 ++++++++++++++++++++-------- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/main/precompiled/pre-ecAdd.zkasm b/main/precompiled/pre-ecAdd.zkasm index 54bf9722..eaaf7a16 100644 --- a/main/precompiled/pre-ecAdd.zkasm +++ b/main/precompiled/pre-ecAdd.zkasm @@ -74,7 +74,7 @@ funcEcAdd: :JMP(endECADD) continueEcAdd: - :CALL(MSTOREX); in: [bytesToStore, E: offset] out: [E: new offset] + :CALL(MSTOREX); in: [bytesToStore, E: offset, C: length] out: [E: new offset] :JMP(endECADD) preEndECADD: diff --git a/main/precompiled/pre-ecMul.zkasm b/main/precompiled/pre-ecMul.zkasm index a6b144aa..2c143390 100644 --- a/main/precompiled/pre-ecMul.zkasm +++ b/main/precompiled/pre-ecMul.zkasm @@ -72,7 +72,7 @@ funcEcMul: :JMP(endECMUL) continueEcMul: - :CALL(MSTOREX); in: [bytesToStore, E: offset] out: [E: new offset] + :CALL(MSTOREX); in: [bytesToStore, E: offset, C: length] out: [E: new offset] :JMP(endECMUL) preEndECMUL: diff --git a/main/precompiled/pre-ecPairing.zkasm b/main/precompiled/pre-ecPairing.zkasm index fb592c6d..e8e47693 100644 --- a/main/precompiled/pre-ecPairing.zkasm +++ b/main/precompiled/pre-ecPairing.zkasm @@ -35,10 +35,6 @@ funcEcPairing: %MAX_CNT_STEPS - STEP - 550000 - 200000*A :JMPN(outOfCountersStep) :JMP(afterCounts) - $ => A :MLOAD(retCallLength) - 32 => B - $ :LT,JMPC(preEndFail) - counters6: %MAX_CNT_BINARY - CNT_BINARY - 400 :JMPN(outOfCountersBinary) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 887ae1ee..991c81ff 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -37,6 +37,8 @@ VAR GLOBAL modexp_Msize VAR GLOBAL modexp_Mend VAR GLOBAL modexp_offset VAR GLOBAL modexp_returnIndex +VAR GLOBAL modexp_returnFirstIndex +VAR GLOBAL modexp_returnIndexRem VAR GLOBAL expLenBits funcModexp: @@ -71,9 +73,8 @@ funcModexp: E :MSTORE(modexp_offset) ; get exp offset = 96 bytes (Bsize | Esize | Msize) + Bsize $ => A :MLOAD(modexp_Bsize) - A :MSTORE(arithA) - 96 :MSTORE(arithB), CALL(addARITH) - $ => A :MLOAD(arithRes1) + 96 => B + $ => A :ADD $ => B :MLOAD(txCalldataLen) ; expLenBits = bit length of first 32 bytes of exp 0 :MSTORE(expLenBits) @@ -145,7 +146,9 @@ calculateGas: $ => A :MLOAD(arithRes1) $ => B :MLOAD(expLenBits) ; iteration_count = (8 * (Esize - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) - A + B => E :JMP(finalGas) + A :MSTORE(arithA) + B :MSTORE(arithB), CALL(addARITH) + $ => E :MLOAD(arithRes1), JMP(finalGas) ; E = iteration_count modexp_expLT32: @@ -187,10 +190,10 @@ lastChecks: 0 => A $ => B :MLOAD(modexp_Msize) $ :EQ, JMPC(save0outMod0) ; if Msize = 0 --> save0outMod0 - ; M > 0 from here + ; Msize > 0 from here $ => B :MLOAD(modexp_Bsize) $ :EQ, JMPC(save0out) ; if Bsize = 0 --> save0out - ; B > 0 from here + ; Bsize > 0 from here %MAX_SIZE_MODEXP => A $ => B :MLOAD(modexp_Bsize) $ :LT, JMPC(preEndFail) ; if Bsize > MAX_SIZE_MODEXP --> preEndFail @@ -211,7 +214,7 @@ lastChecks: 1 => B ; if mod == 0 --> return 0 $ => A :MLOAD(modexp_Mlen), JMPZ(save0out) - ; if Mlen != 1 --> checkBaseLen + ; if Mlen != 1 --> checkExpLen $ :EQ, JMPNC(checkExpLen) ; if Mlen == 1 && mod == 1 --> return 0 $ => A :MLOAD(modexp_M) @@ -224,7 +227,7 @@ checkExpLen: checkBaseLen: ; if base == 0 --> return 0 $ => A :MLOAD(modexp_Blen), JMPZ(save0out) - ; if Blen != 1 --> checkExpLen + ; if Blen != 1 --> callMODEXP $ :EQ, JMPNC(callMODEXP) ; if Blen == 1 && base == 1 --> return 1 $ => A :MLOAD(modexp_B) @@ -247,17 +250,50 @@ save0outMod0: 0 :MSTORE(modexp_out), JMP(preEndMODEXP) finalMODEXP: - - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) ; write data into memory - 0 => E + 0 => B $ => C :MLOAD(modexp_Msize) + C :MSTORE(arithA) + 32 :MSTORE(arithB), CALL(divARITH) + $ => E :MLOAD(arithRes1) + E :MSTORE(modexp_returnFirstIndex) + $ => A :MLOAD(arithRes2) + A :MSTORE(modexp_returnIndexRem), JMPZ(memoryLoop) + ; if Msize % 32 > 0, copy last bytes, else --> memoryLoop + A => C + $ => A :MLOAD(modexp_out+E) + 32 - C => D :CALL(SHLarith) + A :MSTORE(bytesToStore) + B => E + :CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset] + E => B + $ => A :MLOAD(modexp_Msize) + A - C => C :JMPZ(modexpReturn) + $ => E :MLOAD(modexp_returnFirstIndex) + +memoryLoop: + + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + + E - 1 => E :MSTORE(modexp_returnIndex) + $ => A :MLOAD(modexp_out+E) + A :MSTORE(bytesToStore) + B => E + :CALL(MSTORE32) ; in: [bytesToStore, E: offset] out: [E: new offset] + E => B + $ => E :MLOAD(modexp_returnIndex) + C - 32 => C :JMPNZ(memoryLoop) + +modexpReturn: + %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) + ; prepare return data 0 :MSTORE(retDataOffset) + $ => C :MLOAD(modexp_Msize) C :MSTORE(retDataLength) $ => B :MLOAD(retCallOffset) $ => A :MLOAD(originCTX), JMPZ(handleGas) @@ -266,21 +302,18 @@ finalMODEXP: A => CTX E :MSTORE(retDataCTX) - C :MSTORE(arithA) - 32 :MSTORE(arithB), CALL(divARITH) - $ => E :MLOAD(arithRes1) - E :MSTORE(modexp_returnIndex) - $ => A :MLOAD(arithRes2), JMPZ(returnLoop) + $ => E :MLOAD(modexp_returnFirstIndex) + $ => A :MLOAD(modexp_returnIndexRem), JMPZ(returnLoop) A => C $ => A :MLOAD(modexp_out+E) 32 - C => D :CALL(SHLarith) A :MSTORE(bytesToStore) B => E - :CALL(MSTOREX) ; in: [bytesToStore, E: offset] out: [E: new offset] + :CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset] E => B $ => A :MLOAD(modexp_Msize) A - C => C :JMPZ(endMODEXP) - $ => E :MLOAD(modexp_returnIndex) + $ => E :MLOAD(modexp_returnFirstIndex) returnLoop: %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) @@ -290,7 +323,7 @@ returnLoop: $ => A :MLOAD(modexp_out+E) A :MSTORE(bytesToStore) B => E - :CALL(MSTORE32) + :CALL(MSTORE32) ; in: [bytesToStore, E: offset] out: [E: new offset] E => B $ => E :MLOAD(modexp_returnIndex) C - 32 => C :JMPZ(endMODEXP, returnLoop) From ec8a2c200d656e2f819723e803c9494a0bd5ca38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 18 Dec 2023 19:39:11 +0100 Subject: [PATCH 072/121] WIP --- main/modexp/array_lib/array_add_short.zkasm | 8 +- main/modexp/array_lib/array_div.zkasm | 79 ++++++-------- main/modexp/array_lib/array_div_long.zkasm | 102 ++++++++---------- main/modexp/array_lib/array_div_short.zkasm | 51 ++++----- main/modexp/array_lib/array_mul.zkasm | 1 + main/modexp/array_lib/array_mul_long.zkasm | 1 + main/modexp/array_lib/array_mul_short.zkasm | 1 + main/modexp/array_lib/array_square.zkasm | 1 + .../array_lib/unused/array_is_one.zkasm | 4 +- .../array_lib/unused/array_is_zero.zkasm | 4 +- main/modexp/modexp.zkasm | 12 +-- 11 files changed, 113 insertions(+), 151 deletions(-) diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index cbb05c66..a4717ca5 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -59,9 +59,9 @@ array_add_short_loopZero2inA: ; · Otherwise, the number cannot be GT base, two chunks $ => A :MLOAD(array_add_short_inA + E) $ => B :MLOAD(array_add_short_carry) - $ => C :ADD, JMPNC(__array_add_short_continue1) + $ => C :ADD, JMPNC(__array_add_short_continue_1) 1 => D - __array_add_short_continue1: + __array_add_short_continue_1: C :MSTORE(array_add_short_out + E) D :MSTORE(array_add_short_carry) @@ -72,12 +72,12 @@ array_add_short_loopZero2inA: array_add_short_check_carry: D => A - A :JMPZ(__array_add_short_continue2) + A :JMPZ(__array_add_short_continue_2) ; In this case, the carry = 1 and we should append it to the result 1 :MSTORE(array_add_short_out + E) E + 1 :MSTORE(array_add_short_len_out) :JMP(array_add_short_end) - __array_add_short_continue2: + __array_add_short_continue_2: E :MSTORE(array_add_short_len_out) array_add_short_end: diff --git a/main/modexp/array_lib/array_div.zkasm b/main/modexp/array_lib/array_div.zkasm index 2bada0d5..2e22d4ff 100644 --- a/main/modexp/array_lib/array_div.zkasm +++ b/main/modexp/array_lib/array_div.zkasm @@ -56,42 +56,36 @@ array_div: %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_div_RR) + C :MSTORE(array_div_len_inA) D :MSTORE(array_div_len_inB) ; Let's cover the edge cases - ; 1] Is C == 1 and inA == 0? - C => A 1 => B - $ :EQ, JMPNC(array_div_inA_continue) - 0 => B + ; 1] Is C == 1 and inA == 0? + C - B :JMPNZ(__array_div_inA_continue) $ => A :MLOAD(array_div_inA) - $ :EQ, JMPC(array_div_inA_is_zero) - array_div_inA_continue: + $ :LT, JMPC(array_div_inA_is_zero) + __array_div_inA_continue: ; 2] Is D == 1 and inB == 0? - D => A - 1 => B - $ :EQ, JMPNC(array_div_inB_continue1) - 0 => B + D - B :JMPNZ(__array_div_inB_continue_1) $ => A :MLOAD(array_div_inB) - $ :EQ, JMPC(array_div_inB_is_zero) - array_div_inB_continue1: + $ :LT, JMPC(array_div_inB_is_zero) + __array_div_inB_continue_1: ; 3] Check if inA = inB or inA < inB - C => RR - D => E + C - 1 => RR + D - 1 => E array_div_compare_inA: - RR - 1 => RR $ => A :MLOAD(array_div_inA + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_compare_inB, array_div_compare_inA) + RR - 1 => RR :JMPN(array_div_compare_inB, array_div_compare_inA) array_div_compare_inB: - E - 1 => E $ => A :MLOAD(array_div_inB + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_compare, array_div_compare_inB) + E - 1 => E :JMPN(array_div_compare, array_div_compare_inB) array_div_compare: :CALL(array_compare) @@ -100,25 +94,20 @@ array_div_compare: %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_prep_inALTinB) - 1 => B - $ :EQ, JMPC(array_div_same_input) + A - 1 :JMPZ(array_div_same_input) ; From here, inA > inB - C => RR - D => A,E - 1 => B - $ :EQ, JMPC(array_div_inA_to_div_short, array_div_inA_to_div_long); worst case is div long + C - 1 => RR + D - 1 => E + D - 1 :JMPZ(array_div_inA_to_div_short, array_div_inA_to_div_long); worst case is div long ; Begin of edge cases array_div_inA_is_zero: ;Is D == 1 and inB == 0? 0/0 is undefined - D => A - 1 => B - $ :EQ, JMPNC(array_div_inB_continue2) - 0 => B + D - B :JMPNZ(__array_div_inB_continue_2) $ => A :MLOAD(array_div_inB) - $ :EQ, JMPC(array_div_inB_is_zero) - array_div_inB_continue2: + $ :LT, JMPC(array_div_inB_is_zero) + __array_div_inB_continue_2: ; From here, inB != 0 ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 @@ -145,13 +134,11 @@ array_div_prep_inALTinB: %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) - 0 => RR - + C - 1 => RR array_div_inALTinB: $ => A :MLOAD(array_div_inA + RR) A :MSTORE(array_div_rem + RR) - RR + 1 => RR - C - 1 => C :JMPNZ(array_div_inALTinB) + RR - 1 => RR :JMPN(array_div_inALTinB_before_end, array_div_inALTinB) array_div_inALTinB_before_end: 0 :MSTORE(array_div_quo) @@ -160,16 +147,14 @@ array_div_inALTinB_before_end: ; Long array_div_inA_to_div_long: - RR - 1 => RR $ => A :MLOAD(array_div_inA + RR) A :MSTORE(array_div_long_inA + RR) - RR :JMPZ(array_div_inB_to_div_long, array_div_inA_to_div_long) + RR - 1 => RR :JMPN(array_div_inB_to_div_long, array_div_inA_to_div_long) array_div_inB_to_div_long: - E - 1 => E $ => A :MLOAD(array_div_inB + E) A :MSTORE(array_div_long_inB + E) - E :JMPZ(array_div_compute_long, array_div_inB_to_div_long) + E - 1 => E :JMPN(array_div_compute_long, array_div_inB_to_div_long) array_div_compute_long: :CALL(array_div_long) @@ -180,29 +165,26 @@ array_div_compute_long: $ => D :MLOAD(array_div_long_len_rem) C :MSTORE(array_div_len_quo) D :MSTORE(array_div_len_rem) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 2 :JMPN(outOfCountersStep) array_div_assign_long_quo: - RR - 1 => RR $ => A :MLOAD(array_div_long_quo + RR) A :MSTORE(array_div_quo + RR) - RR :JMPZ(array_div_assign_long_rem, array_div_assign_long_quo) + RR - 1 => RR :JMPN(array_div_assign_long_rem, array_div_assign_long_quo) array_div_assign_long_rem: - E - 1 => E $ => A :MLOAD(array_div_long_rem + E) A :MSTORE(array_div_rem + E) - E :JMPZ(array_div_end, array_div_assign_long_rem) + E - 1 => E :JMPN(array_div_end, array_div_assign_long_rem) ; Short array_div_inA_to_div_short: - RR - 1 => RR $ => A :MLOAD(array_div_inA + RR) A :MSTORE(array_div_short_inA + RR) - RR :JMPZ(array_div_inB_to_div_short, array_div_inA_to_div_short) + RR - 1 => RR :JMPN(array_div_inB_to_div_short, array_div_inA_to_div_short) array_div_inB_to_div_short: $ => A :MLOAD(array_div_inB) @@ -216,15 +198,14 @@ array_div_compute_short: $ => C :MLOAD(array_div_short_len_quo) C :MSTORE(array_div_len_quo) 1 :MSTORE(array_div_len_rem) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 4 :JMPN(outOfCountersStep) array_div_assign_short_quo: - RR - 1 => RR $ => A :MLOAD(array_div_short_quo + RR) A :MSTORE(array_div_quo + RR) - RR :JMPZ(array_div_assign_short_rem, array_div_assign_short_quo) + RR - 1 => RR :JMPN(array_div_assign_short_rem, array_div_assign_short_quo) array_div_assign_short_rem: $ => A :MLOAD(array_div_short_rem) diff --git a/main/modexp/array_lib/array_div_long.zkasm b/main/modexp/array_lib/array_div_long.zkasm index c9792a7d..e3352750 100644 --- a/main/modexp/array_lib/array_div_long.zkasm +++ b/main/modexp/array_lib/array_div_long.zkasm @@ -54,42 +54,36 @@ array_div_long: %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_div_long_RR) + C :MSTORE(array_div_long_len_inA) D :MSTORE(array_div_long_len_inB) ; Let's cover the edge cases - ; 1] Is C == 1 and inA == 0? - C => A 1 => B - $ :EQ, JMPNC(array_div_long_inA_continue) - 0 => B + ; 1] Is C == 1 and inA == 0? + C - B :JMPNZ(__array_div_long_inA_continue) $ => A :MLOAD(array_div_long_inA) - $ :EQ, JMPC(array_div_long_inA_is_zero) - array_div_long_inA_continue: + $ :LT, JMPC(array_div_long_inA_is_zero) + __array_div_long_inA_continue: ; 2] Is D == 1 and inB == 0? - D => A - 1 => B - $ :EQ, JMPNC(array_div_long_inB_continue1) - 0 => B + D - B :JMPNZ(__array_div_long_inB_continue_1) $ => A :MLOAD(array_div_long_inB) - $ :EQ, JMPC(array_div_long_inB_is_zero) - array_div_long_inB_continue1: + $ :LT, JMPC(array_div_long_inB_is_zero) + __array_div_long_inB_continue_1: ; 3] Check if inA = inB or inA < inB - C => RR - D => E + C - 1 => RR + D - 1 => E array_div_long_compare_inA1: - RR - 1 => RR $ => A :MLOAD(array_div_long_inA + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_long_compare_inB1, array_div_long_compare_inA1) + RR - 1 => RR :JMPN(array_div_long_compare_inB1, array_div_long_compare_inA1) array_div_long_compare_inB1: - E - 1 => E $ => A :MLOAD(array_div_long_inB + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_long_compare1, array_div_long_compare_inB1) + E - 1 => E :JMPN(array_div_long_compare1, array_div_long_compare_inB1) array_div_long_compare1: :CALL(array_compare) @@ -98,10 +92,10 @@ array_div_long_compare1: %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_long_prep_inALTinB) - 1 => B - $ :EQ, JMPC(array_div_long_same_input) + A - 1 :JMPZ(array_div_long_same_input) ; From here, inA > inB + ; Strategy: Divide outside and check the result inside $${MPdiv(addr.array_div_long_inA,mem.array_div_long_len_inA,addr.array_div_long_inB,mem.array_div_long_len_inB)} :JMP(array_div_long_prepare_mul_quo_inB) @@ -109,14 +103,11 @@ array_div_long_compare1: ; Begin of edge cases array_div_long_inA_is_zero: ; Is D == 1 and inB == 0? 0/0 is undefined - D => A - 1 => B - $ :EQ, JMPNC(array_div_long_inB_continue2) - 0 => B + D - B :JMPNZ(__array_div_long_inB_continue_2) $ => A :MLOAD(array_div_long_inB) - $ :EQ, JMPC(array_div_long_inB_is_zero) - array_div_long_inB_continue2: - ; From here, inB != 0 + $ :LT, JMPC(array_div_long_inB_is_zero) + __array_div_long_inB_continue_2: + ; From here, inA == 0 and inB != 0 ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 0 :MSTORE(array_div_long_quo) @@ -130,6 +121,7 @@ array_div_long_inB_is_zero: 1 => B :JMP(array_div_long_end) array_div_long_same_input: + ; if inA = inB, then return [1, 0] and len(q) = 1, len(r) = 1 1 :MSTORE(array_div_long_quo) 0 :MSTORE(array_div_long_rem) 1 :MSTORE(array_div_long_len_quo) @@ -137,18 +129,17 @@ array_div_long_same_input: 0 => B :JMP(array_div_long_end) array_div_long_prep_inALTinB: - C :MSTORE(array_div_long_len_rem) + ; if inA < inB, then return [0, inA] and len(q) = 1, len(r) = C 1 :MSTORE(array_div_long_len_quo) + C :MSTORE(array_div_long_len_rem) %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) - 0 => RR - + C - 1 => RR array_div_long_inALTinB: $ => A :MLOAD(array_div_long_inA + RR) A :MSTORE(array_div_long_rem + RR) - RR + 1 => RR - C - 1 => C :JMPNZ(array_div_long_inALTinB) + RR - 1 => RR :JMPN(array_div_long_inALTinB_before_end, array_div_long_inALTinB) array_div_long_inALTinB_before_end: 0 :MSTORE(array_div_long_quo) @@ -171,24 +162,23 @@ array_div_long_prepare_mul_quo_inB: ; From here, the quotient is trimmed C :MSTORE(array_div_long_len_quo) + $ => D :MLOAD(array_div_long_len_inB) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4*D - 1 :JMPN(outOfCountersStep) array_div_long_quo_to_mul: - RR - 1 => RR ${receiveQuotientChunk(RR)} => A A :MSTORE(array_div_long_quo + RR) A :MSTORE(array_mul_inA + RR) - RR :JMPZ(array_div_long_inB_to_mul, array_div_long_quo_to_mul) + RR - 1 => RR :JMPN(array_div_long_inB_to_mul, array_div_long_quo_to_mul) array_div_long_inB_to_mul: - E - 1 => E $ => A :MLOAD(array_div_long_inB + E) A :MSTORE(array_mul_inB + E) - E :JMPZ(array_div_long_mul_quo_inB, array_div_long_inB_to_mul) + E - 1 => E :JMPN(array_div_long_mul_quo_inB, array_div_long_inB_to_mul) array_div_long_mul_quo_inB: :CALL(array_mul) @@ -200,7 +190,7 @@ array_div_long_mul_quo_inB: $0{receiveLenRemainder()} => D ; 1] The received length must be between 1 and %ARRAY_MAX_LEN - D - 1 => E :JMPN(failAssert) ; If D = 0, then fail + D - 1 => E :JMPN(failAssert) ; If D = 0, then fail %ARRAY_MAX_LEN - D :JMPN(failAssert) ; If D > %ARRAY_MAX_LEN, then fail ; From here, 1 <= D <= %ARRAY_MAX_LEN @@ -213,22 +203,20 @@ array_div_long_mul_quo_inB: ; 3] Finally, we must ensure that the remainder is lower than inB $ => C :MLOAD(array_div_long_len_inB) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) array_div_long_compare_inB2: - RR - 1 => RR - $ => A :MLOAD(array_div_inB + RR) + $ => A :MLOAD(array_div_long_inB + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_long_compare_rem, array_div_long_compare_inB2) + RR - 1 => RR :JMPN(array_div_long_compare_rem, array_div_long_compare_inB2) array_div_long_compare_rem: - E - 1 => E ${receiveRemainderChunk(E)} => A A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_long_compare2, array_div_long_compare_rem) + E - 1 => E :JMPN(array_div_long_compare2, array_div_long_compare_rem) array_div_long_compare2: :CALL(array_compare) @@ -241,23 +229,21 @@ array_div_long_compare2: ; prepare output and remainder to be added $ => C :MLOAD(array_mul_len_out) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 5*D - 1 :JMPN(outOfCountersStep) array_div_long_res_to_add: - RR - 1 => RR $ => A :MLOAD(array_mul_out + RR) A :MSTORE(array_add_AGTB_inA + RR) - RR :JMPZ(array_div_long_rem_to_add, array_div_long_res_to_add) + RR - 1 => RR :JMPN(array_div_long_rem_to_add, array_div_long_res_to_add) array_div_long_rem_to_add: - E - 1 => E ${receiveRemainderChunk(E)} => A A :MSTORE(array_div_long_rem + E) A :MSTORE(array_add_AGTB_inB + E) - E :JMPZ(array_div_long_add_res_rem, array_div_long_rem_to_add) + E - 1 => E :JMPN(array_div_long_add_res_rem, array_div_long_rem_to_add) array_div_long_add_res_rem: :CALL(array_add_AGTB) @@ -267,22 +253,20 @@ array_div_long_add_res_rem: ; prepare next $ => C :MLOAD(array_add_AGTB_len_out) $ => D :MLOAD(array_div_long_len_inA) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) array_div_long_compare_inA2: - RR - 1 => RR $ => A :MLOAD(array_add_AGTB_out + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_long_compare_inB3, array_div_long_compare_inA2) + RR - 1 => RR :JMPN(array_div_long_compare_inB3, array_div_long_compare_inA2) array_div_long_compare_inB3: - E - 1 => E $ => A :MLOAD(array_div_long_inA + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_long_compare3, array_div_long_compare_inB3) + E - 1 => E :JMPN(array_div_long_compare3, array_div_long_compare_inB3) array_div_long_compare3: :CALL(array_compare) @@ -290,7 +274,7 @@ array_div_long_compare3: %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) 1 :MLOAD(array_compare_result) - 0 => B ; everything worked fine + 0 => B array_div_long_end: $ => RR :MLOAD(array_div_long_RR) diff --git a/main/modexp/array_lib/array_div_short.zkasm b/main/modexp/array_lib/array_div_short.zkasm index 27fe5e63..be44622f 100644 --- a/main/modexp/array_lib/array_div_short.zkasm +++ b/main/modexp/array_lib/array_div_short.zkasm @@ -52,32 +52,29 @@ array_div_short: %MAX_CNT_STEPS - STEP - 15 - 4*C - 3 :JMPN(outOfCountersStep) RR :MSTORE(array_div_short_RR) + C :MSTORE(array_div_short_len_inA) C :MSTORE(array_div_short_len_quo) ; Let's cover the edge cases - ; 1] Is inA == 0? - C => A 1 => B - $ :EQ, JMPNC(array_div_short_inA_continue) - 0 => B + ; 1] Is C == 1 and inA == 0? + C - B :JMPNZ(__array_div_short_inA_continue) $ => A :MLOAD(array_div_short_inA) - $ :EQ, JMPC(array_div_short_inA_is_zero) - array_div_short_inA_continue: + $ :LT, JMPC(array_div_short_inA_is_zero) + __array_div_short_inA_continue: ; 2] Is inB == 0? - 0 => B $ => A :MLOAD(array_div_short_inB) - $ :EQ, JMPC(array_div_short_inB_is_zero) + $ :LT, JMPC(array_div_short_inB_is_zero) ; Check whether inA = inB or inA < inB - C => RR + C - 1 => RR 1 => D array_div_short_inA_to_compare1: - RR - 1 => RR $ => A :MLOAD(array_div_short_inA + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_short_inB_to_compare, array_div_short_inA_to_compare1) + RR - 1 => RR :JMPN(array_div_short_inB_to_compare, array_div_short_inA_to_compare1) array_div_short_inB_to_compare: $ => A :MLOAD(array_div_short_inB) @@ -90,10 +87,8 @@ array_div_short_compare_inA_inB: %MAX_CNT_STEPS - STEP - 18 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_short_inALTinB) - 1 => B - $ :EQ, JMPC(array_div_short_same_input) - - ; From here, it is known that inA > inB + A - 1 :JMPZ(array_div_short_same_input) + ; From here, inA > inB ; Strategy: Divide outside and check the result inside $${MPdiv_short(addr.array_div_short_inA,mem.array_div_short_len_inA,mem.array_div_short_inB)} @@ -104,7 +99,7 @@ array_div_short_compare_inA_inB: array_div_short_inA_is_zero: ; Is inB == 0? 0/0 is undefined $ => A :MLOAD(array_div_short_inB) - $ :EQ, JMPC(array_div_short_inB_is_zero) + $ :LT, JMPC(array_div_short_inB_is_zero) ; From here, inB != 0 ; Return [q,r] = [0,0] and len(q) = 1, len(r) = 1 @@ -149,16 +144,16 @@ array_div_short_prepare_mul_quo_inB: ; From here, the quotient is trimmed C :MSTORE(array_div_short_len_quo) - C => RR + + C - 1 => RR %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4 :JMPN(outOfCountersStep) array_div_short_quo_to_mul: - RR - 1 => RR ${receiveQuotientChunk_short(RR)} => A A :MSTORE(array_div_short_quo + RR) A :MSTORE(array_mul_short_inA + RR) - RR :JMPZ(array_div_short_inB_to_mul, array_div_short_quo_to_mul) + RR - 1 => RR :JMPN(array_div_short_inB_to_mul, array_div_short_quo_to_mul) array_div_short_inB_to_mul: $ => A :MLOAD(array_div_short_inB) @@ -171,16 +166,15 @@ array_div_short_mul_quo_inB: ; prepare next $ => C :MLOAD(array_mul_short_len_out) - C => RR + C - 1 => RR %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 4*C - 6 :JMPN(outOfCountersStep) array_div_short_result_to_add: - RR - 1 => RR $ => A :MLOAD(array_mul_short_out + RR) A :MSTORE(array_add_short_inA + RR) - RR :JMPZ(array_div_short_rem_to_add, array_div_short_result_to_add) + RR - 1 => RR :JMPN(array_div_short_rem_to_add, array_div_short_result_to_add) array_div_short_rem_to_add: ${receiveRemainderChunk_short()} => A @@ -200,22 +194,20 @@ array_div_short_add_result_rem: ; prepare next $ => C :MLOAD(array_add_short_len_out) $ => D :MLOAD(array_div_short_len_inA) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) array_div_short_result_to_compare: - RR - 1 => RR $ => A :MLOAD(array_add_short_out + RR) A :MSTORE(array_compare_inA + RR) - RR :JMPZ(array_div_short_inA_to_compare2, array_div_short_result_to_compare) + RR - 1 => RR :JMPN(array_div_short_inA_to_compare2, array_div_short_result_to_compare) array_div_short_inA_to_compare2: - E - 1 => E $ => A :MLOAD(array_div_short_inA + E) A :MSTORE(array_compare_inB + E) - E :JMPZ(array_div_short_compare_result_inA, array_div_short_inA_to_compare2) + E - 1 => E :JMPN(array_div_short_compare_result_inA, array_div_short_inA_to_compare2) array_div_short_compare_result_inA: :CALL(array_compare) @@ -223,7 +215,8 @@ array_div_short_compare_result_inA: %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) 1 :MLOAD(array_compare_result) - 0 => B + + 0 => B ; error code array_div_short_end: $ => RR :MLOAD(array_div_short_RR) diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm index df12797a..c022e820 100644 --- a/main/modexp/array_lib/array_mul.zkasm +++ b/main/modexp/array_lib/array_mul.zkasm @@ -33,6 +33,7 @@ array_mul: %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_mul_RR) + C :MSTORE(array_mul_len_inA) D :MSTORE(array_mul_len_inB) diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index bb5f6c30..32fdd3f5 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -64,6 +64,7 @@ array_mul_long: %MAX_CNT_STEPS - STEP - 7 - 3*C - 3*D - 35*E - 2 - 4*C - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_mul_long_RR) + C :MSTORE(array_mul_long_len_inA) D :MSTORE(array_mul_long_len_inB) C + D :MSTORE(array_mul_long_len_out) diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index c06a7a8f..ffe26d61 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -48,6 +48,7 @@ array_mul_short: %MAX_CNT_STEPS - STEP - 6 - 3*C-3 - 18*C - 7 :JMPN(outOfCountersStep) RR :MSTORE(array_mul_short_RR) + C :MSTORE(array_mul_short_len_inA) C + 1 :MSTORE(array_mul_short_len_out) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 897d85e4..5c779185 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -64,6 +64,7 @@ array_square: %MAX_CNT_STEPS - STEP - 14 - 3*C - 83*E - 2 :JMPN(outOfCountersStep) RR :MSTORE(array_square_RR) + C :MSTORE(array_square_len_in) C + C :MSTORE(array_square_len_out) diff --git a/main/modexp/array_lib/unused/array_is_one.zkasm b/main/modexp/array_lib/unused/array_is_one.zkasm index 81f96e99..90f86d8d 100644 --- a/main/modexp/array_lib/unused/array_is_one.zkasm +++ b/main/modexp/array_lib/unused/array_is_one.zkasm @@ -18,10 +18,10 @@ array_is_one: ; Is C == 1 and in == 1? C => A 1 => B - $ :EQ, JMPNC(array_is_one_continue) + $ :EQ, JMPNC(__array_is_one_continue) $ => A :MLOAD(array_is_one_in) $ :EQ, JMPC(array_is_one_sure) - array_is_one_continue: + __array_is_one_continue: 0 :MSTORE(array_is_one_result) :JMP(array_is_one_end) diff --git a/main/modexp/array_lib/unused/array_is_zero.zkasm b/main/modexp/array_lib/unused/array_is_zero.zkasm index fca7224d..022f310f 100644 --- a/main/modexp/array_lib/unused/array_is_zero.zkasm +++ b/main/modexp/array_lib/unused/array_is_zero.zkasm @@ -18,11 +18,11 @@ array_is_zero: ; Is C == 1 and in == 0? C => A 1 => B - $ :EQ, JMPNC(array_is_zero_continue) + $ :EQ, JMPNC(__array_is_zero_continue) 0 => B $ => A :MLOAD(array_is_zero_in) $ :EQ, JMPC(array_is_zero_sure) - array_is_zero_continue: + __array_is_zero_continue: 0 :MSTORE(array_is_zero_result) :JMP(array_is_zero_end) diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 77b50cc1..292980ca 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -194,21 +194,21 @@ modexp_pre_loop: ; Is E = 0? $ => A :MLOAD(modexp_Elen) 1 => B - $ :EQ, JMPNC(modexp_E_continue2) + $ :EQ, JMPNC(__modexp_E_continue_2) $ => A :MLOAD(modexp_E) - 0 => B + 0 => B ; error code $ :EQ, JMPC(modexp_end) - modexp_E_continue2: + __modexp_E_continue_2: modexp_loop: ; Is B = 0? $ => A :MLOAD(modexp_Blen) 1 => B - $ :EQ, JMPNC(modexp_B_continue3) + $ :EQ, JMPNC(__modexp_B_continue_3) $ => A :MLOAD(modexp_B) - 0 => B + 0 => B ; error code $ :EQ, JMPC(modexp_B_is_zero) - modexp_B_continue3: + __modexp_B_continue_3: ; Is E is odd? ; The base is 2^256, so I only need to check if the first chunk is odd to conclude that the whole number is odd. From e3269a8b27369403dec784be6babdba207516814 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Mon, 18 Dec 2023 22:55:57 +0100 Subject: [PATCH 073/121] PR review --- main/utils.zkasm | 458 +++++++++++++++++++++++------------------------ 1 file changed, 229 insertions(+), 229 deletions(-) diff --git a/main/utils.zkasm b/main/utils.zkasm index db413c0b..247481e6 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -1495,7 +1495,7 @@ verifyMerkleProof: ; 1 keccak for the leaf and 32 for the L1InfoTree %MAX_CNT_KECCAK_F - CNT_KECCAK_F - E - 33 :JMPN(outOfCountersKeccak) ; 7 steps at most per bit + 21 statics - %MAX_CNT_STEPS - STEP - 7 * 32 - 21 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 7 * 32 - 21 :JMPN(outOfCountersStep) RR :MSTORE(tmpZkPCVerifyMerkleProof) @@ -1527,562 +1527,562 @@ verifyMerkleProof: 0 => D, A $ => B :MLOAD(indexL1InfoTree) - ; :CALL(u32ToBits) + ; prepare new hash $ => E :MLOAD(lastHashKIdUsed) E + 1 => E :MSTORE(lastHashKIdUsed) 32 => D - ;;;;;;;;;;;;;;;;;;;;; - ;; loop unrolling - ;;;;;;;;;;;;;;;;;;;;; + ; - Start loop 32 levels: + ; - provide each 'indexL1InfoTree' bit to either hash left/right the merkle tree nodes + ; - compute linear combination of 'indexL1InfoTree' bits to match the 'indexL1InfoTree' itself at the end of the loop ; BIT 0 0 => HASHPOS - ${B & 0x00000001} :JMPZ(hashLeft0) + ${B & 0x00000001} :JMPZ(hashLeft0) hashRight0: - ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E+0) - C :HASHK(E+0) - A + 0x00000001 => A :JMP(hashBranchEnd0) + ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E+0) + C :HASHK(E+0) + A + 0x00000001 => A :JMP(hashBranchEnd0) hashLeft0: C :HASHK(E+0) - ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E+0) + ${getSmtProof(mem.indexL1InfoTree, 0)} :HASHK(E+0) hashBranchEnd0: - HASHPOS :HASHKLEN(E+0) - $ => C :HASHKDIGEST(E+0) + HASHPOS :HASHKLEN(E+0) + $ => C :HASHKDIGEST(E+0) ; BIT 1 0 => HASHPOS - ${B & 0x00000002} :JMPZ(hashLeft1) + ${B & 0x00000002} :JMPZ(hashLeft1) hashRight1: - ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) - C :HASHK(E+1) - A + 0x00000002 => A :JMP(hashBranchEnd1) + ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) + C :HASHK(E+1) + A + 0x00000002 => A :JMP(hashBranchEnd1) hashLeft1: C :HASHK(E+1) - ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) + ${getSmtProof(mem.indexL1InfoTree, 1)} :HASHK(E+1) hashBranchEnd1: - HASHPOS :HASHKLEN(E+1) - $ => C :HASHKDIGEST(E+1) + HASHPOS :HASHKLEN(E+1) + $ => C :HASHKDIGEST(E+1) ; BIT 2 0 => HASHPOS - ${B & 0x00000004} :JMPZ(hashLeft2) + ${B & 0x00000004} :JMPZ(hashLeft2) hashRight2: - ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) - C :HASHK(E+2) - A + 0x00000004 => A :JMP(hashBranchEnd2) + ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) + C :HASHK(E+2) + A + 0x00000004 => A :JMP(hashBranchEnd2) hashLeft2: C :HASHK(E+2) - ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) + ${getSmtProof(mem.indexL1InfoTree, 2)} :HASHK(E+2) hashBranchEnd2: - HASHPOS :HASHKLEN(E+2) - $ => C :HASHKDIGEST(E+2) + HASHPOS :HASHKLEN(E+2) + $ => C :HASHKDIGEST(E+2) ; BIT 3 0 => HASHPOS - ${B & 0x00000008} :JMPZ(hashLeft3) + ${B & 0x00000008} :JMPZ(hashLeft3) hashRight3: - ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) - C :HASHK(E+3) - A + 0x00000008 => A :JMP(hashBranchEnd3) + ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) + C :HASHK(E+3) + A + 0x00000008 => A :JMP(hashBranchEnd3) hashLeft3: C :HASHK(E+3) - ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) + ${getSmtProof(mem.indexL1InfoTree, 3)} :HASHK(E+3) hashBranchEnd3: - HASHPOS :HASHKLEN(E+3) - $ => C :HASHKDIGEST(E+3) + HASHPOS :HASHKLEN(E+3) + $ => C :HASHKDIGEST(E+3) ; BIT 4 0 => HASHPOS - ${B & 0x00000010} :JMPZ(hashLeft4) + ${B & 0x00000010} :JMPZ(hashLeft4) hashRight4: - ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) - C :HASHK(E+4) - A + 0x00000010 => A :JMP(hashBranchEnd4) + ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) + C :HASHK(E+4) + A + 0x00000010 => A :JMP(hashBranchEnd4) hashLeft4: C :HASHK(E+4) - ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) + ${getSmtProof(mem.indexL1InfoTree, 4)} :HASHK(E+4) hashBranchEnd4: - HASHPOS :HASHKLEN(E+4) - $ => C :HASHKDIGEST(E+4) + HASHPOS :HASHKLEN(E+4) + $ => C :HASHKDIGEST(E+4) ; BIT 5 0 => HASHPOS - ${B & 0x00000020} :JMPZ(hashLeft5) + ${B & 0x00000020} :JMPZ(hashLeft5) hashRight5: - ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) - C :HASHK(E+5) - A + 0x00000020 => A :JMP(hashBranchEnd5) + ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) + C :HASHK(E+5) + A + 0x00000020 => A :JMP(hashBranchEnd5) hashLeft5: C :HASHK(E+5) - ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) + ${getSmtProof(mem.indexL1InfoTree, 5)} :HASHK(E+5) hashBranchEnd5: - HASHPOS :HASHKLEN(E+5) - $ => C :HASHKDIGEST(E+5) + HASHPOS :HASHKLEN(E+5) + $ => C :HASHKDIGEST(E+5) ; BIT 6 0 => HASHPOS - ${B & 0x00000040} :JMPZ(hashLeft6) + ${B & 0x00000040} :JMPZ(hashLeft6) hashRight6: - ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) - C :HASHK(E+6) - A + 0x00000040 => A :JMP(hashBranchEnd6) + ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) + C :HASHK(E+6) + A + 0x00000040 => A :JMP(hashBranchEnd6) hashLeft6: C :HASHK(E+6) - ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) + ${getSmtProof(mem.indexL1InfoTree, 6)} :HASHK(E+6) hashBranchEnd6: - HASHPOS :HASHKLEN(E+6) - $ => C :HASHKDIGEST(E+6) + HASHPOS :HASHKLEN(E+6) + $ => C :HASHKDIGEST(E+6) ; BIT 7 0 => HASHPOS ${B & 0x00000080} :JMPZ(hashLeft7) hashRight7: - ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) - C :HASHK(E+7) - A + 0x00000080 => A :JMP(hashBranchEnd7) + ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) + C :HASHK(E+7) + A + 0x00000080 => A :JMP(hashBranchEnd7) hashLeft7: C :HASHK(E+7) - ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) + ${getSmtProof(mem.indexL1InfoTree, 7)} :HASHK(E+7) hashBranchEnd7: - HASHPOS :HASHKLEN(E+7) - $ => C :HASHKDIGEST(E+7) + HASHPOS :HASHKLEN(E+7) + $ => C :HASHKDIGEST(E+7) ; BIT 8 0 => HASHPOS - ${B & 0x00000100} :JMPZ(hashLeft8) + ${B & 0x00000100} :JMPZ(hashLeft8) hashRight8: - ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) - C :HASHK(E+8) - A + 0x00000100 => A :JMP(hashBranchEnd8) + ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) + C :HASHK(E+8) + A + 0x00000100 => A :JMP(hashBranchEnd8) hashLeft8: C :HASHK(E+8) - ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) + ${getSmtProof(mem.indexL1InfoTree, 8)} :HASHK(E+8) hashBranchEnd8: - HASHPOS :HASHKLEN(E+8) - $ => C :HASHKDIGEST(E+8) + HASHPOS :HASHKLEN(E+8) + $ => C :HASHKDIGEST(E+8) ; BIT 9 0 => HASHPOS - ${B & 0x00000200} :JMPZ(hashLeft9) + ${B & 0x00000200} :JMPZ(hashLeft9) hashRight9: - ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) - C :HASHK(E+9) - A + 0x00000200 => A :JMP(hashBranchEnd9) + ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) + C :HASHK(E+9) + A + 0x00000200 => A :JMP(hashBranchEnd9) hashLeft9: C :HASHK(E+9) - ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) + ${getSmtProof(mem.indexL1InfoTree, 9)} :HASHK(E+9) hashBranchEnd9: - HASHPOS :HASHKLEN(E+9) - $ => C :HASHKDIGEST(E+9) + HASHPOS :HASHKLEN(E+9) + $ => C :HASHKDIGEST(E+9) ; BIT 10 0 => HASHPOS - ${B & 0x00000400} :JMPZ(hashLeft10) + ${B & 0x00000400} :JMPZ(hashLeft10) hashRight10: - ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) - C :HASHK(E+10) - A + 0x00000400 => A :JMP(hashBranchEnd10) + ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) + C :HASHK(E+10) + A + 0x00000400 => A :JMP(hashBranchEnd10) hashLeft10: C :HASHK(E+10) - ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) + ${getSmtProof(mem.indexL1InfoTree, 10)} :HASHK(E+10) hashBranchEnd10: - HASHPOS :HASHKLEN(E+10) - $ => C :HASHKDIGEST(E+10) + HASHPOS :HASHKLEN(E+10) + $ => C :HASHKDIGEST(E+10) ; BIT 11 0 => HASHPOS - ${B & 0x00000800} :JMPZ(hashLeft11) + ${B & 0x00000800} :JMPZ(hashLeft11) hashRight11: - ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) - C :HASHK(E+11) - A + 0x00000800 => A :JMP(hashBranchEnd11) + ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) + C :HASHK(E+11) + A + 0x00000800 => A :JMP(hashBranchEnd11) hashLeft11: C :HASHK(E+11) - ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) + ${getSmtProof(mem.indexL1InfoTree, 11)} :HASHK(E+11) hashBranchEnd11: - HASHPOS :HASHKLEN(E+11) - $ => C :HASHKDIGEST(E+11) + HASHPOS :HASHKLEN(E+11) + $ => C :HASHKDIGEST(E+11) ; BIT 12 0 => HASHPOS - ${B & 0x00001000} :JMPZ(hashLeft12) + ${B & 0x00001000} :JMPZ(hashLeft12) hashRight12: - ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) - C :HASHK(E+12) - A + 0x00001000 => A :JMP(hashBranchEnd12) + ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) + C :HASHK(E+12) + A + 0x00001000 => A :JMP(hashBranchEnd12) hashLeft12: C :HASHK(E+12) - ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) + ${getSmtProof(mem.indexL1InfoTree, 12)} :HASHK(E+12) hashBranchEnd12: - HASHPOS :HASHKLEN(E+12) - $ => C :HASHKDIGEST(E+12) + HASHPOS :HASHKLEN(E+12) + $ => C :HASHKDIGEST(E+12) ; BIT 13 0 => HASHPOS - ${B & 0x00002000} :JMPZ(hashLeft13) + ${B & 0x00002000} :JMPZ(hashLeft13) hashRight13: - ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) - C :HASHK(E+13) - A + 0x00002000 => A :JMP(hashBranchEnd13) + ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) + C :HASHK(E+13) + A + 0x00002000 => A :JMP(hashBranchEnd13) hashLeft13: C :HASHK(E+13) - ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) + ${getSmtProof(mem.indexL1InfoTree, 13)} :HASHK(E+13) hashBranchEnd13: - HASHPOS :HASHKLEN(E+13) - $ => C :HASHKDIGEST(E+13) + HASHPOS :HASHKLEN(E+13) + $ => C :HASHKDIGEST(E+13) ; BIT 14 0 => HASHPOS - ${B & 0x00004000} :JMPZ(hashLeft14) + ${B & 0x00004000} :JMPZ(hashLeft14) hashRight14: - ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) - C :HASHK(E+14) - A + 0x00004000 => A :JMP(hashBranchEnd14) + ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) + C :HASHK(E+14) + A + 0x00004000 => A :JMP(hashBranchEnd14) hashLeft14: C :HASHK(E+14) - ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) + ${getSmtProof(mem.indexL1InfoTree, 14)} :HASHK(E+14) hashBranchEnd14: - HASHPOS :HASHKLEN(E+14) - $ => C :HASHKDIGEST(E+14) + HASHPOS :HASHKLEN(E+14) + $ => C :HASHKDIGEST(E+14) ; BIT 15 0 => HASHPOS - ${B & 0x00008000} :JMPZ(hashLeft15) + ${B & 0x00008000} :JMPZ(hashLeft15) hashRight15: - ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) - C :HASHK(E+15) - A + 0x00008000 => A :JMP(hashBranchEnd15) + ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) + C :HASHK(E+15) + A + 0x00008000 => A :JMP(hashBranchEnd15) hashLeft15: C :HASHK(E+15) - ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) + ${getSmtProof(mem.indexL1InfoTree, 15)} :HASHK(E+15) hashBranchEnd15: - HASHPOS :HASHKLEN(E+15) - $ => C :HASHKDIGEST(E+15) + HASHPOS :HASHKLEN(E+15) + $ => C :HASHKDIGEST(E+15) ; BIT 16 0 => HASHPOS - ${B & 0x00010000} :JMPZ(hashLeft16) + ${B & 0x00010000} :JMPZ(hashLeft16) hashRight16: - ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) - C :HASHK(E+16) - A + 0x00010000 => A :JMP(hashBranchEnd16) + ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) + C :HASHK(E+16) + A + 0x00010000 => A :JMP(hashBranchEnd16) hashLeft16: C :HASHK(E+16) - ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) + ${getSmtProof(mem.indexL1InfoTree, 16)} :HASHK(E+16) hashBranchEnd16: - HASHPOS :HASHKLEN(E+16) - $ => C :HASHKDIGEST(E+16) + HASHPOS :HASHKLEN(E+16) + $ => C :HASHKDIGEST(E+16) ; BIT 17 0 => HASHPOS - ${B & 0x00020000} :JMPZ(hashLeft17) + ${B & 0x00020000} :JMPZ(hashLeft17) hashRight17: - ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) - C :HASHK(E+17) - A + 0x00020000 => A :JMP(hashBranchEnd17) + ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) + C :HASHK(E+17) + A + 0x00020000 => A :JMP(hashBranchEnd17) hashLeft17: C :HASHK(E+17) - ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) + ${getSmtProof(mem.indexL1InfoTree, 17)} :HASHK(E+17) hashBranchEnd17: - HASHPOS :HASHKLEN(E+17) - $ => C :HASHKDIGEST(E+17) + HASHPOS :HASHKLEN(E+17) + $ => C :HASHKDIGEST(E+17) ; BIT 18 0 => HASHPOS - ${B & 0x00040000} :JMPZ(hashLeft18) + ${B & 0x00040000} :JMPZ(hashLeft18) hashRight18: - ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) - C :HASHK(E+18) - A + 0x00040000 => A :JMP(hashBranchEnd18) + ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) + C :HASHK(E+18) + A + 0x00040000 => A :JMP(hashBranchEnd18) hashLeft18: C :HASHK(E+18) - ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) + ${getSmtProof(mem.indexL1InfoTree, 18)} :HASHK(E+18) hashBranchEnd18: - HASHPOS :HASHKLEN(E+18) - $ => C :HASHKDIGEST(E+18) + HASHPOS :HASHKLEN(E+18) + $ => C :HASHKDIGEST(E+18) ; BIT 19 0 => HASHPOS - ${B & 0x00080000} :JMPZ(hashLeft19) + ${B & 0x00080000} :JMPZ(hashLeft19) hashRight19: - ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) - C :HASHK(E+19) - A + 0x00080000 => A :JMP(hashBranchEnd19) + ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) + C :HASHK(E+19) + A + 0x00080000 => A :JMP(hashBranchEnd19) hashLeft19: C :HASHK(E+19) - ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) + ${getSmtProof(mem.indexL1InfoTree, 19)} :HASHK(E+19) hashBranchEnd19: - HASHPOS :HASHKLEN(E+19) - $ => C :HASHKDIGEST(E+19) + HASHPOS :HASHKLEN(E+19) + $ => C :HASHKDIGEST(E+19) ; BIT 20 0 => HASHPOS - ${B & 0x00100000} :JMPZ(hashLeft20) + ${B & 0x00100000} :JMPZ(hashLeft20) hashRight20: - ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) - C :HASHK(E+20) - A + 0x00100000 => A :JMP(hashBranchEnd20) + ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) + C :HASHK(E+20) + A + 0x00100000 => A :JMP(hashBranchEnd20) hashLeft20: C :HASHK(E+20) - ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) + ${getSmtProof(mem.indexL1InfoTree, 20)} :HASHK(E+20) hashBranchEnd20: - HASHPOS :HASHKLEN(E+20) - $ => C :HASHKDIGEST(E+20) + HASHPOS :HASHKLEN(E+20) + $ => C :HASHKDIGEST(E+20) ; BIT 21 0 => HASHPOS - ${B & 0x00200000} :JMPZ(hashLeft21) + ${B & 0x00200000} :JMPZ(hashLeft21) hashRight21: - ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) - C :HASHK(E+21) - A + 0x00200000 => A :JMP(hashBranchEnd21) + ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) + C :HASHK(E+21) + A + 0x00200000 => A :JMP(hashBranchEnd21) hashLeft21: C :HASHK(E+21) - ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) + ${getSmtProof(mem.indexL1InfoTree, 21)} :HASHK(E+21) hashBranchEnd21: - HASHPOS :HASHKLEN(E+21) - $ => C :HASHKDIGEST(E+21) + HASHPOS :HASHKLEN(E+21) + $ => C :HASHKDIGEST(E+21) ; BIT 22 0 => HASHPOS - ${B & 0x00400000} :JMPZ(hashLeft22) + ${B & 0x00400000} :JMPZ(hashLeft22) hashRight22: - ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) - C :HASHK(E+22) - A + 0x00400000 => A :JMP(hashBranchEnd22) + ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) + C :HASHK(E+22) + A + 0x00400000 => A :JMP(hashBranchEnd22) hashLeft22: C :HASHK(E+22) - ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) + ${getSmtProof(mem.indexL1InfoTree, 22)} :HASHK(E+22) hashBranchEnd22: - HASHPOS :HASHKLEN(E+22) - $ => C :HASHKDIGEST(E+22) + HASHPOS :HASHKLEN(E+22) + $ => C :HASHKDIGEST(E+22) ; BIT 23 0 => HASHPOS - ${B & 0x00800000} :JMPZ(hashLeft23) + ${B & 0x00800000} :JMPZ(hashLeft23) hashRight23: - ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) - C :HASHK(E+23) - A + 0x00800000 => A :JMP(hashBranchEnd23) + ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) + C :HASHK(E+23) + A + 0x00800000 => A :JMP(hashBranchEnd23) hashLeft23: C :HASHK(E+23) - ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) + ${getSmtProof(mem.indexL1InfoTree, 23)} :HASHK(E+23) hashBranchEnd23: - HASHPOS :HASHKLEN(E+23) - $ => C :HASHKDIGEST(E+23) + HASHPOS :HASHKLEN(E+23) + $ => C :HASHKDIGEST(E+23) ; BIT 24 0 => HASHPOS - ${B & 0x01000000} :JMPZ(hashLeft24) + ${B & 0x01000000} :JMPZ(hashLeft24) hashRight24: - ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) - C :HASHK(E+24) - A + 0x01000000 => A :JMP(hashBranchEnd24) + ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) + C :HASHK(E+24) + A + 0x01000000 => A :JMP(hashBranchEnd24) hashLeft24: C :HASHK(E+24) - ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) + ${getSmtProof(mem.indexL1InfoTree, 24)} :HASHK(E+24) hashBranchEnd24: - HASHPOS :HASHKLEN(E+24) - $ => C :HASHKDIGEST(E+24) + HASHPOS :HASHKLEN(E+24) + $ => C :HASHKDIGEST(E+24) ; BIT 25 0 => HASHPOS - ${B & 0x02000000} :JMPZ(hashLeft25) + ${B & 0x02000000} :JMPZ(hashLeft25) hashRight25: - ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) - C :HASHK(E+25) - A + 0x02000000 => A :JMP(hashBranchEnd25) + ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) + C :HASHK(E+25) + A + 0x02000000 => A :JMP(hashBranchEnd25) hashLeft25: C :HASHK(E+25) - ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) + ${getSmtProof(mem.indexL1InfoTree, 25)} :HASHK(E+25) hashBranchEnd25: - HASHPOS :HASHKLEN(E+25) - $ => C :HASHKDIGEST(E+25) + HASHPOS :HASHKLEN(E+25) + $ => C :HASHKDIGEST(E+25) ; BIT 26 0 => HASHPOS - ${B & 0x04000000} :JMPZ(hashLeft26) + ${B & 0x04000000} :JMPZ(hashLeft26) hashRight26: - ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) - C :HASHK(E+26) - A + 0x04000000 => A :JMP(hashBranchEnd26) + ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) + C :HASHK(E+26) + A + 0x04000000 => A :JMP(hashBranchEnd26) hashLeft26: C :HASHK(E+26) - ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) + ${getSmtProof(mem.indexL1InfoTree, 26)} :HASHK(E+26) hashBranchEnd26: - HASHPOS :HASHKLEN(E+26) - $ => C :HASHKDIGEST(E+26) + HASHPOS :HASHKLEN(E+26) + $ => C :HASHKDIGEST(E+26) ; BIT 27 0 => HASHPOS - ${B & 0x08000000} :JMPZ(hashLeft27) + ${B & 0x08000000} :JMPZ(hashLeft27) hashRight27: - ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) - C :HASHK(E+27) - A + 0x08000000 => A :JMP(hashBranchEnd27) + ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) + C :HASHK(E+27) + A + 0x08000000 => A :JMP(hashBranchEnd27) hashLeft27: C :HASHK(E+27) - ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) + ${getSmtProof(mem.indexL1InfoTree, 27)} :HASHK(E+27) hashBranchEnd27: - HASHPOS :HASHKLEN(E+27) - $ => C :HASHKDIGEST(E+27) + HASHPOS :HASHKLEN(E+27) + $ => C :HASHKDIGEST(E+27) ; BIT 28 0 => HASHPOS - ${B & 0x10000000} :JMPZ(hashLeft28) + ${B & 0x10000000} :JMPZ(hashLeft28) hashRight28: - ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) - C :HASHK(E+28) - A + 0x10000000 => A :JMP(hashBranchEnd28) + ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) + C :HASHK(E+28) + A + 0x10000000 => A :JMP(hashBranchEnd28) hashLeft28: C :HASHK(E+28) - ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) + ${getSmtProof(mem.indexL1InfoTree, 28)} :HASHK(E+28) hashBranchEnd28: - HASHPOS :HASHKLEN(E+28) - $ => C :HASHKDIGEST(E+28) + HASHPOS :HASHKLEN(E+28) + $ => C :HASHKDIGEST(E+28) ; BIT 29 0 => HASHPOS - ${B & 0x20000000} :JMPZ(hashLeft29) + ${B & 0x20000000} :JMPZ(hashLeft29) hashRight29: - ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) - C :HASHK(E+29) - A + 0x20000000 => A :JMP(hashBranchEnd29) + ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) + C :HASHK(E+29) + A + 0x20000000 => A :JMP(hashBranchEnd29) hashLeft29: C :HASHK(E+29) - ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) + ${getSmtProof(mem.indexL1InfoTree, 29)} :HASHK(E+29) hashBranchEnd29: - HASHPOS :HASHKLEN(E+29) - $ => C :HASHKDIGEST(E+29) + HASHPOS :HASHKLEN(E+29) + $ => C :HASHKDIGEST(E+29) ; BIT 30 0 => HASHPOS - ${B & 0x40000000} :JMPZ(hashLeft30) + ${B & 0x40000000} :JMPZ(hashLeft30) hashRight30: - ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) - C :HASHK(E+30) - A + 0x40000000 => A :JMP(hashBranchEnd30) + ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) + C :HASHK(E+30) + A + 0x40000000 => A :JMP(hashBranchEnd30) hashLeft30: C :HASHK(E+30) - ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) + ${getSmtProof(mem.indexL1InfoTree, 30)} :HASHK(E+30) hashBranchEnd30: - HASHPOS :HASHKLEN(E+30) - $ => C :HASHKDIGEST(E+30) + HASHPOS :HASHKLEN(E+30) + $ => C :HASHKDIGEST(E+30) ; BIT 31 0 => HASHPOS - ${B & 0x80000000} :JMPZ(hashLeft31) + ${B & 0x80000000} :JMPZ(hashLeft31) hashRight31: - ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) - C :HASHK(E+31) - A + 0x80000000 => A :JMP(hashBranchEnd31) + ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) + C :HASHK(E+31) + A + 0x80000000 => A :JMP(hashBranchEnd31) hashLeft31: C :HASHK(E+31) - ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) + ${getSmtProof(mem.indexL1InfoTree, 31)} :HASHK(E+31) hashBranchEnd31: - HASHPOS :HASHKLEN(E+31) - $ => C :HASHKDIGEST(E+31) + HASHPOS :HASHKLEN(E+31) + $ => C :HASHKDIGEST(E+31) - ; verify linear combination in A + ; verify linear combination of 'indexL1InfoTree' B :ASSERT E + 31 => E :MSTORE(lastHashKIdUsed) From 98798b3ead9145366674342c2ab5adf65c774ed5 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Tue, 19 Dec 2023 10:38:36 +0100 Subject: [PATCH 074/121] update package proverjs --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea2719fb..45db0895 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.1-fork.7", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/improve-errors-and-events", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.1-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", From 4a2ccb6df1bd3e242093aecdb91705b979a431fe Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 12 Dec 2023 13:50:29 +0100 Subject: [PATCH 075/121] Fix multiple free inputs --- main/load-change-l2-block.zkasm | 3 --- main/load-tx-rlp.zkasm | 16 ++++++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/main/load-change-l2-block.zkasm b/main/load-change-l2-block.zkasm index cb14cb23..9d9b8227 100644 --- a/main/load-change-l2-block.zkasm +++ b/main/load-change-l2-block.zkasm @@ -8,9 +8,6 @@ decodeChangeL2BlockTx: ; No changeL2BlockTx allowed at forced batches $ :MLOAD(isForced), JMPNZ(invalidDecodeChangeL2Block) - ; decode txType / 1 byte - %TYPE_BYTES => D :CALL(getTxData) - C + D => C :CALL(addBatchHashData) ; Decode deltaTimestamp / 4 bytes %DELTA_TIMESTAMP_BYTES => D :CALL(getTxData) C + D => C :CALL(addBatchHashData) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 61432789..2f0614f1 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -21,15 +21,14 @@ loadTx_rlp: $ => D :MLOAD(cntKeccakPreProcess) %MAX_CNT_KECCAK_F - CNT_KECCAK_F - 1 - D :JMPN(outOfCountersKeccak) - ; A new hash with position 0 is started - 0 => HASHPOS - ; Pointer to next RLP bytes to read 0 => C ; Check it is a change L2 block transaction - 1 => D + %TYPE_BYTES => D ${getTxs(p,D)} => A - A - %CHANGE_L2_BLOCK_TX_TYPE :JMPZ(decodeChangeL2BlockTx) + $${p = p + D} + C + D => C :CALL(addBatchHashData) + A - %CHANGE_L2_BLOCK_TX_TYPE :JMPZ(decodeChangeL2BlockTx) checkFirstTxType: ; First transaction must be a change L2 block transaction if it is NOT a forced batch $ :MLOAD(pendingTxs), JMPNZ(loadTx_rlp_continue) @@ -48,9 +47,10 @@ loadTx_rlp_continue: ;;;;;;;;;;;;;;;;;; ;; Read RLP list length - ; Should be a list - 1 => D :CALL(addHashTxBegin) - :CALL(addBatchHashData) + ; Add first byte to tx hash and batch hash + ; A new hash with position 0 is started + 0 => HASHPOS + A :HASHK(E) A - 0xc0 :JMPN(invalidTxRLP) A - 0xf8 :JMPN(shortList) ; do not allow lists over 2**24 bytes length From f57d079082de54cf45a31d1a411128b89f5ffcc2 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 19 Dec 2023 16:58:08 +0100 Subject: [PATCH 076/121] Fix finalize batch for empty batchL2Data --- main/main.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/main.zkasm b/main/main.zkasm index 9412d2ef..22d49ed0 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -82,7 +82,7 @@ txLoopRLP: $ => A :MLOAD(lastCtxUsed) A+1 => CTX :MSTORE(lastCtxUsed) - $ => A :MLOAD(batchL2DataLength) + $ => A :MLOAD(batchL2DataLength), JMPZ(finalizeBatch) $ => C :MLOAD(batchL2DataParsed) C - A :JMPN(loadTx_rlp, endCheckRLP) From 3bc929adebcab9514056ebc46ee044ff8ce1daf3 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 19 Dec 2023 18:41:52 +0100 Subject: [PATCH 077/121] comments --- main/load-tx-rlp.zkasm | 1 + main/main.zkasm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 2f0614f1..37b9d05f 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -25,6 +25,7 @@ loadTx_rlp: 0 => C ; Check it is a change L2 block transaction %TYPE_BYTES => D + ; batchL2DataLength is not zero (at least 1 byte), checked at main ${getTxs(p,D)} => A $${p = p + D} C + D => C :CALL(addBatchHashData) diff --git a/main/main.zkasm b/main/main.zkasm index 22d49ed0..31c30f93 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -81,7 +81,7 @@ computeKeccaks: txLoopRLP: $ => A :MLOAD(lastCtxUsed) A+1 => CTX :MSTORE(lastCtxUsed) - + ; If batchL2DataLength is zero, we finalize batch $ => A :MLOAD(batchL2DataLength), JMPZ(finalizeBatch) $ => C :MLOAD(batchL2DataParsed) C - A :JMPN(loadTx_rlp, endCheckRLP) From 87426e4073e0d0ada74135cbaac6fede95dc6d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 19 Dec 2023 19:20:49 +0100 Subject: [PATCH 078/121] Two bugs fixed in array_mul_long/short --- main/modexp/array_lib/array_mul_long.zkasm | 80 ++++++++++----------- main/modexp/array_lib/array_mul_short.zkasm | 49 ++++++------- 2 files changed, 62 insertions(+), 67 deletions(-) diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index 32fdd3f5..3a625257 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -13,23 +13,19 @@ ;; · out = inA·inB, with len(out) <= C + D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_mul_long(a: bigint[], b: bigint[], B: bigint): bigint[] { +; function array_mul_long(a: bigint[], b: bigint[], base: bigint): bigint[] { ; const alen = a.length; ; const blen = b.length; ; const len = alen + blen; ; const result = new Array(len).fill(0n); ; let product: bigint; ; let carry: bigint; -; let ai: bigint; -; let bj: bigint; ; for (let i = 0; i < alen; i++) { -; ai = a[i]; ; for (let j = 0; j < blen; j++) { -; bj = b[j]; -; product = ai * bj + result[i + j]; -; carry = product / B; -; result[i + j] = product - carry * B; -; result[i + j + 1] += carry; +; product = a[i] * b[j] + out[i+j]; +; carry = product / base; +; out[i+j] = product - carry * base; +; out[i + j + 1] += carry; ; } ; } ; trim(result); @@ -43,7 +39,7 @@ VAR GLOBAL array_mul_long_len_inA VAR GLOBAL array_mul_long_len_inB VAR GLOBAL array_mul_long_len_out -VAR GLOBAL array_mul_long_result_carry +VAR GLOBAL array_mul_long_out_chunk_2 VAR GLOBAL array_mul_long_RR @@ -69,36 +65,28 @@ array_mul_long: D :MSTORE(array_mul_long_len_inB) C + D :MSTORE(array_mul_long_len_out) - C + D => E ; auxiliar index + C + D - 1 => E ; auxiliar index 0 => RCX ; first index in loops 0 => RR ; second index in loops array_mul_long_clean_out: - E - 1 => E 0 :MSTORE(array_mul_long_out + E) - E :JMPZ(array_mul_long_loopZero2inB, array_mul_long_clean_out) + E - 1 => E :JMPN(array_mul_long_loopZero2inB, array_mul_long_clean_out) ; Begin of branching -array_mul_long_add_carry: - D + 1 => D :JMP(return_array_mul_long_add_carry) - -array_mul_long_add_result_carry: - 1 :MSTORE(array_mul_long_result_carry) - :JMP(return_array_mul_long_add_result_carry) - array_mul_long_loop_index_check: RCX + 1 => RCX - RCX => A $ => B :MLOAD(array_mul_long_len_inA) - $ :EQ, JMPC(array_mul_long_prep_trim_in) + B - RCX :JMPZ(array_mul_long_prep_trim_in) - 0 => RR - :JMP(return_array_mul_long_loop_index_check) + 0 => RR ; reset the second index ; End of branching array_mul_long_loopZero2inB: + ; The result will be stored as D·base + C + RCX => E - ; product = a_i * b_j + out[i + j] + ; 1] a[i]·b[j], where a[i],a[j] ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks $ => A :MLOAD(array_mul_long_inA + E) $ => B :MLOAD(array_mul_long_inB + RR) 0 => C @@ -106,46 +94,52 @@ array_mul_long_loopZero2inB: ${_arrayLongMul_AB >> 256} => D ${_arrayLongMul_AB} => E :ARITH - ; sum lower part + ; 2] proudct = a[i]·b[j] + out[i+j], where out[i+j] ∈ [0,base-1]: This number cannot be GT (base - 1)·base, two chunks E => A RCX + RR => E $ => B :MLOAD(array_mul_long_out + E) - $ => C :ADD, JMPC(array_mul_long_add_carry) - return_array_mul_long_add_carry: - - ; sum higher part + $ => C :ADD, JMPNC(__array_mul_long_no_carry_continue_1) + ;----------------- + ; Since here D ∈ [0, base - 2], there cannot be carry in the following addition D => A - $ => B :MLOAD(array_mul_long_result_carry) + 1 => B $ => D :ADD + ;----------------- + __array_mul_long_no_carry_continue_1: + $ => A :MLOAD(array_mul_long_out_chunk_2) + D => B + $ => D :ADD ; the number is of two chunks, no carry can be generated here - ; out[i + j] = product - carry·B + ; out[i+j] = product - carry·B C :MSTORE(array_mul_long_out + E) - ; out[i + j + 1] += carry + ; out[i+j+1] += carry, where carry ∈ [0,base-1]: This number cannot be GT base + (base-3), two chunks E + 1 => E $ => A :MLOAD(array_mul_long_out + E) D => B - $ => C :ADD, JMPC(array_mul_long_add_result_carry) - 0 :MSTORE(array_mul_long_result_carry) - return_array_mul_long_add_result_carry: + $ => C :ADD, JMPNC(__array_mul_long_no_carry_continue_2) + ;----------------- + 1 :MSTORE(array_mul_long_out_chunk_2) + :JMP(__array_mul_long_carry_continue) + __array_mul_long_no_carry_continue_2: + 0 :MSTORE(array_mul_long_out_chunk_2) + __array_mul_long_carry_continue: + ;----------------- + C :MSTORE(array_mul_long_out + E) RR + 1 => RR - RR => A $ => B :MLOAD(array_mul_long_len_inB) - $ :EQ, JMPC(array_mul_long_loop_index_check) - return_array_mul_long_loop_index_check: - :JMP(array_mul_long_loopZero2inB) + B - RR :JMPZ(array_mul_long_loop_index_check, array_mul_long_loopZero2inB) array_mul_long_prep_trim_in: $ => C :MLOAD(array_mul_long_len_out) - C => E + C - 1 => E array_mul_long_trim_in: - E - 1 => E $ => A :MLOAD(array_mul_long_out + E) A :MSTORE(array_trim_in + E) - E :JMPZ(array_mul_long_trim, array_mul_long_trim_in) + E - 1 => E :JMPN(array_mul_long_trim, array_mul_long_trim_in) array_mul_long_trim: :CALL(array_trim) diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index ffe26d61..892dae46 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -11,7 +11,7 @@ ;; · out = inA·inB, with len(out) <= C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_mul_short(a: bigint[], b: bigint, B: bigint): bigint[] { +; function array_mul_short(a: bigint[], b: bigint, base: bigint): bigint[] { ; const alen = a.length; ; const len = alen; ; const result = new Array(len).fill(0n); @@ -20,8 +20,8 @@ ; let i; ; for (i = 0; i < alen; i++) { ; product = a[i] * b + carry; -; carry = product / B; -; result[i] = product - carry * B; +; carry = product / base; +; out[i] = product - carry * base; ; } ; if (carry > 0n) { @@ -52,23 +52,19 @@ array_mul_short: C :MSTORE(array_mul_short_len_inA) C + 1 :MSTORE(array_mul_short_len_out) - C + 1 => E ; auxiliar index + C => E ; auxiliar index 0 => RCX ; index in loops 0 :MSTORE(array_mul_short_carry) array_mul_short_clean_out: - E - 1 => E 0 :MSTORE(array_mul_short_out + E) - E :JMPZ(array_mul_short_loopZero2inA, array_mul_short_clean_out) - -; Begin of branching -array_mul_short_add_carry: - D + 1 => D :JMP(return_array_mul_short_add_carry) -; End of branching + E - 1 => E :JMPN(array_mul_short_loopZero2inA, array_mul_short_clean_out) array_mul_short_loopZero2inA: + ; The result will be stored as D·base + C + RCX => E - ; product = a_i * b + carry + ; 1] a[i] * b, where a[i],b ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks $ => A :MLOAD(array_mul_short_inA + E) $ => B :MLOAD(array_mul_short_inB) 0 => C @@ -76,41 +72,46 @@ array_mul_short_loopZero2inA: ${_arrayShortMul_AB >> 256} => D ${_arrayShortMul_AB} => E :ARITH + ; 2] product = a[i] * b + carry, where carry ∈ [0,base-1]: This number cannot be GT (base - 1)·base, two chunks E => A $ => B :MLOAD(array_mul_short_carry) - $ => C :ADD, JMPC(array_mul_short_add_carry) - return_array_mul_short_add_carry: + $ => C :ADD, JMPNC(__array_mul_short_no_carry_continue) + ;----------------- + ; Since here D ∈ [0, base - 2], there cannot be carry in the following addition + D => A + 1 => B + $ => D :ADD + ;----------------- + __array_mul_short_no_carry_continue: + + ; carry = product / base D :MSTORE(array_mul_short_carry) - ; out[i] = product - carry·2²⁵⁶ + ; out[i] = product - carry·base RCX => E C :MSTORE(array_mul_short_out + E) RCX + 1 => RCX - RCX => A $ => B :MLOAD(array_mul_short_len_inA) - $ :EQ, JMPC(array_mul_short_carry_check, array_mul_short_loopZero2inA) + B - RCX :JMPZ(array_mul_short_carry_check, array_mul_short_loopZero2inA) -; If carry > 0, we need to add it to the output +; If the last carry > 0, we need to insert it to the output array_mul_short_carry_check: - $ => A :MLOAD(array_mul_short_carry) - 0 => B - $ :EQ, JMPC(array_mul_short_prep_trim_in) + $ => A :MLOAD(array_mul_short_carry), JMPZ(array_mul_short_prep_trim_in) RCX => E A :MSTORE(array_mul_short_out + E) array_mul_short_prep_trim_in: $ => C :MLOAD(array_mul_short_len_out) - C => E + C - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) array_mul_short_trim_in: - E - 1 => E $ => A :MLOAD(array_mul_short_out + E) A :MSTORE(array_trim_in + E) - E :JMPZ(array_mul_short_trim, array_mul_short_trim_in) + E - 1 => E :JMPZ(array_mul_short_trim, array_mul_short_trim_in) array_mul_short_trim: :CALL(array_trim) From b99c96b2f304ebd1d7004755453c0d121629449b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 19 Dec 2023 19:57:18 +0100 Subject: [PATCH 079/121] A first full refactor done --- main/modexp/array_lib/array_add_AGTB.zkasm | 10 +- main/modexp/array_lib/array_add_short.zkasm | 6 +- main/modexp/array_lib/array_div.zkasm | 6 +- main/modexp/array_lib/array_div_long.zkasm | 2 +- main/modexp/array_lib/array_div_short.zkasm | 2 +- main/modexp/array_lib/array_mul.zkasm | 32 +++--- main/modexp/array_lib/array_square.zkasm | 46 ++++---- .../array_lib/utils/array_compare.zkasm | 13 +-- main/modexp/array_lib/utils/array_trim.zkasm | 1 + main/modexp/modexp.zkasm | 103 ++++++++---------- 10 files changed, 94 insertions(+), 127 deletions(-) diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index 8e28339c..3e43b739 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -13,7 +13,7 @@ ;; · out = inA + inB, with len(out) <= C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_add_AGTB(a: bigint[], b: bigint[], B: bigint): bigint[] { +; function array_add_AGTB(a: bigint[], b: bigint[], base: bigint): bigint[] { ; const alen = a.length; ; const blen = b.length; ; let result = new Array(alen); @@ -21,13 +21,13 @@ ; let carry = 0n; ; for (let i = 0; i < blen; i++) { ; sum = a[i] + b[i] + carry; -; carry = sum >= B ? 1n : 0n; -; result[i] = sum - carry * B; +; carry = sum >= base ? 1n : 0n; +; out[i] = sum - carry * base; ; } ; for (let i = blen; i < alen; i++) { ; sum = a[i] + carry; -; carry = sum == B ? 1n : 0n; // the past carry is at most 1n -; result[i] = sum - carry * B; +; carry = sum == base ? 1n : 0n; // the past carry is at most 1n +; out[i] = sum - carry * base; ; } ; if (carry === 1n) { diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index a4717ca5..b2afa1ef 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -10,15 +10,15 @@ ;; · out = inA + inB, with len(out) <= C + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_add_short(a: bigint[], b: bigint, B: bigint): bigint[] { +; function array_add_short(a: bigint[], b: bigint, base: bigint): bigint[] { ; const alen = a.length; ; let result = new Array(alen); ; let sum = 0n; ; let carry = b; ; for (let i = 0; i < alen; i++) { ; sum = a[i] + carry; -; carry = sum >= B ? 1n : 0n; -; result[i] = sum - carry * B; +; carry = sum >= base ? 1n : 0n; +; out[i] = sum - carry * base; ; } ; if (carry === 1n) { diff --git a/main/modexp/array_lib/array_div.zkasm b/main/modexp/array_lib/array_div.zkasm index 2e22d4ff..7e1f7787 100644 --- a/main/modexp/array_lib/array_div.zkasm +++ b/main/modexp/array_lib/array_div.zkasm @@ -13,7 +13,7 @@ ;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_div(a: bigint[], b: bigint[], B: bigint): bigint[] { +; function array_div(a: bigint[], b: bigint[], base: bigint): bigint[] { ; if (a === [0n]) { ; if (b === [0n]) { ; throw new Error("Division by zero"); @@ -30,9 +30,9 @@ ; } ; ; if (b.length === 1) { -; return array_div_short(a, b, B); +; return array_div_short(a, b, base); ; } -; return array_div_long(a, b, B); +; return array_div_long(a, b, base); ; } VAR GLOBAL array_div_inA[%ARRAY_MAX_LEN] diff --git a/main/modexp/array_lib/array_div_long.zkasm b/main/modexp/array_lib/array_div_long.zkasm index e3352750..47776e7a 100644 --- a/main/modexp/array_lib/array_div_long.zkasm +++ b/main/modexp/array_lib/array_div_long.zkasm @@ -13,7 +13,7 @@ ;; · [quo,rem] = [inA / inB, inA % inB], with len(quo) <= C - D + 1, len(rem) <= D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_div_long(a: bigint[], b: bigint[], B: bigint): bigint[] { +; function array_div_long(a: bigint[], b: bigint[], base: bigint): bigint[] { ; if (a === [0n]) { ; if (b === [0n]) { ; throw new Error("Division by zero"); diff --git a/main/modexp/array_lib/array_div_short.zkasm b/main/modexp/array_lib/array_div_short.zkasm index be44622f..7b07b403 100644 --- a/main/modexp/array_lib/array_div_short.zkasm +++ b/main/modexp/array_lib/array_div_short.zkasm @@ -12,7 +12,7 @@ ;; · [quo,rem] = [inA / inB[0], inA % inB[0]], with len(quo) <= C, len(rem) = 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_div_short(a: bigint[], b: bigint, B: bigint): bigint[] { +; function array_div_short(a: bigint[], b: bigint, base: bigint): bigint[] { ; if (a === [0n]) { ; if (b === 0n) { ; throw new Error("Division by zero"); diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm index c022e820..98b73bbb 100644 --- a/main/modexp/array_lib/array_mul.zkasm +++ b/main/modexp/array_lib/array_mul.zkasm @@ -12,11 +12,11 @@ ;; · out = inA·inB, with len(out) <= C + D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; function array_mul(a: bigint[], b: bigint[], B: bigint): bigint[] { +; function array_mul(a: bigint[], b: bigint[], base: bigint): bigint[] { ; if (b.length === 1) { -; return array_mul_short(a, b, B); +; return array_mul_short(a, b, base); ; } -; return array_mul_long(a, b, B); +; return array_mul_long(a, b, base); ; } VAR GLOBAL array_mul_inA[%ARRAY_MAX_LEN] @@ -37,22 +37,19 @@ array_mul: C :MSTORE(array_mul_len_inA) D :MSTORE(array_mul_len_inB) - C => RR - D => A,E - 1 => B - $ :EQ, JMPC(array_mul_inA_to_mul_short) ; worst case is mul long + C - 1 => RR + D - 1 => E + D - 1 :JMPZ(array_mul_inA_to_mul_short) ; worst case is mul long ; Long array_mul_inA_to_mul_long: - RR - 1 => RR $ => A :MLOAD(array_mul_inA + RR) A :MSTORE(array_mul_long_inA + RR) - RR :JMPZ(array_mul_inB_to_mul_long, array_mul_inA_to_mul_long) + RR - 1 => RR :JMPN(array_mul_inB_to_mul_long, array_mul_inA_to_mul_long) array_mul_inB_to_mul_long: - E - 1 => E $ => A :MLOAD(array_mul_inB + E) A :MSTORE(array_mul_long_inB + E) - E :JMPZ(array_mul_compute_long, array_mul_inB_to_mul_long) + E - 1 => E :JMPN(array_mul_compute_long, array_mul_inB_to_mul_long) array_mul_compute_long: :CALL(array_mul_long) @@ -61,22 +58,20 @@ array_mul_compute_long: $ => C :MLOAD(array_mul_long_len_out) C :MSTORE(array_mul_len_out) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) array_mul_assign_long: - RR - 1 => RR $ => A :MLOAD(array_mul_long_out + RR) A :MSTORE(array_mul_out + RR) - RR :JMPZ(array_mul_end, array_mul_assign_long) + RR - 1 => RR :JMPN(array_mul_end, array_mul_assign_long) ; Short array_mul_inA_to_mul_short: - RR - 1 => RR $ => A :MLOAD(array_mul_inA + RR) A :MSTORE(array_mul_short_inA + RR) - RR :JMPZ(array_mul_inB_to_mul_short, array_mul_inA_to_mul_short) + RR - 1 => RR :JMPN(array_mul_inB_to_mul_short, array_mul_inA_to_mul_short) array_mul_inB_to_mul_short: $ => A :MLOAD(array_mul_inB) @@ -89,15 +84,14 @@ array_mul_compute_short: $ => C :MLOAD(array_mul_short_len_out) C :MSTORE(array_mul_len_out) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) array_mul_assign_short: - RR - 1 => RR $ => A :MLOAD(array_mul_short_out + RR) A :MSTORE(array_mul_out + RR) - RR :JMPZ(array_mul_end, array_mul_assign_short) + RR - 1 => RR :JMPN(array_mul_end, array_mul_assign_short) array_mul_end: $ => RR :MLOAD(array_mul_RR) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 5c779185..a6eec480 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -15,17 +15,13 @@ ; let out = new Array(2*len).fill(0n); ; let product: bigint; ; let carry: bigint; -; let a_i: bigint; -; let a_j: bigint; ; for (let i = 0; i < len; i++) { -; a_i = a[i]; -; carry = 0n - a_i * a_i; +; carry = 0n - a[i] * a[i]; ; for (var j = i; j < len; j++) { -; a_j = a[j]; -; product = 2n * (a_i * a_j) + out[i + j] + carry; +; product = 2n * (a[i] * a[j]) + out[i+j] + carry; ; carry = product / base; -; out[i + j] = product - carry * base; +; out[i+j] = product - carry * base; ; } ; out[i + len] = carry; ; } @@ -68,12 +64,11 @@ array_square: C :MSTORE(array_square_len_in) C + C :MSTORE(array_square_len_out) - 0 => RCX ; first index in loops - C + C => RR ; second index in loops + 0 => RCX,RR ; first and second indexes in loops + C + C - 1 => E array_square_clean_out: - RR - 1 => RR - 0 :MSTORE(array_square_out + RR) - RR :JMPZ(array_square_ai_times_ai, array_square_clean_out) + 0 :MSTORE(array_square_out + E) + E - 1 => E :JMPN(array_square_ai_times_ai, array_square_clean_out) ; Begin of branching ; We perform subtraction of a value with three chunks @@ -112,8 +107,8 @@ array_square_loop_index_check: ; End of branching array_square_ai_times_ai: - ; carry = 0 - a_i·a_i - ; a_i·a_i, where a_i ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks + ; carry = 0 - a[i]·a[i] + ; a[i]·a[i], where a[i] ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks $ => A,B :MLOAD(array_square_in + RR) 0 => C $${var _arraySquare_aiai = A*B} @@ -124,10 +119,10 @@ array_square_ai_times_ai: 0 :MSTORE(array_square_carry_sign) array_square_loopRR2len: - ; product = 2·(a_i·a_j) + out[i + j] + carry (in the worst case, this is a 3-chunk number) + ; product = 2·(a[i]·a[j]) + out[i+j] + carry (in the worst case, this is a 3-chunk number) ; The result will be stored as array_square_chunk_3·base² + D·base + C - ; 1] a_i·a_j, where a_i,a_j ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks + ; 1] a[i]·a[j], where a[i],a[j] ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks RCX => E $ => A :MLOAD(array_square_in + E) $ => B :MLOAD(array_square_in + RR) @@ -137,7 +132,7 @@ array_square_loopRR2len: ${_arraySquare_aiaj} => E :ARITH D :MSTORE(array_square_aiaj_chunk_2) - ; 2] 2·a_i·a_j: This number cannot be GT base² + (base - 4)·base + 2, three chunks + ; 2] 2·a[i]·a[j]: This number cannot be GT base² + (base - 4)·base + 2, three chunks E => A,B $ => C :ADD, JMPNC(__array_square_no_carry_continue_1) ;----------------- @@ -155,8 +150,8 @@ array_square_loopRR2len: ;----------------- __array_square_no_carry_continue_2: - ; 3] 2·a_i·a_j + out[i + j]: - ; a) j < len-1: This number cannot be GT base² + (base - 3)·base + 1, as out[i + j] < base + ; 3] 2·a[i]·a[j] + out[i+j]: + ; a) j < len-1: This number cannot be GT base² + (base - 3)·base + 1, as out[i+j] < base ; b) j == len-1: This number cannot be GT base² + (base - 3)·base + base - 1, as out[i + len] <= base + (base - 3) ; In both cases, three chunks RCX + RR => E @@ -185,7 +180,7 @@ array_square_loopRR2len: ;----------------- __array_square_no_carry_continue_4: - ; 4] product = 2·a_i·a_j + out[i + j] + carry: This number cannot be GT base² + (base - 2)·base, three chunks + ; 4] product = 2·a[i]·a[j] + out[i+j] + carry: This number cannot be GT base² + (base - 2)·base, three chunks C => A $ => B :MLOAD(array_square_carry_chunk_1) $ :MLOAD(array_square_carry_sign), JMPZ(array_square_is_negative_1) @@ -216,26 +211,25 @@ array_square_loopRR2len: A :MSTORE(array_square_carry_chunk_2) 1 :MSTORE(array_square_carry_sign) - ; out[i + j] = product - carry·base; + ; out[i+j] = product - carry·base; RCX + RR => E C :MSTORE(array_square_out + E) 0 :MSTORE(array_square_chunk_3) ; reset the third chunk - RR + 1 => RR,A + RR + 1 => RR $ => B :MLOAD(array_square_len_in) - B - A :JMPZ(array_square_loop_index_check, array_square_loopRR2len) ; This subtraction is safe + B - RR :JMPZ(array_square_loop_index_check, array_square_loopRR2len) ; This subtraction is safe array_square_prep_trim_in: $ => C :MLOAD(array_square_len_out) - C => E %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + C - 1 => E array_square_trim_in: - E - 1 => E $ => A :MLOAD(array_square_out + E) A :MSTORE(array_trim_in + E) - E :JMPZ(array_square_trim, array_square_trim_in) + E - 1 => E :JMPN(array_square_trim, array_square_trim_in) array_square_trim: :CALL(array_trim) diff --git a/main/modexp/array_lib/utils/array_compare.zkasm b/main/modexp/array_lib/utils/array_compare.zkasm index 292626d0..3a803d12 100644 --- a/main/modexp/array_lib/utils/array_compare.zkasm +++ b/main/modexp/array_lib/utils/array_compare.zkasm @@ -51,16 +51,11 @@ array_compare: RR :MSTORE(array_compare_RR) ; Start by comparing the lengths of the arrays - C => A - D => B - $ :LT, JMPC(array_compare_ALTB) - C => B - D => A - $ :LT, JMPC(array_compare_AGTB) + C - D :JMPN(array_compare_ALTB) + D - C :JMPN(array_compare_AGTB) - C => E + C - 1 => E array_compare_same_len: - E - 1 => E $ => A :MLOAD(array_compare_inA + E) $ => B :MLOAD(array_compare_inB + E) $ :LT, JMPC(array_compare_ALTB) @@ -69,7 +64,7 @@ array_compare_same_len: $ => B :MLOAD(array_compare_inA + E) $ :LT, JMPC(array_compare_AGTB) - E :JMPZ(array_compare_AEQB, array_compare_same_len) + E - 1 => E :JMPN(array_compare_AEQB, array_compare_same_len) array_compare_AGTB: 2 :MSTORE(array_compare_result) diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm index e0d5341f..a52fd645 100644 --- a/main/modexp/array_lib/utils/array_trim.zkasm +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -35,6 +35,7 @@ array_trim_loop: %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) E - 1 => E :JMPZ(array_trim_end) + $ => A :MLOAD(array_trim_in + E) 0 => B $ :EQ, JMPZ(array_trim_end, array_trim_loop) diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 292980ca..4310c3f7 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -17,21 +17,21 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; function modexp(b: bigint[], exp: bigint[], mod: bigint[], B: bigint): bigint[] { +;; function modexp(b: bigint[], exp: bigint[], mod: bigint[], base: bigint): bigint[] { ;; if (array_is_zero(mod) || array_is_one(mod)) return [0n]; ;; if (array_is_zero(b)) return [0n]; ;; if (array_is_one(b)) return [1n]; ;; if (array_is_zero(e)) return [1n]; ;; ;; let r = [1n]; -;; let base = array_div(b, mod, B)[1]; +;; let base = array_div(b, mod, base)[1]; ;; while (!array_is_zero(exp)) { ;; if (array_is_zero(base)) return [0n]; ;; if (isOdd(exp)) { -;; r = array_div(array_mul(r, base, B),mod,B)[1]; +;; r = array_div(array_mul(r, base, base),mod,base)[1]; ;; } -;; exp = array_div_short(exp, 2n, B)[0]; -;; base = array_div(array_square(base, B),mod,B)[1]; +;; exp = array_div_short(exp, 2n, base)[0]; +;; base = array_div(array_square(base, base),mod,base)[1]; ;; } ;; return r; ;; }; @@ -75,24 +75,22 @@ modexp: ; prepare for computing B % M $ => C :MLOAD(modexp_Blen) $ => D :MLOAD(modexp_Mlen) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) ; Compute B = B % M ; ------------------- modexp_B_to_div: - RR - 1 => RR $ => A :MLOAD(modexp_B + RR) A :MSTORE(array_div_inA + RR) - RR :JMPZ(modexp_M_to_div1, modexp_B_to_div) + RR - 1 => RR :JMPN(modexp_M_to_div1, modexp_B_to_div) modexp_M_to_div1: - E - 1 => E $ => A :MLOAD(modexp_M + E) A :MSTORE(array_div_inB + E) - E :JMPZ(modexp_div_B_and_M, modexp_M_to_div1) + E - 1 => E :JMPN(modexp_div_B_and_M, modexp_M_to_div1) modexp_div_B_and_M: :CALL(array_div) @@ -101,15 +99,14 @@ modexp_div_B_and_M: $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_Blen) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C :JMPN(outOfCountersStep) modexp_rem_from_div1: - RR - 1 => RR $ => A :MLOAD(array_div_rem + RR) A :MSTORE(modexp_B + RR) - RR :JMPZ(modexp_pre_loop, modexp_rem_from_div1) + RR - 1 => RR :JMPN(modexp_pre_loop, modexp_rem_from_div1) ; ------------------- ; Begin of edge cases @@ -123,24 +120,22 @@ modexp_B_is_zero: modexp_loop_multiply: $ => C :MLOAD(modexp_outlen) $ => D :MLOAD(modexp_Blen) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) ; Compute out * B ; ------------------- modexp_out_to_mul_long: - RR - 1 => RR $ => A :MLOAD(modexp_out + RR) A :MSTORE(array_mul_inA + RR) - RR :JMPZ(modexp_B_to_mul_long, modexp_out_to_mul_long) + RR - 1 => RR :JMPN(modexp_B_to_mul_long, modexp_out_to_mul_long) modexp_B_to_mul_long: - E - 1 => E $ => A :MLOAD(modexp_B + E) A :MSTORE(array_mul_inB + E) - E :JMPZ(modexp_mul_long_out_and_B, modexp_B_to_mul_long) + E - 1 => E :JMPN(modexp_mul_long_out_and_B, modexp_B_to_mul_long) modexp_mul_long_out_and_B: :CALL(array_mul) @@ -149,23 +144,21 @@ modexp_mul_long_out_and_B: $ => C :MLOAD(array_mul_len_out) $ => D :MLOAD(modexp_Mlen) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) ; Compute out = (out * B) % M modexp_out_to_div1: - RR - 1 => RR $ => A :MLOAD(array_mul_out + RR) A :MSTORE(array_div_inA + RR) - RR :JMPZ(modexp_M_to_div, modexp_out_to_div1) + RR - 1 => RR :JMPN(modexp_M_to_div, modexp_out_to_div1) modexp_M_to_div: - E - 1 => E $ => A :MLOAD(modexp_M + E) A :MSTORE(array_div_inB + E) - E :JMPZ(modexp_div_out_and_M2, modexp_M_to_div) + E - 1 => E :JMPN(modexp_div_out_and_M2, modexp_M_to_div) modexp_div_out_and_M2: :CALL(array_div) @@ -174,15 +167,14 @@ modexp_div_out_and_M2: $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_outlen) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) modexp_rem_from_div2: - RR - 1 => RR $ => A :MLOAD(array_div_rem + RR) A :MSTORE(modexp_out + RR) - RR :JMPZ(return_modexp_loop_multiply, modexp_rem_from_div2) + RR - 1 => RR :JMPN(return_modexp_loop_multiply, modexp_rem_from_div2) ; ------------------- ; End of branching @@ -191,24 +183,21 @@ modexp_pre_loop: %MAX_CNT_BINARY - CNT_BINARY - 5 :JMPN(outOfCountersBinary) %MAX_CNT_STEPS - STEP - 21 :JMPN(outOfCountersStep) - ; Is E = 0? - $ => A :MLOAD(modexp_Elen) + ; Is Elen = 1 and E = 0? 1 => B - $ :EQ, JMPNC(__modexp_E_continue_2) + $ => A :MLOAD(modexp_Elen) + A - B :JMPNZ(__modexp_E_continue) $ => A :MLOAD(modexp_E) - 0 => B ; error code - $ :EQ, JMPC(modexp_end) - __modexp_E_continue_2: + $ :LT, JMPC(modexp_end) ; we are done + __modexp_E_continue: modexp_loop: - ; Is B = 0? + ; Is Blen = 1 and B = 0? $ => A :MLOAD(modexp_Blen) - 1 => B - $ :EQ, JMPNC(__modexp_B_continue_3) + A - B :JMPNZ(__modexp_B_continue) $ => A :MLOAD(modexp_B) - 0 => B ; error code - $ :EQ, JMPC(modexp_B_is_zero) - __modexp_B_continue_3: + $ :LT, JMPC(modexp_B_is_zero) + __modexp_B_continue: ; Is E is odd? ; The base is 2^256, so I only need to check if the first chunk is odd to conclude that the whole number is odd. @@ -220,50 +209,47 @@ modexp_loop: %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) $ => C :MLOAD(modexp_Elen) - 2 :MSTORE(array_div_short_inB) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) ; Compute E = E // 2 ; ------------------- modexp_E_to_div_short: - RR - 1 => RR $ => A :MLOAD(modexp_E + RR) A :MSTORE(array_div_short_inA + RR) - RR :JMPZ(modexp_div_E_and_2, modexp_E_to_div_short) + RR - 1 => RR :JMPN(modexp_div_E_and_2, modexp_E_to_div_short) modexp_div_E_and_2: + 2 :MSTORE(array_div_short_inB) :CALL(array_div_short) %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) $ => C :MLOAD(array_div_short_len_quo) C :MSTORE(modexp_Elen) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) modexp_quo_from_div_short: - RR - 1 => RR $ => A :MLOAD(array_div_short_quo + RR) A :MSTORE(modexp_E + RR) - RR :JMPZ(modexp_pre_B_square, modexp_quo_from_div_short) + RR - 1 => RR :JMPN(modexp_pre_B_square, modexp_quo_from_div_short) ; ------------------- ; Compute B^2 ; ------------------- modexp_pre_B_square: $ => C :MLOAD(modexp_Blen) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) modexp_B_to_square1: - RR - 1 => RR $ => A :MLOAD(modexp_B + RR) A :MSTORE(array_square_in + RR) - RR :JMPZ(modexp_square_B, modexp_B_to_square1) + RR - 1 => RR :JMPN(modexp_square_B, modexp_B_to_square1) modexp_square_B: :CALL(array_square) @@ -272,23 +258,21 @@ modexp_square_B: $ => C :MLOAD(array_square_len_out) $ => D :MLOAD(modexp_Mlen) - C => RR - D => E + C - 1 => RR + D - 1 => E %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) ; Compute B = (B^2) % M modexp_out_to_div2: - RR - 1 => RR $ => A :MLOAD(array_square_out + RR) A :MSTORE(array_div_inA + RR) - RR :JMPZ(modexp_M_to_div2, modexp_out_to_div2) + RR - 1 => RR :JMPN(modexp_M_to_div2, modexp_out_to_div2) modexp_M_to_div2: - E - 1 => E $ => A :MLOAD(modexp_M + E) A :MSTORE(array_div_inB + E) - E :JMPZ(modexp_div_out_and_M1, modexp_M_to_div2) + E - 1 => E :JMPN(modexp_div_out_and_M1, modexp_M_to_div2) modexp_div_out_and_M1: :CALL(array_div) @@ -297,15 +281,14 @@ modexp_div_out_and_M1: $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_Blen) - C => RR + C - 1 => RR %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) modexp_rem_from_div3: - RR - 1 => RR $ => A :MLOAD(array_div_rem + RR) A :MSTORE(modexp_B + RR) - RR :JMPZ(modexp_pre_loop, modexp_rem_from_div3) + RR - 1 => RR :JMPN(modexp_pre_loop, modexp_rem_from_div3) ; ------------------- modexp_end: From 0d41b5b4325c35f3c819420cf6510d6e3ed4fdf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 20 Dec 2023 10:01:55 +0100 Subject: [PATCH 080/121] Utils refactor done --- main/modexp/array_lib/utils/array_compare.zkasm | 5 ++--- main/modexp/array_lib/utils/array_trim.zkasm | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/main/modexp/array_lib/utils/array_compare.zkasm b/main/modexp/array_lib/utils/array_compare.zkasm index 3a803d12..39388f56 100644 --- a/main/modexp/array_lib/utils/array_compare.zkasm +++ b/main/modexp/array_lib/utils/array_compare.zkasm @@ -45,8 +45,8 @@ VAR GLOBAL array_compare_result VAR GLOBAL array_compare_RR array_compare: - %MAX_CNT_BINARY - CNT_BINARY - 2 - 2*C :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 8 - 8*C - 4 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2*C :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 4 - 7*C - 4 :JMPN(outOfCountersStep) RR :MSTORE(array_compare_RR) @@ -76,7 +76,6 @@ array_compare_AEQB: array_compare_ALTB: 0 :MSTORE(array_compare_result) - :JMP(array_compare_end) array_compare_end: $ => RR :MLOAD(array_compare_RR) diff --git a/main/modexp/array_lib/utils/array_trim.zkasm b/main/modexp/array_lib/utils/array_trim.zkasm index a52fd645..efb9b750 100644 --- a/main/modexp/array_lib/utils/array_trim.zkasm +++ b/main/modexp/array_lib/utils/array_trim.zkasm @@ -23,21 +23,22 @@ VAR GLOBAL array_trim_in[%ARRAY_MAX_LEN_DOUBLED] VAR GLOBAL array_trim_RR array_trim: - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) RR :MSTORE(array_trim_RR) + 0 => B ; used for comparison in the whole loop + C => E ; scan from the last chunk to the first chunks until we find a non-zero chunk ; in case of zero input array, we return 1 array_trim_loop: %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) E - 1 => E :JMPZ(array_trim_end) $ => A :MLOAD(array_trim_in + E) - 0 => B $ :EQ, JMPZ(array_trim_end, array_trim_loop) array_trim_end: From c51fd319baa754d741ded28e18035c502629eadb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 20 Dec 2023 11:18:48 +0100 Subject: [PATCH 081/121] Counters corrected --- main/modexp/array_lib/array_add_AGTB.zkasm | 4 +-- main/modexp/array_lib/array_add_short.zkasm | 6 ++-- main/modexp/array_lib/array_div.zkasm | 13 ++++---- main/modexp/array_lib/array_div_long.zkasm | 20 ++++++------ main/modexp/array_lib/array_div_short.zkasm | 15 ++++----- main/modexp/array_lib/array_mul.zkasm | 11 +++---- main/modexp/array_lib/array_mul_long.zkasm | 6 ++-- main/modexp/array_lib/array_mul_short.zkasm | 8 ++--- main/modexp/array_lib/array_square.zkasm | 10 +++--- main/modexp/modexp.zkasm | 36 ++++++++++----------- 10 files changed, 63 insertions(+), 66 deletions(-) diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index 3e43b739..7bcbccf8 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -50,8 +50,8 @@ VAR GLOBAL array_add_AGTB_carry VAR GLOBAL array_add_AGTB_RR array_add_AGTB: - %MAX_CNT_BINARY - CNT_BINARY - 3*D - 1 - C+ D - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 6 - 17*D - 4 - 11*C+11*D - 8 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2*D - C+ D :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 5 - 14*D - 3 - 9*C+9*D - 8 :JMPN(outOfCountersStep) RR :MSTORE(array_add_AGTB_RR) diff --git a/main/modexp/array_lib/array_add_short.zkasm b/main/modexp/array_lib/array_add_short.zkasm index b2afa1ef..6fe10b0b 100644 --- a/main/modexp/array_lib/array_add_short.zkasm +++ b/main/modexp/array_lib/array_add_short.zkasm @@ -38,8 +38,8 @@ VAR GLOBAL array_add_short_carry VAR GLOBAL array_add_short_RR array_add_short: - %MAX_CNT_BINARY - CNT_BINARY - 2*C - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 6 - 12*C - 8 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - C :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 5 - 10*C - 8 :JMPN(outOfCountersStep) RR :MSTORE(array_add_short_RR) @@ -78,7 +78,7 @@ array_add_short_check_carry: E + 1 :MSTORE(array_add_short_len_out) :JMP(array_add_short_end) __array_add_short_continue_2: - E :MSTORE(array_add_short_len_out) + E :MSTORE(array_add_short_len_out) array_add_short_end: $ => RR :MLOAD(array_add_short_RR) diff --git a/main/modexp/array_lib/array_div.zkasm b/main/modexp/array_lib/array_div.zkasm index 7e1f7787..9a1e4e5e 100644 --- a/main/modexp/array_lib/array_div.zkasm +++ b/main/modexp/array_lib/array_div.zkasm @@ -52,8 +52,8 @@ VAR GLOBAL array_div_RR ; 1 - inB is zero array_div: - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 12 - 3*C - 3*D - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_div_RR) @@ -90,8 +90,7 @@ array_div_compare_inB: array_div_compare: :CALL(array_compare) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 - 3*C - 3*D - 1 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_prep_inALTinB) A - 1 :JMPZ(array_div_same_input) @@ -159,7 +158,7 @@ array_div_inB_to_div_long: array_div_compute_long: :CALL(array_div_long) - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 7 :JMPN(outOfCountersStep) $ => C :MLOAD(array_div_long_len_quo) $ => D :MLOAD(array_div_long_len_rem) @@ -168,7 +167,7 @@ array_div_compute_long: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 2 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*D - 2 :JMPN(outOfCountersStep) array_div_assign_long_quo: $ => A :MLOAD(array_div_long_quo + RR) @@ -200,7 +199,7 @@ array_div_compute_short: 1 :MSTORE(array_div_len_rem) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 4 :JMPN(outOfCountersStep) array_div_assign_short_quo: $ => A :MLOAD(array_div_short_quo + RR) diff --git a/main/modexp/array_lib/array_div_long.zkasm b/main/modexp/array_lib/array_div_long.zkasm index 47776e7a..51201964 100644 --- a/main/modexp/array_lib/array_div_long.zkasm +++ b/main/modexp/array_lib/array_div_long.zkasm @@ -50,8 +50,8 @@ VAR GLOBAL array_div_long_RR ; 1 - inB is zero array_div_long: - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 19 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 12 - 3*C - 3*D - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_div_long_RR) @@ -88,8 +88,8 @@ array_div_long_compare_inB1: array_div_long_compare1: :CALL(array_compare) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 15 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_long_prep_inALTinB) A - 1 :JMPZ(array_div_long_same_input) @@ -167,7 +167,7 @@ array_div_long_prepare_mul_quo_inB: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4*%ARRAY_MAX_LEN - 3*D - 1 :JMPN(outOfCountersStep) array_div_long_quo_to_mul: ${receiveQuotientChunk(RR)} => A @@ -183,8 +183,8 @@ array_div_long_inB_to_mul: array_div_long_mul_quo_inB: :CALL(array_mul) - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 14 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) ; Check the remainder $0{receiveLenRemainder()} => D @@ -206,7 +206,7 @@ array_div_long_mul_quo_inB: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) array_div_long_compare_inB2: $ => A :MLOAD(array_div_long_inB + RR) @@ -232,7 +232,7 @@ array_div_long_compare2: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 5*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 4*D - 1 :JMPN(outOfCountersStep) array_div_long_res_to_add: $ => A :MLOAD(array_mul_out + RR) @@ -256,7 +256,7 @@ array_div_long_add_res_rem: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) array_div_long_compare_inA2: $ => A :MLOAD(array_add_AGTB_out + RR) diff --git a/main/modexp/array_lib/array_div_short.zkasm b/main/modexp/array_lib/array_div_short.zkasm index 7b07b403..22b2ddf7 100644 --- a/main/modexp/array_lib/array_div_short.zkasm +++ b/main/modexp/array_lib/array_div_short.zkasm @@ -47,9 +47,8 @@ VAR GLOBAL array_div_short_RR ; 1 - inB is zero array_div_short: - - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 15 - 4*C - 3 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 11 - 3*C - 3 :JMPN(outOfCountersStep) RR :MSTORE(array_div_short_RR) @@ -83,8 +82,8 @@ array_div_short_inB_to_compare: array_div_short_compare_inA_inB: :CALL(array_compare) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 18 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 13 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_short_inALTinB) A - 1 :JMPZ(array_div_short_same_input) @@ -147,7 +146,7 @@ array_div_short_prepare_mul_quo_inB: C - 1 => RR - %MAX_CNT_STEPS - STEP - 5*%ARRAY_MAX_LEN - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4*%ARRAY_MAX_LEN - 3 :JMPN(outOfCountersStep) array_div_short_quo_to_mul: ${receiveQuotientChunk_short(RR)} => A @@ -169,7 +168,7 @@ array_div_short_mul_quo_inB: C - 1 => RR %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 4*C - 6 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 6 :JMPN(outOfCountersStep) array_div_short_result_to_add: $ => A :MLOAD(array_mul_short_out + RR) @@ -197,7 +196,7 @@ array_div_short_add_result_rem: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) array_div_short_result_to_compare: $ => A :MLOAD(array_add_short_out + RR) diff --git a/main/modexp/array_lib/array_mul.zkasm b/main/modexp/array_lib/array_mul.zkasm index 98b73bbb..e4551c1b 100644 --- a/main/modexp/array_lib/array_mul.zkasm +++ b/main/modexp/array_lib/array_mul.zkasm @@ -29,8 +29,7 @@ VAR GLOBAL array_mul_len_out VAR GLOBAL array_mul_RR array_mul: - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 7 - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 6 - 3*C - 3*D - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_mul_RR) @@ -54,13 +53,13 @@ array_mul_inB_to_mul_long: array_mul_compute_long: :CALL(array_mul_long) - %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) $ => C :MLOAD(array_mul_long_len_out) C :MSTORE(array_mul_len_out) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 2 :JMPN(outOfCountersStep) array_mul_assign_long: $ => A :MLOAD(array_mul_long_out + RR) @@ -80,13 +79,13 @@ array_mul_inB_to_mul_short: array_mul_compute_short: :CALL(array_mul_short) - %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) $ => C :MLOAD(array_mul_short_len_out) C :MSTORE(array_mul_len_out) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 2 :JMPN(outOfCountersStep) array_mul_assign_short: $ => A :MLOAD(array_mul_short_out + RR) diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index 3a625257..3f63c3a9 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -45,7 +45,7 @@ VAR GLOBAL array_mul_long_RR array_mul_long: %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 9 :JMPN(outOfCountersStep) C => A D => B @@ -55,9 +55,9 @@ array_mul_long: B => D ; E holds C*D - %MAX_CNT_BINARY - CNT_BINARY - 5*E :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 4*E :JMPN(outOfCountersBinary) %MAX_CNT_ARITH - CNT_ARITH - E :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 7 - 3*C - 3*D - 35*E - 2 - 4*C - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 7 - 2*C - 2*D - 33*E - 2 - 3*C - 1 :JMPN(outOfCountersStep) RR :MSTORE(array_mul_long_RR) diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index 892dae46..506b9b6f 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -43,16 +43,16 @@ VAR GLOBAL array_mul_short_carry VAR GLOBAL array_mul_short_RR array_mul_short: - %MAX_CNT_BINARY - CNT_BINARY - 2*C - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 2*C :JMPN(outOfCountersBinary) %MAX_CNT_ARITH - CNT_ARITH - C :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 6 - 3*C-3 - 18*C - 7 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 6 - 2*C-2 - 18*C - 6 :JMPN(outOfCountersStep) RR :MSTORE(array_mul_short_RR) C :MSTORE(array_mul_short_len_inA) C + 1 :MSTORE(array_mul_short_len_out) - C => E ; auxiliar index + C => E ; auxiliar index 0 => RCX ; index in loops 0 :MSTORE(array_mul_short_carry) @@ -106,7 +106,7 @@ array_mul_short_prep_trim_in: $ => C :MLOAD(array_mul_short_len_out) C - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 1 :JMPN(outOfCountersStep) array_mul_short_trim_in: $ => A :MLOAD(array_mul_short_out + E) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index a6eec480..25e9a9a8 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -47,7 +47,7 @@ VAR GLOBAL array_square_RR array_square: %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 7 :JMPN(outOfCountersStep) C => A,B 0 => C,D @@ -55,9 +55,9 @@ array_square: A => C ; E holds C*C - %MAX_CNT_BINARY - CNT_BINARY - 10*E :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1 - 2*E :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 14 - 3*C - 83*E - 2 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 9*E :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1 - 2*E :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 5 - 2*C - 68*E - 2 :JMPN(outOfCountersStep) RR :MSTORE(array_square_RR) @@ -223,7 +223,7 @@ array_square_loopRR2len: array_square_prep_trim_in: $ => C :MLOAD(array_square_len_out) - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 1 - 3*C - 1 :JMPN(outOfCountersStep) C - 1 => E array_square_trim_in: diff --git a/main/modexp/modexp.zkasm b/main/modexp/modexp.zkasm index 4310c3f7..6491c42a 100644 --- a/main/modexp/modexp.zkasm +++ b/main/modexp/modexp.zkasm @@ -78,7 +78,7 @@ modexp: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) ; Compute B = B % M ; ------------------- @@ -95,13 +95,13 @@ modexp_M_to_div1: modexp_div_B_and_M: :CALL(array_div) - %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_Blen) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C :JMPN(outOfCountersStep) modexp_rem_from_div1: $ => A :MLOAD(array_div_rem + RR) @@ -123,7 +123,7 @@ modexp_loop_multiply: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) ; Compute out * B ; ------------------- @@ -140,14 +140,14 @@ modexp_B_to_mul_long: modexp_mul_long_out_and_B: :CALL(array_mul) - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) $ => C :MLOAD(array_mul_len_out) $ => D :MLOAD(modexp_Mlen) C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) ; Compute out = (out * B) % M modexp_out_to_div1: @@ -163,13 +163,13 @@ modexp_M_to_div: modexp_div_out_and_M2: :CALL(array_div) - %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_outlen) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 1 :JMPN(outOfCountersStep) modexp_rem_from_div2: $ => A :MLOAD(array_div_rem + RR) @@ -180,8 +180,8 @@ modexp_rem_from_div2: modexp_pre_loop: ; In the worst case, the exponent is odd in each iteration - %MAX_CNT_BINARY - CNT_BINARY - 5 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 21 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 13 :JMPN(outOfCountersStep) ; Is Elen = 1 and E = 0? 1 => B @@ -211,7 +211,7 @@ modexp_loop: $ => C :MLOAD(modexp_Elen) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 2 :JMPN(outOfCountersStep) ; Compute E = E // 2 ; ------------------- @@ -224,13 +224,13 @@ modexp_div_E_and_2: 2 :MSTORE(array_div_short_inB) :CALL(array_div_short) - %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) $ => C :MLOAD(array_div_short_len_quo) C :MSTORE(modexp_Elen) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 2 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3 :JMPN(outOfCountersStep) modexp_quo_from_div_short: $ => A :MLOAD(array_div_short_quo + RR) @@ -244,7 +244,7 @@ modexp_pre_B_square: $ => C :MLOAD(modexp_Blen) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 1 :JMPN(outOfCountersStep) modexp_B_to_square1: $ => A :MLOAD(modexp_B + RR) @@ -254,14 +254,14 @@ modexp_B_to_square1: modexp_square_B: :CALL(array_square) - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) $ => C :MLOAD(array_square_len_out) $ => D :MLOAD(modexp_Mlen) C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 4*C - 4*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) ; Compute B = (B^2) % M modexp_out_to_div2: @@ -277,13 +277,13 @@ modexp_M_to_div2: modexp_div_out_and_M1: :CALL(array_div) - %MAX_CNT_STEPS - STEP - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) $ => C :MLOAD(array_div_len_rem) C :MSTORE(modexp_Blen) C - 1 => RR - %MAX_CNT_STEPS - STEP - 4*C - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*C - 2 :JMPN(outOfCountersStep) modexp_rem_from_div3: $ => A :MLOAD(array_div_rem + RR) From 8c498331634523b2aefc51eb42b348005c1e8fdf Mon Sep 17 00:00:00 2001 From: laisolizq Date: Wed, 20 Dec 2023 11:19:57 +0100 Subject: [PATCH 082/121] add test modexp memory --- test/testModExpReturn.zkasm | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 test/testModExpReturn.zkasm diff --git a/test/testModExpReturn.zkasm b/test/testModExpReturn.zkasm new file mode 100644 index 00000000..cc25ca0c --- /dev/null +++ b/test/testModExpReturn.zkasm @@ -0,0 +1,81 @@ +; constants needed by executor C++ +start: + + STEP => A + 0 :ASSERT + + 2 => CTX + 1 :MSTORE(originCTX) + 2 :MSTORE(currentCTX) + 128 :MSTORE(retCallLength) + 0 :MSTORE(retCallOffset) + 4*32 :MSTORE(modexp_Bsize) + 32 :MSTORE(modexp_Esize) + 4*32 :MSTORE(modexp_Msize) + + CTX => A + + ; 256 BITS EXPONENT TESTS + ; --------------------------------------------------------------------------------------------- + ; 1] B = [100n, 2831023n, 0n, 73916234139162n], E = [2n**256n - 1n], M = [0n, 0n, 8238129386n, 23102318237n] + ; Hamming weight of E is 256 + 4 :MSTORE(modexp_Blen) + 1 :MSTORE(modexp_Elen) + 4 :MSTORE(modexp_Mlen) + + 100n :MSTORE(modexp_B) + 1 => E + 2831023n :MSTORE(modexp_B + E) + 2 => E + 0n :MSTORE(modexp_B + E) + 3 => E + 73916234139162n :MSTORE(modexp_B + E) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(modexp_E) + 0n :MSTORE(modexp_M) + 1 => E + 0n :MSTORE(modexp_M + E) + 2 => E + 8238129386n :MSTORE(modexp_M + E) + 3 => E + 23102318237n :MSTORE(modexp_M + E) + :JMP(callMODEXP) + +INCLUDE "../main/main.zkasm" + +VAR GLOBAL testModexp1 +VAR GLOBAL testModexp2 +VAR GLOBAL testModexp3 +VAR GLOBAL testModexp4 + +preEnd: + 0n :MLOAD(modexp_out) + 1 => E + 0n :MLOAD(modexp_out + E) + 2 => E + 25636070175539943947777314844209202718110211581133019863886488575898865601868n :MLOAD(modexp_out + E) + 3 => E + 4679155145n :MLOAD(modexp_out + E) + 4 :MLOAD(modexp_outlen) + ; get return data + 1 => CTX + $ => E :MLOAD(retCallOffset),CALL(MLOAD32) + A :MSTORE(testModexp1) + :CALL(MLOAD32) + A :MSTORE(testModexp2) + :CALL(MLOAD32) + A :MSTORE(testModexp3) + :CALL(MLOAD32) + A :MSTORE(testModexp4) + ;assert return data === memory + 2 => CTX + 0 => E :CALL(MLOAD32) + A :MLOAD(testModexp1) + :CALL(MLOAD32) + A :MLOAD(testModexp2) + :CALL(MLOAD32) + A :MLOAD(testModexp3) + :CALL(MLOAD32) + A :MLOAD(testModexp4) + +0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, HASHPOS, RR ; Set all registers to 0 + :JMP(finalizeExecution) \ No newline at end of file From 2f779d5397bce678beb708cb1a91c5e49f76e250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 20 Dec 2023 11:21:58 +0100 Subject: [PATCH 083/121] Link added to ecPairing --- main/precompiled/pre-ecPairing.zkasm | 1 + 1 file changed, 1 insertion(+) diff --git a/main/precompiled/pre-ecPairing.zkasm b/main/precompiled/pre-ecPairing.zkasm index fb592c6d..0386873a 100644 --- a/main/precompiled/pre-ecPairing.zkasm +++ b/main/precompiled/pre-ecPairing.zkasm @@ -7,6 +7,7 @@ * @process-precompiled * - stack input: [x1, y1, x2, y2, ..., xk, yk] * - stack output: [success] + * @note For implementation details, see: https://hackmd.io/kcEJAWISQ56eE6YpBnurgw?view */ funcEcPairing: From 8a0a1c95c97e218a853437148c2911edabac3a21 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Wed, 20 Dec 2023 11:28:55 +0100 Subject: [PATCH 084/121] update MAX_CNT_SHA256_F_LIMIT --- main/constants.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/constants.zkasm b/main/constants.zkasm index c29c6cd4..57bce7ca 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -112,7 +112,7 @@ CONST %MAX_CNT_MEM_ALIGN_LIMIT = %TOTAL_STEPS_LIMIT / 32 CONST %MAX_CNT_KECCAK_F_LIMIT = (%TOTAL_STEPS_LIMIT / 155286) * 44 CONST %MAX_CNT_PADDING_PG_LIMIT = (%TOTAL_STEPS_LIMIT / 56) CONST %MAX_CNT_POSEIDON_G_LIMIT = (%TOTAL_STEPS_LIMIT / 30) -CONST %MAX_CNT_SHA256_F_LIMIT = (%TOTAL_STEPS_LIMIT / 31487) * 7 +CONST %MAX_CNT_SHA256_F_LIMIT = ((%TOTAL_STEPS_LIMIT - 1) / 31488) * 7 CONST %SAFE_RANGE = 20 ; safe guard counters to not take into account (%RANGE = 1 / SAFE_RANGE) From 452db4572498cb0e96b249d4c153ad9398c0a3d9 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Wed, 20 Dec 2023 11:34:27 +0100 Subject: [PATCH 085/121] Renaming constant --- main/constants.zkasm | 6 +++--- main/load-change-l2-block.zkasm | 4 ++-- main/load-tx-rlp.zkasm | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/main/constants.zkasm b/main/constants.zkasm index c29c6cd4..d2ddeeef 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -139,6 +139,6 @@ CONSTL %MAX_GAS_IT_MODEXP = 90000000 ; %TX_GAS_LIMIT * 3 ; CONSTANTS TX CHANGEL2BLOCK CONST %CHANGE_L2_BLOCK_TX_TYPE = 0x0b -CONST %DELTA_TIMESTAMP_BYTES = 4 -CONST %INDEX_L1INFOTREE_BYTES = 4 -CONST %TYPE_BYTES = 1 +CONST %DELTA_TIMESTAMP_NUM_BYTES = 4 +CONST %INDEX_L1INFOTREE_NUM_BYTES = 4 +CONST %TX_TYPE_NUM_BYTES = 1 diff --git a/main/load-change-l2-block.zkasm b/main/load-change-l2-block.zkasm index 9d9b8227..92bb4711 100644 --- a/main/load-change-l2-block.zkasm +++ b/main/load-change-l2-block.zkasm @@ -9,11 +9,11 @@ decodeChangeL2BlockTx: $ :MLOAD(isForced), JMPNZ(invalidDecodeChangeL2Block) ; Decode deltaTimestamp / 4 bytes - %DELTA_TIMESTAMP_BYTES => D :CALL(getTxData) + %DELTA_TIMESTAMP_NUM_BYTES => D :CALL(getTxData) C + D => C :CALL(addBatchHashData) A :MSTORE(deltaTimestamp) ; Decode indexL1InfoTree / 4 bytes - %INDEX_L1INFOTREE_BYTES => D :CALL(getTxData) + %INDEX_L1INFOTREE_NUM_BYTES => D :CALL(getTxData) C + D => C :CALL(addBatchHashData) A :MSTORE(indexL1InfoTree) 1 :MSTORE(isChangeL2BlockTx), JMP(finishLoadChangeL2BlockTx) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 37b9d05f..4506007b 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -24,7 +24,7 @@ loadTx_rlp: ; Pointer to next RLP bytes to read 0 => C ; Check it is a change L2 block transaction - %TYPE_BYTES => D + %TX_TYPE_NUM_BYTES => D ; batchL2DataLength is not zero (at least 1 byte), checked at main ${getTxs(p,D)} => A $${p = p + D} From 5ac03018134052d575023dbd56a7550a32f57a3f Mon Sep 17 00:00:00 2001 From: laisolizq Date: Fri, 15 Dec 2023 10:37:21 +0100 Subject: [PATCH 086/121] fix modexp length gas --- main/precompiled/end.zkasm | 18 ++++++++++++++++++ main/precompiled/pre-modexp.zkasm | 9 +++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/main/precompiled/end.zkasm b/main/precompiled/end.zkasm index 3dbdfd2b..f6194123 100644 --- a/main/precompiled/end.zkasm +++ b/main/precompiled/end.zkasm @@ -18,4 +18,22 @@ preEndFail: $ => GAS :MLOAD(gasCTX) $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) + 0 :MSTORE(SP++), JMP(readCode) + +VAR GLOBAL preGAS + +preFailLength: + $ => SR :MLOAD(initSR), CALL(revertTouched) + :CALL(revertBlockInfoTree) + $ => A :MLOAD(originCTX), JMPZ(errorAtFirstContext) + A => CTX + ; Add return data context value to origin context + ; Clear return data context + 0 :MSTORE(retDataCTX) + CTX :MSTORE(currentCTX) + $ => A :MLOAD(gasCTX) + $ => B :MLOAD(preGAS) + A + B => GAS + $ => SP :MLOAD(lastSP) + $ => PC :MLOAD(lastPC) 0 :MSTORE(SP++), JMP(readCode) \ No newline at end of file diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 6a387d1d..1d0d47f9 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -185,6 +185,7 @@ dynamicGas: A => B lastChecks: + B :MSTORE(preGAS) ; B = max(200, multiplication_complexity * iteration_count / 3) GAS - B => GAS :JMPN(outOfGas) 0 => A @@ -196,11 +197,11 @@ lastChecks: ; Bsize > 0 from here %MAX_SIZE_MODEXP => A $ => B :MLOAD(modexp_Bsize) - $ :LT, JMPC(preEndFail) ; if Bsize > MAX_SIZE_MODEXP --> preEndFail + $ :LT, JMPC(preFailLength) ; if Bsize > MAX_SIZE_MODEXP --> preFailLength $ => B :MLOAD(modexp_Esize) - $ :LT, JMPC(preEndFail) ; if Esize > MAX_SIZE_MODEXP --> preEndFail + $ :LT, JMPC(preFailLength) ; if Esize > MAX_SIZE_MODEXP --> preFailLength $ => B :MLOAD(modexp_Msize) - $ :LT, JMPC(preEndFail) ; if Msize > MAX_SIZE_MODEXP --> preEndFail + $ :LT, JMPC(preFailLength) ; if Msize > MAX_SIZE_MODEXP --> preFailLength ; get base value $ => E :MLOAD(modexp_offset) ; This is used in modexp_getBase, modexp_getExp and modexp_getMod $ => C :MLOAD(modexp_Bsize) @@ -243,7 +244,7 @@ save1out: save0out: $ => B :MLOAD(modexp_Msize) %MAX_SIZE_MODEXP => A - $ :LT,JMPC(preEndFail) + $ :LT,JMPC(preFailLength) 0 :MSTORE(modexp_out), JMP(finalMODEXP) save0outMod0: From 1c9e5154c6ede7d57a1579ca4162e843465c5843 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Mon, 18 Dec 2023 15:17:02 +0100 Subject: [PATCH 087/121] Fix modexp error handling --- main/precompiled/end.zkasm | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/main/precompiled/end.zkasm b/main/precompiled/end.zkasm index f6194123..5c0198f4 100644 --- a/main/precompiled/end.zkasm +++ b/main/precompiled/end.zkasm @@ -33,7 +33,7 @@ preFailLength: CTX :MSTORE(currentCTX) $ => A :MLOAD(gasCTX) $ => B :MLOAD(preGAS) - A + B => GAS + A + B + GAS => GAS $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) 0 :MSTORE(SP++), JMP(readCode) \ No newline at end of file diff --git a/package.json b/package.json index 45db0895..308cde4f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.1-fork.7", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.1-fork.7", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fix-gas-modexp", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From e6a5f87cd67b66c8ead86e5e12b80216aa67b4a5 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 19 Dec 2023 11:18:29 +0100 Subject: [PATCH 088/121] Fix mul arith overflow at modexp --- main/precompiled/pre-modexp.zkasm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 1d0d47f9..f5eefed0 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -142,6 +142,8 @@ calculateGas: $ => A :MLOAD(arithRes1) A :MSTORE(arithA) 8 :MSTORE(arithB), CALL(mulARITH) + ; check arith overflow + $ :MLOAD(mulArithOverflowFlag), JMPNZ(outOfGas) ; A = 8 * (Esize - 32) $ => A :MLOAD(arithRes1) $ => B :MLOAD(expLenBits) @@ -172,6 +174,8 @@ dynamicGas: $ => A :MLOAD(multiplication_complexity) A :MSTORE(arithA) E :MSTORE(arithB), CALL(mulARITH) + ; check arith overflow + $ :MLOAD(mulArithOverflowFlag), JMPNZ(outOfGas) ; A = multiplication_complexity * iteration_count $ => A :MLOAD(arithRes1) A :MSTORE(arithA) From 6e3675d5857fccd999c005ee86ec6d3fef79e9e1 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 19 Dec 2023 16:54:44 +0100 Subject: [PATCH 089/121] Fix add arith overflow at modexp --- main/precompiled/pre-modexp.zkasm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index f5eefed0..15dedbc4 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -119,6 +119,8 @@ calculateGas: B :MSTORE(arithA) 7 :MSTORE(arithB), CALL(addARITH) + ; check arith overflow + $ :MLOAD(addArithOverflow), JMPNZ(outOfGas) $ => B :MLOAD(arithRes1) B :MSTORE(arithA) 8 :MSTORE(arithB), CALL(divARITH) @@ -150,6 +152,8 @@ calculateGas: ; iteration_count = (8 * (Esize - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) A :MSTORE(arithA) B :MSTORE(arithB), CALL(addARITH) + ; check arith overflow + $ :MLOAD(addArithOverflow), JMPNZ(outOfGas) $ => E :MLOAD(arithRes1), JMP(finalGas) ; E = iteration_count @@ -260,7 +264,6 @@ finalMODEXP: ; write data into memory 0 => B $ => C :MLOAD(modexp_Msize) - C :MSTORE(arithA) 32 :MSTORE(arithB), CALL(divARITH) $ => E :MLOAD(arithRes1) From 57d7f1d4d529030f8941306b2c875ce6f9990e35 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 19 Dec 2023 18:40:10 +0100 Subject: [PATCH 090/121] Implement batch data length at change l2 block parsing --- main/load-change-l2-block-utils.zkasm | 11 +++++++++++ main/load-change-l2-block.zkasm | 10 +++------- 2 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 main/load-change-l2-block-utils.zkasm diff --git a/main/load-change-l2-block-utils.zkasm b/main/load-change-l2-block-utils.zkasm new file mode 100644 index 00000000..d73adaa8 --- /dev/null +++ b/main/load-change-l2-block-utils.zkasm @@ -0,0 +1,11 @@ +;; get D bytes from transaction bytes +;@in D: number of bytes to get +;@in C: current data parsed pointer +;@out A: D bytes from batch data aot offset C +getChangeL2TxBytes: + $ => A :MLOAD(batchL2DataLength) + $ => B :MLOAD(batchL2DataParsed) + A - B - C - D :JMPN(invalidDecodeChangeL2Block) + ${getTxs(p,D)} => A + $${p = p + D} + :RETURN \ No newline at end of file diff --git a/main/load-change-l2-block.zkasm b/main/load-change-l2-block.zkasm index 92bb4711..e26e7415 100644 --- a/main/load-change-l2-block.zkasm +++ b/main/load-change-l2-block.zkasm @@ -1,3 +1,4 @@ +INCLUDE "load-change-l2-block-utils.zkasm" ;;;;;;;;;;;;;;;;;; ;; ChangeL2BlockTx: ;; - fields: [type | deltaTimestamp | indexL1InfoTree ] @@ -9,20 +10,15 @@ decodeChangeL2BlockTx: $ :MLOAD(isForced), JMPNZ(invalidDecodeChangeL2Block) ; Decode deltaTimestamp / 4 bytes - %DELTA_TIMESTAMP_NUM_BYTES => D :CALL(getTxData) + %DELTA_TIMESTAMP_NUM_BYTES => D :CALL(getChangeL2TxBytes) C + D => C :CALL(addBatchHashData) A :MSTORE(deltaTimestamp) ; Decode indexL1InfoTree / 4 bytes - %INDEX_L1INFOTREE_NUM_BYTES => D :CALL(getTxData) + %INDEX_L1INFOTREE_NUM_BYTES => D :CALL(getChangeL2TxBytes) C + D => C :CALL(addBatchHashData) A :MSTORE(indexL1InfoTree) 1 :MSTORE(isChangeL2BlockTx), JMP(finishLoadChangeL2BlockTx) -getTxData: - ${getTxs(p,D)} => A - $${p = p + D} - :RETURN - finishLoadChangeL2BlockTx: ;; update bytes parsed $ => A :MLOAD(batchL2DataParsed) From 1803a50463a3b25400bdc0da6ecba33f19b53f30 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 20 Dec 2023 12:27:16 +0100 Subject: [PATCH 091/121] add comments --- main/precompiled/end.zkasm | 5 ++++- main/precompiled/pre-modexp.zkasm | 10 +++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/main/precompiled/end.zkasm b/main/precompiled/end.zkasm index 5c0198f4..ed75777b 100644 --- a/main/precompiled/end.zkasm +++ b/main/precompiled/end.zkasm @@ -20,9 +20,10 @@ preEndFail: $ => PC :MLOAD(lastPC) 0 :MSTORE(SP++), JMP(readCode) +; 'preGAS' is the gas on the modExp precompiled before extracting the gas consumed VAR GLOBAL preGAS -preFailLength: +preFailModExpLength: $ => SR :MLOAD(initSR), CALL(revertTouched) :CALL(revertBlockInfoTree) $ => A :MLOAD(originCTX), JMPZ(errorAtFirstContext) @@ -34,6 +35,8 @@ preFailLength: $ => A :MLOAD(gasCTX) $ => B :MLOAD(preGAS) A + B + GAS => GAS + ; set 0 to preGAS for the next iteration + 0 :MSTORE(preGAS) $ => SP :MLOAD(lastSP) $ => PC :MLOAD(lastPC) 0 :MSTORE(SP++), JMP(readCode) \ No newline at end of file diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 15dedbc4..030ea6b3 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -196,6 +196,7 @@ lastChecks: B :MSTORE(preGAS) ; B = max(200, multiplication_complexity * iteration_count / 3) GAS - B => GAS :JMPN(outOfGas) + ; check first modulo size and base size to match ethereum specification 0 => A $ => B :MLOAD(modexp_Msize) $ :EQ, JMPC(save0outMod0) ; if Msize = 0 --> save0outMod0 @@ -203,13 +204,16 @@ lastChecks: $ => B :MLOAD(modexp_Bsize) $ :EQ, JMPC(save0out) ; if Bsize = 0 --> save0out ; Bsize > 0 from here + + ; Check maximum length allowed in the zkEVM reagrding the modExp + ; If parameters (length > %MAX_SIZE_MODEXP) --> zkEVM does a revert returning all the gas consumed %MAX_SIZE_MODEXP => A $ => B :MLOAD(modexp_Bsize) - $ :LT, JMPC(preFailLength) ; if Bsize > MAX_SIZE_MODEXP --> preFailLength + $ :LT, JMPC(preFailModExpLength) ; if Bsize > MAX_SIZE_MODEXP --> preFailModExpLength $ => B :MLOAD(modexp_Esize) - $ :LT, JMPC(preFailLength) ; if Esize > MAX_SIZE_MODEXP --> preFailLength + $ :LT, JMPC(preFailModExpLength) ; if Esize > MAX_SIZE_MODEXP --> preFailModExpLength $ => B :MLOAD(modexp_Msize) - $ :LT, JMPC(preFailLength) ; if Msize > MAX_SIZE_MODEXP --> preFailLength + $ :LT, JMPC(preFailModExpLength) ; if Msize > MAX_SIZE_MODEXP --> preFailModExpLength ; get base value $ => E :MLOAD(modexp_offset) ; This is used in modexp_getBase, modexp_getExp and modexp_getMod $ => C :MLOAD(modexp_Bsize) From cb679f62fe7ea4ed63c36d6477668950601e2103 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Wed, 20 Dec 2023 12:47:39 +0100 Subject: [PATCH 092/121] comments --- main/load-change-l2-block-utils.zkasm | 2 +- main/load-tx-rlp-utils.zkasm | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/main/load-change-l2-block-utils.zkasm b/main/load-change-l2-block-utils.zkasm index d73adaa8..6041c2b0 100644 --- a/main/load-change-l2-block-utils.zkasm +++ b/main/load-change-l2-block-utils.zkasm @@ -1,7 +1,7 @@ ;; get D bytes from transaction bytes ;@in D: number of bytes to get ;@in C: current data parsed pointer -;@out A: D bytes from batch data aot offset C +;@out A: D bytes from batch data at offset C getChangeL2TxBytes: $ => A :MLOAD(batchL2DataLength) $ => B :MLOAD(batchL2DataParsed) diff --git a/main/load-tx-rlp-utils.zkasm b/main/load-tx-rlp-utils.zkasm index 7ec5500d..d5c67f56 100644 --- a/main/load-tx-rlp-utils.zkasm +++ b/main/load-tx-rlp-utils.zkasm @@ -9,6 +9,9 @@ addBatchHashData: $ => E :MLOAD(lastHashKIdUsed), RETURN ;; get D bytes from transaction bytes +;@in D: number of bytes to get +;@in C: current data parsed pointer +;@out A: D bytes from batch data at offset C getTxBytes: $ => A :MLOAD(batchL2DataLength) $ => B :MLOAD(batchL2DataParsed) From d50d0da4de3a048ef1b37ef3ac77fb26f2ff31ed Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 20 Dec 2023 12:53:12 +0100 Subject: [PATCH 093/121] fix label preFailLength --- main/precompiled/pre-modexp.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/precompiled/pre-modexp.zkasm b/main/precompiled/pre-modexp.zkasm index 030ea6b3..6e0e26d3 100644 --- a/main/precompiled/pre-modexp.zkasm +++ b/main/precompiled/pre-modexp.zkasm @@ -256,7 +256,7 @@ save1out: save0out: $ => B :MLOAD(modexp_Msize) %MAX_SIZE_MODEXP => A - $ :LT,JMPC(preFailLength) + $ :LT,JMPC(preFailModExpLength) 0 :MSTORE(modexp_out), JMP(finalMODEXP) save0outMod0: From 318b30e5b3fb21b511a39128d190d5b7fbf22033 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 20 Dec 2023 12:56:55 +0100 Subject: [PATCH 094/121] update packages --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 9a288edc..c38d2289 100644 --- a/package.json +++ b/package.json @@ -37,13 +37,13 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/hash-id-offset", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.1-fork.7", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#feature/fork-etrog", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fix-gas-modexp", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#6162488869ce2c6393337141ebd38b7b96767dc5", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From c627e640b5a8b01299e2bbc5c43c25d677ff536a Mon Sep 17 00:00:00 2001 From: laisolizq Date: Wed, 20 Dec 2023 16:30:10 +0100 Subject: [PATCH 095/121] fix array_mul_short_carry_check --- main/modexp/array_lib/array_mul_short.zkasm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/modexp/array_lib/array_mul_short.zkasm b/main/modexp/array_lib/array_mul_short.zkasm index 506b9b6f..d850064c 100644 --- a/main/modexp/array_lib/array_mul_short.zkasm +++ b/main/modexp/array_lib/array_mul_short.zkasm @@ -97,7 +97,9 @@ array_mul_short_loopZero2inA: ; If the last carry > 0, we need to insert it to the output array_mul_short_carry_check: - $ => A :MLOAD(array_mul_short_carry), JMPZ(array_mul_short_prep_trim_in) + $ => A :MLOAD(array_mul_short_carry) + 0 => B + $ :EQ, JMPC(array_mul_short_prep_trim_in) RCX => E A :MSTORE(array_mul_short_out + E) From b99317ca2ab61c7b6cb683e525d20cdd50643d74 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 20 Dec 2023 23:32:38 +0100 Subject: [PATCH 096/121] update packages --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index c38d2289..27a79b9c 100644 --- a/package.json +++ b/package.json @@ -37,13 +37,13 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/fork-etrog", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#v2.0.0-rc.2-fork.7", "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/fork-etrog", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#6162488869ce2c6393337141ebd38b7b96767dc5", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/fork-etrog", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.2-fork.7", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#5999f90e0f6c5f6e735bdef6ab3d0424fec90f75", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.2-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 101d7fb1015c59fe9b0ab80bce3e2208de6889d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 9 Jan 2024 16:03:50 +0100 Subject: [PATCH 097/121] Solving a soundness bug in invFp2 --- main/pairings/FP2BN254/invFp2BN254.zkasm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/main/pairings/FP2BN254/invFp2BN254.zkasm b/main/pairings/FP2BN254/invFp2BN254.zkasm index bc2da18f..0635b151 100644 --- a/main/pairings/FP2BN254/invFp2BN254.zkasm +++ b/main/pairings/FP2BN254/invFp2BN254.zkasm @@ -1,5 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) +;; POST: The result is in the range [0,BN254_P) ;; ;; invFp2BN254 ;; in: (A + B·u) ∈ Fp2, where A,B ∈ Fp @@ -33,7 +33,7 @@ invFp2BN254: invFp2BN254_zero_check: ; Check if A = B = 0, and if so, return 0 - $ => B :MLOAD(invFp2BN254_x) + $ => B :MLOAD(invFp2BN254_x) 0 => A $ :EQ, JMPNC(invFp2BN254_normalized) $ => B :MLOAD(invFp2BN254_y) @@ -50,7 +50,13 @@ invFp2BN254_normalized: ${fp2InvBN254_y(mem.invFp2BN254_x,mem.invFp2BN254_y)} => D 1n => E 0n :ARITH_BN254_MULFP2 - :JMP(invFp2BN254_end) + + ; Check that the resulting elements are lower than BN254_P + %BN254_P => B + C => A + 1 :LT + D => A + 1 :LT, JMP(invFp2BN254_end) invFp2BN254_input_is_zero: 0 => C,D From 582c3a4757dad8f2a97116f3fe3e5f6a110336e8 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Mon, 8 Jan 2024 09:49:33 +0100 Subject: [PATCH 098/121] Fix binaries check at SSTORE operations --- main/block-info.zkasm | 7 ++++++- main/opcodes/create-terminate-context.zkasm | 8 ++++---- main/process-change-l2-block.zkasm | 2 +- main/process-tx.zkasm | 3 ++- main/touched.zkasm | 3 ++- main/utils.zkasm | 2 +- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/main/block-info.zkasm b/main/block-info.zkasm index 8fa8940a..4fa3e22a 100644 --- a/main/block-info.zkasm +++ b/main/block-info.zkasm @@ -23,6 +23,8 @@ setupNewBlockInfoTree: ; checks zk-counters %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*7 :JMPN(outOfCountersPoseidon) + %MAX_CNT_BINARY - CNT_BINARY - 7 :JMPN(outOfCountersBinary) + ; save current state root & load block info root SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) @@ -98,7 +100,8 @@ setupNewBlockInfoTree: fillBlockInfoTreeWithTxReceipt: ; checks zk-counters %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*4 :JMPN(outOfCountersPoseidon) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) ; save current state root & load block info root SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) @@ -144,6 +147,7 @@ consolidateBlock: ; checks zk-counters %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) ; save current state root & load block info root SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) @@ -178,6 +182,7 @@ fillBlockInfoTreeWithLog: ; checks zk-counters %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE :JMPN(outOfCountersPoseidon) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; save current state root & load block info root SR :MSTORE(tmpSR) $ => SR :MLOAD(blockInfoSR) diff --git a/main/opcodes/create-terminate-context.zkasm b/main/opcodes/create-terminate-context.zkasm index 7e10e43d..92ad41d3 100644 --- a/main/opcodes/create-terminate-context.zkasm +++ b/main/opcodes/create-terminate-context.zkasm @@ -51,7 +51,7 @@ opSTOPend: opCREATE: ; checks zk-counters %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*3 :JMPN(outOfCountersPoseidon) ; check out-of-gas @@ -480,7 +480,7 @@ opRETURNcreate: ; checks zk-counters %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) - + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) ; save offset memory and length to compute contract hash E :MSTORE(memOffsetLinearPoseidon) C :MSTORE(memSizeLinearPoseidon), CALL(checkBytecodeStartsEF) ; in: [memOffset], out: [startsWithEF] @@ -620,7 +620,7 @@ opDELEGATECALLend: opCREATE2: ; checks zk-counters %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 5 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) ; check out-of-gas GAS - %CREATE_2_GAS => GAS :JMPN(outOfGas) @@ -908,7 +908,7 @@ VAR GLOBAL sendAllAddress opSENDALL: ; checks zk-counters %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*4 :JMPN(outOfCountersPoseidon) ; check out-of-gas GAS - %SENDALL_GAS => GAS :JMPN(outOfGas) diff --git a/main/process-change-l2-block.zkasm b/main/process-change-l2-block.zkasm index bed79ed1..75581d64 100644 --- a/main/process-change-l2-block.zkasm +++ b/main/process-change-l2-block.zkasm @@ -5,7 +5,7 @@ processChangeL2Block: $ => A :MLOAD(cntKeccakPreProcess) %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 2 :JMPN(outOfCountersKeccak) %MAX_CNT_STEPS - STEP - 500 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 8 :JMPN(outOfCountersBinary) ; If it is not the first transaction, we must consolidate previous block $ => A :MLOAD(currentTx) diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index b9fc3eda..ae9fb5c3 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -460,7 +460,7 @@ endDeploy: ; checks zk-counters %MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) - + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) ; called from `opRETURNDeploy` which has: C --> length, E --> offset ; only when first context ends on deploy ; If length is 0 do not modify state-tree @@ -498,6 +498,7 @@ handleGasFromError: handleGas: %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*4 :JMPN(outOfCountersPoseidon) + %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) 0 => A $ => B :MLOAD(gasRefund), JMPZ(refundGas) $ => A :MLOAD(txGasLimit) diff --git a/main/touched.zkasm b/main/touched.zkasm index 9cd3f222..32b82c67 100644 --- a/main/touched.zkasm +++ b/main/touched.zkasm @@ -23,7 +23,7 @@ revertTouched: isColdAddress: ; checks zk-counters %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) ; store previous registers values temporary B :MSTORE(tmpB) @@ -82,6 +82,7 @@ isColdSlot: ; checks zk-counters %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*2 :JMPN(outOfCountersPoseidon) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; store previous registers values temporary B :MSTORE(tmpB) D :MSTORE(tmpD) diff --git a/main/utils.zkasm b/main/utils.zkasm index 247481e6..ba021a52 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -935,7 +935,7 @@ moveBalances: ; evmCALL (Move Balances) ;;;;;;;; %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) - %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) + %MAX_CNT_BINARY - CNT_BINARY - 5 :JMPN(outOfCountersBinary) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - %MAX_CNT_POSEIDON_SLOAD_SSTORE*4 :JMPN(outOfCountersPoseidon) ;Check if is a delegate call $ => A :MLOAD(isDelegateCall), JMPNZ(endMoveBalances) From ca9eb0a7a834197a6971fa594dcf6b5f182577bd Mon Sep 17 00:00:00 2001 From: Ignasi Date: Tue, 9 Jan 2024 19:08:05 +0100 Subject: [PATCH 099/121] PR review --- counters/countersConstants.zkasm | 2 +- main/load-tx-rlp.zkasm | 1 + main/opcodes/calldata-returndata-code.zkasm | 10 +++------- main/opcodes/logs.zkasm | 1 + 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/counters/countersConstants.zkasm b/counters/countersConstants.zkasm index b35d6a4a..7e72db47 100644 --- a/counters/countersConstants.zkasm +++ b/counters/countersConstants.zkasm @@ -233,7 +233,7 @@ CONST %OPCODECOPY_CNT_PADDING_PG = 0 CONST %OPCODECOPY_CNT_POSEIDON_G = 0 ; opEXTCODECOPY - COMPLEX - hardcoded values at test CONST %OPEXTCODECOPY_STEP = 2000 -CONST %OPEXTCODECOPY_CNT_BINARY = 105 +CONST %OPEXTCODECOPY_CNT_BINARY = 104 CONST %OPEXTCODECOPY_CNT_ARITH = 4 CONST %OPEXTCODECOPY_CNT_KECCAK_F = 0 CONST %OPEXTCODECOPY_CNT_MEM_ALIGN = 43 diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 4506007b..95df6882 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -366,6 +366,7 @@ checkAndSaveFrom: $ => HASHPOS :MLOAD(l2HASHP) A :HASHP(E) HASHPOS :HASHPLEN(E) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) $ => B :HASHPDIGEST(E) B :MSTORE(l2TxHash),JMP(txLoopRLP) diff --git a/main/opcodes/calldata-returndata-code.zkasm b/main/opcodes/calldata-returndata-code.zkasm index 02d1ff45..2514b80a 100644 --- a/main/opcodes/calldata-returndata-code.zkasm +++ b/main/opcodes/calldata-returndata-code.zkasm @@ -436,17 +436,14 @@ opEXTCODECOPYLoadBytecode: %SMT_KEY_SC_LENGTH => B 0 => C $ => D :SLOAD - D :MSTORE(tmpContractLength) ; if length is 0, nothing to check - A => E - 0 => A - D => B - $ :EQ, JMPC(opEXTCODECOPYCheckHashEnd) + ; after the implementation of EIP170, the maximum bytecode size is 24.576 bytes, less than 2**32 + D :MSTORE(tmpContractLength), JMPZ(opEXTCODECOPYCheckHashEnd) ; check poseidon counters ; 56 is the value used by the prover to increment poseidon counters depending on the hash length RR :MSTORE(tmpZkPCext) - B + 1 :MSTORE(arithA) + D + 1 :MSTORE(arithA) 56 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => RR :MLOAD(tmpZkPCext) $ => B :MLOAD(arithRes1) @@ -454,7 +451,6 @@ opEXTCODECOPYLoadBytecode: %MAX_CNT_PADDING_PG_LIMIT - CNT_PADDING_PG - 1 - B :JMPN(outOfCountersPadding) ; set key for smt smart contract code query - E => A %SMT_KEY_SC_CODE => B 0 => C $ => A :SLOAD diff --git a/main/opcodes/logs.zkasm b/main/opcodes/logs.zkasm index 6b37991a..ca8f75fa 100644 --- a/main/opcodes/logs.zkasm +++ b/main/opcodes/logs.zkasm @@ -181,6 +181,7 @@ opSaveTopicsLoop: A - 1 => A :JMP(opSaveTopicsLoop) finishSaveTopics: + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; Update nextHashPId E + 1 :MSTORE(nextHashPId) ; Compute hash of the log From 6621279e825f57e2873a24ac147136b50a6d4a77 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Mon, 15 Jan 2024 17:20:04 +0100 Subject: [PATCH 100/121] Remove unnecessary binaries from rlp parsing --- main/load-tx-rlp.zkasm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 95df6882..769b6c26 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -267,10 +267,10 @@ readDataFinal: :CALL(checkShortDataRLP) endData: - ; Check all bytes read to detect pre EIP-155 tx - C => A + ; Check all bytes read to detect pre EIP-155 tx, if bytes read are the same as txLength, we reached the end, so it's a pre EIP-155 tx + ; txRLPLength and C is at most 300.000 bytes, no need to use a binary for comparison $ => B :MLOAD(txRLPLength) - $ :EQ,JMPC(setPreEIP155Flag) + C - B :JMPZ(setPreEIP155Flag) ;; Read RLP 'chainId' ; 64 bits max @@ -297,17 +297,17 @@ endChainId: ;; Read RLP last two values (0, 0) 2 => D :CALL(addHashTx) :CALL(addBatchHashData) - 0x8080 => B - $ :EQ,JMPC(sizeVerification, invalidTxRLP) + ; We compare the last two bytes of the RLP with 0x8080, no need to use a binary + A - 0x8080 :JMPZ(sizeVerification, invalidTxRLP) setPreEIP155Flag: 1 :MSTORE(isPreEIP155) ;; size verification ; checks RLP length read at the RLP header with bytes read during RLP parsing sizeVerification: - C => A + ; txRLPLength and C is at most 300.000 bytes, no need to use a binary for comparison $ => B :MLOAD(txRLPLength) - $ :EQ,JMPC(sizeVerificationSuccess, invalidTxRLP) + C - B :JMPZ(sizeVerificationSuccess, invalidTxRLP) sizeVerificationSuccess: HASHPOS :HASHKLEN(E) From e194c55cf1bf15626dba3b616e0b841c2fcf25a6 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Tue, 16 Jan 2024 11:39:12 +0100 Subject: [PATCH 101/121] fix argsLengthCall pre-ecPairing --- main/precompiled/pre-ecPairing.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/precompiled/pre-ecPairing.zkasm b/main/precompiled/pre-ecPairing.zkasm index 6bc4039f..b3319509 100644 --- a/main/precompiled/pre-ecPairing.zkasm +++ b/main/precompiled/pre-ecPairing.zkasm @@ -20,7 +20,7 @@ funcEcPairing: GAS - %ECPAIRING_GAS => GAS :JMPN(outOfGas) ; gas static = 45000 1 => C - $ => B :MLOAD(argsLengthCall),JMPZ(continueInput0) + $ => B :MLOAD(txCalldataLen),JMPZ(continueInput0) B :MSTORE(arithA) 192 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => A :MLOAD(arithRes2), JMPNZ(preEndFail) From 4bdb4922ee1e2becd98a6f3bccde88e2c571d516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 08:46:38 +0100 Subject: [PATCH 102/121] Reset carry fix in array add AGTB --- main/modexp/array_lib/array_add_AGTB.zkasm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/modexp/array_lib/array_add_AGTB.zkasm b/main/modexp/array_lib/array_add_AGTB.zkasm index 7bcbccf8..62816554 100644 --- a/main/modexp/array_lib/array_add_AGTB.zkasm +++ b/main/modexp/array_lib/array_add_AGTB.zkasm @@ -91,8 +91,9 @@ array_add_AGTB_loop_index_check: $ => B :MLOAD(array_add_AGTB_len_inA) B - A :JMPZ(array_add_AGTB_check_carry) - 0 => D array_add_AGTB_loopInB2InA: + 0 => D ; reset the carry chunk + ; sum = a[i] + carry: This number cannot be GT base, two chunks $ => A :MLOAD(array_add_AGTB_inA + E) $ => B :MLOAD(array_add_AGTB_carry) From 4bc9d530f9afa993e682f945ce800fc9c7a5308d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 08:47:02 +0100 Subject: [PATCH 103/121] Initialization fix in array mul long --- main/modexp/array_lib/array_mul_long.zkasm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/main/modexp/array_lib/array_mul_long.zkasm b/main/modexp/array_lib/array_mul_long.zkasm index 3f63c3a9..28dea0ef 100644 --- a/main/modexp/array_lib/array_mul_long.zkasm +++ b/main/modexp/array_lib/array_mul_long.zkasm @@ -64,6 +64,7 @@ array_mul_long: C :MSTORE(array_mul_long_len_inA) D :MSTORE(array_mul_long_len_inB) C + D :MSTORE(array_mul_long_len_out) + 0 :MSTORE(array_mul_long_out_chunk_2) ; initialize the out chunk 2 C + D - 1 => E ; auxiliar index 0 => RCX ; first index in loops @@ -86,7 +87,7 @@ array_mul_long_loopZero2inB: ; The result will be stored as D·base + C RCX => E - ; 1] a[i]·b[j], where a[i],a[j] ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks + ; 1] a[i]·b[j], where a[i],b[j] ∈ [0,base-1]: This number cannot be GT (base - 2)·base + 1, two chunks $ => A :MLOAD(array_mul_long_inA + E) $ => B :MLOAD(array_mul_long_inB + RR) 0 => C @@ -94,7 +95,7 @@ array_mul_long_loopZero2inB: ${_arrayLongMul_AB >> 256} => D ${_arrayLongMul_AB} => E :ARITH - ; 2] proudct = a[i]·b[j] + out[i+j], where out[i+j] ∈ [0,base-1]: This number cannot be GT (base - 1)·base, two chunks + ; 2] product = a[i]·b[j] + out[i+j], where out[i+j] ∈ [0,base-1]: This number cannot be GT (base - 1)·base, two chunks E => A RCX + RR => E $ => B :MLOAD(array_mul_long_out + E) @@ -106,10 +107,12 @@ array_mul_long_loopZero2inB: $ => D :ADD ;----------------- __array_mul_long_no_carry_continue_1: - $ => A :MLOAD(array_mul_long_out_chunk_2) + $ => A :MLOAD(array_mul_long_out_chunk_2) ; out_chunk_2 ∈ [0,1] D => B $ => D :ADD ; the number is of two chunks, no carry can be generated here + ; NOTE: It cannot happen that a[i]·b[j] + out[i+j] produces carry and out_chunk_2 is 1. + ; out[i+j] = product - carry·B C :MSTORE(array_mul_long_out + E) From 80fb62f2b4436cfb7ba2e0f7da60aed5b4bdf503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 08:47:15 +0100 Subject: [PATCH 104/121] Initialization fix in array square --- main/modexp/array_lib/array_square.zkasm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main/modexp/array_lib/array_square.zkasm b/main/modexp/array_lib/array_square.zkasm index 25e9a9a8..e42ed6a5 100644 --- a/main/modexp/array_lib/array_square.zkasm +++ b/main/modexp/array_lib/array_square.zkasm @@ -64,6 +64,9 @@ array_square: C :MSTORE(array_square_len_in) C + C :MSTORE(array_square_len_out) + 0 :MSTORE(array_square_chunk_3) ; initialize the third chunk + 0 :MSTORE(array_square_out_chunk_2) ; initialize the second chunk of out + 0 => RCX,RR ; first and second indexes in loops C + C - 1 => E array_square_clean_out: From e83a9efc82015f8a2d1aee93f44bca4da2d63753 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Fri, 12 Jan 2024 13:36:39 +0100 Subject: [PATCH 105/121] Cumulative gas used fix --- main/constants.zkasm | 2 +- main/main.zkasm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main/constants.zkasm b/main/constants.zkasm index ee6aff89..2d6b650a 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -4,7 +4,7 @@ CONSTL %ADDRESS_SYSTEM = 0x000000000000000000000000000000005ca1ab1en CONST %MAX_STACK_SIZE = 1024 CONST %BATCH_DIFFICULTY = 0 CONST %TX_GAS_LIMIT = 30000000 -CONST %BLOCK_GAS_LIMIT = 2**32-1 +CONSTL %BLOCK_GAS_LIMIT = 2**64-1 CONST %MAX_MEM_EXPANSION_BYTES = 0x3fffe0 CONST %FORK_ID = 7 CONST %L1INFO_TREE_LEVELS = 32 diff --git a/main/main.zkasm b/main/main.zkasm index 31c30f93..1b53b07d 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -121,12 +121,12 @@ txLoop: A - 1 :JMPZ(processChangeL2Block, processTx) processTxFinished: + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) ; Increase cumulativeGasUsed $ => A :MLOAD(txGasLimit) A - GAS => A $ => B :MLOAD(cumulativeGasUsed) - ; Fill block info tree with tx receipt - A + B :MSTORE(cumulativeGasUsed), CALL(fillBlockInfoTreeWithTxReceipt) + $ :ADD, MSTORE(cumulativeGasUsed), CALL(fillBlockInfoTreeWithTxReceipt) ; Increase txIndex $ => A :MLOAD(txIndex) A + 1 :MSTORE(txIndex) From bc57552e2dafed77828e420f5537c94b33eb0528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 10:53:02 +0100 Subject: [PATCH 106/121] Soundness issus fixed in array div long --- main/modexp/array_lib/array_div_long.zkasm | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/main/modexp/array_lib/array_div_long.zkasm b/main/modexp/array_lib/array_div_long.zkasm index 51201964..74fa7d23 100644 --- a/main/modexp/array_lib/array_div_long.zkasm +++ b/main/modexp/array_lib/array_div_long.zkasm @@ -162,11 +162,15 @@ array_div_long_prepare_mul_quo_inB: ; From here, the quotient is trimmed C :MSTORE(array_div_long_len_quo) - $ => D :MLOAD(array_div_long_len_inB) C - 1 => RR D - 1 => E + ; save the first non-zero chunk of quo + A :MSTORE(array_div_long_quo + RR) + A :MSTORE(array_mul_inA + RR) + RR - 1 => RR :JMPN(array_div_long_inB_to_mul) + %MAX_CNT_STEPS - STEP - 4*%ARRAY_MAX_LEN - 3*D - 1 :JMPN(outOfCountersStep) array_div_long_quo_to_mul: @@ -206,22 +210,26 @@ array_div_long_mul_quo_inB: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 3*C - 3*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) + ; save the first non-zero chunk of rem + A :MSTORE(array_compare_inB + E) + E - 1 => E :JMPN(array_div_long_compare_inB2) -array_div_long_compare_inB2: - $ => A :MLOAD(array_div_long_inB + RR) - A :MSTORE(array_compare_inA + RR) - RR - 1 => RR :JMPN(array_div_long_compare_rem, array_div_long_compare_inB2) + %MAX_CNT_STEPS - STEP - 3*C - 3*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) array_div_long_compare_rem: ${receiveRemainderChunk(E)} => A A :MSTORE(array_compare_inB + E) - E - 1 => E :JMPN(array_div_long_compare2, array_div_long_compare_rem) + E - 1 => E :JMPN(array_div_long_compare_inB2, array_div_long_compare_rem) + +array_div_long_compare_inB2: + $ => A :MLOAD(array_div_long_inB + RR) + A :MSTORE(array_compare_inA + RR) + RR - 1 => RR :JMPN(array_div_long_compare2, array_div_long_compare_inB2) array_div_long_compare2: :CALL(array_compare) - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) 2 :MLOAD(array_compare_result) @@ -240,7 +248,7 @@ array_div_long_res_to_add: RR - 1 => RR :JMPN(array_div_long_rem_to_add, array_div_long_res_to_add) array_div_long_rem_to_add: - ${receiveRemainderChunk(E)} => A + $ => A :MLOAD(array_compare_inB + E) ; Load the remainder used in the comparison A :MSTORE(array_div_long_rem + E) A :MSTORE(array_add_AGTB_inB + E) E - 1 => E :JMPN(array_div_long_add_res_rem, array_div_long_rem_to_add) From 8107714953764112d327cb0b68aa0381591aa1b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 10:53:10 +0100 Subject: [PATCH 107/121] Soundness issus fixed in array div short --- main/modexp/array_lib/array_div_short.zkasm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main/modexp/array_lib/array_div_short.zkasm b/main/modexp/array_lib/array_div_short.zkasm index 22b2ddf7..999fdd17 100644 --- a/main/modexp/array_lib/array_div_short.zkasm +++ b/main/modexp/array_lib/array_div_short.zkasm @@ -143,9 +143,13 @@ array_div_short_prepare_mul_quo_inB: ; From here, the quotient is trimmed C :MSTORE(array_div_short_len_quo) - C - 1 => RR + ; save the first non-zero chunk of quo + A :MSTORE(array_div_short_quo + RR) + A :MSTORE(array_mul_short_inA + RR) + RR - 1 => RR :JMPN(array_div_short_inB_to_mul) + %MAX_CNT_STEPS - STEP - 4*%ARRAY_MAX_LEN - 3 :JMPN(outOfCountersStep) array_div_short_quo_to_mul: From bbfa28f57b11d62814646e22589adf9d3f8bf0c9 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 17 Jan 2024 10:54:52 +0100 Subject: [PATCH 108/121] add fixes to wrong comments --- main/load-tx-rlp-utils.zkasm | 7 +++++-- main/load-tx-rlp.zkasm | 17 +++++++++++------ main/main.zkasm | 7 ++++++- main/opcodes/block.zkasm | 4 ++-- main/utils.zkasm | 3 ++- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/main/load-tx-rlp-utils.zkasm b/main/load-tx-rlp-utils.zkasm index d5c67f56..8f8af699 100644 --- a/main/load-tx-rlp-utils.zkasm +++ b/main/load-tx-rlp-utils.zkasm @@ -22,7 +22,8 @@ getTxBytes: VAR CTX l2HASHP VAR GLOBAL addL2HashTxAux -;Add bytes to generate L2 transaction hash. transactionHash = linearPoseidon(nonce, gasprice, gaslimit, to, value, data, from) +;; Add bytes to generate L2 transaction hash +;; transactionHashL2 = linearPoseidon(nonce, gasprice, gaslimit, to, value, data, from) ; @in A => bytes to add to hash ; @in D => length of the bytes to add to hash addL2HashTx: @@ -35,7 +36,9 @@ addL2HashTx: $ => HASHPOS :MLOAD(addL2HashTxAux) B => E :RETURN -;; Add bytes to generate ethereum transaction hash. transactionHash = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)) +;; Add bytes to generate ethereum signed message +;; - legacy transaction: signedMessage = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)) +;; - pre EIP-155: signedMessage = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data)) addHashTx: $ => A :MLOAD(txRLPLength) A - HASHPOS - D :JMPN(invalidTxRLP) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 769b6c26..6637716d 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -10,8 +10,13 @@ INCLUDE "load-change-l2-block.zkasm" ;;;;;;;;;;;;;;;;;; ;; A - Initialization -;; - Data to parse: [rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)|r|s|v] -;; - Signed Ethereum transaction: H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)) +;; - Data to parse +;; - legaxy transaction: [rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)|r|s|v|effectivePercentage] +;; - pre EIP-155 transaction (https://eips.ethereum.org/EIPS/eip-155): [rlp(nonce, gasprice, gaslimit, to, value, data)|r|s|v|effectivePercentage] +;; - internal transaction changeL2Block: [txType, deltaTimestamp, indexL1InfoTree] +;; - Signed Ethereum transaction +;; - legacy transaction: H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)) +;; - pre EIP-155 transaction: H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data)) ;; - RLP encoding information: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp ;; - Entire batch is discarded (no transaction is processed) if any error is found ;;;;;;;;;;;;;;;;;; @@ -55,7 +60,7 @@ loadTx_rlp_continue: A - 0xc0 :JMPN(invalidTxRLP) A - 0xf8 :JMPN(shortList) ; do not allow lists over 2**24 bytes length - ; Transaction could not have more than 300.000 due to smart contract limitation (keccaks counters) + ; Transaction could not have more than 120.000 due to smart contract limitation (keccaks counters) ; meaning that the RLP encoding is wrong A - 0xfb :JMPN(longList, invalidTxRLP) @@ -202,7 +207,7 @@ dataREAD: A - 0x81 :JMPN(endData) A - 0xb8 :JMPN(shortData) ; do not allow string over 2**24 bytes length - ; Transaction could not have more than 300.000 due to smart contract limitation (keccaks counters) + ; Transaction could not have more than 120.000 due to smart contract limitation (keccaks counters) ; meaning that the RLP encoding is wrong A - 0xbb :JMPN(longData, invalidTxRLP) @@ -268,7 +273,7 @@ readDataFinal: endData: ; Check all bytes read to detect pre EIP-155 tx, if bytes read are the same as txLength, we reached the end, so it's a pre EIP-155 tx - ; txRLPLength and C is at most 300.000 bytes, no need to use a binary for comparison + ; txRLPLength and C is at most 120.000 bytes, no need to use a binary for comparison $ => B :MLOAD(txRLPLength) C - B :JMPZ(setPreEIP155Flag) @@ -305,7 +310,7 @@ setPreEIP155Flag: ;; size verification ; checks RLP length read at the RLP header with bytes read during RLP parsing sizeVerification: - ; txRLPLength and C is at most 300.000 bytes, no need to use a binary for comparison + ; txRLPLength and C is at most 120.000 bytes, no need to use a binary for comparison $ => B :MLOAD(txRLPLength) C - B :JMPZ(sizeVerificationSuccess, invalidTxRLP) sizeVerificationSuccess: diff --git a/main/main.zkasm b/main/main.zkasm index 31c30f93..77f0acf4 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -32,7 +32,7 @@ start: ; main zkROM entry point ${getL1InfoRoot()} :MSTORE(l1InfoRoot) ${getSequencerAddr()} :MSTORE(sequencerAddr) ${getTimestampLimit()} :MSTORE(timestampLimit) - ${getTxsLen()} :MSTORE(batchL2DataLength) ; less than 300.000 bytes. Enforced by the smart contract + ${getTxsLen()} :MSTORE(batchL2DataLength) ; less than 120000 bytes. Enforced by the smart contract ${getForcedBlockHashL1()} => A :MSTORE(forcedBlockHashL1) ;set initial state root @@ -146,6 +146,11 @@ finalizeBatch: ;; - compute newAccInputHash ;;;;;;;;;;;;;;;;;; +;; Batch must be always end correctly +;; Meaning that enough zk-counters should be available to finalize it +;; - 'keccaks' are reserved at the very beginning of the batch in order to be able to perform the final 'accInputHash' hash +;; - the rest of counters will not overflow since it is added a %SAFE_RANGE bandwith + ;; Get local exit root ; Read 'localExitRoot' variable from GLOBAL_EXIT_ROOT_MANAGER_L2 and store ; it to the 'newLocalExitRoot' input diff --git a/main/opcodes/block.zkasm b/main/opcodes/block.zkasm index a1059329..a72452f3 100644 --- a/main/opcodes/block.zkasm +++ b/main/opcodes/block.zkasm @@ -97,7 +97,7 @@ opNUMBER: ; check out-of-gas GAS - %GAS_QUICK_STEP => GAS :JMPN(outOfGas) - ; Get current tx count + ; Get current block number $ => A :MLOAD(blockNum) A :MSTORE(SP++); [blockNumber => SP] ; check stack overflow @@ -137,7 +137,7 @@ opGASLIMIT: ; check out-of-gas GAS-%GAS_QUICK_STEP => GAS :JMPN(outOfGas) - ; constant tx gas limit + ; constant block gas limit %BLOCK_GAS_LIMIT => A A :MSTORE(SP++); [gasLimit => SP] ; check stack overflow diff --git a/main/utils.zkasm b/main/utils.zkasm index ba021a52..45d5637a 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -870,7 +870,7 @@ handleError: ;revert all state changes $ => SR :MLOAD(initSR), CALL(revertTouched) :CALL(revertBlockInfoTree) - ;remaining gas = 0 + $ => A :MLOAD(originCTX), JMPZ(errorAtFirstContext) A => CTX ; Add return data context value to origin context @@ -895,6 +895,7 @@ errorAtFirstContext: 0 :MSTORE(txStatus) ;save Root and jump to send gas to sequencer 0 :MSTORE(gasRefund) + ;remaining gas = 0 0 => GAS :JMP(sendGasSeq) VAR GLOBAL tmpVarAoffsetUtil From 54d3e709aaac2317ce7f6b261f5d581a1012602b Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 17 Jan 2024 11:09:33 +0100 Subject: [PATCH 109/121] PR review --- main/load-tx-rlp.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 6637716d..a2240ad8 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -11,7 +11,7 @@ INCLUDE "load-change-l2-block.zkasm" ;;;;;;;;;;;;;;;;;; ;; A - Initialization ;; - Data to parse -;; - legaxy transaction: [rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)|r|s|v|effectivePercentage] +;; - legacy transaction: [rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)|r|s|v|effectivePercentage] ;; - pre EIP-155 transaction (https://eips.ethereum.org/EIPS/eip-155): [rlp(nonce, gasprice, gaslimit, to, value, data)|r|s|v|effectivePercentage] ;; - internal transaction changeL2Block: [txType, deltaTimestamp, indexL1InfoTree] ;; - Signed Ethereum transaction From 4b84e6c9823a68559f4b00925f6a6e3cdd6cab43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 13:12:25 +0100 Subject: [PATCH 110/121] Soundness issus fixed in counters of array div long --- main/modexp/array_lib/array_div_long.zkasm | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/main/modexp/array_lib/array_div_long.zkasm b/main/modexp/array_lib/array_div_long.zkasm index 74fa7d23..f0ef8c2b 100644 --- a/main/modexp/array_lib/array_div_long.zkasm +++ b/main/modexp/array_lib/array_div_long.zkasm @@ -88,8 +88,8 @@ array_div_long_compare_inB1: array_div_long_compare1: :CALL(array_compare) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 15 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 16 - 4*(%ARRAY_MAX_LEN - 1) - 3*D - 1 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_long_prep_inALTinB) A - 1 :JMPZ(array_div_long_same_input) @@ -133,7 +133,7 @@ array_div_long_prep_inALTinB: 1 :MSTORE(array_div_long_len_quo) C :MSTORE(array_div_long_len_rem) - %MAX_CNT_STEPS - STEP - 1 - 4*C - 2 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 1 - 3*C - 2 :JMPN(outOfCountersStep) C - 1 => RR array_div_long_inALTinB: @@ -171,8 +171,6 @@ array_div_long_prepare_mul_quo_inB: A :MSTORE(array_mul_inA + RR) RR - 1 => RR :JMPN(array_div_long_inB_to_mul) - %MAX_CNT_STEPS - STEP - 4*%ARRAY_MAX_LEN - 3*D - 1 :JMPN(outOfCountersStep) - array_div_long_quo_to_mul: ${receiveQuotientChunk(RR)} => A A :MSTORE(array_div_long_quo + RR) @@ -187,8 +185,8 @@ array_div_long_inB_to_mul: array_div_long_mul_quo_inB: :CALL(array_mul) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 11 - 3*(%ARRAY_MAX_LEN - 1) - 3*D - 1 :JMPN(outOfCountersStep) ; Check the remainder $0{receiveLenRemainder()} => D @@ -214,8 +212,6 @@ array_div_long_mul_quo_inB: A :MSTORE(array_compare_inB + E) E - 1 => E :JMPN(array_div_long_compare_inB2) - %MAX_CNT_STEPS - STEP - 3*C - 3*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) - array_div_long_compare_rem: ${receiveRemainderChunk(E)} => A A :MSTORE(array_compare_inB + E) @@ -229,7 +225,7 @@ array_div_long_compare_inB2: array_div_long_compare2: :CALL(array_compare) - %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 - 3*%ARRAY_MAX_LEN - 4*%ARRAY_MAX_LEN - 1 :JMPN(outOfCountersStep) 2 :MLOAD(array_compare_result) @@ -240,8 +236,6 @@ array_div_long_compare2: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 3*C - 4*D - 1 :JMPN(outOfCountersStep) - array_div_long_res_to_add: $ => A :MLOAD(array_mul_out + RR) A :MSTORE(array_add_AGTB_inA + RR) @@ -264,7 +258,7 @@ array_div_long_add_res_rem: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*%ARRAY_MAX_LEN - 3*D - 1 :JMPN(outOfCountersStep) array_div_long_compare_inA2: $ => A :MLOAD(array_add_AGTB_out + RR) From f5e50a76a67ed4ad74237eabfffbd446ea4e3b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 13:12:35 +0100 Subject: [PATCH 111/121] Soundness issus fixed in counters of array div short --- main/modexp/array_lib/array_div_short.zkasm | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/main/modexp/array_lib/array_div_short.zkasm b/main/modexp/array_lib/array_div_short.zkasm index 999fdd17..46f508e0 100644 --- a/main/modexp/array_lib/array_div_short.zkasm +++ b/main/modexp/array_lib/array_div_short.zkasm @@ -82,8 +82,8 @@ array_div_short_inB_to_compare: array_div_short_compare_inA_inB: :CALL(array_compare) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 13 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 14 - 4*(%ARRAY_MAX_LEN - 1) - 3 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_short_inALTinB) A - 1 :JMPZ(array_div_short_same_input) @@ -150,8 +150,6 @@ array_div_short_prepare_mul_quo_inB: A :MSTORE(array_mul_short_inA + RR) RR - 1 => RR :JMPN(array_div_short_inB_to_mul) - %MAX_CNT_STEPS - STEP - 4*%ARRAY_MAX_LEN - 3 :JMPN(outOfCountersStep) - array_div_short_quo_to_mul: ${receiveQuotientChunk_short(RR)} => A A :MSTORE(array_div_short_quo + RR) @@ -165,15 +163,13 @@ array_div_short_inB_to_mul: array_div_short_mul_quo_inB: :CALL(array_mul_short) - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + %MAX_CNT_STEPS - STEP - 2 - 3*%ARRAY_MAX_LEN - 6 :JMPN(outOfCountersStep) ; prepare next $ => C :MLOAD(array_mul_short_len_out) C - 1 => RR - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 3*C - 6 :JMPN(outOfCountersStep) - array_div_short_result_to_add: $ => A :MLOAD(array_mul_short_out + RR) A :MSTORE(array_add_short_inA + RR) @@ -200,7 +196,7 @@ array_div_short_add_result_rem: C - 1 => RR D - 1 => E - %MAX_CNT_STEPS - STEP - 3*C - 3*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 3*%ARRAY_MAX_LEN - 3*D - 1 :JMPN(outOfCountersStep) array_div_short_result_to_compare: $ => A :MLOAD(array_add_short_out + RR) From 89f6782569a2a917de5ddaae6b2c3df56eb21322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 17 Jan 2024 13:24:00 +0100 Subject: [PATCH 112/121] Minor issues solved in coutners computation --- main/modexp/array_lib/array_div_long.zkasm | 5 +++-- main/modexp/array_lib/array_div_short.zkasm | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/main/modexp/array_lib/array_div_long.zkasm b/main/modexp/array_lib/array_div_long.zkasm index f0ef8c2b..95d17a08 100644 --- a/main/modexp/array_lib/array_div_long.zkasm +++ b/main/modexp/array_lib/array_div_long.zkasm @@ -89,7 +89,7 @@ array_div_long_compare1: :CALL(array_compare) %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 16 - 4*(%ARRAY_MAX_LEN - 1) - 3*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 12 - 4*%ARRAY_MAX_LEN - 3*D - 1 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_long_prep_inALTinB) A - 1 :JMPZ(array_div_long_same_input) @@ -185,8 +185,9 @@ array_div_long_inB_to_mul: array_div_long_mul_quo_inB: :CALL(array_mul) + $ => D :MLOAD(array_div_long_len_inB) %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 11 - 3*(%ARRAY_MAX_LEN - 1) - 3*D - 1 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 8 - 3*%ARRAY_MAX_LEN - 3*D - 1 :JMPN(outOfCountersStep) ; Check the remainder $0{receiveLenRemainder()} => D diff --git a/main/modexp/array_lib/array_div_short.zkasm b/main/modexp/array_lib/array_div_short.zkasm index 46f508e0..577b57ad 100644 --- a/main/modexp/array_lib/array_div_short.zkasm +++ b/main/modexp/array_lib/array_div_short.zkasm @@ -83,7 +83,7 @@ array_div_short_compare_inA_inB: :CALL(array_compare) %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - %MAX_CNT_STEPS - STEP - 14 - 4*(%ARRAY_MAX_LEN - 1) - 3 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 10 - 4*%ARRAY_MAX_LEN - 3 :JMPN(outOfCountersStep) $ => A :MLOAD(array_compare_result), JMPZ(array_div_short_inALTinB) A - 1 :JMPZ(array_div_short_same_input) From 77c255ed6ed5c8896844e4a9c67b2404eab4ffe6 Mon Sep 17 00:00:00 2001 From: laisolizq Date: Wed, 17 Jan 2024 17:39:31 +0100 Subject: [PATCH 113/121] update commonjs & testvectors cumulative-gas-fix --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 27a79b9c..5684ebc4 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.2-fork.7", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/cumulative-gas-fix", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#5999f90e0f6c5f6e735bdef6ab3d0424fec90f75", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.2-fork.7", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/cumulative-gas-fix", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From 70dd6475dcdb6c07e2371f46db8868fc970f664e Mon Sep 17 00:00:00 2001 From: laisolizq Date: Mon, 22 Jan 2024 12:08:12 +0100 Subject: [PATCH 114/121] update tags --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5684ebc4..15d86d1f 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/cumulative-gas-fix", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.3-fork.7", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#5999f90e0f6c5f6e735bdef6ab3d0424fec90f75", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/cumulative-gas-fix", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.3-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From d7e0cf92b0eb675f6032ed5603f57e180dfed6db Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 24 Jan 2024 18:54:40 +0100 Subject: [PATCH 115/121] new l2 hash --- compare.json | 51 +++++++++++++++++++ main/ecrecover/constEc.zkasm | 4 +- main/ecrecover/ecrecover.zkasm | 2 +- main/l2-tx-hash.zkasm | 89 ++++++++++++++++++++++++++++++++++ main/load-tx-rlp-utils.zkasm | 16 ------ main/load-tx-rlp.zkasm | 45 +++++++++++------ main/process-tx.zkasm | 2 +- 7 files changed, 176 insertions(+), 33 deletions(-) create mode 100644 compare.json create mode 100644 main/l2-tx-hash.zkasm diff --git a/compare.json b/compare.json new file mode 100644 index 00000000..2ed382bf --- /dev/null +++ b/compare.json @@ -0,0 +1,51 @@ +``` + [ 1 bytes ] txType = 0 + [ 8 bytes ] nonce + [ 32 bytes ] gasPrice + [ 8 bytes ] gasLimit + [ 1 bytes ] deployment ('0' or '1') + [ 20 bytes ] to (0 if it is a deployment) + [ 32 bytes ] value + [ 3 bytes ] dataLength + [ XX bytes ] data + [ 8 bytes ] chainID + [ 20 bytes ] from +``` + +{ + "from": "0x4d5Cf5032B2a844602278b01199ED191A86c93ff", + "to": "0x1275fbb540c8efc58b812ba83b0d0b8b9917ae98", + "nonce": 0, + "value": "0", + "contractName": "Test", + "function": "setFirst", + "params": [ + 7 + ], + "chainId": 1000, + "reason": "", + "gasLimit": 100000, + "gasPrice": "1000000000", + "data": "0x5ef3d3dd0000000000000000000000000000000000000000000000000000000000000007", + "customRawTx": "0xf84a80843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae9880a45ef3d3dd00000000000000000000000000000000000000000000000000000000000000078203e880803943e5a952e27d85c91f61610159fd8caf0dd68db76a1df7fb52934156d9ec935ceec6b0f908e36ee8b2c70350b3813d72558572ff95deac79069168e68726571cff", + "rawTx": "0xf88a80843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae9880a45ef3d3dd00000000000000000000000000000000000000000000000000000000000000078207f4a03943e5a952e27d85c91f61610159fd8caf0dd68db76a1df7fb52934156d9ec93a05ceec6b0f908e36ee8b2c70350b3813d72558572ff95deac79069168e6872657" + } + +0000000000000000000000000000000000000000000000000000000000000000000000003b9aca0000000000000186a0001275fbb540c8efc58b812ba83b0d0b8b9917ae980000000000000000000000000000000000000000000000000000000000000000000024 +5ef3d3dd00000000000000000000000000000000000000000000000000000000 + +0x0b73e6af6f00000000 + +f8 +4a +80 +843b9aca00 +830186a0 +941275fbb540c8efc58b812ba83b0d0b8b9917ae98 --> to +80 +a4 +5ef3d3dd0000000000000000000000000000000000000000000000000000000000000007 +8203e8 +80 +80 +3943e5a952e27d85c91f61610159fd8caf0dd68db76a1df7fb52934156d9ec935ceec6b0f908e36ee8b2c70350b3813d72558572ff95deac79069168e68726571cffee80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff88016345785d8a0000808203e880801cee7e01dc62f69a12c3510c6d64de04ee6346d84b6a017f3e786c7d87f963e75d8cc91fa983cd6d9cf55fff80d73bd26cd333b0f098acc1e58edb1fd484ad731bff \ No newline at end of file diff --git a/main/ecrecover/constEc.zkasm b/main/ecrecover/constEc.zkasm index b858190e..705560fd 100644 --- a/main/ecrecover/constEc.zkasm +++ b/main/ecrecover/constEc.zkasm @@ -10,4 +10,6 @@ CONSTL %FNEC_MINUS_ONE = %FNEC - 1 CONSTL %ECGX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n CONSTL %ECGY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8n CONSTL %P2_160 = 2n ** 160n -CONSTL %P2_96 = 2n ** 96n \ No newline at end of file +CONSTL %P2_96 = 2n ** 96n + +CONSTL %ADDRESS_ECRECOVER_ERROR = 0x0102030405060708090102030405060708090102n \ No newline at end of file diff --git a/main/ecrecover/ecrecover.zkasm b/main/ecrecover/ecrecover.zkasm index ebe99b09..f3eb39fa 100644 --- a/main/ecrecover/ecrecover.zkasm +++ b/main/ecrecover/ecrecover.zkasm @@ -263,7 +263,7 @@ ecrecover_p3_point_at_infinity: 7 => B :JMP(ecrecover_error) ecrecover_error: - 0 => A + %ADDRESS_ECRECOVER_ERROR => A ecrecover_end: $ => RR :MLOAD(ecrecover_RR) diff --git a/main/l2-tx-hash.zkasm b/main/l2-tx-hash.zkasm new file mode 100644 index 00000000..1a878462 --- /dev/null +++ b/main/l2-tx-hash.zkasm @@ -0,0 +1,89 @@ +VAR CTX l2HASHP +VAR GLOBAL addL2HashTxAux +VAR GLOBAL tmpVarA_addL2HashTx +VAR GLOBAL tmpVarB_addL2HashTx +VAR GLOBAL tmpVarD_addL2HashTx +VAR GLOBAL tmpVarE_addL2HashTx + +;; Add bytes to generate L2 transaction hash +; @in A => bytes to add to hash +; @in D => length of the bytes to add to hash +addL2HashTx: + E => B + $ => E :MLOAD(l2TxHashPointer) + HASHPOS :MSTORE(addL2HashTxAux) + $ => HASHPOS :MLOAD(l2HASHP) + A :HASHP(E) + HASHPOS :MSTORE(l2HASHP) + $ => HASHPOS :MLOAD(addL2HashTxAux) + B => E :RETURN + +;; Add byte to determine if it is a deployment +addL2HashTx_isDeploy: + A :MSTORE(tmpVarA_addL2HashTx) + D :MSTORE(tmpVarD_addL2HashTx) + E => B + $ => E :MLOAD(l2TxHashPointer) + HASHPOS :MSTORE(addL2HashTxAux) + $ => HASHPOS :MLOAD(l2HASHP) + 1 => D + 1 :HASHP(E) + HASHPOS :MSTORE(l2HASHP) + $ => HASHPOS :MLOAD(addL2HashTxAux) + $ => D :MLOAD(tmpVarD_addL2HashTx) + $ => A :MLOAD(tmpVarA_addL2HashTx) + B => E :RETURN + +;; Add byte to determine if it is not a deployment +addL2HashTx_isNotDeploy: + A :MSTORE(tmpVarA_addL2HashTx) + D :MSTORE(tmpVarD_addL2HashTx) + E => B + $ => E :MLOAD(l2TxHashPointer) + HASHPOS :MSTORE(addL2HashTxAux) + $ => HASHPOS :MLOAD(l2HASHP) + 1 => D + 0 :HASHP(E) + HASHPOS :MSTORE(l2HASHP) + $ => HASHPOS :MLOAD(addL2HashTxAux) + $ => D :MLOAD(tmpVarD_addL2HashTx) + $ => A :MLOAD(tmpVarA_addL2HashTx) + B => E :RETURN + +;; Add 3 bytes which will be the data length +addL2HashTx_dataLength: + A :MSTORE(tmpVarA_addL2HashTx) + B :MSTORE(tmpVarB_addL2HashTx) + D :MSTORE(tmpVarD_addL2HashTx) + E :MSTORE(tmpVarE_addL2HashTx) + $ => E :MLOAD(l2TxHashPointer) + HASHPOS :MSTORE(addL2HashTxAux) + $ => HASHPOS :MLOAD(l2HASHP) + 3 => D + $ => A :MLOAD(txCalldataLen) + A :HASHP(E) + HASHPOS :MSTORE(l2HASHP) + $ => HASHPOS :MLOAD(addL2HashTxAux) + $ => E :MLOAD(tmpVarE_addL2HashTx) + $ => D :MLOAD(tmpVarD_addL2HashTx) + $ => B :MLOAD(tmpVarB_addL2HashTx) + $ => A :MLOAD(tmpVarA_addL2HashTx), RETURN + +;; Add 1 bytes which will be the txType +addL2HashTx_txType: + A :MSTORE(tmpVarA_addL2HashTx) + D :MSTORE(tmpVarD_addL2HashTx) + $ => E :MLOAD(l2TxHashPointer) + HASHPOS :MSTORE(addL2HashTxAux) + 0 => HASHPOS + 1 => D + $ => A :MLOAD(isPreEIP155), JMPZ(addL2HashTx_txType_write_1) +addL2HashTx_txType_write_0: + 0 :HASHP(E), JMP(addL2HashTx_txType_finish) +addL2HashTx_txType_write_1: + 1 :HASHP(E) +addL2HashTx_txType_finish: + ; recover total length HASHPOS + $ => HASHPOS :MLOAD(l2HASHP) + $ => D :MLOAD(tmpVarD_addL2HashTx) + $ => A :MLOAD(tmpVarA_addL2HashTx), RETURN \ No newline at end of file diff --git a/main/load-tx-rlp-utils.zkasm b/main/load-tx-rlp-utils.zkasm index 8f8af699..e81d810a 100644 --- a/main/load-tx-rlp-utils.zkasm +++ b/main/load-tx-rlp-utils.zkasm @@ -20,22 +20,6 @@ getTxBytes: $${p = p + D} :RETURN -VAR CTX l2HASHP -VAR GLOBAL addL2HashTxAux -;; Add bytes to generate L2 transaction hash -;; transactionHashL2 = linearPoseidon(nonce, gasprice, gaslimit, to, value, data, from) -; @in A => bytes to add to hash -; @in D => length of the bytes to add to hash -addL2HashTx: - E => B - $ => E :MLOAD(l2TxHashPointer) - HASHPOS :MSTORE(addL2HashTxAux) - $ => HASHPOS :MLOAD(l2HASHP) - A :HASHP(E) - HASHPOS :MSTORE(l2HASHP) - $ => HASHPOS :MLOAD(addL2HashTxAux) - B => E :RETURN - ;; Add bytes to generate ethereum signed message ;; - legacy transaction: signedMessage = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)) ;; - pre EIP-155: signedMessage = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data)) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index a2240ad8..f01577a0 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -1,5 +1,6 @@ INCLUDE "load-tx-rlp-utils.zkasm" INCLUDE "load-change-l2-block.zkasm" +INCLUDE "l2-tx-hash.zkasm" ; Blocks RLP parsing ; A - Initialization @@ -84,6 +85,9 @@ endList: $ => D :MLOAD(cntKeccakPreProcess) %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1 :JMPN(outOfCountersKeccak) +; reserve one byte for the txType in the l2HashTx + 1 :MSTORE(l2HASHP) + ;; Read RLP 'nonce' ; 64 bits max nonceREAD: @@ -104,6 +108,7 @@ shortNonce: :CALL(checkNonLeadingZeros) endNonce: + 8 => D A :MSTORE(txNonce), CALL(addL2HashTx) ;; Read RLP 'gas price' @@ -125,6 +130,7 @@ shortGasPrice: :CALL(checkNonLeadingZeros) endGasPrice: + 32 => D A :MSTORE(txGasPriceRLP), CALL(addL2HashTx) @@ -147,6 +153,7 @@ shortGasLimit: :CALL(checkNonLeadingZeros) endGasLimit: + 8 => D A :MSTORE(txGasLimit), CALL(addL2HashTx) ;; Read RLP 'to' @@ -160,10 +167,12 @@ toREAD: A - 0x95 :JMPN(shortTo, invalidTxRLP) noTo: - 1 :MSTORE(isCreateContract), JMP(endTo) + 1 :MSTORE(isCreateContract), CALL(addL2HashTx_isDeploy) + :JMP(endTo) shortTo: A - 0x80 => D :CALL(addHashTx) + :CALL(addL2HashTx_isNotDeploy) :CALL(addL2HashTx) :CALL(addBatchHashData) A :MSTORE(txDestAddr) @@ -190,6 +199,7 @@ shortValue: :CALL(checkNonLeadingZeros) endValue: + 32 => D A :MSTORE(txValue), CALL(addL2HashTx) ;; Read RLP 'data' @@ -204,7 +214,7 @@ dataREAD: 1 => D :CALL(addHashTx) :CALL(addBatchHashData) A - 0x80 :JMPN(veryShortData) - A - 0x81 :JMPN(endData) + A - 0x81 :JMPN(zeroBytesData) A - 0xb8 :JMPN(shortData) ; do not allow string over 2**24 bytes length ; Transaction could not have more than 120.000 due to smart contract limitation (keccaks counters) @@ -212,7 +222,8 @@ dataREAD: A - 0xbb :JMPN(longData, invalidTxRLP) veryShortData: - 1 :MSTORE(txCalldataLen), CALL(addL2HashTx) + 1 :MSTORE(txCalldataLen), CALL(addL2HashTx_dataLength) + :CALL(addL2HashTx) 31 => D :CALL(SHLarith) ; in: [A: value, D: #bytes to left shift] out: [A: shifted result] ; Store current CTX CTX => B @@ -228,7 +239,8 @@ veryShortData: shortData: $ => D :MLOAD(batchHashPos) D :MSTORE(dataStarts) - A - 0x80 => B :MSTORE(txCalldataLen), JMP(readData) + A - 0x80 => B :MSTORE(txCalldataLen), CALL(addL2HashTx_dataLength) + :JMP(readData) longData: A - 0xb7 => D :CALL(addHashTx) @@ -237,7 +249,7 @@ longData: :CALL(checkNonLeadingZeros) $ => D :MLOAD(batchHashPos) D :MSTORE(dataStarts) - A => B :MSTORE(txCalldataLen) + A => B :MSTORE(txCalldataLen), CALL(addL2HashTx_dataLength) readData: 32 => D @@ -270,6 +282,10 @@ readDataFinal: E + 1 :MSTORE(globalCalldataMemoryOffset) 32 - D => D :CALL(addBatchHashByteByByte); in: [A: bytes to add, D: bytes length] out: [E: lastHashKIdUsed, A: shifted bytes to add] :CALL(checkShortDataRLP) + :JMP(endData) + +zeroBytesData: + :CALL(addL2HashTx_dataLength) endData: ; Check all bytes read to detect pre EIP-155 tx, if bytes read are the same as txLength, we reached the end, so it's a pre EIP-155 tx @@ -297,7 +313,8 @@ shortChainId: :CALL(checkNonLeadingZeros) endChainId: - A :MSTORE(txChainId) + 8 => D + A :MSTORE(txChainId), CALL(addL2HashTx) ;; Read RLP last two values (0, 0) 2 => D :CALL(addHashTx) @@ -366,14 +383,14 @@ finishLoadRLP: checkAndSaveFrom: ; warning: we need to insert one transition step between label `checkAndSafeFrom` and `MSTORE(txSrcAddr)` to allow unsigned transactions from executor 20 => D - A :MSTORE(txSrcAddr) - $ => E :MLOAD(l2TxHashPointer) - $ => HASHPOS :MLOAD(l2HASHP) - A :HASHP(E) - HASHPOS :HASHPLEN(E) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - $ => B :HASHPDIGEST(E) - B :MSTORE(l2TxHash),JMP(txLoopRLP) + ; save 'from' to l2TxHash + A :MSTORE(txSrcAddr), CALL(addL2HashTx) + ; save txType to l2TxHash + :CALL(addL2HashTx_txType) + HASHPOS :HASHPLEN(E) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + $ => B :HASHPDIGEST(E) + B :MSTORE(l2TxHash),JMP(txLoopRLP) ;;;;;;;;; ;; E - Handler error RLP fields diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index ae9fb5c3..d80a380d 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -35,7 +35,7 @@ processTx: %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) ; Check the signature - 0 => B + %ADDRESS_ECRECOVER_ERROR => B $ => A :MLOAD(txSrcAddr) A :MSTORE(txSrcOriginAddr) $ :EQ,JMPC(invalidIntrinsicTxSignature) From b59f3758b916d69d093b3d3bf48a0a7df822a236 Mon Sep 17 00:00:00 2001 From: Ignasi Date: Wed, 24 Jan 2024 19:12:26 +0100 Subject: [PATCH 116/121] Update package --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 15d86d1f..4e4a42b9 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.3-fork.7", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#5999f90e0f6c5f6e735bdef6ab3d0424fec90f75", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.3-fork.7", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/new-l2hash", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", From ba28b60a9930c1145c25b6a52ca4be2d77b06bfc Mon Sep 17 00:00:00 2001 From: Ignasi Date: Wed, 24 Jan 2024 21:55:06 +0100 Subject: [PATCH 117/121] Fix ecrecover test --- test/ecrecover.zkasm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/ecrecover.zkasm b/test/ecrecover.zkasm index 1999e51d..a5e69882 100644 --- a/test/ecrecover.zkasm +++ b/test/ecrecover.zkasm @@ -293,7 +293,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1an => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT ; #28 v > 28 @@ -302,7 +302,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1dn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT ; #29 r == 0 @@ -311,7 +311,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT ; #30 r == field @@ -320,7 +320,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT ; #31 r > field @@ -329,7 +329,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT ; #32 r = field - 1 @@ -338,7 +338,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT ; #33 s == 0 @@ -347,7 +347,7 @@ repeat_ecrecover_test: 0x0000000000000000000000000000000000000000000000000000000000000000n => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT ; #34 s == field/2 + 1. Valid (precompiled) @@ -405,7 +405,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT B => A 4n :ASSERT @@ -425,7 +425,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140n => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT B => A 4n :ASSERT @@ -436,7 +436,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142n => C 0x1cn => D :CALL(ecrecover_tx) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT edge_cases: @@ -489,7 +489,7 @@ edge_cases: 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1n => C ; s 0x1bn => D :CALL(ecrecover_precompiled) - 0x0000000000000000000000000000000000000000n :ASSERT + %ADDRESS_ECRECOVER_ERROR :ASSERT B => A 7 :ASSERT From 6a0ae436c5af2da3d82c2cd07dd8cd0ed70d16e4 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 24 Jan 2024 23:08:25 +0100 Subject: [PATCH 118/121] final version --- main/ecrecover/constEc.zkasm | 4 +- main/ecrecover/ecrecover.zkasm | 2 +- main/l2-tx-hash.zkasm | 186 +++++++++++++++++++++++---------- main/load-tx-rlp.zkasm | 15 ++- main/process-tx.zkasm | 3 +- main/vars.zkasm | 2 +- 6 files changed, 139 insertions(+), 73 deletions(-) diff --git a/main/ecrecover/constEc.zkasm b/main/ecrecover/constEc.zkasm index 705560fd..b858190e 100644 --- a/main/ecrecover/constEc.zkasm +++ b/main/ecrecover/constEc.zkasm @@ -10,6 +10,4 @@ CONSTL %FNEC_MINUS_ONE = %FNEC - 1 CONSTL %ECGX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n CONSTL %ECGY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8n CONSTL %P2_160 = 2n ** 160n -CONSTL %P2_96 = 2n ** 96n - -CONSTL %ADDRESS_ECRECOVER_ERROR = 0x0102030405060708090102030405060708090102n \ No newline at end of file +CONSTL %P2_96 = 2n ** 96n \ No newline at end of file diff --git a/main/ecrecover/ecrecover.zkasm b/main/ecrecover/ecrecover.zkasm index f3eb39fa..ebe99b09 100644 --- a/main/ecrecover/ecrecover.zkasm +++ b/main/ecrecover/ecrecover.zkasm @@ -263,7 +263,7 @@ ecrecover_p3_point_at_infinity: 7 => B :JMP(ecrecover_error) ecrecover_error: - %ADDRESS_ECRECOVER_ERROR => A + 0 => A ecrecover_end: $ => RR :MLOAD(ecrecover_RR) diff --git a/main/l2-tx-hash.zkasm b/main/l2-tx-hash.zkasm index 1a878462..48bf0598 100644 --- a/main/l2-tx-hash.zkasm +++ b/main/l2-tx-hash.zkasm @@ -1,89 +1,159 @@ -VAR CTX l2HASHP -VAR GLOBAL addL2HashTxAux -VAR GLOBAL tmpVarA_addL2HashTx -VAR GLOBAL tmpVarB_addL2HashTx -VAR GLOBAL tmpVarD_addL2HashTx -VAR GLOBAL tmpVarE_addL2HashTx - -;; Add bytes to generate L2 transaction hash -; @in A => bytes to add to hash -; @in D => length of the bytes to add to hash +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Compute l2TxHash for legacy and preEIP155 transactions +;; +;; - preEIP155 (message to sign in Ethereum: rlp[nonce, gasprice, gaslimit, to, value, data]) +;; [ 1 bytes ] txType = 0 +;; [ 8 bytes ] nonce +;; [ 32 bytes ] gasPrice +;; [ 8 bytes ] gasLimit +;; [ 1 bytes ] deployment ('0': no deloyment, '1': deployment) +;; [ 20 bytes ] to (0 bytes if it is a deployment) +;; [ 32 bytes ] value +;; [ 3 bytes ] dataLength +;; [ XX bytes ] data +;; [ 20 bytes ] from +;; +;; +;; - Legacy (message to sign in Ethereum: rlp[nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0]) +;; [ 1 bytes ] txType = 0 +;; [ 8 bytes ] nonce +;; [ 32 bytes ] gasPrice +;; [ 8 bytes ] gasLimit +;; [ 1 bytes ] deployment ('0': no deloyment, '1': deployment) +;; [ 20 bytes ] to (0 bytes if it is a deployment) +;; [ 32 bytes ] value +;; [ 3 bytes ] dataLength +;; [ XX bytes ] data +;; [ 8 bytes ] chainId +;; [ 20 bytes ] from +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +VAR CTX l2TxHashPointer ; Pointer to l2TxHash hash address +VAR CTX l2HASHP ; pointer to the l2TxHash to store the bytes +VAR GLOBAL tmpVar_HASHPOS_L2HashTx ; temporary variable register HASHPOS +VAR GLOBAL tmpVar_A_L2HashTx ; temporary variable register A +VAR GLOBAL tmpVar_D_L2HashTx ; temporary variable register D +VAR GLOBAL tmpVar_E_L2HashTx ; temporary variable register E + +;; Check counters to do the hashp and initialize HASHPOS of the l2TxHash +initL2HashTx: + ; check one binary available to perform correctly the HASHPDIGEST + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + ; reserve one byte for the txType in the l2HashTx + ; txType will be known at the end of the RLP parsing + 1 :MSTORE(l2HASHP), RETURN + +;; Write generic bytes to the l2TxHash +; @in A => value to write +; @in D => bytes size to write addL2HashTx: - E => B + ; store temporary register values + E :MSTORE(tmpVar_E_L2HashTx) + HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx) + + ; load pointer l2HashTx and write bytes $ => E :MLOAD(l2TxHashPointer) - HASHPOS :MSTORE(addL2HashTxAux) $ => HASHPOS :MLOAD(l2HASHP) A :HASHP(E) HASHPOS :MSTORE(l2HASHP) - $ => HASHPOS :MLOAD(addL2HashTxAux) - B => E :RETURN -;; Add byte to determine if it is a deployment + ; load temporary register values + $ => E :MLOAD(tmpVar_E_L2HashTx) + $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN + +;; Write 1 byte to l2TxHash: flag deployment = 1 ('0': no deployment transaction, '1': deployment transaction) addL2HashTx_isDeploy: - A :MSTORE(tmpVarA_addL2HashTx) - D :MSTORE(tmpVarD_addL2HashTx) - E => B + ; store temporary register values + A :MSTORE(tmpVar_A_L2HashTx) + E :MSTORE(tmpVar_E_L2HashTx) + HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx) + + ; load pointer l2HashTx and write deployment flag $ => E :MLOAD(l2TxHashPointer) - HASHPOS :MSTORE(addL2HashTxAux) $ => HASHPOS :MLOAD(l2HASHP) - 1 => D - 1 :HASHP(E) + 1 :HASHP1(E) HASHPOS :MSTORE(l2HASHP) - $ => HASHPOS :MLOAD(addL2HashTxAux) - $ => D :MLOAD(tmpVarD_addL2HashTx) - $ => A :MLOAD(tmpVarA_addL2HashTx) - B => E :RETURN -;; Add byte to determine if it is not a deployment + ; load temporary register values + $ => A :MLOAD(tmpVar_A_L2HashTx) + $ => E :MLOAD(tmpVar_E_L2HashTx) + $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN + +;; Write 1 byte to l2TxHash: flag deployment = 0 ('0': no deployment transaction, '1': deployment transaction) addL2HashTx_isNotDeploy: - A :MSTORE(tmpVarA_addL2HashTx) - D :MSTORE(tmpVarD_addL2HashTx) - E => B + ; store temporary register values + E :MSTORE(tmpVar_E_L2HashTx) + HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx) + + ; load pointer l2HashTx and write deployment flag $ => E :MLOAD(l2TxHashPointer) - HASHPOS :MSTORE(addL2HashTxAux) $ => HASHPOS :MLOAD(l2HASHP) - 1 => D - 0 :HASHP(E) + 0 :HASHP1(E) HASHPOS :MSTORE(l2HASHP) - $ => HASHPOS :MLOAD(addL2HashTxAux) - $ => D :MLOAD(tmpVarD_addL2HashTx) - $ => A :MLOAD(tmpVarA_addL2HashTx) - B => E :RETURN -;; Add 3 bytes which will be the data length + ; load temporary register values + $ => E :MLOAD(tmpVar_E_L2HashTx) + $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN + +;; Write 3 bytes to l2TxHash: data length addL2HashTx_dataLength: - A :MSTORE(tmpVarA_addL2HashTx) - B :MSTORE(tmpVarB_addL2HashTx) - D :MSTORE(tmpVarD_addL2HashTx) - E :MSTORE(tmpVarE_addL2HashTx) + ; store temporary register values + A :MSTORE(tmpVar_A_L2HashTx) + D :MSTORE(tmpVar_D_L2HashTx) + E :MSTORE(tmpVar_E_L2HashTx) + HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx) + + ; load pointer l2HashTx and write data length $ => E :MLOAD(l2TxHashPointer) - HASHPOS :MSTORE(addL2HashTxAux) $ => HASHPOS :MLOAD(l2HASHP) 3 => D $ => A :MLOAD(txCalldataLen) A :HASHP(E) HASHPOS :MSTORE(l2HASHP) - $ => HASHPOS :MLOAD(addL2HashTxAux) - $ => E :MLOAD(tmpVarE_addL2HashTx) - $ => D :MLOAD(tmpVarD_addL2HashTx) - $ => B :MLOAD(tmpVarB_addL2HashTx) - $ => A :MLOAD(tmpVarA_addL2HashTx), RETURN -;; Add 1 bytes which will be the txType + ; load temporary register values + $ => A :MLOAD(tmpVar_A_L2HashTx) + $ => D :MLOAD(tmpVar_D_L2HashTx) + $ => E :MLOAD(tmpVar_E_L2HashTx) + $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN + +;; Write 1 byte to l2TxHash: txType +; note: HASHPOS is not reovered and the outcome register is the l2TxHash length addL2HashTx_txType: - A :MSTORE(tmpVarA_addL2HashTx) - D :MSTORE(tmpVarD_addL2HashTx) + ; store temporary register values + A :MSTORE(tmpVar_A_L2HashTx) + E :MSTORE(tmpVar_E_L2HashTx) + HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx) + + ; load pointer l2HashTx and write txType $ => E :MLOAD(l2TxHashPointer) - HASHPOS :MSTORE(addL2HashTxAux) + ; write txType in the first byte of the l2TxHash 0 => HASHPOS - 1 => D $ => A :MLOAD(isPreEIP155), JMPZ(addL2HashTx_txType_write_1) -addL2HashTx_txType_write_0: - 0 :HASHP(E), JMP(addL2HashTx_txType_finish) + 0 :HASHP1(E), JMP(addL2HashTx_txType_finish) addL2HashTx_txType_write_1: - 1 :HASHP(E) + 1 :HASHP1(E) addL2HashTx_txType_finish: - ; recover total length HASHPOS + ; load temporary register values + $ => A :MLOAD(tmpVar_A_L2HashTx) + $ => E :MLOAD(tmpVar_E_L2HashTx) + $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN + +;; Closes l2TxHash and store the result +closeL2TxHash: + ; store temporary register values + E :MSTORE(tmpVar_E_L2HashTx) + HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx) + + ; load HASHPOS l2TxHash $ => HASHPOS :MLOAD(l2HASHP) - $ => D :MLOAD(tmpVarD_addL2HashTx) - $ => A :MLOAD(tmpVarA_addL2HashTx), RETURN \ No newline at end of file + $ => E :MLOAD(l2TxHashPointer) + HASHPOS :HASHPLEN(E) + ; digest l2TxHash + $ => E :HASHPDIGEST(E) + E :MSTORE(l2TxHash) + + ; load temporary register values + $ => E :MLOAD(tmpVar_E_L2HashTx) + $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN \ No newline at end of file diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index f01577a0..b7f846bf 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -84,9 +84,7 @@ endList: $ => B :MLOAD(arithRes1) $ => D :MLOAD(cntKeccakPreProcess) %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1 :JMPN(outOfCountersKeccak) - -; reserve one byte for the txType in the l2HashTx - 1 :MSTORE(l2HASHP) + :CALL (initL2HashTx) ;; Read RLP 'nonce' ; 64 bits max @@ -383,14 +381,15 @@ finishLoadRLP: checkAndSaveFrom: ; warning: we need to insert one transition step between label `checkAndSafeFrom` and `MSTORE(txSrcAddr)` to allow unsigned transactions from executor 20 => D + ; save ecrecover error code + B :MSTORE(ecrecoverErrorCode) ; save 'from' to l2TxHash A :MSTORE(txSrcAddr), CALL(addL2HashTx) - ; save txType to l2TxHash + ; save 'txType' to l2TxHash :CALL(addL2HashTx_txType) - HASHPOS :HASHPLEN(E) - %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) - $ => B :HASHPDIGEST(E) - B :MSTORE(l2TxHash),JMP(txLoopRLP) + ; close l2 tx hash + :CALL(closeL2TxHash) + :JMP(txLoopRLP) ;;;;;;;;; ;; E - Handler error RLP fields diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index d80a380d..07dc98dd 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -35,10 +35,9 @@ processTx: %MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith) ; Check the signature - %ADDRESS_ECRECOVER_ERROR => B $ => A :MLOAD(txSrcAddr) A :MSTORE(txSrcOriginAddr) - $ :EQ,JMPC(invalidIntrinsicTxSignature) + $ :MLOAD(ecrecoverErrorCode), JMPNZ(invalidIntrinsicTxSignature) ;;;;;;;;;;;;;;;;;; ;; B - Verify tx.sender does not have any code deployed (EIP3607) diff --git a/main/vars.zkasm b/main/vars.zkasm index 85252c22..63ec168f 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -56,7 +56,6 @@ VAR GLOBAL isLoadingRLP ; flag to determine if the function is called from RLP l VAR GLOBAL globalCalldataMemoryOffset ; Aux variable to store current calldata memory offset at calldata CTX's memory VAR GLOBAL txIndex ; index of the current tx in the block -VAR CTX l2TxHashPointer ; Pointer to tx's hash hashp VAR CTX txGasLimit ; transaction parameter: 'gas limit' VAR CTX txDestAddr ; transaction parameter: 'to' VAR CTX storageAddr ; address which the storage will be modified @@ -69,6 +68,7 @@ VAR CTX txS ; transaction parameter: ecdsa signature S VAR CTX txR ; transaction parameter: ecdsa signature R VAR CTX txV ; transaction parameter: ecdsa signature V VAR CTX txSrcAddr ; address that sends a transaction 'message.sender' +VAR CTX ecrecoverErrorCode ; ecrecover result error code VAR CTX txStatus ; flag indicating success or failure of current transaction VAR CTX txHash ; signed tx hash VAR CTX l2TxHash ; L2 tx hash linearPoseidon[nonce, gasPrice, gasLimit, to, value, data, from] From 97398037a34aa394ab995f862c72095dee060749 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 24 Jan 2024 23:18:11 +0100 Subject: [PATCH 119/121] back ecrecover test & update package --- package.json | 2 +- test/ecrecover.zkasm | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 4e4a42b9..fe52bca2 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.3-fork.7", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/new-l2hash", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#5999f90e0f6c5f6e735bdef6ab3d0424fec90f75", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/new-l2hash", "chai": "^4.3.6", diff --git a/test/ecrecover.zkasm b/test/ecrecover.zkasm index a5e69882..bff8bf55 100644 --- a/test/ecrecover.zkasm +++ b/test/ecrecover.zkasm @@ -293,7 +293,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1an => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT ; #28 v > 28 @@ -302,7 +302,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1dn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT ; #29 r == 0 @@ -311,7 +311,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT ; #30 r == field @@ -320,7 +320,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT ; #31 r > field @@ -329,7 +329,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT ; #32 r = field - 1 @@ -338,7 +338,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT ; #33 s == 0 @@ -347,7 +347,7 @@ repeat_ecrecover_test: 0x0000000000000000000000000000000000000000000000000000000000000000n => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT ; #34 s == field/2 + 1. Valid (precompiled) @@ -405,7 +405,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT B => A 4n :ASSERT @@ -425,7 +425,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140n => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT B => A 4n :ASSERT @@ -436,7 +436,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142n => C 0x1cn => D :CALL(ecrecover_tx) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT edge_cases: @@ -489,7 +489,7 @@ edge_cases: 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1n => C ; s 0x1bn => D :CALL(ecrecover_precompiled) - %ADDRESS_ECRECOVER_ERROR :ASSERT + 0 :ASSERT B => A 7 :ASSERT From 941ef600131184cd0606bb05575288d9315bb296 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Thu, 25 Jan 2024 10:36:48 +0100 Subject: [PATCH 120/121] remove unnecessary file & fix wrong comment --- compare.json | 51 ------------------------------------------- main/l2-tx-hash.zkasm | 2 +- 2 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 compare.json diff --git a/compare.json b/compare.json deleted file mode 100644 index 2ed382bf..00000000 --- a/compare.json +++ /dev/null @@ -1,51 +0,0 @@ -``` - [ 1 bytes ] txType = 0 - [ 8 bytes ] nonce - [ 32 bytes ] gasPrice - [ 8 bytes ] gasLimit - [ 1 bytes ] deployment ('0' or '1') - [ 20 bytes ] to (0 if it is a deployment) - [ 32 bytes ] value - [ 3 bytes ] dataLength - [ XX bytes ] data - [ 8 bytes ] chainID - [ 20 bytes ] from -``` - -{ - "from": "0x4d5Cf5032B2a844602278b01199ED191A86c93ff", - "to": "0x1275fbb540c8efc58b812ba83b0d0b8b9917ae98", - "nonce": 0, - "value": "0", - "contractName": "Test", - "function": "setFirst", - "params": [ - 7 - ], - "chainId": 1000, - "reason": "", - "gasLimit": 100000, - "gasPrice": "1000000000", - "data": "0x5ef3d3dd0000000000000000000000000000000000000000000000000000000000000007", - "customRawTx": "0xf84a80843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae9880a45ef3d3dd00000000000000000000000000000000000000000000000000000000000000078203e880803943e5a952e27d85c91f61610159fd8caf0dd68db76a1df7fb52934156d9ec935ceec6b0f908e36ee8b2c70350b3813d72558572ff95deac79069168e68726571cff", - "rawTx": "0xf88a80843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae9880a45ef3d3dd00000000000000000000000000000000000000000000000000000000000000078207f4a03943e5a952e27d85c91f61610159fd8caf0dd68db76a1df7fb52934156d9ec93a05ceec6b0f908e36ee8b2c70350b3813d72558572ff95deac79069168e6872657" - } - -0000000000000000000000000000000000000000000000000000000000000000000000003b9aca0000000000000186a0001275fbb540c8efc58b812ba83b0d0b8b9917ae980000000000000000000000000000000000000000000000000000000000000000000024 -5ef3d3dd00000000000000000000000000000000000000000000000000000000 - -0x0b73e6af6f00000000 - -f8 -4a -80 -843b9aca00 -830186a0 -941275fbb540c8efc58b812ba83b0d0b8b9917ae98 --> to -80 -a4 -5ef3d3dd0000000000000000000000000000000000000000000000000000000000000007 -8203e8 -80 -80 -3943e5a952e27d85c91f61610159fd8caf0dd68db76a1df7fb52934156d9ec935ceec6b0f908e36ee8b2c70350b3813d72558572ff95deac79069168e68726571cffee80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff88016345785d8a0000808203e880801cee7e01dc62f69a12c3510c6d64de04ee6346d84b6a017f3e786c7d87f963e75d8cc91fa983cd6d9cf55fff80d73bd26cd333b0f098acc1e58edb1fd484ad731bff \ No newline at end of file diff --git a/main/l2-tx-hash.zkasm b/main/l2-tx-hash.zkasm index 48bf0598..deb5ae77 100644 --- a/main/l2-tx-hash.zkasm +++ b/main/l2-tx-hash.zkasm @@ -15,7 +15,7 @@ ;; ;; ;; - Legacy (message to sign in Ethereum: rlp[nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0]) -;; [ 1 bytes ] txType = 0 +;; [ 1 bytes ] txType = 1 ;; [ 8 bytes ] nonce ;; [ 32 bytes ] gasPrice ;; [ 8 bytes ] gasLimit From e0bf830be8d5e0d8217c0044bd096facc1e83200 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Thu, 25 Jan 2024 17:21:16 +0100 Subject: [PATCH 121/121] update packages to last version --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index fe52bca2..4d136136 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/new-l2hash", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#5999f90e0f6c5f6e735bdef6ab3d0424fec90f75", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#feature/new-l2hash", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.4-fork.7", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs-internal#b651f11268981a9af6667fba624cb2ce638cb2fb", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors-internal#v4.0.0-rc.4-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0",