From 820e00e72fd624650099fc34fabfbc3f75fedb6a Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 2 Jul 2024 20:44:50 +0530 Subject: [PATCH 01/97] chore: make workspace --- Scarb.toml | 6 +- cairo_project.toml | 2 - .../bn_contracts}/.gitignore | 0 .../bn_contracts}/Scarb.lock | 0 .../bn_contracts}/Scarb.toml | 3 +- .../bn_contracts}/src/bench_contract.cairo | 5 +- .../bn_contracts/src/groth16_contract.cairo | 1234 +++++++ .../bn_contracts}/src/lib.cairo | 0 .../bn_contracts/src/schzipv2_contract.cairo | 156 + packages/bn_legacy/Scarb.toml | 7 + {src => packages/bn_legacy/src}/bench.cairo | 0 .../bn_legacy/src}/bench/curve.cairo | 0 .../bn_legacy/src}/bench/fq01.cairo | 0 .../bn_legacy/src}/bench/fq02.cairo | 0 .../bn_legacy/src}/bench/fq06.cairo | 0 .../bn_legacy/src}/bench/fq12.cairo | 0 .../bn_legacy/src}/bench/sprs.cairo | 0 .../bn_legacy/src}/bench/u512.cairo | 0 {src => packages/bn_legacy/src}/curve.cairo | 0 .../bn_legacy/src}/curve/constants.cairo | 0 .../bn_legacy/src}/curve/groups.cairo | 0 .../bn_legacy/src}/curve/groups_tests.cairo | 0 .../src}/curve/pairing/ate_tests.cairo | 0 .../src}/curve/pairing/miller_utils.cairo | 0 .../src}/curve/pairing/optimal_ate.cairo | 0 .../curve/pairing/optimal_ate_impls.cairo | 0 .../curve/pairing/optimal_ate_utils.cairo | 0 .../src}/curve/pairing/tate_bkls.cairo | 0 .../bn_legacy/src}/curve/pairing/tests.cairo | 0 .../src}/curve/residue_witness.cairo | 0 .../bn_legacy/src}/fields/fq_1.cairo | 0 .../bn_legacy/src}/fields/fq_12.cairo | 0 .../bn_legacy/src}/fields/fq_12_direct.cairo | 0 .../src}/fields/fq_12_exponentiation.cairo | 0 .../src}/fields/fq_12_squaring.cairo | 0 .../bn_legacy/src}/fields/fq_2.cairo | 0 .../bn_legacy/src}/fields/fq_6.cairo | 0 .../bn_legacy/src}/fields/fq_generics.cairo | 0 .../bn_legacy/src}/fields/fq_sparse.cairo | 0 .../bn_legacy/src}/fields/frobenius.cairo | 0 .../bn_legacy/src}/fields/print.cairo | 0 .../bn_legacy/src}/fields/tests/fq.cairo | 0 .../bn_legacy/src}/fields/tests/fq12.cairo | 0 .../src}/fields/tests/fq12_expo.cairo | 0 .../bn_legacy/src}/fields/tests/fq2.cairo | 0 .../bn_legacy/src}/fields/tests/fq6.cairo | 0 .../src}/fields/tests/fq_sparse.cairo | 0 .../src}/fields/tests/frobenius.cairo | 0 .../bn_legacy/src}/fields/tests/u512.cairo | 0 .../bn_legacy/src}/groth16/fixture.cairo | 0 .../src}/groth16/fixture/groth16.cairo | 0 .../src}/groth16/fixture/lines.cairo | 0 .../src}/groth16/fixture/schzip_v1.cairo | 0 .../src}/groth16/fixture/schzip_v2.cairo | 0 .../src}/groth16/fixture/tests.cairo | 0 .../bn_legacy/src}/groth16/schzip.cairo | 0 .../bn_legacy/src}/groth16/schzip/base.cairo | 0 .../bn_legacy/src}/groth16/schzip/eval.cairo | 0 .../bn_legacy/src}/groth16/schzip/tests.cairo | 0 .../bn_legacy/src}/groth16/schzip/utils.cairo | 0 .../bn_legacy/src}/groth16/schzip/v1.cairo | 2 +- .../bn_legacy/src}/groth16/setup.cairo | 0 .../bn_legacy/src}/groth16/tests.cairo | 0 .../bn_legacy/src}/groth16/utils.cairo | 0 .../bn_legacy/src}/groth16/utils_line.cairo | 0 .../bn_legacy/src}/groth16/verifier.cairo | 0 {src => packages/bn_legacy/src}/lib.cairo | 0 .../bn_legacy/src}/math/fast_mod.cairo | 0 .../src}/math/fast_mod/add_sub.cairo | 0 .../src}/math/fast_mod/div_inv.cairo | 0 .../src}/math/fast_mod/mul_scale_sqr.cairo | 0 .../src}/math/fast_mod/u512_ops.cairo | 0 .../bn_legacy/src}/math/fast_mod/utils.cairo | 0 .../bn_legacy/src}/math/fast_mod_tests.cairo | 0 .../bn_legacy/src}/math/i257.cairo | 0 .../bn_legacy/src}/playground.cairo | 0 {src => packages/bn_legacy/src}/tests.cairo | 0 .../bn_legacy/src}/tests_tate.cairo | 0 {src => packages/bn_legacy/src}/traits.cairo | 0 scripts/residue_witness_bls381.py | 249 ++ scripts/schzip.py | 3059 +++++++++++++++++ scripts/schzip_runner.py | 286 ++ 82 files changed, 4998 insertions(+), 11 deletions(-) delete mode 100644 cairo_project.toml rename {bn_contracts => packages/bn_contracts}/.gitignore (100%) rename {bn_contracts => packages/bn_contracts}/Scarb.lock (100%) rename {bn_contracts => packages/bn_contracts}/Scarb.toml (73%) rename {bn_contracts => packages/bn_contracts}/src/bench_contract.cairo (94%) create mode 100644 packages/bn_contracts/src/groth16_contract.cairo rename {bn_contracts => packages/bn_contracts}/src/lib.cairo (100%) create mode 100644 packages/bn_contracts/src/schzipv2_contract.cairo create mode 100644 packages/bn_legacy/Scarb.toml rename {src => packages/bn_legacy/src}/bench.cairo (100%) rename {src => packages/bn_legacy/src}/bench/curve.cairo (100%) rename {src => packages/bn_legacy/src}/bench/fq01.cairo (100%) rename {src => packages/bn_legacy/src}/bench/fq02.cairo (100%) rename {src => packages/bn_legacy/src}/bench/fq06.cairo (100%) rename {src => packages/bn_legacy/src}/bench/fq12.cairo (100%) rename {src => packages/bn_legacy/src}/bench/sprs.cairo (100%) rename {src => packages/bn_legacy/src}/bench/u512.cairo (100%) rename {src => packages/bn_legacy/src}/curve.cairo (100%) rename {src => packages/bn_legacy/src}/curve/constants.cairo (100%) rename {src => packages/bn_legacy/src}/curve/groups.cairo (100%) rename {src => packages/bn_legacy/src}/curve/groups_tests.cairo (100%) rename {src => packages/bn_legacy/src}/curve/pairing/ate_tests.cairo (100%) rename {src => packages/bn_legacy/src}/curve/pairing/miller_utils.cairo (100%) rename {src => packages/bn_legacy/src}/curve/pairing/optimal_ate.cairo (100%) rename {src => packages/bn_legacy/src}/curve/pairing/optimal_ate_impls.cairo (100%) rename {src => packages/bn_legacy/src}/curve/pairing/optimal_ate_utils.cairo (100%) rename {src => packages/bn_legacy/src}/curve/pairing/tate_bkls.cairo (100%) rename {src => packages/bn_legacy/src}/curve/pairing/tests.cairo (100%) rename {src => packages/bn_legacy/src}/curve/residue_witness.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_1.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_12.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_12_direct.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_12_exponentiation.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_12_squaring.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_2.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_6.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_generics.cairo (100%) rename {src => packages/bn_legacy/src}/fields/fq_sparse.cairo (100%) rename {src => packages/bn_legacy/src}/fields/frobenius.cairo (100%) rename {src => packages/bn_legacy/src}/fields/print.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/fq.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/fq12.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/fq12_expo.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/fq2.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/fq6.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/fq_sparse.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/frobenius.cairo (100%) rename {src => packages/bn_legacy/src}/fields/tests/u512.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/fixture.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/fixture/groth16.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/fixture/lines.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/fixture/schzip_v1.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/fixture/schzip_v2.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/fixture/tests.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/schzip.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/schzip/base.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/schzip/eval.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/schzip/tests.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/schzip/utils.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/schzip/v1.cairo (99%) rename {src => packages/bn_legacy/src}/groth16/setup.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/tests.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/utils.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/utils_line.cairo (100%) rename {src => packages/bn_legacy/src}/groth16/verifier.cairo (100%) rename {src => packages/bn_legacy/src}/lib.cairo (100%) rename {src => packages/bn_legacy/src}/math/fast_mod.cairo (100%) rename {src => packages/bn_legacy/src}/math/fast_mod/add_sub.cairo (100%) rename {src => packages/bn_legacy/src}/math/fast_mod/div_inv.cairo (100%) rename {src => packages/bn_legacy/src}/math/fast_mod/mul_scale_sqr.cairo (100%) rename {src => packages/bn_legacy/src}/math/fast_mod/u512_ops.cairo (100%) rename {src => packages/bn_legacy/src}/math/fast_mod/utils.cairo (100%) rename {src => packages/bn_legacy/src}/math/fast_mod_tests.cairo (100%) rename {src => packages/bn_legacy/src}/math/i257.cairo (100%) rename {src => packages/bn_legacy/src}/playground.cairo (100%) rename {src => packages/bn_legacy/src}/tests.cairo (100%) rename {src => packages/bn_legacy/src}/tests_tate.cairo (100%) rename {src => packages/bn_legacy/src}/traits.cairo (100%) create mode 100644 scripts/residue_witness_bls381.py create mode 100644 scripts/schzip.py create mode 100644 scripts/schzip_runner.py diff --git a/Scarb.toml b/Scarb.toml index 1235ea5..28286d1 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,11 +1,9 @@ [workspace] - members = [ - "bn_contracts", + "packages/*", ] -[package] -name = "bn" +[workspace.package] version = "0.1.0" cairo-version = "2.6.2" diff --git a/cairo_project.toml b/cairo_project.toml deleted file mode 100644 index 019fb8b..0000000 --- a/cairo_project.toml +++ /dev/null @@ -1,2 +0,0 @@ -[crate_roots] -bn = "src" diff --git a/bn_contracts/.gitignore b/packages/bn_contracts/.gitignore similarity index 100% rename from bn_contracts/.gitignore rename to packages/bn_contracts/.gitignore diff --git a/bn_contracts/Scarb.lock b/packages/bn_contracts/Scarb.lock similarity index 100% rename from bn_contracts/Scarb.lock rename to packages/bn_contracts/Scarb.lock diff --git a/bn_contracts/Scarb.toml b/packages/bn_contracts/Scarb.toml similarity index 73% rename from bn_contracts/Scarb.toml rename to packages/bn_contracts/Scarb.toml index 5cf6b75..77910eb 100644 --- a/bn_contracts/Scarb.toml +++ b/packages/bn_contracts/Scarb.toml @@ -1,10 +1,9 @@ [package] name = "bn_contracts" version = "0.1.0" -edition = "2023_11" [dependencies] -bn = { path = ".." } +bn = { path = "../bn_legacy" } starknet = "2.5.0" [[target.starknet-contract]] diff --git a/bn_contracts/src/bench_contract.cairo b/packages/bn_contracts/src/bench_contract.cairo similarity index 94% rename from bn_contracts/src/bench_contract.cairo rename to packages/bn_contracts/src/bench_contract.cairo index 4b2c9e7..c07a8ce 100644 --- a/bn_contracts/src/bench_contract.cairo +++ b/packages/bn_contracts/src/bench_contract.cairo @@ -90,9 +90,10 @@ mod BN_Pairing { inputs: Array, ) { let lines = LinesArray { gamma: array![], delta: array![] }; - let circuit_setup = setup_precompute(alpha, beta, gamma, delta, ic, lines); + let _circuit_setup = setup_precompute(alpha, beta, gamma, delta, ic, lines); - let verified = verify(pi_a, pi_b, pi_c, inputs, circuit_setup); + // let verified = verify(pi_a, pi_b, pi_c, inputs, circuit_setup); + let verified = false; assert(verified, 'verification failed'); } diff --git a/packages/bn_contracts/src/groth16_contract.cairo b/packages/bn_contracts/src/groth16_contract.cairo new file mode 100644 index 0000000..26ac044 --- /dev/null +++ b/packages/bn_contracts/src/groth16_contract.cairo @@ -0,0 +1,1234 @@ +use bn::fields::{Fq12, fq12, Fq6}; +use bn::curve::{AffineG1, AffineG2}; + +#[starknet::interface] +trait IGroth16 { + fn verify( + ref self: T, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: Fq6 + ); + fn verify1( + ref self: T, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: Fq6 + ); + fn verify2( + ref self: T, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: Fq6 + ); +} + +#[starknet::contract] +mod Groth16 { + use core::hash::HashStateTrait; + use super::{Fq12, fq12, Fq6, AffineG1, AffineG2}; + + use bn::groth16::{verify}; + use bn::groth16::utils::{LinesArray, G16CircuitSetup, LineFn, line_fn_from_u256}; + use bn::curve::groups::{g1, g2}; + + fn circuit_setup() -> G16CircuitSetup { + G16CircuitSetup { + alpha_beta: fq12( + 0x27c20318505e03cea84a04223b8679a6c84c1e55e83957a21e8986c1b8140510, + 0x104bb1b78f934618c94ba0290a964c58f1400e450e9e19680c39a8aca6fa15f4, + 0x2e56f81476f8d79f0caef927ac110b77cec88490d0860c746d82583440bb8919, + 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, + 0x19bdc2cd81965796abc4dd1ac13a5941ce94ead67c26445a67ca63f07def54fa, + 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, + 0x159ad96d8a0f81d1e048379cb2dee2671581cb84e58de9cbf2d4ea8d11a5a262, + 0xf63ca25374f5b91be7d57a067f1e5ec7a906be473fb01f091d1793fd999b926, + 0x231b22b4c91411c1aeb9724839622abf9d9297cad863a0312452df9f56e9872a, + 0x2cc3c64540e5e5af46b3c583a7314a94fedb672da5da977c6ac70927247c73bb, + 0xbd670107051399799978f2a70d7a08ed0bb130d1fa74638dce3d81536701c96, + 0x221446e74ef53a921abb7b8a0fa2afee56481780d136bc649916f1beeb52aaa + ), + gamma: g2( + 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed, + 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, + 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d, + 0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec + ), + gamma_neg: g2( + 10857046999023057135944570762232829481370756359578518086990519993285655852781, + 11559732032986387107991004021392285783925812861821192530917403151452391805634, + 8495653923123431417604973247489272438418190587263600148770280649306958101930, + 4082367875863433681332203403145435568316851327593401208105741076214120093531 + ), + delta: g2( + 0x29a90e4d611e9d08120c9dc6d165625795d3f80ea2b9831b8e16693e4d7f11fc, + 0x2e4b801bb7360ff6d90a87d882ac82b4de3914e3aa2068ee755a669878e684a6, + 0x3d53213f8bcba0e4267b8fe667b9ba9fcf7365d12b83cf9717e8b2f3e48534e, + 0x2656bc524250d4ea3a0ae2858e13402ba1b1754e60617286821c31aba408c5de + ), + delta_neg: g2( + 18843522656454103229460441939617973919282852773928454389351548381771109175804, + 20939788735433971235553050176856161353732417040828392785429509147312127378598, + 20154620275540267962893477662314018482859018034691595131178696575286779357689, + 4547106032091524596969837323375385497187441697194445474662172759730343393129 + ), + lines: LinesArray { gamma: gamma_lines(), delta: delta_lines(), }, + ic: ( + // Starter point + g1( + 1655549413518972190198478012616802994254462093161203201613599472264958303841, + 21742734017792296281216385119397138748114275727065024271646515586404591497876 + ), + // Remaining input constraints + array![ + g1( + 16497930821522159474595176304955625435616718625609462506360632944366974274906, + 10404924572941018678793755094259635830045501866471999610240845041996101882275 + ) + ] + ) + } + } + + fn gamma_lines() -> Array { + array![ + line_fn_from_u256( + 0xce69bdf84ed6d6d204fe74db6b371d37e4615ab1b3d578c32d1af5736582972, + 0x1e23d69196b41dbf47d406f500e66ea29c8764b3fd262357407c3d96bb3ba710, + 0x2cad36e65bbb6f4f41d975b678200fce07c48a5e1ec8ee6f65402483ad127f3a, + 0x54c8bc1b50aa258d4fe3a18872139b0287570c3cfa9b8144c3ea2ab524386f5 + ), + line_fn_from_u256( + 0x237db2935c4432bc98005e68cacde68a193b54e64d347301094edcbfa224d3d5, + 0x124077e14a7d826a707c3ec1809ae9bafafa05dd6b4ba735fba44e801d415637, + 0x3b7178c857630da7676d0000961488f8fbce03349a8dc1dd6e067932b6a7e0d, + 0x2b17c2b12c26fdd0e3520b9dfa601ead6f0bf9cd98c81278efe1e96b86397652 + ), + line_fn_from_u256( + 0x2a0dd3f377bee86df8af1493203288c14f2e45f5b283a7d2e9789f0a85418bd4, + 0x27ca8354ad922aa6f422d09ed311ff1858d237c9992f9b668fa9e7c6a2dd7ba9, + 0x1f4279a8c504f4f387a0d0750b107a29b7d80bb6c9494b44f94a033f28a32fe0, + 0x28255bfe26b88c84293b4ef2de9e8e864c4cee92ec2574cacb0f994d3654056f + ), + line_fn_from_u256( + 0x1234f85fbc425be21a706f9958e5f2b3e35c261a6c4e24186b96a246f981df8f, + 0x2fcf4f59596004c6eb77f32d49eb2eef4a62976071f75fef0a29f4bbb676ba5d, + 0x3678848c935b15e518d6de5b00ab4a1438de3a93265a03271c6f2a9b3b0e400, + 0x1d73ac7a11db5fc209b5495eed3a0fa561b590823a9557549e46e2339714249e + ), + line_fn_from_u256( + 0x15b641064299177ca11814969284e168319e1c06cbdb8e4161421f33041c4cd0, + 0x46d5f98b3a5be977f09c53b7a2a6fe73107dbb65f4aa50b3e2881127be0be3d, + 0x24f4c6aef1273059e048d611f1ed67c01658c7e929dc542b88c6f6c1a8c88769, + 0x190536b710848e1067034108e8e5c676ffd710829959f3c01b1f5c0491d40ae3 + ), + line_fn_from_u256( + 0x174dc1209fccabc5e390a081696248d73dd106addf2609007513ea7e5a416da8, + 0x534c43aa39d5089188b5a40b5d1309c5face74fe362e1bc526b009466e28eb5, + 0x2d1c7506fb49a5f7e06fad7ec8deb4a60901856c142001f5f1aff79315cc7d8a, + 0x11e03f84b9d48fc64dee9658d14b9419aa71e91ee6329eeac7e1a9c1f3bb7329 + ), + line_fn_from_u256( + 0x2059fa5c7e77d2ad20e8633b7ed87e265667430a4f9b9a33adc7d0b9d77a4a39, + 0x28da2376ea0e8841e3b3774bc430a2e8a4653d1f6825235bfe2daaadf09712d7, + 0x87ce08da73093489ac933e35fdfc49f644dae28fad892023206244023ef7567, + 0x2901a083df0a5821f28134db6a760872e821db75f13dae985ac02d7ea8d7f28a + ), + line_fn_from_u256( + 0x25af34756438b82fc30d0e30bffa8b4c96d5ff10c73a10fb81904367ee82f180, + 0x2e2694f8e8e983cab6d0caf4782e3139a5573645d7ee9b4768e6ffb62e628865, + 0x1e35d5988c27b24e882042a95b4038d974252f9bf636bc6979a001b9b9d64c2a, + 0x2ac1b254b9d034f4c261d7bc45ae3132687779c977003e6f1a76cfd8105a0a2e + ), + line_fn_from_u256( + 0x1838369b4d45f8dcaaf5e56345b089e52d91ae7bac52ec4533ac8f2b5143ac29, + 0x1354ed1c38975de540fa1387dda550cb0dac4b63e4b291b423a9de8d3f2b9185, + 0xac0f5dc6704f80bf8bc1d4a5d29c373882b3b5efdb7655e22a4a31d417544bb, + 0x2fe0633a013d0a1ae568b3c10a52842292157eefa848fe8df36077e2efcac7df + ), + line_fn_from_u256( + 0x1d523e5da70f885364dd99cb8c19137eb17408f8a5cf13056339732ebf0c21c7, + 0x20433aa92a32eff3c0f3a3bff235ca729c642f48f82fb10d0ae2826e3797551a, + 0x1438d78ea783d75d11da43f9de9bc329ff4e5177221d096fc862e3ce649e61c1, + 0x1278b4f94558e9ef16d62d300c297eeddfbe7247cc1e260075b46cc9743bf755 + ), + line_fn_from_u256( + 0x25fbed7d17c8a87bd61572b7594dbf4a624db771a551a3c7d8df629737fc843b, + 0x23f10de776cd38a8bca7c70e212c6482400cca023f0afb679e5a795033a467ca, + 0x18458d883acb91e43a546e26e11c4efd4b747e0405fefc33c5479d5ccf8691ff, + 0x1f1c7188a78d256c109a63d4731c81b3edb2dc301fc292cb99ec56c0dc8459f0 + ), + line_fn_from_u256( + 0x2b6eda24b76fb4f90135ff8cdd17ed363d8888f3283e056ecdd9f3fe86602a99, + 0x1899dfce5bda496e34f103457a8cb1a4ffba9b6dc37d4ed0db5585ccfbdb35d5, + 0x13f1f62946c5e16aaf94f0bb764acf92cefb5b80e8ed80577431de21c6967ef0, + 0x36f87c4c5dbc7abe9e076c01a144ab0c3eb8e77579f60cbc480f5826a2b7b01 + ), + line_fn_from_u256( + 0x1b64711d78d622a728035578e450a65ef9ba571cbcfd23d258b5746505b0ecc6, + 0xf7502d2ab2bd262f826821ff70ba24b674527f940f2590c84515817f9aba50b, + 0xb9a3c568ac2e7d2aedcd2b46dab8150591e93b592ca28112074e89dbdcb73f0, + 0xda761c6b55bbb0ea9f7fa4b5c670635d0751908c9259ca3378d96ce29ff5eb4 + ), + line_fn_from_u256( + 0x25f7392b502c30e347095429abef843a1037d3aa346547f5ecae6a7198ba099b, + 0x150cd696c87f168e302db4eb2dc9c2acafb8a888f7e87be6fa97fb419d1e1c1d, + 0x5cd0517de029ae70680c359009fbe97cdb9d4dbced0e564669e8bac761af691, + 0xb6429c69c6e41e9fd4644932afa36221c0f99aba0a26f47deb1506f9a9111a2 + ), + line_fn_from_u256( + 0x55be8e443d5fa5e0348cf53b0b2bae83c9026259b7988bde003932238349f1f, + 0x2ff20a1caca8e57758568a390d30fd585529e7f7fb8ba9089aca065c1b050ac8, + 0x8a1c914805e3e6ca5dcad76680c285ce9f85d5d7bfa4a4468dbdfa5b11f672a, + 0xc7c5f48b0a35657f005d5e26560e2bda08253f75df7ca1b59f5992330e2ea6d + ), + line_fn_from_u256( + 0x74b649254bb5401a56e0f7ecb3fad4f3c4f3fb8f76cc840f90658ae9adff1aa, + 0x5f97cd0e98151330b54fc184b5ec68ce72dae9b423981136a2b4a9893621288, + 0x27982ece4cbf361d5db80b4b86e4a02c9d2603aaae2415777dafc892d06d334e, + 0x44c14c302cbe52ec9184f4b7bf60bc679e4d3e10ea81af9a2338bd453919c42 + ), + line_fn_from_u256( + 0xdd60383235a6749c0c2edc5f7c15a6d1b19fede61b2b6eac1113d60730240fc, + 0x6a524cf10bfb3ddbe1091673700f442fbcdae88193026823733f5d0befaccf4, + 0x2e9772f9ca18cee53ea3b2c56da32f387aaa2ff8e4ef8cbf3d1dce4e37965344, + 0x893b910091beb83a95c9eb64d37e406cfb168ebc7fd1cb36bb9b07cae1cb691 + ), + line_fn_from_u256( + 0x1496f20487b42ccba04ed69fffff05278a54dfb1e0cd7d58ff592b11692dce99, + 0x195113107fb23c829ae2aeb47627892f4c48ac420f34564878a9954045f3973c, + 0x1177d4b9060a542022934b370575e7d24a0def94dfa700f4d26558b80f27c2d7, + 0x5243191f0d2b96e31c1ffea6d995ac062a05257840c254e9c40062b7fd63ed2 + ), + line_fn_from_u256( + 0x28a7a65ca2ad7441bef2b2833cec147f1ebacc1be47d3ad2765ed2d251ba2d10, + 0x6bec470982420d6b5458c9ded8464bff9b24f08085c4f5d453bb4def5a23adc, + 0x2d5a9dfd5e00261693a9618a692184f2dc1aa5d716622dd7bc1a2047ab948a6c, + 0x1c5f063c4781fe20a8851f3faad72f9365fc50bf0e25689d91e3827085b5d8d6 + ), + line_fn_from_u256( + 0x156687599d240f38bee69bfd1fdeccd6692abfcea891efa4db1ea9793494938f, + 0x2016c26ff5b23f60f8acbe0fecbb1690a89d26567a2e00f7d3b1785c2ecc8ae1, + 0x1c3e9d124fa63014e5086b80526958e2e990172db2cb48a88c74d9d4d90254c, + 0x9a3b3e4180167f358a56a7ffd04b84d5fed7046f9f7645cc860a38cad7acad8 + ), + line_fn_from_u256( + 0x3c5527e6780608538e4b844a06203d24a2eab602614bd19a476a9a0dc4f48ae, + 0x28f3418e225dcf23a7bd7a8e6397f70b451ae9e46d224a59888f49027b1fa5eb, + 0xfb1679a312b90d4c29815c29cea9ca490410fbda2991f50753b08370fe6e70b, + 0x264f356a8fdea1f1ce8071e70f6eff09a910d7fb235863b36a60533b2ed17261 + ), + line_fn_from_u256( + 0x60e5d585d1ec3072522d5d26bf076edc83a41b2bb9dd153556bad96c2a7f2fd, + 0x135f614f3d7dbe6b7dde31aefb47af3f6d7c6329e8fb88075a561830893e2e6e, + 0x1b5e3871d3c1fcba38ad0262452b09bf1407244cfe85468b42312247129df38c, + 0x1b9c6933672f0233e2c1eadc049dce8ca51398ff70f5e0107552879f2a3c0ef + ), + line_fn_from_u256( + 0x10ebba94e16374fffee9b95f9ab6c4fd44e7676ee52c5015e98b66a2ad351016, + 0x27f7f4667be45dbe34b91209e24854d7b80609e00435b16f0341d1baf73af164, + 0x2337ba8f4f1d43d284b492818b075cb97c2f7c9338bfc06103c02e3f51dc21f8, + 0x26893fa62e5681b639306df869eaba330c27d3be259ceb9ca59b892dd067c020 + ), + line_fn_from_u256( + 0x1708c536fd78b531e07184496f17bbd59a4b7bbd95b7b32bcc3119c64a62a8de, + 0x2d2287dd024e42189a00c53309a9e525bef171afa85b5778c77166c1523a75e, + 0x23c7f99715257261537e04ea344beb57ee64502631fd0884eaf2208bf8831e72, + 0x2973d5159ddc479af838a99d9ec8ed6dcec6a2a88c38b3aeea525f3c2d2fdc22 + ), + line_fn_from_u256( + 0xc5963c4d9ada42f9945b51e54baca0fbaa92c3a296c3d00d822fbb99bda6205, + 0x24f135b47e8d2979f62fb7489900eb6905c3f5bd5991dc0b6412e905da8c2c6f, + 0x1335321a292d6d47951dbbb61e6eb13ae97816062c08a9c499dc3750a3897449, + 0x10e321f4be3e6663ead90a2e92372e9c2ffca4e2b1484a35eca604a1519ec2e4 + ), + line_fn_from_u256( + 0x758737f279112661bd6e2caf5c29f02fad99b406985e163fa2730a836ac678c, + 0x44b932705030ac20679a79ecccb6c67487418b00004d07b724bd2e06333a7ae, + 0xa5bd2c1e049a08a37649eb77f08da1fae1cc5c066fdb0dc4580401a3fa5e820, + 0x2c59dc52037e0c4845d987dc538a83436e63b02850acdc4a782a79529e7406be + ), + line_fn_from_u256( + 0x9d95c905b75462a5335194af558383d16070751e5645311231c86a536a5cd77, + 0x1dc253f4a5fb0de764404c4ad35f8ad1fc9c27057a8a3ee304043048d0fdb90a, + 0x22be3ec7b36bf9f080f096b5906ce206dfc06331eef5c484567b563e650fb182, + 0x1c3d1f900ed27f725c8aed258279f035f6e2e64d0764a484df24a03ba7aeb5d9 + ), + line_fn_from_u256( + 0x2ebac378f05d105621573f48a2adb484fe7f0f9c91eb9c72ef7cd95be184249d, + 0x1d97b695ee090974720cabd0a17ddd47ff1ab84b410689107601e9bd1768cbf9, + 0x1f943ade068b815983c808cc67c2be148ced9b6578ff660deff3831ad4f0b9d0, + 0x2181a66524118d862708c525f2b2f37633b4ca2e893d78534f3cdf6c75eb6704 + ), + line_fn_from_u256( + 0x25179a093e54ab37eb3e00d8eba4285d382e4b104b1798986b967d575a75df47, + 0x109327d0273e23c2b5bd9aade8262f22d7b5c945ec1891df8ce7d8c1cf4f1b56, + 0x182425e04f6e45b740fb6d6312917e3d71e0f750f9d495623978c09fb8b0c94e, + 0x20c14d5068b0f7e7c05941f2c52b58d39586d72b801284392468cea14c288219 + ), + line_fn_from_u256( + 0x2f53ab5e410f2d7845018b905fefcddb8c9d240cc46c494353f1e70375c56163, + 0x16ba267f96816aa477b421470b555736f5cdb2d985bd91294cd036379c586734, + 0x1aed29b4b7273b0a4cad231cd12226acfddd7b8450d71d2dda1ef824b079dfe5, + 0x17c9832d6f5c99979225f43211377ea8beb2c7f9c536a1b3971d8b321cb36c10 + ), + line_fn_from_u256( + 0xc50ffb9cc2150e68e63027141e757d0060a7a8d3eb4870b8dd58faf59997e71, + 0x16b7ec843d2769ad0d1487d089c5a37e2d160e77e7184b0a80b8a30c9a0a3f75, + 0x285b9964d26641dbc34f558dda46a0a5bc8065ed856751590c6d728086ce1a4d, + 0x1ca0a22e5885cef0c172c4ef66ca6fc9a4b221b6127f4908e85d6e82b4382371 + ), + line_fn_from_u256( + 0x29c0cc1bf29aaf160cd0c7e966be2cd6ffecf8c1972b8823803591c2692761b8, + 0x1545ee1f9627356f8345461a9a87f332c33fc6e3772479f4edba925a969daec9, + 0x54bb85ad08b70a1e8c71fd64255a29bdd7807b3c9d97a0f95543b71697ac4fe, + 0x1c6f64d777029dcb4903d9a283f0636fd45ef1222e2568d4044c34d8994f5aae + ), + line_fn_from_u256( + 0x1180e991be100fdfa989ca56b797171357615731886070142a15a384314dbf7c, + 0x1b1bd6c00fa116946050652161fb1a8cd5be8116c124c126cc8c6254e678e06e, + 0x18431c50ee9e252dd1a35ba22c1db8126f5f997167a5e4a8694dc2f9fb3030a7, + 0x1de8f6eabaf70dab9e14f5254fed0525d42adac16a511ae64542a0ea21145799 + ), + line_fn_from_u256( + 0x6435a1c85b1a7a3bc5ee39034e109788b10aca880ab71de6e753e63103d8420, + 0x8e0eaffd0a87a551d826d23bcf54f7f930ed3d522c0079c9afe28b4e4567987, + 0x214360c6582c61b6eca8f6ec0a78ed6b51b00a22a78737f888daa5424f5686a0, + 0xe9fa5adbc7fb1ac7e34096081e43772d6776fde1bdf27fe14a6e6ef31f269bb + ), + line_fn_from_u256( + 0x703e7850008109d5c23495abcb43d14a311295cc1f1a8b7a85c29d0295aa7a9, + 0x162c43c078a099456a1a6827f220cfa28357cb036a59ed25d634f080b29192c3, + 0xc278da41bf5289e16f260c74cde5848d1de80e2e5b6fb59bf7ff3c2f93a40ee, + 0xa7ffc6c2ff25c65833cfa917bb5a2b8ce625fcc9d47ae9bade4e2e23d727155 + ), + line_fn_from_u256( + 0xc26a096993bca6740e9333dd54d66dfa0cf8f08d9da1a853c4702fb079586f7, + 0xeb9b5e44c2449e9c0ff00ab7eb81bdfb8d811590311e5c4803a9e102ddcf7fc, + 0x231d8b9d27d34af733af429f1ac973f7a1c57684b3568f21b69dadd82828682f, + 0x250dc322f90080968ec81315c53a6c700b82090117baecb496319c10622ae429 + ), + line_fn_from_u256( + 0x1b8acae46418876dc13612b6684009edb89a13908abceef360b86ee0e162e7ab, + 0x28ad74f1bb94f45018870628ddf28c344050310f48353ee0ca8b71b7ac17c637, + 0x2171a8afd24199d717d4fab422c2ebc788a36e3ac1484db1e03fbfd103f05698, + 0x16ee28cd883e73f377d2e0939f878a31cb895bb6b0816e1663bfa304ad461070 + ), + line_fn_from_u256( + 0x2c90e0619f25bfd5dbf6752ebb5984da629bb127b7817c935d574414f3f28d50, + 0x640f9c0590a9982b8cba5eac599985113d6180ea062c38d3a767690bfdefb32, + 0x2437193ef44a47aff1ed16bc09cdee13822f9a8e1fa259c52d17d54efc044f95, + 0x15e24858aded9beddd81936ba3dbb813d8aed04104899eead6094aaccd061f9d + ), + line_fn_from_u256( + 0x2f1c5ace8696577deed18f6b4bc6e001b8e5919d71ecbbe2cce58012bb53589, + 0x7e0465f35a7801db9640c66c2482d4bd115bc6a634085cd581d7cd7391dff9f, + 0x1fa2ad292abc847b5cf0b8196a67ba48fae37b2289ae196d7ff7d910fee38e80, + 0x27a92c994b231cadba78d8af9d1276b453c8f20402133bd5544d1573ff5b34be + ), + line_fn_from_u256( + 0x14e26dacb00e379e44b9157c4ceac86c1b7a82902e0a080324ce8b30a6d2acdd, + 0x18c49b1deb28c628cc38103db865c7a66928e2da33e0fab84ba9c5f4fdb85c1b, + 0x27958928b81241d1bbdbc39b1af422ecccaddb05d54f0cab37d2adbece044314, + 0x289a83d73621a3aa2ad4e09bb01965b95a073d86a5f03f22a6ef9d9103ca4efe + ), + line_fn_from_u256( + 0x15579c902baa8dc5d749191c6a8f5570a401ae5cc2fb89fdb91faddc61681699, + 0x2cf58215232b025f63919e9d2a3ee95d7278737c4748e85bf58bd5b3b00eda29, + 0x28fe26d488ac0d6a005b598abf108a2d43f180d950aa4db4ac8333a64304ac79, + 0x29145d3e461939617798d37edee4aabb43c043cb4d051cae23425ce5de17fc25 + ), + line_fn_from_u256( + 0xbbd38cd07a990f12c14bced487edfd659acba49326ea41f36ca802a2d460258, + 0x18b10442023975734289a223d636f5de335e66af7e7c34dc2a50bc09baaa74b6, + 0x19f59419b27fa3b1a183c6764ecd6471c8b3d113816aebfe067408a471dd3474, + 0x818b53fa7fcc0bb56571ad5280bdc1920972be609c459c3967a5c90cbfe15e + ), + line_fn_from_u256( + 0x22aa9c6c52ec91191cbc0b0544d41342aa6661ef614f76b402bd5c8aaf81a5e4, + 0x154878971322f6c32e48b3e1af93f7a52931827de781a4b07f3d5cb28e82862e, + 0x2bffa3e8e8ce84ef68341beecad29c137c3d2a11bdff276f54487668670b9773, + 0x12c160dad27460ffdafddb6574b909488abc9536fce4b70f1d7c4f422686e696 + ), + line_fn_from_u256( + 0x2e48aefac027ba824e184803c8e819707ec66c02e1f4fbb49c10070d7f88dd52, + 0xcf5ddef544391540b9a22e7eed974c9bba05eeff56a830fd71a73306a997038, + 0x7175d5d3efcf6406253d3d39043cbac6bac4c1cb30d2784912aae75e3cdee3a, + 0x1e005a1793f9093a8b11bffbc723b8efbfb7df5ab5b6a355ccacae11ffdc754 + ), + line_fn_from_u256( + 0x119bb68b40f056ead6a7abdc5fbf7d624f24fa128996cb5b3664f6dbac43f1bd, + 0x646570bfb4df5faf1fd9b968c4d76b2c02e478b73458e5c6ed35a14253c7367, + 0xeb8fe90d39a11b25b6d4c901ad28f3332717bafedab34b95a831264a3a24e0a, + 0xcda946d734c359c5194252b306c548c6f820bb2c2273953127edd41f80376e3 + ), + line_fn_from_u256( + 0x4df9bc930416151851e02024445d86c0a74a41f8fe6b3a6b61feae86c5d9d41, + 0x1fbcf0267353ebe7e087b102833005c6dc7c1d61748f150f617409ea8adc63b6, + 0x256bc45cd6c66a55965b58e54145a0d66db980f5f4ab6ad18bb610f5201750f1, + 0x23b7eac83cfb6e3a3d95e498dd8777e8f1690a5ba8badac309bf9407e7d9477 + ), + line_fn_from_u256( + 0x1a5934840fdf790d8d669f2ae415c16a04a29d2588e675daf8100c0df083c9f7, + 0x8fe333291489ec777c2f3ce9cd36a84a2881d8aa6e740f86c655d88e43618fe, + 0x1870543f6dc9c24da37ad2b48b81288a6e8e944454e117e989a1481f2c097a1b, + 0x2a57fb6b39fbf019eed66ec2fb8673a7b3090fc1eea7118de02d94b41345cdc7 + ), + line_fn_from_u256( + 0x2059a63628ee6aeab97d5b6ef2e7364d6ef0f0af30044f697543c08f750ce47e, + 0x18ebbcf067da10d9903f3f4583641f985784a39a45d56e64dd1bef1214a0a060, + 0x25d877fbd5c44580ca50f052bdbd708ababd67a47ec49e11b208ea2575fd0caa, + 0x1fbe3fc7004562b133e1d1e562543f5f19634fef01ac08de4ec487cfcd2e730a + ), + line_fn_from_u256( + 0x19780bbd16496e28e781765a2200c5f11f842220dfa7b16fb6626caab82aa558, + 0x31ca9f538face826200d9cad57bb3699c6e16e55325100af619395d8f66e4da, + 0x1612b518975c91032486de12f198e9561dc2292db4d57d2beb632762712dba8d, + 0x2469b29aebd6c77da653aba435f4e3a9c22b5bec7cf5ebc8843d875b2837f73f + ), + line_fn_from_u256( + 0x1e0812b4f625cd4ee60ca9bed1757a98c7d14f8538957340b6518009f29c82f6, + 0x37e6b907dbf46e86ef4444439f0d3284e8b85b2cb0b8378813b4f670d1e07ea, + 0x1b4d71523dea855f459dc6edc558566c26112f1d06aabd53d97c3048d8ec5d3, + 0x2a5f8ded032df077e7509ebfba0ec80a7b691660448c7143f33e6e64d25f32b5 + ), + line_fn_from_u256( + 0x28d6722d6d35803c8cca34f234599aa12bdebfcb79af395f2629ce733b2efce9, + 0x3c4500563b309f858670ea67819829143321fa02068307f9b01e9f8f867daaa, + 0x185fcccd620ea326b5a297eb045fbcac3f72fbf4c164a57aa53171335b918044, + 0xa46195c1de8f2172df7fc9e6bb9f2fb04d9ed67bb7d5cd3d9105439453e461d + ), + line_fn_from_u256( + 0x1f802bf10ae8986f3e2b66768dba46c33dacd7793c77979c9b844de9dced930f, + 0xe4a6352d2a401d852d9b7426e4b5ed825df7e39a2fb312d552a0d4d0abdf3b, + 0x2e0f7c1f172b0d9a7d7b455665c5e9dec651571a05c8caf83f041086a2cdb901, + 0x7c3f06283cc7171387cd17337efcafad35445c46f80521063395b4dd3c8c4da + ), + line_fn_from_u256( + 0xdd8401c5212e669b1e63ea5fd05f253c8a71950f97eac879ec0637eddee7c9f, + 0x1cb5e0bdbbe3b00f4d0140c90fcbcaadc7161815ed2a18dc085f629b92af25ac, + 0xa4377cd04abe6d47f88dea837eb3f3c866037a9a79ac0445016c909591f6d, + 0x28cfdad039ee1cd5fb765ef375936a4c2c7d2d043b483245f90c144e3f26ee78 + ), + line_fn_from_u256( + 0x6c4f6e5d1fc4b4311818b53924e09edae6e68bc02baaaa6a638bf42241c2279, + 0x29bc54937219443197bb43a94a4743860109d2e6b8f9acbd0b7e172eeb8c2da3, + 0x297aa17ec0d57206d6bda416b358fc4ad10a6a07d9dfe7b195a3790ccd55af54, + 0xa700e869f5eede4b1f99dd395b9d607c25d3de7ab9c08868626c499720b7388 + ), + line_fn_from_u256( + 0x73679c87dc32900abd153562e21a101fa4361f21a1ae419ff526b3d12cb8fb1, + 0x2f57a1c6cdbd8e3e7be98855ec7127c9119f44c9f9f3ba5488e998b1beb30298, + 0x1e06a7b577e8446ffe0860329f0c4d1a9e44d4601e333ef71495cb83da2dc232, + 0x1173881a183279cf48de1f6abf5582cd71dc602b9f773e1f08af1b7781c281e + ), + line_fn_from_u256( + 0x16b47175144ea41ca652e9409f1760ba87dd55423853c20773d364db6b4acc23, + 0xb06c3a8b03cbf32e4191025ec397dea13f8f5952b5e78eda8db65585720c497, + 0x14c38138414acb6e7ef8a2e5fcf503a48fe1a97cd7ccc4d5ccfae8dd6a5012ce, + 0x1279385c73e98e9e1f1629051a978451abd667dea3f8999194a6452b26a1cc9e + ), + line_fn_from_u256( + 0xa7fd54af803af45ef45b93c867cfc092e90293fb7160fa0eb214243ca3305fd, + 0x2e4f007e20e1e32cdfde08e53601e990b68169f107b6183664c7e1b4c01afeb, + 0xfba3cff44e6047544c589a0fd38c25dc30e350a3e42735223864f8ea659e9b3, + 0x1f3d602fc4df728950ea9acfb5f7fe3990da8d1317086bc7272e8cca0a4d9776 + ), + line_fn_from_u256( + 0x2d4008a677bf268d1c8777672b3f28542679f9a8d65cce5b322f3a8bd27fdb81, + 0x20e9cd258a0ac5dee9f5d19be939b718c7d1ddfad4828a6e6e839133742fda61, + 0x1ca3ce987fc6cb565b27fe836681c4e3055005e96df65b3b52f2865a4d3e13b, + 0x264d009e34a2ba016aa059063545a6216032660b2ad9f3a447d0194a39f71935 + ), + line_fn_from_u256( + 0x67ce5239a4dfdb732b54b1a0b186afc44a89eedcf9919c88e516459ed4ca11b, + 0x1d99d69ee5a2b1c5e84d6c7ba9ed7708e79bb5f64adac24805caf7e65cd387f1, + 0x2541a116b970144fc04e797c12ad04a7d90e32ac94895924c686588b7ac1a10, + 0xb043d1a485a69ff526a76bc3ecefddeaeef0aeaed955dd4beb54916ca589691 + ), + line_fn_from_u256( + 0x10532e033b2bb556bb44f4e2d8fa5d69626b2450399662905b852eaca478083, + 0xd0b7528c94575e566843dee925876a4be4cae5e8c3e01b2dfc92d276ef55c66, + 0x159363c7d180e27e7441112833056b3de59622de72184631b984d07374dab3cc, + 0x2b3eb6499aedfb7fa52d2bd76e236a7fa1c6bc2a4f2d0f243a7edca82ecd564b + ), + line_fn_from_u256( + 0xe819f089e2009c3f56fc2a65c8adb3c96435eb3f17435c7552f0c7064612569, + 0x28644760132e0d36dae84d34c34ea7bffd14f3f0bb48bbe2035a40094d6975ac, + 0xdb632cc13acc807b4bf02a18c95015e359ea7f29567839881f29dda5daef310, + 0x1ff7bed8b95d85da24173048980c84622a1590230ae940144540bd7863380c05 + ), + line_fn_from_u256( + 0x23da8ba2397ed80ae5766f0981a9d5cd30b520c2d5b12c45a6001096b714c92c, + 0x17af81ac9650f7d2519cfeace61d21e44a9107a6208e08bdcf451cd7da0570c8, + 0x14a418fc00e60b5a18494480b75392ebe4f32df4eb1a372cd1acd9a2cc0bb4fd, + 0x2c36c3e6aa470863a2c1168bb545355cdbe1d86c4cc96f63b4c2288ac78b90ae + ), + line_fn_from_u256( + 0x2bd603b1e0b09b9c64d549aa7482c86635bf1c88d4311d79fb9d72480d75f4cc, + 0x264704574b35c2aab18adc624f1a00e2c1e5c95c4f21262387dcb5badd7f0f8, + 0x14f31515fb637f7ad70e764e74d601155b7e85c9a3149bdb518b59a0f0fc16ec, + 0x83b5c5d8cc1361b68c313eef38d7c78ec0f4b9e8377156b4aff61f9a86c9769 + ), + line_fn_from_u256( + 0x29e09ca4e15b955c20a432030511989660dd963adb82079a8cf65b9420ec84f9, + 0x2e5da216038d7cb29f7cb26a694880a0af663ba5c60b2274b193f8d9087ed045, + 0x68dca455e98d0ab4292c41d3e43f7e662401ba8d83ea43af8a11dff5ab94abb, + 0xd7c62956e6aa887fbde0c07e46d05381749ab95ba83d61fad7f72e3fd7ce466 + ), + line_fn_from_u256( + 0x20209760e8c5ecea64f8b96fd0269d23bd4bc52333e3b557be8df2315679cc11, + 0x1e4620ee839a7994414f1b6ac90c453af37b6843c8cf99e7126939fee82b6ecb, + 0x46f52c38560cf4a4871e3be0a85e1fc77c8fe771270d7b81cfeb2372c471237, + 0x65537323e9db939048b4cf30a7d558b5218462c913f2081dabee116fd93aa23 + ), + line_fn_from_u256( + 0x795cc16a26f851a21441908b14712fe88e7552be8edae92175f36b7f0a7407, + 0x15724757f9c04e65c9f39187f6558ec3b46e8a5f2cba1ab97b78f0ac15b83ce4, + 0x23c5ba32e554a25e9824fabc9c6278957ced2ca44b82ae7fb2c9b44825cb9a60, + 0x1bf18e49d37c5fe76268223f4fed48568de673d886e6af58c29581fe02cfb96a + ), + line_fn_from_u256( + 0x214cd2fb310046bc80f5cb790b283f7f7301286e5d2551295b4eb00eaa9c8ae9, + 0xa3bcd2c7b276715492cf898b9901f1241fbe280e0ca10c74b1b8b66246f8329, + 0x1962a3b6bc270362b1f854b8a76da664a9501e6ec2413e036d624bd25dbdb2ad, + 0x1baf7035ba743947fa5683f52735835af6676ef8cab80b272e590f58b0f455f2 + ), + line_fn_from_u256( + 0x29144cf60028f43632a18d309d6f1bb4c45e3ab214ad2e2a718a8b98c439aab2, + 0x4e036cbb58ac6e97e71c1f74a7585a38612e68bae05d6aadee98a93f3faeb0e, + 0x2da087fc860c000c61b8deff82b6f719f1a38bf3bf4ed587eb4d42923d68cccc, + 0x147057da0326d1c8fd9bb28a96c81a7efc25e035085bc9715fe53bb174cc0c30 + ), + line_fn_from_u256( + 0x118e401882ba14e7564e753240cec9b724c77ffdae816a8f98326b873f6d099f, + 0x23510bb5dff171003fc74b2b5930b79841d3b34dd9ed61d4049b3f7ad824d011, + 0x1f6609eb38bffc10841e2071942768411423980572ad0422a4d3462a6331c4d4, + 0x1d6b2665f90d190532bd5710ed947416aecea2557a7d1b5f445f4eb398766631 + ), + line_fn_from_u256( + 0x10d12fe49dedf001261c630d24421c1da48984d881f257c667c170669479e9a8, + 0x13ccf493e8881180deb4df7e92e4e5488c312bed478276fcc12974130a40577d, + 0x1805c17c2d4d0b42d8ae3da33ed9afc891522c40c7ce1840ab96b9f2564d4ff4, + 0x29e5cecefe2e414aa3bd0398e119b42f18445b01e11f2969a76def0b30e318d1 + ), + line_fn_from_u256( + 0x1aa4c3c9f415b032d185d21137f30b904bcadac9fb1091c3e7bba62f63ce81a7, + 0x26fae34bba8f737d1b26e90b4bc5e8044018538bc9a053328d1b81123e6900b, + 0x64bd7f7a0537f6bd5141add1f058d1294f54738eb7da1fc5e1d36171634f001, + 0x51286410df152cb0fc0576057c8413ba4b48d99eefe4d42b425d6b5e4a4eb81 + ), + line_fn_from_u256( + 0x2831206a2e464e3c77ee824b78ab9b898ed01b77d05ed478df28a2ccde5c7e27, + 0x5973e1fe421b082013099f8b9f64735265437ec5e274fa445c4ea9613593214, + 0x1cb53a3058cc46e5158df39c13a865569f13fcd9f9cc70ff1a016657b08d372f, + 0xb9364065a4d13ccc04b1f21b08384698c27fe707e2b2e4203197570576cfdea + ), + line_fn_from_u256( + 0x26c80957657a7951c3113b4c60df66e55c72c7c13a380c2bee904066ee24547a, + 0x26bd3ca5330703d00ccdfbc39cb76cb6705ef0a3f8575e87192e3de5870a60a, + 0x129241b613460704fe9314c59844fcc9ea4e2ee56d01a8051fb61c3726ef189d, + 0x21b589017bb6318c27a4bd72ec30bcc3713cf7bd5198eaadc31620356e6ea78d + ), + line_fn_from_u256( + 0x2ad444ad1192f9c6565784fa0220aaf981ab867799f8ce28364588aac78235d6, + 0xc6ace849343f7e286d55035249b985dd1daadf9b4bdd3f53febb5cb38294433, + 0xef09af90beaa4e268a8f12b07b38808b57e01f47317e9f0448065a22c4d5705, + 0x274c88322c783daae05ccba6795e1ce8d2f81b3bf2e1df31ea55bf173adc05b8 + ), + line_fn_from_u256( + 0x29a5b46507ae5f83f9afa81234532162c71bf0ef61d3c7fa7b512ae95ad106f, + 0x1c433c8c39f471a6e14747cd0f404f0563b31088bf2e0c099523fbd5955c880c, + 0x15c6ea0197ad73d6b1b84a2250c7ab588a93fdc2a0d33d38d6342cee605ecca5, + 0x1be8f967e5e614a4f9d760126aa7f201b13963b2ccc68123e9caf8b48015d77a + ), + line_fn_from_u256( + 0x13aa8efc408ac4bc256679971ff4e4a52153656dd8f19362deefcafe72468b42, + 0x243fa5e8b9565d2527ee90891a4192164a243bcb3f3515228ccac772bf9e840e, + 0x2b6c78c812d5036dd4646ce9f56e69e1234898096d88616fd7671c934b67f3a1, + 0x16825f2842c5dd61e02dd08c8b3ea89d9bde59ee69d6100c0c6d31d48dbced05 + ), + line_fn_from_u256( + 0x86f50436454be20ba540c955fa08cb8bcfa53e632461b91acc8d930363308b8, + 0x9e20218e575a76319cc4a473b10f440ad557754ac002130d3a38ff1567db39c, + 0x27726610b8d257db2b42208845bf722da09e06ab82953cc3b1b1b23a1d354e74, + 0x14373a4260fe55bb0c257dea535abcdc404ff479b96163973aa783a0cbc22ab3 + ), + line_fn_from_u256( + 0xf765326a27e70d7077919a5b106cb1d202cb4c18117b5632d73735485fa3674, + 0x131c6f4607605a68bf8efebc20466eeaa529d318ca2cf15d67ba6ab317dec91d, + 0x22c49dc88c57f9d36a51b6e9b8e5ef107116fc9ec267a0e91d05c9ca8efc505f, + 0x19f0fdcd8f9dfc07b91977ba2f9d8befc9ae4c39e5f3448915dbd3107af2959a + ), + line_fn_from_u256( + 0x18ab5d81a42189be0afe799a518490c033fd2a05ffcca3b351bf73357f99e094, + 0x1f63cf46a33ffd8b1d26a42ea08abd1bdb69dab4ed91899416f35cfbe028eb54, + 0xc09fe2cfac26846b3850e7b0a6c7e59c9c699d292f05026915a81ac8411e58, + 0xb8d9042a40b396e918bf5ca23c9769a886cca7ac277e8c70ae098f2fdb76515 + ), + line_fn_from_u256( + 0x1e4cd3ce251500e339fa57e60537ea76a5e0c999f011901f31e93b080616d687, + 0xe360102ba300ba962c6ff353b74aa1b8e9ce94b3339ba3fdafcc05ddefb8dcd, + 0x132702d05d634a6b43e94bead0bdb9145a2ba5b68b99d8b36e5ff08ce35eae1f, + 0x2886c3aba521cf7118a71fbcd9583010b1a1e0bc3c3d65df27967bbf6c2073e5 + ), + line_fn_from_u256( + 0xbc57607e5b1e3aaf770f9a14887cb94fb1a7b12757b3511113109e85c136cb4, + 0x142050ec99c7fd7fbc25ca9f178f77d9c1b59e0d062603785d74eba713946a68, + 0x83a0901f39cdb9e218fba92a1e71230f0279ae1d4b077e7e830410c3e3f4337, + 0xa80ef6b234d8cb6ea1c0687589c67a077581c659ad1377a9e75ed0191b164fa + ), + line_fn_from_u256( + 0x8c2fe2799316543181a00de27ba4be1b380d6c8537ecf0916b38aeea21d4e47, + 0x7b4be349766aba47b8685c8a725ae79cfac8f99e68fff5ee73364fff3fe403b, + 0x22ea21f18ddec9470ce316c76191f1e7cd7d03f3df7c93c0095545ad5e5361ea, + 0x16fc78a64c45f518ffa1e4be3bed5faba2ccbbf4a19620b4c32db68cc1c2ef0c + ), + line_fn_from_u256( + 0x2d16988cf5101f59df065736e2f8e3f40c785ac73d06d61646ffd7575838e78b, + 0xe1c66e17fe968c5f56a0e5b06fd97bd8321e14f2a6b27684be7df8c1b81d470, + 0x2fc95dc9bc835c6f08cc51ad2c1325b311d2d7d1f7ea56b48de6788554fa01aa, + 0xbed6635e2a3f5cd62ad97bb5ae768ffb1294f6fc173dd6c0c2ad9485f07a250 + ), + line_fn_from_u256( + 0x104d49466efb90e6cdbe52a4a70e25df68ad630c4c2a70d0445a841898f95ffa, + 0x18cef9d4307828a5bbbffe2e27ea96bf12a995a72fa24049d3601b7d58635d84, + 0x239d5d6c3534acb21a711e6a56e1ce735bbc9421b1624bbd7d5fa1227037147b, + 0x104f8810a211eacb5bedaae405cb3a1570c6577d7172b8bf130829df91f0d6af + ), + line_fn_from_u256( + 0x9a58fbbecc5719cd94b3edbad8d87c4d647070aa229c53ef0bf575adb14b4c8, + 0x1f3c75c1623edfc5881142d69b67e3328179d573cb64ef6492de879f6c0e91a1, + 0x10d55e3e5e149ef7b60cf0807f393ac20eb7587f85252974b092d7326f3293db, + 0x2c5e7e0243209425e1bf9032d49f0cbd63a446b084cbeadbc3c9fb3bffe22c3b + ), + line_fn_from_u256( + 0x14b2d427197b5c3c5762ea1a6103d92b9c1f35e5f5a59d9e149abdc6e3934598, + 0x4ca140f253cf090176d06dac6d779cefb610a37d44cdf77871dbe2f46008817, + 0x274db3ec80605cc12d7384d20f945a0b282a8e582639b8c1d899a6100955b30b, + 0x2acf77cafa7e5576ebbc31aef713b1c4f9d2feff725b0229b3144f88a56a8416 + ), + line_fn_from_u256( + 0x3f186433881bce446d0baa5ad17b66f69ef78ff759bb0dec41bf01dc460c778, + 0x450954848cc8b9746ffdba98cd39f787bc9b337afdea96b009de93a5f40fbc2, + 0x16bb15a1f9a76a9603fb6f2ffbd5ecf4209a4bcc1f29db60b2f91c9edeaaf405, + 0x28fad6cfdfd3dec50e49ce1d5f7cd90a98d50daaa9e98bdc22bff0ce3c7b3442 + ), + line_fn_from_u256( + 0xd7a5f3383e67d9214d4bbdde00912daa6bc496b24c86034bc1b87dc91d21e1b, + 0x211acad86bc52df8cd335f0a0bee496bcfe662abdc025d08c7511dbc80367316, + 0x1b90fe2784a45d9a8c33bc9dd301303b8ecab853e5b983f995c9c32e16839a4a, + 0x1ad1e9af7069003d4b1fb4eb91927c9a6148a31707827b4a174b2a7b77d941c3 + ), + ] + } + + fn delta_lines() -> Array { + array![ + line_fn_from_u256( + 0x2fdabad1256f90e9ef80508d117bc0ab728c7910bd7f0eb9f1e931282f6df16c, + 0x11042a7f3b24652129c8834d81a09f749515a935cb6ead8d8172aa24dc6053ee, + 0x1cdd347b021affa40c7797b12a3919a1256ef84d4f6a65643445140b1f8a49e6, + 0xb201fc4350d5d3632ed5542856407700cc551fd087e0948af68e114d5d7e889 + ), + line_fn_from_u256( + 0x8993a1bbc20f3fc8cff529700597b224f4f180aaf2bbd34a375aeea90f0bdb, + 0x1f6023f3a60d3b088e87c268ffe0b8e9026bc15b9d031cffbaade1f1fc1ca959, + 0x138719f7df16a085abd8ae0557483ebc721272441907652907db780bb8f2b361, + 0x25442eaeac2442f38562f073fc1d50ed8abc18945ff3c1448cb7ab0202a514be + ), + line_fn_from_u256( + 0x2d720e8e9b0644e435ed7d3883440c92693d6247cc507fe4d09161f74e0bb2c2, + 0x2b1baddbcbf3638fc097ae76d46c27ebe0603a492efb74dafe3b922ad7cf52e2, + 0x20bafc4c80882e096d8c8bef4840a8a595dc9d76a2c00842fbf52760c82ca237, + 0x2cae87e8cf8f589a7be249871630e36b4c29c8668616c21e1522675277138683 + ), + line_fn_from_u256( + 0x2dcb2d7bec5de5f3bc5c18aa7672f3b6c887079c3e8088c015c104139b908d49, + 0x199c4241d6b6487dc8f15b7b299c28f52f012ca14d6d0a62b5ad4889db5c94b3, + 0x245e7eae771493bcca8b88fdef963ab4f49b87e03e3205e1f55b145905ca9cc3, + 0x19508ac7d56c95e2126d5894cb975303860f4fa8cfa047d9deb6385125b02be0 + ), + line_fn_from_u256( + 0x9b2e572df202924457b828337e91d2f746aecf7b4b57a9cbf71554ad0ea13c1, + 0x9050bb2c953c506a5a0e4ea2f876859fa71b5bcbb82a29f6ab5f642d3447b8e, + 0x20b304fdc594722410b55bc6266f78c0e18c51433bdda0d58f53162f432dbd11, + 0x1367d211b31a0949c99d744b599d17c176a7ab9e17bd8041209763a587d2a613 + ), + line_fn_from_u256( + 0x21cb15fcf25eff54ae58c29a831f08080621913c868e6fb19853fa3eb5ad768d, + 0x1a3fb15f03bfb074556d370c79429114479336488b5a96cf142eafb4d0792d85, + 0x1a9dbd6313c4d944cc8e9a1645a60754f2846356e721707049f7764239f5f7f4, + 0x2a7be1ac2741e294e27a96881dd644e5037d21b2b45743fc5b61afc192adfc3b + ), + line_fn_from_u256( + 0x2b160150afdf67bbf0e889a4e5f76359df9e33c8db532196e1f8ffdb08864633, + 0x278cfba759f2d6abcb2bfa922869943195b1917a4db6af53c6043ee5d034a8f0, + 0x20bea5cdb1c9c65911e8a6035e9e96b4f2b9efda00524662f040b9e23949d484, + 0x1b7e612780b108ed889b8fccbe830bb9230a64854c8b95d0b01c995a06d97a3b + ), + line_fn_from_u256( + 0x232b42a4d831499986fb6c14f23876f1e8b906cc2993ec4e72b9341537880db0, + 0x1cf9078300b3179b9d7b9525d68214a917951f32b0a6f9d662790675a7bb5b03, + 0x145ad18b427285dee644e84b8aeffd03bd9a7a4f72b5a51b26e287f6863c2394, + 0xa4764ddb29b9183d07f278df9aebf87bc11469f40ecd2a648a68260fa9f1a66 + ), + line_fn_from_u256( + 0x10af9f0eaaf5a458b83b476f0927aeeb66c50bd1e9c11041f1b772100fed1fe0, + 0x2aedc397d5a6936ef6081bd1f8ecb9ce787168ad4e4145c75a3691c388850f7c, + 0xb834d431ff295c3b1ae5f65452f1da4f146a6d8a9d1fa4d2f4aec55842bff92, + 0x160057bc5d5a209bc21bb9af3fd1ba5b27d97736bc4bdc0ae59f5698e6f271f7 + ), + line_fn_from_u256( + 0x274a3e8b38572a34875e9eb4145d5187c7d55b079c6395f5609d05c0d0a3577e, + 0x3c8dcf91e69ea61995e16c04c5a2193b5c79e8e27f640585615475eb41c45c3, + 0x2282a5f5cc5c55e6688532761629f856ebf2d8992aa657b67e2529e07cfe0b83, + 0x14fdfc684f10f315e6650ed1faa78f559b81772699327aed413feac2f97249fb + ), + line_fn_from_u256( + 0x4b7c89609e6a873bc5fa8392d5ce81cde0e629324422b60a3e3cac2df50e170, + 0x24e94ab04dea70668edf0802b206fc43007e46af99c5482d29bfbe6d7dd70b14, + 0x27402d871a854e72dee9eeb67aaec5de73c77d2130d9bdd6d161a58e30c96a05, + 0x4b9a57054c57c32e4e2cac8b7257771b5e5aeafb6f1b32d4d69d0e0f7d0db44 + ), + line_fn_from_u256( + 0x20711846506035486796f8c2611ae2df9755399cc4599f84832408e7f0963aeb, + 0x1ff0bde7a987445a9c48e018e7a9e96b9c9e25a73e24fab4dafb82e6f108be7, + 0x24c3ec9e0af950f377448b6ff6332b6159223cb0cb973be9378b6136c8c0f57d, + 0x235053a4f4bcb6ae772932d23e6a03f5ebe7418517e16433d64d4d67c6816e67 + ), + line_fn_from_u256( + 0x1f91263cbec3472d2a21481a3d3fcaa6e77a02cb94cbd577b249cc33233f212e, + 0x2caa111dac10fd2fb1472d261b4d89523938380cc48791a9e599f10f4212402b, + 0x123414cb35c4954fbd6f8eae42a7479af2e3ac0475ba0e23968874b4fe3e0d58, + 0x1229c5490203c44805768f8e25774cb108d0075c66dfcd27ff1457f17dd733c3 + ), + line_fn_from_u256( + 0x16c10f3d7a950f83bc5bd3b72a31878bdacdc16fbdd382de6716f239ee89f6d5, + 0x2a13e56a257d1455a8c481135db2f1b4fbad9d8d007d8bc145b120443c7d6fcb, + 0xe84fcaf4f337256c31ad5193aeabe80d48bd9819db9cdddd07930789b9f93c0, + 0x27d919bc9734a293ef146abfd7e43d7a543ab4fbfe65d525429ced7f8c7548b7 + ), + line_fn_from_u256( + 0x18f418614ee4154688d2ea0c372727dc01859b5a61f6c3588de34bd1a9a5d725, + 0x124cf78b550dfc1345507287aee8aafdf8f8efc5a8c649f7647c40be15a3513d, + 0x184f713604a8ffa399891862ce71be6e22532e25819034f3cfc19e06e5173d2b, + 0x1a6d2742d9bd945288692af03248455f1cd399b28d55a8600ad221d1b489994d + ), + line_fn_from_u256( + 0x15e7c4da43d549d8c3604afbfe82e9859182a71ac3d1a953aadcee28ddcc4441, + 0x2c921c9cd12f7cb2cd8967cf169d71acd7d5ce257370f158cee83f625e24f849, + 0x13a92b478419903d5b57f637186ee5ad497e869be80e50184543913d30397f3a, + 0xf8cc1cef3968ef3656138eb60f91fa1fd8f506a802d0f8b97277bda4a5ed44 + ), + line_fn_from_u256( + 0x2b3384434041685428c8ea6d4c11b33a9e83046fafde063f17edb2f78000f06c, + 0x1e99bf7c724101d42f96e8559c9880caaf514b9932fdef908a04d41214115a8e, + 0x6229e45f72bb3f3187c4c36d3eea036ab9f521e03f214289e4823472901c2b7, + 0xadec309f2466faabc2c8499b57585ca0f462840e8c9e37a8fb6a292143d09b6 + ), + line_fn_from_u256( + 0x24b9a8531497fed694bc29e87df6f9b525b7238051e58905d6f4cede7f8ddc0c, + 0x11c56774186dc8a23a9a35a72317a254e41d0306c8c7468bbdc34b40388d8d1a, + 0x2a8cc10094813210a022e20074d00196506ea777ffc1e25f85f424e8ab9d6529, + 0x1798c0462d349e391cb6274612ad932b9f9b0edcafac358b3ef8f6cf98282ae5 + ), + line_fn_from_u256( + 0x1aa04f71f00aa01f691319b34829607c387fcbaa91459a44af08207486d46950, + 0x169e4fd0433c270c0c96208f148460a41affc843782f4ec0e69bf0dc3f14b59a, + 0x14260231363742729cc8d97bb95a68f2d18e2bf09048c6918e2966baddd32c0c, + 0x96ab8a26e2079028b28fc8e6dc147be6755cfd78677d81ae43f01ea3c6f4917 + ), + line_fn_from_u256( + 0xd89324f46c65d12649cb3b2abf202c66fc9af293ddeeafaac8b2c90f4acf5a4, + 0x26307183d5112a453aa7b230bda53d7f041352a14c191b48d02aa3e9815b7035, + 0x114fc57244a5a7ba1ff5166ec3d3c3f01f1a494eb6a87669fc60d30ea054682a, + 0x2c1d18272880226e44ff5593b136e791ad737152f4f3bb3594aa8f785944b14b + ), + line_fn_from_u256( + 0x2a585c5de066b966d5e988ae33a73fbc0f6fe351aeec43e8c2b78b84cd803274, + 0x161f65c0ecd6c47871390192f68c276716d9d9ca533800f6184854f6e6b5dd1d, + 0x556f354235c8598847e0ae125a016a18bcf3d7860ea833d1a50b501b64f4208, + 0xcb4e88aff0d08bce636350b781c86bf9b3d2dd53318b79e9ff5e7d8d407e5fc + ), + line_fn_from_u256( + 0x2bef9f154148e4417e2b71a3971adff7cb54bdf4e5c3e9c8fb20e38ea8ae9f8e, + 0x71bef8498d885815d9c16ae6ee0a5ad051306ccf36fb6214ca70b8dd68b5fe6, + 0x1e390d6a5ba5faf1c4307cddc6e1355a710f7be8c84fa00bb68728a861baf12b, + 0x20e0794d0ea20210025d6eb2098165f7a14d6ca86566ce632ec85f6f110a4afe + ), + line_fn_from_u256( + 0x13e1d7d545981975a871533d7c31d996a07e38904fb251f0ed7f4c1f15eaaaad, + 0x2dea57c19b72b5f4f179e1ff60bf94698d5447f2adf263729deb71a34f1bb07, + 0x277fd63e7bb52f775c80e5c5495b71556077eb4768aa00d52070a480ceafd14, + 0x179b585282c30df456d655baea02f9e63673c37e69162ecc41ed0ba402ad5d56 + ), + line_fn_from_u256( + 0x266ecfc0992af01eafb93b8bac6bcf3a3a0e543add46cf319bd112cd12614803, + 0x16022ad4df0b2ce88f7afd090f24748c060e2171bb22507a33639b332a850c0a, + 0x20804576420862b70594b87eaa5990a5dffff09886f0389addde609a711daa82, + 0x10740ac3cb457b1d829f1a1dd4c842b2604869f8a096e136dbe6e702676c648c + ), + line_fn_from_u256( + 0x1b1fb460b83718374e770b729355356badeefc30ab8856a0654df0188a9ca50e, + 0x2b320cf98cf9d0fcdaca85cf10856f48bc13945616c9ff6578723602f047eefe, + 0x28eeec73908d37f46d964ce79feb9e9cdd697b76c1d3a850949b0ca6096fb62c, + 0x1159050fe7f1df9dd74e7987da981705df176b60168e0a291bbe95396704821b + ), + line_fn_from_u256( + 0x1769bc3a1614a547f1257ba2970a44c717ec9e6a1278b5ba6870972b303ca076, + 0x10882ee55f25bc59ee411a4802ee1649c20872c6e1d5dee428ab886890fdcd37, + 0xe61c09d2eeedfbb80cbc7cc234240aa76f6de63c1252aed782d0b175b22e4fc, + 0x203f16bf76afd1249552338c683fb4c4c2a89a625724d1bf20790047a66df2fa + ), + line_fn_from_u256( + 0x2cdbcb0609d09f3e061c4b0a179616c86de1b219db6291b3a1aedf03bc89c870, + 0x2a36270f90dd1475ab3912365cd55872efa1523170ed782b6bc0a4863078fd50, + 0xc99ae925ac414035e4c72662218f1dcf07449c1bbb4420147290411099df03f, + 0xb2ba0a2a48a5668daf2b93ac5b675d437e257be63c9850b2063c93ee0338795 + ), + line_fn_from_u256( + 0x4586d09d5a69ba63149cbe1d9c7d9f8cdd257d27de171e52f248344dc1304d2, + 0x1c19294e84271fbf67b00899e72280ba58cae6b8556881c92da5c88eba1c4dc4, + 0xbb4114eef5b1fdec7e4d75d0aaeb01b988baf03b316567b0b14cc64176ef36e, + 0x28ede8be76a366ee5cc947ae0ea41597e26e8d97d797f4f82dfa5e1050cf74bf + ), + line_fn_from_u256( + 0x1cc87dfc856efa16e6e79e5e2915488d6b61e6504a986eecf470ab7875a3cd11, + 0xe48e7cce3cf5fab172a50ad753bc367f356d55f9f2f3dab2985c280242ec99c, + 0x50dcff53c4630026bf28585f37bb409b12cd1c910b9e4b4572049535bd3ed6a, + 0x24c1a05b6fed19b7e22fc60976d6d3202882010944f4e9f711a37c91cc857fd + ), + line_fn_from_u256( + 0x131b33ee52f3104903c8ffc51349ab0d5f2fdd58e0306b48ddc0e841b435b8ad, + 0x10b77e123dada6b41a5e8d54bd8434f7a039eb607b73a7027d951628fd38c43b, + 0x12e550d2b2de3e0865ffd36a344a404cd56a83d946dd41fe2b17f53f3266225, + 0x17afbc991ac366d82df72ca19365c2e68076a29b6854a915ba78aee7c56ce1b1 + ), + line_fn_from_u256( + 0x2b8ec6bd0d531d306f3c06c16b41c30b237475295a675ec2d55c4e577fc54f88, + 0xb014e1c51d34f7700d245635cc6fd0bfd1e6aa9003cc1f82ba5e415416fd983, + 0xb4a84a99f4e1b60b23d2a65c151ca042b14ec4ae3a1843652adf6c9b4f36702, + 0xb5965dbf3946fbb3e8a6456a8fdd1ce49ef7f6293028ea4cc4646e39a48df70 + ), + line_fn_from_u256( + 0xc90f6dbc47bf5e9dcf07699b7921daf7935ac88d22007b423e395406d4e3e75, + 0x15a8fb913687ef4c249e52aabd7f77a8f333dd28aed5dc8b4a2dc143423c1f6b, + 0x11da5f26d16bec8868ae57c835f09de32307eb47bb4a7555fdf2edbf1a2651d9, + 0x203ef360a5ab56ff5c9903456d6b1a2919457ed831fd3d480774f7a27b4a3bc9 + ), + line_fn_from_u256( + 0x2697981c7f99a76c8431b25e9c105c62829c38a688900b13a440f06e8ae15ade, + 0x2aa8766edab0329c144f45102f33482aa159c1872d5706f3e82a5fb876ee1a50, + 0x2822469685ce15739bad4064469bb2484ad228db0d7977db1451384a850be557, + 0xc4e00338e8b10adf42d861ca1f14463b04f1a2324e1d72a1dd4989d812a9409 + ), + line_fn_from_u256( + 0xc1025fac56f2ca61c980e5c0b83d8660ae5d390e4a5ddee8ae433a6cd4987ca, + 0x29617bcfa335048f0cbe3ae0fe1ade658239cd523a430814f680bb2a867cbf99, + 0x2ce83d6ed486715781f2ea6f3d2835d7925517bbde24a21812601430cd295196, + 0x2c5c4a69cb68a803c49f9eb32d566bf85952970eecf21096ca64e721d7a1b43f + ), + line_fn_from_u256( + 0x1bd5850f7029ad6b370c00e5c59db5cc5ea464185ba03fdef766d5c461fbb75d, + 0x19f97053ad37fbc1177c36b0979775a957dad66d411d4d0a673af78fc757fff2, + 0xff399f2b6b02d01d7bff3a10a75300ecd342f62f182fe64a741f897128cdcf3, + 0x2e7e1492bcbd2c0303526dc440c754eba82525ba7e6ce4bf0b892a77a8935aea + ), + line_fn_from_u256( + 0x3449bcb7d00300bd3cb6ea46704c0837b6ce3d56be26cca0104b583dc0a1dd2, + 0xd3c2c7a9d0c0e9cd910366738312770c75f546cf6b383016265e3508f0b98a6, + 0xf53f60068a70fdf07f04649ac307e4c17591ae8bf78155b54f898d4bd5cccbb, + 0x8c03e474458826a62f9197116300cc9e6a2251f931141e00cf28bd602d6263a + ), + line_fn_from_u256( + 0x15030decf151af1edef10f24de3f1b9c4b26ce7cc885ade3a9efb2d1d64a214f, + 0x11ea4828a4f7ef1953c8f28cc5265749216c3286410932cb71d37d1f0079a4c2, + 0xa7f2692aa30eaf765be0a5c558497f2ea5c3c33331d4632c2b82a3be3810171, + 0xb4912457c57cd820cd0374073044b9aff8ba3bd4d569599d9bc2c3270a62703 + ), + line_fn_from_u256( + 0x24e430e7348d8d9f681a1a95e910e54f6a4a3920b8bf75ca3e431d3c0ed5cfbd, + 0xe531a0cced9ea4d21476b6820e0970facd196a09832655ab9552614b27dc5ab, + 0x14d0e1cf727051270517b0a77393cd1a7cb36192848dea9f8fa825ad91ad3ec4, + 0x2bf61ba6ab33b0c3e50ac9fd8b22b2d92035b937badb306c1cc45290a68a1d11 + ), + line_fn_from_u256( + 0x11df59726b043aec513df5d83177eb4147bd906e11186d70c226d8569b03867, + 0x1cba05736cdb324bfd114277b41bdf95480839b9feb4b0fc4283bd25a5b85355, + 0xa6ccdc982724fd187fcc50c1be8f071f348d85dba52303725df77c883199894, + 0x266d459f68741430ae28e0f085942a4b51634f8bd8b5bdfbde678a2970a815b9 + ), + line_fn_from_u256( + 0x24d227efbc2c10e2b8d93be29e0c99e8efac86cecac761d0f95a18a70443c631, + 0x2da9441eb302a5ba3edb227b6a8619bd89eb19a09ab6dc693c4e67c9723f8a69, + 0x16b6c902418dea04bb1da162d600c054b9a7b77af47184f7dc1ff3dbfeaf8be4, + 0x1335a3476e89930366f918746dd706a09186937e73fc32c39741da9fb918e8c2 + ), + line_fn_from_u256( + 0x5494eb0916139460dfbe3f70008fbdc8479950e26530b69cb7c021b15c398c7, + 0x1b5ed2ef8f5d9d4c3b02edfe02571fadf76e3961539f246eac112437001da0e8, + 0x1451bb463d512be27e54cb6a04d7433667305861555d721ad642cc775cbc32c3, + 0x16046a5b09ea7e82f1673ece4615095146922884df632f276b22a272fc40d2a2 + ), + line_fn_from_u256( + 0x2fc684f8433ccac8958bf25b5df25e14a6d77eb22f06050b64e017f35147765, + 0xa4e0f712f695419af2a21282355dca0f9987c252c70470c36b89e0e5460dad, + 0x1c510c7bcd373ac244fc110a8e14764b0fc2b8be0f0212d9bb62b8354dde76b3, + 0x1c3b6de16cf13f3b986fa039045e920ecaed0c7c053f3e0d34f4c4097db5ca20 + ), + line_fn_from_u256( + 0x12740f7e27555dc25297c66fb23ba9742faa145ce514f8802d5960e840ab4bf8, + 0x1b922c09c6453f49d6adc75387d566fbae6c7ab6243826389eb0e95fc45f9e55, + 0x8a21a7c10e37cc0b88e122003a4c8e011518e3d008f156fbc5d231dbd32f8d1, + 0x110d0dbd62107e3529d9404a574447a9b36575a43a9157158c10ab7a50e9c84d + ), + line_fn_from_u256( + 0x13db441b005605aa79d6c762e210615b5b431295960bc287a30547678b3ff960, + 0xf7048767ce6a220e58bda6c130f915da8f788cc637506d5ebd352832864d0df, + 0x1e527ad59c2c8c9464fa2ddb6186b418cfa4d1df6bc4434671c61373ad240099, + 0x1e74389daa3a6fbe38cbdb5ad9bf72fd725f1e20bc7b28cff4580b74c802307a + ), + line_fn_from_u256( + 0x292a1bfdd96b013de55a79eb043a6758d998975d6f96a661af507452f99d9b63, + 0x16e9808632ed33edf46b339903f069d6a1737384eb802bf8cb2d2422d63c359a, + 0x1c273bef35523133199155862c980a5845d3a6cf53e0382bcfb79a75ff5dc3a1, + 0x94084a0c89f4405460cb54015446353647c643051fc340e374e6083d061a0a9 + ), + line_fn_from_u256( + 0x24cf495f0f56b278fc2523b85b30cdd5369c73302172176f97b0fcb2e916cd9a, + 0xd39b5db69a3da7abbd52078a55067dc6155123a21b11e619885061638b3dde0, + 0x56890634ebc625c9fbf5dc05629a5fd7d7b8e6733368c3db0d9230016819621, + 0x2c4f6fa293c565169f24dff8de7f4f7a1a83d8a5c6b7decdc79972c2b9553d2d + ), + line_fn_from_u256( + 0x1d4dfbe62109acb073dc6fa60566099efdca92767b35c171c8a6a9f4ee12be0, + 0x1f0aed1ea5dcbba14f0ee27c22cfe88a558fff9fddf51f9b9b4412ce1bb0cd03, + 0x2fe9ac6a7c8f2e971d0ce931ea938a8993ce10f3e89a90701c4501aa21c576ea, + 0x19b214898405e49b795eaec3d284d0b917734f28893a9952889c34b183738353 + ), + line_fn_from_u256( + 0x2deac60432bcb17f32ce1c35eb55eee72b025f6678e715233e251383b202e8a5, + 0x14d28cc0fe56d59d04e4c6a483f17f260ebf99f25c29c1fa9b3d8d5d458f9d92, + 0x9b266dc4e801f47d545bb34ec2fab397c42cee3d99efabd9ef99bff0a6bc450, + 0x2164566b910483dd94b6214707e1a4680e66030419ce782a64159bb7fcd1a97d + ), + line_fn_from_u256( + 0x23c04c43b9a420967c1f7e55fe66212bc1f162f96bd716afab0ff6bb1cf88767, + 0xf53235dc5f4c072a4384d0231f0cfce167ce1f86451f3a9db4a9a26a0d71454, + 0x15edb8132be58f7ac7510bc402d604940001982d421409ab255228115736fb7f, + 0x2925dc04132d5e361cb5a912cf5532505a9a0af092029dfaae7f694ca1af291e + ), + line_fn_from_u256( + 0x142429b292fcee082872c88dc88a624af79e9f0a65b56a2c38aac130cc687c91, + 0x1252d471bed9bf47421efec55a104b55888af34e0692c18df2e843b35243da11, + 0x23333b06092247c15e2b17ec9428c4857b9778fdf08b382c725acd606ec7d5d3, + 0x13d52e0d7581c379f05cc28d5bdcc048c8083dd4ef2923c8d27c8ba67f1285b9 + ), + line_fn_from_u256( + 0xb2f53155751174f71926c9e843a20e208d23071e19abd6e6ec386dc11fe816a, + 0x18eea752d7f957d25491aae04e659e101c1e1800b0ed33648f1de2b4ee6bac70, + 0x2313d49aa08b41a71064cdc3d89f9da600457224aa5ec7e9d2ee24a32a41798c, + 0xbdc71449498f894b8ca5c5b80078946aaee0b1a797adf9e25f4863a286fd932 + ), + line_fn_from_u256( + 0x22ce4c87a12cdfde0d3efb158d625fde567d67706653707c272e3825ea4a89, + 0x2511f9709a1469dd248e129dcc4dd8849fab8c1a329b96694f94a5dda1d7aa76, + 0x92be181f71c6f0a66707f46352c06fd1957dfbe8be8a9222562601d571a750e, + 0x34eb4b57fd5a17bb21b7ef74a6d47e3313f60968c1f15d786c628d1f7267120 + ), + line_fn_from_u256( + 0x25bd33cb96e002a63bb7b432087f333fd127181164fba1b646aa422168297a5f, + 0x1c60f7bf5b4e86e7161bba8f4cb3e6d8e4ad9b59518e427ced3e7cc324eeca6d, + 0x10b5c6536f9cee9c767eff17ebb12363ae7618a8950cdc42a5a007eb511fdce9, + 0x293a026087852522d22ac87672851aa47db846342dddde4273843a62ee56dc70 + ), + line_fn_from_u256( + 0x1352e6b28eda78caf995705c9fda7f78da8a6e5a0fd4e8a63fcc68373f23d4c0, + 0x6ef3ebf0dc777a73d6dd93efa92c2ee0b9752a094b54995332a980c5bb7913a, + 0x2798c288f8ca08c141f4205aea9cb6259e09702331ccf99eb66d618abc28ed98, + 0x2a5ee3055bd03cf775a4ee61da2797d47b01a779a09cadf10b6f4d1df4d6bf7e + ), + line_fn_from_u256( + 0x2f380621a58bd9e81a4771f2a07906250c665a3e4f5279cd29a0e4f8d5f88d29, + 0x1f8e2f982f098350cea0d2e822d61618db4319a615521864d5f4a011dda19a0c, + 0x2f97ae7a8516c4b79b0b14c6a1184ca2d5107db26713c87a400b39eacaf8f4ec, + 0x8d132a7c2554b2fa3072e1df6c97ec9074c319d72aadb4dc35f6986f6b3545c + ), + line_fn_from_u256( + 0x8f2a054eb3ec03e49d81221ae0e221216328e551e815ffe58e2b28590b29ff5, + 0x32d96e9db0d6be06951c328965fd8184715573ea27cb560e9c9efc87d7017a0, + 0x14c2becf6f559bc62f54bdf35abc79700f11703cfd2ab4c79e12fcbdc47591f4, + 0xef73ab583b40f689376709b14b4a226de65495657740e71564b48b6e89f8146 + ), + line_fn_from_u256( + 0x126ceecb0d509abacc7062d05e305aa277f5b1944e9bc42c5850920db0f302ef, + 0x95aca621c1ce4b5bcb46fef97a60dd6dbc40960fbca9cc104f5e5bed06ad7d5, + 0x1bbb609be1cb202015b837c3f90c3e29a05d4600f6c427417aeeb5ab64dde35f, + 0xfb3779e4a945d16d5cb97fc98bbf69c2dada6c70add23ff870643b8ac9892b8 + ), + line_fn_from_u256( + 0x2cc4b3afde19e4e5a1b37caa18b15121914d3af4bae13f14ccd6acd0df31f94d, + 0xa555efcfdacb863e263b215304d143211e5c15b89ed4cbc7ace3abdbe200119, + 0x1eb75bc34588966738d4a317381a540364b60b709804338f1e9e05b10541d596, + 0x972dc5f62a36a73e3e5bcd12a616acaafc86fce7f9cb3e92874cef7e1acf38e + ), + line_fn_from_u256( + 0x289843fd54be2e56795eee8bfd7466a0cca2222d70176d873e059508ebdfc144, + 0x1265a7d4fcff644eedcbc76a723ad7c63baa65767efe52ec99b4f46d6b94a071, + 0x64cdc94cbcef5dbedb970b5107c0863e41d235173541029c7ba712086ba1af3, + 0x12922af0838b2a1185775ffca4e3cd6849dfedec077b5bb3bd40c622130f83b4 + ), + line_fn_from_u256( + 0x228fc068f58dbca46db1b2ecb2e51c1661b5b93f7d6dbf48118177e3fafc0216, + 0x271165c0cd3f335bf46e1f80533716036318ced1373288e955f2f4830e1510af, + 0x9b7d7aae6e8d129152ddf18a6a724c0dfeb92bc9fd91a32411aca099a4eae83, + 0x84314f5d065277ce0ddbf5797fa9fa7690a68d97586f73fee62c60c843259a9 + ), + line_fn_from_u256( + 0x1f48e5cb355f14c146a6c05b4c79b95735fc5de30a2e9a5eede7e093a8f07c2b, + 0x2c4b058e601277d432a4f8b6c183ccef16ebdb76805d3b8e9fd46ef92f060f3, + 0x20d8429768eb37891b86621aceb9d324575a7f83f0a54371fb1cde8af3623d87, + 0x1a16f81a4eee2f3eb349bd78e313ec818718a03f22cb53787b3bcf94871252df + ), + line_fn_from_u256( + 0x2f50000fcd45d94db85ebe81b596bbcd823728b1e0963de87decb015b73b3c6c, + 0x1e8b8627bb1c5233cee91c234265f62c7fb6463d7712bfcddc2379e256fbab41, + 0x27942046cf1fc2d7c5969df1a08d80c2612b370ba6111a207b04dc26a56d5930, + 0x2f19f4f81ce14734ff3f573e90e5e24be2abba106825e6755d68fa4403d3441f + ), + line_fn_from_u256( + 0x2ac7bbe4b4d42a0cc5a08b19df1e32fa4bf81c5996f24d32b21569462781f4d2, + 0x1f30cb991919b4bc7c0e7c02c1e5cdaf8de38028b15cd5a18f044a70aa7aa4e0, + 0x1cd42c2d4a827f5a809f72f80d21e3413620e4e6f09d7962d176ecf91b721b7d, + 0x20f031c32478ab847295f57c051de9d75fa7888dbb02fee72504bc73c9836e0d + ), + line_fn_from_u256( + 0x1cae0c309d5726e4d49de2fe0d8d6f5222202ee58bd5e1fe42cc04162ceeaaad, + 0x9e407f6d690eb79bbf77ba46d9fb588c23588749e5d60af7eb8811c2bab0e8, + 0x12cd75a84153d64e3d05405d4244411b5b6053e7542d0f3c87de91bb0df0a68f, + 0x19492eab9d3069b575e6676ba13783e1d83f7ef3ecf3a272cb4773deace4dd1f + ), + line_fn_from_u256( + 0x63df3526fd94660608a76c0a5501f07800da53d2f954bfe94511644b6937e4a, + 0x5b3caeacf2ced8d58f6fd2a73b31f5732f615e6beaec4424594bf287ceda161, + 0x108f6c9a6b11729d944ebf61d2875d0663ceb0265a236c76834ff4e316287295, + 0x1d6ef756cf79701824fdeb109ba6f1b69f20859d35884fdebb5f41f22a2c36c1 + ), + line_fn_from_u256( + 0x2f831a8cb11faec5bbd459ca8a7966f631b8c79e7d688186052a9b2a0cb1cc59, + 0x1b689982048ab244b10e5508568b41c58dd072b352ceebff64c3f3280af3ea6f, + 0xa97b986fa8f64815896129e95c4d5d44c4f15c48a61360031f508c15add9cf3, + 0x26a1018621324bb3faa22e0aa2a65ca7058f0c3b68109d24a1f8bfda76c5f67b + ), + line_fn_from_u256( + 0x160dde21dbb5acbf8e86c01feb912100c991767000c2c5e4ab316b0d5921027d, + 0xecb2503feb199f3257be61f788cf2488b00ef6d411e9111e435682c2c7b153b, + 0x169f3ec6d8aa2c99d694ae8fbfd801ec61e4956a5243d012fca42d58f2147729, + 0xf790aff921865b7c9dbed5dc40bd7b0c7ea740edccd2d0e9b39bd109f56e3db + ), + line_fn_from_u256( + 0x2d111191f831e2584af374011b9b3069c90a92411240fa783fbc4316e46e6563, + 0x2f70ca984f3a1d8786d202263e2e9b1b502b1f7f33e8667f9bace3b51bae9a07, + 0x2c000df8ae8bc77bacca0f992795033cefe08d88158e951eb7fc8156d715ac2, + 0x22dc07acf83c443227a3b2fe8129988fb26e2266832edd1bcc6d295e70b12a16 + ), + line_fn_from_u256( + 0x2be6c54a3aca53b95f89bb61bb93ee71eeaccbfbf6511d4f49a9fea592da27b7, + 0x254a6eed29384a5a984278aef6cfdc48ad8a4b4e1127fd5795f12421520a0bac, + 0x1ca6b2d585d3c508844a2f7d24ec647a74bc367df6eba344fc65f401c2f0dfcc, + 0x70f79b94941a9e5552bda2b1f1ce8c87822980645c65d58aaf03f803a25d55c + ), + line_fn_from_u256( + 0x1f41e7d6b435a5d3453153ae3a70a64a64999e0b6e5a4005b66c066183fc6807, + 0x1cf5c3c52d5caa538e4ef3791ab9e6c5a46638251088c60ed9192129769bf85f, + 0xee2136362693dad669c76fb9dd211e4161bb8be830ca39f991369ba879b2aa2, + 0x169a9f98b4915218959297e7835c953b30eabc9566837ac29b92a069d1f13598 + ), + line_fn_from_u256( + 0x2ff64620d6d4b0e48f4656a1f4b31dc00bf1f37d0070309a4934d6ed9b33f0b0, + 0x233bcf9bd44ecc5ecb3863f7096bcb4e4baf2b1f12374e47237f5c77b94c42d0, + 0x1fabe9b214fd503af962ab1cc1b973c53e57b59868949e675381ad36e67fd209, + 0x6730eee288e5f03a35f95f0481483eefe40a635a3ead5ac2b34571879ef0311 + ), + line_fn_from_u256( + 0x1670a12446b68764cbf216773bc9c7b390d04e9bb48e17869133184825f3178a, + 0x1fb4045266b6146a7f5ee2a7957459c2cad7392a4d5089380b2bbb855604168d, + 0x26fecd4849b30f2294bb31e67f99a1049a0af39990c705940ba8dc18c289fb29, + 0x1eba8ab976f2268f79127fbc64bd636237be0df81923e0945d5e1d63cab633bc + ), + line_fn_from_u256( + 0x11e0936d1938a7ab9739f41241833d61f8c1cdeab7171b6071aac03eae8d5663, + 0x279bd36a425b1eccfa54bed2525c7e919732b5bb7f7f9885348924cb32081d18, + 0x1c0df502f251ff2cb52a9f5ed65d9d9a16ef7818863691735aab7dc4940bdb53, + 0x21a55c132c893a8371303ba45c36dfc2398077f6d0b93d7cc1e8e4b9e213a0f5 + ), + line_fn_from_u256( + 0x2d9619066fdc7286cafc1a0674bfa7f29d0df1c01f0600f7cfb8a8a8b1994bb6, + 0x24413483fdd89db80c2897b792fc8b2bcb83b9d63f612366ea6a71913030140e, + 0x12ae159bd5945bfc0b49bbed14ef6262e82f260554d346d7221010e81a72c0fd, + 0x300a8ff0e12500cc88d99268ef4fbe79d748c81249b7ee8ec23b2d14fecf83b3 + ), + line_fn_from_u256( + 0xeee4503a6488ec0000530687efbd8b23b2b0146a602806a2090f68f7376374f, + 0x9d9c0b9464e2fe1aba008237f6ea0321f3110de83d28ab21bf96a39b4f18e13, + 0x2c24a32ad9ace2b3b37daa5db24520043d44844b7de09a7a3f617fffe6acbeb7, + 0x117814eba0ad7a565bfad052f3e88948f1ea639ac303fbd440db53a626eaf673 + ), + line_fn_from_u256( + 0xe264bdd6b983b57919bf4e0a18f77241c87b0df13cdbcfd481fad56ac812508, + 0x239e35df6fec7ad92fe5d0e43b7af8cbd3e7a26ff4ba133a39a2382527dd4ab9, + 0x145737cffd1d4d6d73aa49d216cdbd6a66207ba9da13e852081f79e5dc69e756, + 0xc810a220da9929013580fdd85308728f82768f70c0dbfd873fd6e9c8dc00c0f + ), + line_fn_from_u256( + 0x26c0c160bb1555e6601d253877806c709a5eb8e025cb4c397c29b47ab6747e74, + 0x16e1f4a0bc339441296d6b799c67393dd36e0aa465e4684befb98e3ccfa65d09, + 0x2e55f06a2c4bbdb5bcd95eb84e103bc033106e446ae8d1d433fed7e1b00fb186, + 0x110b6bf7aa4504e2074022b43798abb38bf91128d3794ac6f17fc27d52cb5cee + ), + line_fn_from_u256( + 0x1c419aa8711d1cb7d99f84b7e060878ab95a167078a199208f3b41269dd33c0d, + 0x62e69133bbbbb8184b5f07123810ad71b7450a7acaa5d1200ba6ff68d8b00ff, + 0x6deae6a1cd4b591a44fc130a5157fa857f2d3d7f351d6665fa3e06d1f69273b, + 0x2b2ceb0180b352259730fe0aa86f1b4c011c0de543063099502fdc53507d1c65 + ), + line_fn_from_u256( + 0x2256ae0b565783e3ab7db1558b5b4b8209d590e9a92ccff1b3b0b178f379bf78, + 0x11eb3d2fe46c7a044e943434e35db8bb839777d0220f48e9e6c061d7a681f0c6, + 0x116dfe7a9908288f97c2ec5062554bd4d06d55234cd98b7e94d324ef000aac90, + 0xcaca4f32705b46572d58a6b0a89e36b122ac0d5e02ab65e87beb0a4d7266e8d + ), + line_fn_from_u256( + 0x23fb087072caccebd6a2956c5579e525cde63a01ec900b2c1cc43d629542dc2a, + 0x1b2782d0db0fc4fb031cc81ccacf0a368070358262c6694898955ea21bdd3251, + 0x4be4f20eec5e85102507d1d5cff72ca6b8add52615305b9e0f4ec27fe62245c, + 0x21c8fb29b262a0c4a1b2a6230c7d1a2841a9c01caa9298f0637a542859584afe + ), + line_fn_from_u256( + 0x2bd57fac8dbf72e2f8c05b098d0dd4abbfa3088bc03bf105dffe2c9abd31b397, + 0x26c49dd7fb2012b0a58f6f24f6aaa19c522d5deb9b5ed8ead8c9bfff7ec7133d, + 0x25d2833eff89b609db9fcae0560a2167ed1dd0e3d575507f2c663ea0994c1344, + 0x290f67e7f95b1d325782cac844fdc2dfd6859692566b43ecfdc927497cabd5cf + ), + line_fn_from_u256( + 0xe1c1f9fbae157d9f585b116eec368728284f0319fcbec540957a616da2cdf52, + 0x12d7b3a59f40c36a81a8d014fc888e3d51727090b9b62d212b3feb196c5aa366, + 0x1ef2731936e5ff492cb4412653bd67b2838d556a5dc41925329f42f09c28e1db, + 0x2a3c08fd3a527218408f8998a19df8de4fee00d3c855e0af355d8c23089cfac8 + ), + line_fn_from_u256( + 0x109c36d195cddf609884bbd2afcd1a5bfa125dbb7c5b77e8540e02a354fc7690, + 0xec64849b7cf17616115a08a0291909d58cd752dbb4d517aca4d8835349d98ab, + 0xc1eba49ce4a00e8ba655703630486efa602359a72ebf29ea5fc1d51ecb43800, + 0x3fa906df251eee2a18a633d6e5714810f5fac53ab9e8ac2aedc61858ef01346 + ), + line_fn_from_u256( + 0x28df92a107e08d0140fa05e64f0de78abfc1410ecdbcd905ca8c428503f0ca2e, + 0x16169a7e5714d3f8739f2fdb157c1bfc58098a947451eee154dca4eef2581599, + 0xd324e46a8af58939227a7d78df1a531b49627fbb9647ea715594faa6d2f9e04, + 0xe12b7ed2ad6e5b6a09ca228f15af6c1b22ca69fa1b2af3b8362febb66041101 + ), + line_fn_from_u256( + 0x3d737fdf2648537e0c9c3bbad97a59aeb955fcaa490cc99b350ccea848f79d5, + 0x2e357f1afd5603c08606e3fb00279b240cefb466c19e4b4abf997a63659a904c, + 0x9dcaeda77448a6d8050db07fea9905c549e2b16cf9f2edb77bdcc316dd510fb, + 0x197c0ceb01342a608dc0eb548deae4fecde86f24be97d812980145737267539f + ), + line_fn_from_u256( + 0x22de9f81522e72d34ff54093b4062fa54fc76150097b65e26a25308b29028bbe, + 0x2451bc1124b8b6b80e3d890005fadf817f35a727276b17630c3af600aec1c7ae, + 0x1ac9c92a310afe9d235ba1706ea9bb5e32776055baec7887ffc22c9a792a4ed1, + 0xb6fef3ebc42e3d4ca4248c45205b73cfedf57f5e990d88ae1af1e8a6efdcb64 + ), + line_fn_from_u256( + 0xbe07459780f6a75f8afd124d26f63d3e514a02963c8324eb0ad6b096d22ae51, + 0x1b49bfa5f2b8060569ccfe40a501bc5afbfcd2abae95246d7b8dd8c5668176e2, + 0x1331c2d38c032da3a9fa3659100c5c3e31a599a7809fde679dfc2a5e75a36545, + 0x124c0502033c3162c8bd88ec5111681834f5f21cc1668c3b9630879d8554283b + ), + line_fn_from_u256( + 0xd6fbc7dfbbca1db00dd8704fc3e517862fddeb55f22011d081c8f6f290e54c, + 0x20656b2a9cc50290f76e52a5a8029f24ace3b0b1238677e0742fc367f6ff2eed, + 0x135c0cd040f32ceb48e06a05f2ff10b130c73ad9d2d35dc26d4a9431aa54ff88, + 0x15ad031688735dbf1f513d8987000c008c399c96011e8aaa097b62e3e789ee35 + ), + ] + } + + #[storage] + struct Storage {} + + #[constructor] + fn constructor(ref self: ContractState) {} + + fn proof_hash(pi_a: AffineG1, pi_b: AffineG2, pi_c: AffineG1,) -> felt252 { + let mut hasher = core::poseidon::PoseidonImpl::new(); + hasher = hasher.update(pi_a.x.c0.low.into()); + hasher = hasher.update(pi_a.x.c0.high.into()); + hasher = hasher.update(pi_a.y.c0.low.into()); + hasher = hasher.update(pi_a.y.c0.high.into()); + + hasher = hasher.update(pi_b.x.c0.c0.low.into()); + hasher = hasher.update(pi_b.x.c0.c0.high.into()); + hasher = hasher.update(pi_b.x.c1.c0.low.into()); + hasher = hasher.update(pi_b.x.c1.c0.high.into()); + hasher = hasher.update(pi_b.y.c0.c0.low.into()); + hasher = hasher.update(pi_b.y.c0.c0.high.into()); + hasher = hasher.update(pi_b.y.c1.c0.low.into()); + hasher = hasher.update(pi_b.y.c1.c0.high.into()); + + hasher = hasher.update(pi_c.x.c0.low.into()); + hasher = hasher.update(pi_c.x.c0.high.into()); + hasher = hasher.update(pi_c.y.c0.low.into()); + hasher = hasher.update(pi_c.y.c0.high.into()); + + hasher.finalize() + } + + #[abi(embed_v0)] + impl Groth16 of super::IGroth16 { + fn verify( + ref self: ContractState, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: Fq6 + ) {} + fn verify1( + ref self: ContractState, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: Fq6 + ) {} + fn verify2( + ref self: ContractState, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: Fq6 + ) {} + } +} diff --git a/bn_contracts/src/lib.cairo b/packages/bn_contracts/src/lib.cairo similarity index 100% rename from bn_contracts/src/lib.cairo rename to packages/bn_contracts/src/lib.cairo diff --git a/packages/bn_contracts/src/schzipv2_contract.cairo b/packages/bn_contracts/src/schzipv2_contract.cairo new file mode 100644 index 0000000..bc2349e --- /dev/null +++ b/packages/bn_contracts/src/schzipv2_contract.cairo @@ -0,0 +1,156 @@ +use bn::g::{AffineG1, AffineG2,}; +use bn::groth16::utils::{ICProcess, G16CircuitSetup, LinesArray}; +use fields::{Fq12}; +use bn::curve::residue_witness::{CubicScale}; + +#[starknet::interface] +trait SchZipGro16 { + fn verify( + ref self: TConSta, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: CubicScale, + setup: G16CircuitSetup, + coefficients: Array, + ); +// fn verify_preset( +// ref self: TConSta, +// pi_a: AffineG1, +// pi_b: AffineG2, +// pi_c: AffineG1, +// inputs: Array, +// residue_witness: Fq12, +// residue_witness_inv: Fq12, +// cubic_scale: CubicScale, +// coefficients: Array, +// ); +} + +#[starknet::contract] +mod schzipgro16_contract { + use bn::g::{AffineG1, AffineG2,}; + use bn::groth16::utils::{ICProcess, G16CircuitSetup, LinesArray}; + use fields::{Fq12}; + use bn::curve::residue_witness::{CubicScale}; + use bn::groth16::schzip::schzip_verify_with_commitments; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl SchZipGro16Impl of super::SchZipGro16 { + fn verify( + ref self: ContractState, + pi_a: AffineG1, + pi_b: AffineG2, + pi_c: AffineG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: CubicScale, + setup: G16CircuitSetup, + coefficients: Array, + ) { + schzip_verify_with_commitments( + pi_a, + pi_b, + pi_c, + inputs, + residue_witness, + residue_witness_inv, + cubic_scale, + setup, + coefficients + ); + } + // fn verify_preset( + // ref self: ContractState, + // pi_a: AffineG1, + // pi_b: AffineG2, + // pi_c: AffineG1, + // inputs: Array, + // residue_witness: Fq12, + // residue_witness_inv: Fq12, + // cubic_scale: CubicScale, + // coefficients: Array, + // ) { + // schzip_verify_with_commitments( + // pi_a, + // pi_b, + // pi_c, + // inputs, + // residue_witness, + // residue_witness_inv, + // cubic_scale, + // fixture::circuit_setup(), + // coefficients + // ); + // } + } +} + +#[starknet::interface] +trait SchZipGro16Bench { + fn verify(ref self: TConSta) -> bool; +} + +#[starknet::contract] +mod schzipgro16_bench_contract { + use bn::g::{AffineG1, AffineG2,}; + use bn::groth16::utils::{ICProcess, G16CircuitSetup, LinesArray}; + use fields::{Fq12}; + use bn::curve::residue_witness::{CubicScale}; + use bn::groth16::schzip::schzip_verify_with_commitments; + use bn::groth16::fixture; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl SchZipGro16Impl of super::SchZipGro16Bench { + fn verify(ref self: ContractState) -> bool { + let (pi_a, pi_b, pi_c, pub_input, _) = fixture::proof(); + let (_, residue_witness, residue_witness_inv, _, cubic_scl) = + fixture::residue_witness(); + + schzip_verify_with_commitments( + pi_a, + pi_b, + pi_c, + array![pub_input], + residue_witness, + residue_witness_inv, + cubic_scl, + fixture::circuit_setup(), + fixture::schzip() + ) + } + // fn verify_preset( + // ref self: ContractState, + // pi_a: AffineG1, + // pi_b: AffineG2, + // pi_c: AffineG1, + // inputs: Array, + // residue_witness: Fq12, + // residue_witness_inv: Fq12, + // cubic_scale: CubicScale, + // coefficients: Array, + // ) { + // schzip_verify_with_commitments( + // pi_a, + // pi_b, + // pi_c, + // inputs, + // residue_witness, + // residue_witness_inv, + // cubic_scale, + // fixture::circuit_setup(), + // coefficients + // ); + // } + } +} diff --git a/packages/bn_legacy/Scarb.toml b/packages/bn_legacy/Scarb.toml new file mode 100644 index 0000000..7182cfd --- /dev/null +++ b/packages/bn_legacy/Scarb.toml @@ -0,0 +1,7 @@ +[package] +name = "bn" +version = "0.1.0" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] diff --git a/src/bench.cairo b/packages/bn_legacy/src/bench.cairo similarity index 100% rename from src/bench.cairo rename to packages/bn_legacy/src/bench.cairo diff --git a/src/bench/curve.cairo b/packages/bn_legacy/src/bench/curve.cairo similarity index 100% rename from src/bench/curve.cairo rename to packages/bn_legacy/src/bench/curve.cairo diff --git a/src/bench/fq01.cairo b/packages/bn_legacy/src/bench/fq01.cairo similarity index 100% rename from src/bench/fq01.cairo rename to packages/bn_legacy/src/bench/fq01.cairo diff --git a/src/bench/fq02.cairo b/packages/bn_legacy/src/bench/fq02.cairo similarity index 100% rename from src/bench/fq02.cairo rename to packages/bn_legacy/src/bench/fq02.cairo diff --git a/src/bench/fq06.cairo b/packages/bn_legacy/src/bench/fq06.cairo similarity index 100% rename from src/bench/fq06.cairo rename to packages/bn_legacy/src/bench/fq06.cairo diff --git a/src/bench/fq12.cairo b/packages/bn_legacy/src/bench/fq12.cairo similarity index 100% rename from src/bench/fq12.cairo rename to packages/bn_legacy/src/bench/fq12.cairo diff --git a/src/bench/sprs.cairo b/packages/bn_legacy/src/bench/sprs.cairo similarity index 100% rename from src/bench/sprs.cairo rename to packages/bn_legacy/src/bench/sprs.cairo diff --git a/src/bench/u512.cairo b/packages/bn_legacy/src/bench/u512.cairo similarity index 100% rename from src/bench/u512.cairo rename to packages/bn_legacy/src/bench/u512.cairo diff --git a/src/curve.cairo b/packages/bn_legacy/src/curve.cairo similarity index 100% rename from src/curve.cairo rename to packages/bn_legacy/src/curve.cairo diff --git a/src/curve/constants.cairo b/packages/bn_legacy/src/curve/constants.cairo similarity index 100% rename from src/curve/constants.cairo rename to packages/bn_legacy/src/curve/constants.cairo diff --git a/src/curve/groups.cairo b/packages/bn_legacy/src/curve/groups.cairo similarity index 100% rename from src/curve/groups.cairo rename to packages/bn_legacy/src/curve/groups.cairo diff --git a/src/curve/groups_tests.cairo b/packages/bn_legacy/src/curve/groups_tests.cairo similarity index 100% rename from src/curve/groups_tests.cairo rename to packages/bn_legacy/src/curve/groups_tests.cairo diff --git a/src/curve/pairing/ate_tests.cairo b/packages/bn_legacy/src/curve/pairing/ate_tests.cairo similarity index 100% rename from src/curve/pairing/ate_tests.cairo rename to packages/bn_legacy/src/curve/pairing/ate_tests.cairo diff --git a/src/curve/pairing/miller_utils.cairo b/packages/bn_legacy/src/curve/pairing/miller_utils.cairo similarity index 100% rename from src/curve/pairing/miller_utils.cairo rename to packages/bn_legacy/src/curve/pairing/miller_utils.cairo diff --git a/src/curve/pairing/optimal_ate.cairo b/packages/bn_legacy/src/curve/pairing/optimal_ate.cairo similarity index 100% rename from src/curve/pairing/optimal_ate.cairo rename to packages/bn_legacy/src/curve/pairing/optimal_ate.cairo diff --git a/src/curve/pairing/optimal_ate_impls.cairo b/packages/bn_legacy/src/curve/pairing/optimal_ate_impls.cairo similarity index 100% rename from src/curve/pairing/optimal_ate_impls.cairo rename to packages/bn_legacy/src/curve/pairing/optimal_ate_impls.cairo diff --git a/src/curve/pairing/optimal_ate_utils.cairo b/packages/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo similarity index 100% rename from src/curve/pairing/optimal_ate_utils.cairo rename to packages/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo diff --git a/src/curve/pairing/tate_bkls.cairo b/packages/bn_legacy/src/curve/pairing/tate_bkls.cairo similarity index 100% rename from src/curve/pairing/tate_bkls.cairo rename to packages/bn_legacy/src/curve/pairing/tate_bkls.cairo diff --git a/src/curve/pairing/tests.cairo b/packages/bn_legacy/src/curve/pairing/tests.cairo similarity index 100% rename from src/curve/pairing/tests.cairo rename to packages/bn_legacy/src/curve/pairing/tests.cairo diff --git a/src/curve/residue_witness.cairo b/packages/bn_legacy/src/curve/residue_witness.cairo similarity index 100% rename from src/curve/residue_witness.cairo rename to packages/bn_legacy/src/curve/residue_witness.cairo diff --git a/src/fields/fq_1.cairo b/packages/bn_legacy/src/fields/fq_1.cairo similarity index 100% rename from src/fields/fq_1.cairo rename to packages/bn_legacy/src/fields/fq_1.cairo diff --git a/src/fields/fq_12.cairo b/packages/bn_legacy/src/fields/fq_12.cairo similarity index 100% rename from src/fields/fq_12.cairo rename to packages/bn_legacy/src/fields/fq_12.cairo diff --git a/src/fields/fq_12_direct.cairo b/packages/bn_legacy/src/fields/fq_12_direct.cairo similarity index 100% rename from src/fields/fq_12_direct.cairo rename to packages/bn_legacy/src/fields/fq_12_direct.cairo diff --git a/src/fields/fq_12_exponentiation.cairo b/packages/bn_legacy/src/fields/fq_12_exponentiation.cairo similarity index 100% rename from src/fields/fq_12_exponentiation.cairo rename to packages/bn_legacy/src/fields/fq_12_exponentiation.cairo diff --git a/src/fields/fq_12_squaring.cairo b/packages/bn_legacy/src/fields/fq_12_squaring.cairo similarity index 100% rename from src/fields/fq_12_squaring.cairo rename to packages/bn_legacy/src/fields/fq_12_squaring.cairo diff --git a/src/fields/fq_2.cairo b/packages/bn_legacy/src/fields/fq_2.cairo similarity index 100% rename from src/fields/fq_2.cairo rename to packages/bn_legacy/src/fields/fq_2.cairo diff --git a/src/fields/fq_6.cairo b/packages/bn_legacy/src/fields/fq_6.cairo similarity index 100% rename from src/fields/fq_6.cairo rename to packages/bn_legacy/src/fields/fq_6.cairo diff --git a/src/fields/fq_generics.cairo b/packages/bn_legacy/src/fields/fq_generics.cairo similarity index 100% rename from src/fields/fq_generics.cairo rename to packages/bn_legacy/src/fields/fq_generics.cairo diff --git a/src/fields/fq_sparse.cairo b/packages/bn_legacy/src/fields/fq_sparse.cairo similarity index 100% rename from src/fields/fq_sparse.cairo rename to packages/bn_legacy/src/fields/fq_sparse.cairo diff --git a/src/fields/frobenius.cairo b/packages/bn_legacy/src/fields/frobenius.cairo similarity index 100% rename from src/fields/frobenius.cairo rename to packages/bn_legacy/src/fields/frobenius.cairo diff --git a/src/fields/print.cairo b/packages/bn_legacy/src/fields/print.cairo similarity index 100% rename from src/fields/print.cairo rename to packages/bn_legacy/src/fields/print.cairo diff --git a/src/fields/tests/fq.cairo b/packages/bn_legacy/src/fields/tests/fq.cairo similarity index 100% rename from src/fields/tests/fq.cairo rename to packages/bn_legacy/src/fields/tests/fq.cairo diff --git a/src/fields/tests/fq12.cairo b/packages/bn_legacy/src/fields/tests/fq12.cairo similarity index 100% rename from src/fields/tests/fq12.cairo rename to packages/bn_legacy/src/fields/tests/fq12.cairo diff --git a/src/fields/tests/fq12_expo.cairo b/packages/bn_legacy/src/fields/tests/fq12_expo.cairo similarity index 100% rename from src/fields/tests/fq12_expo.cairo rename to packages/bn_legacy/src/fields/tests/fq12_expo.cairo diff --git a/src/fields/tests/fq2.cairo b/packages/bn_legacy/src/fields/tests/fq2.cairo similarity index 100% rename from src/fields/tests/fq2.cairo rename to packages/bn_legacy/src/fields/tests/fq2.cairo diff --git a/src/fields/tests/fq6.cairo b/packages/bn_legacy/src/fields/tests/fq6.cairo similarity index 100% rename from src/fields/tests/fq6.cairo rename to packages/bn_legacy/src/fields/tests/fq6.cairo diff --git a/src/fields/tests/fq_sparse.cairo b/packages/bn_legacy/src/fields/tests/fq_sparse.cairo similarity index 100% rename from src/fields/tests/fq_sparse.cairo rename to packages/bn_legacy/src/fields/tests/fq_sparse.cairo diff --git a/src/fields/tests/frobenius.cairo b/packages/bn_legacy/src/fields/tests/frobenius.cairo similarity index 100% rename from src/fields/tests/frobenius.cairo rename to packages/bn_legacy/src/fields/tests/frobenius.cairo diff --git a/src/fields/tests/u512.cairo b/packages/bn_legacy/src/fields/tests/u512.cairo similarity index 100% rename from src/fields/tests/u512.cairo rename to packages/bn_legacy/src/fields/tests/u512.cairo diff --git a/src/groth16/fixture.cairo b/packages/bn_legacy/src/groth16/fixture.cairo similarity index 100% rename from src/groth16/fixture.cairo rename to packages/bn_legacy/src/groth16/fixture.cairo diff --git a/src/groth16/fixture/groth16.cairo b/packages/bn_legacy/src/groth16/fixture/groth16.cairo similarity index 100% rename from src/groth16/fixture/groth16.cairo rename to packages/bn_legacy/src/groth16/fixture/groth16.cairo diff --git a/src/groth16/fixture/lines.cairo b/packages/bn_legacy/src/groth16/fixture/lines.cairo similarity index 100% rename from src/groth16/fixture/lines.cairo rename to packages/bn_legacy/src/groth16/fixture/lines.cairo diff --git a/src/groth16/fixture/schzip_v1.cairo b/packages/bn_legacy/src/groth16/fixture/schzip_v1.cairo similarity index 100% rename from src/groth16/fixture/schzip_v1.cairo rename to packages/bn_legacy/src/groth16/fixture/schzip_v1.cairo diff --git a/src/groth16/fixture/schzip_v2.cairo b/packages/bn_legacy/src/groth16/fixture/schzip_v2.cairo similarity index 100% rename from src/groth16/fixture/schzip_v2.cairo rename to packages/bn_legacy/src/groth16/fixture/schzip_v2.cairo diff --git a/src/groth16/fixture/tests.cairo b/packages/bn_legacy/src/groth16/fixture/tests.cairo similarity index 100% rename from src/groth16/fixture/tests.cairo rename to packages/bn_legacy/src/groth16/fixture/tests.cairo diff --git a/src/groth16/schzip.cairo b/packages/bn_legacy/src/groth16/schzip.cairo similarity index 100% rename from src/groth16/schzip.cairo rename to packages/bn_legacy/src/groth16/schzip.cairo diff --git a/src/groth16/schzip/base.cairo b/packages/bn_legacy/src/groth16/schzip/base.cairo similarity index 100% rename from src/groth16/schzip/base.cairo rename to packages/bn_legacy/src/groth16/schzip/base.cairo diff --git a/src/groth16/schzip/eval.cairo b/packages/bn_legacy/src/groth16/schzip/eval.cairo similarity index 100% rename from src/groth16/schzip/eval.cairo rename to packages/bn_legacy/src/groth16/schzip/eval.cairo diff --git a/src/groth16/schzip/tests.cairo b/packages/bn_legacy/src/groth16/schzip/tests.cairo similarity index 100% rename from src/groth16/schzip/tests.cairo rename to packages/bn_legacy/src/groth16/schzip/tests.cairo diff --git a/src/groth16/schzip/utils.cairo b/packages/bn_legacy/src/groth16/schzip/utils.cairo similarity index 100% rename from src/groth16/schzip/utils.cairo rename to packages/bn_legacy/src/groth16/schzip/utils.cairo diff --git a/src/groth16/schzip/v1.cairo b/packages/bn_legacy/src/groth16/schzip/v1.cairo similarity index 99% rename from src/groth16/schzip/v1.cairo rename to packages/bn_legacy/src/groth16/schzip/v1.cairo index 2c77d1f..126951c 100644 --- a/src/groth16/schzip/v1.cairo +++ b/packages/bn_legacy/src/groth16/schzip/v1.cairo @@ -336,7 +336,7 @@ pub impl SchZipPolyCommitImpl of SchZipSteps { residue_inv.frob3(), cubic_scale, f_nz - ); + ) } } diff --git a/src/groth16/setup.cairo b/packages/bn_legacy/src/groth16/setup.cairo similarity index 100% rename from src/groth16/setup.cairo rename to packages/bn_legacy/src/groth16/setup.cairo diff --git a/src/groth16/tests.cairo b/packages/bn_legacy/src/groth16/tests.cairo similarity index 100% rename from src/groth16/tests.cairo rename to packages/bn_legacy/src/groth16/tests.cairo diff --git a/src/groth16/utils.cairo b/packages/bn_legacy/src/groth16/utils.cairo similarity index 100% rename from src/groth16/utils.cairo rename to packages/bn_legacy/src/groth16/utils.cairo diff --git a/src/groth16/utils_line.cairo b/packages/bn_legacy/src/groth16/utils_line.cairo similarity index 100% rename from src/groth16/utils_line.cairo rename to packages/bn_legacy/src/groth16/utils_line.cairo diff --git a/src/groth16/verifier.cairo b/packages/bn_legacy/src/groth16/verifier.cairo similarity index 100% rename from src/groth16/verifier.cairo rename to packages/bn_legacy/src/groth16/verifier.cairo diff --git a/src/lib.cairo b/packages/bn_legacy/src/lib.cairo similarity index 100% rename from src/lib.cairo rename to packages/bn_legacy/src/lib.cairo diff --git a/src/math/fast_mod.cairo b/packages/bn_legacy/src/math/fast_mod.cairo similarity index 100% rename from src/math/fast_mod.cairo rename to packages/bn_legacy/src/math/fast_mod.cairo diff --git a/src/math/fast_mod/add_sub.cairo b/packages/bn_legacy/src/math/fast_mod/add_sub.cairo similarity index 100% rename from src/math/fast_mod/add_sub.cairo rename to packages/bn_legacy/src/math/fast_mod/add_sub.cairo diff --git a/src/math/fast_mod/div_inv.cairo b/packages/bn_legacy/src/math/fast_mod/div_inv.cairo similarity index 100% rename from src/math/fast_mod/div_inv.cairo rename to packages/bn_legacy/src/math/fast_mod/div_inv.cairo diff --git a/src/math/fast_mod/mul_scale_sqr.cairo b/packages/bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo similarity index 100% rename from src/math/fast_mod/mul_scale_sqr.cairo rename to packages/bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo diff --git a/src/math/fast_mod/u512_ops.cairo b/packages/bn_legacy/src/math/fast_mod/u512_ops.cairo similarity index 100% rename from src/math/fast_mod/u512_ops.cairo rename to packages/bn_legacy/src/math/fast_mod/u512_ops.cairo diff --git a/src/math/fast_mod/utils.cairo b/packages/bn_legacy/src/math/fast_mod/utils.cairo similarity index 100% rename from src/math/fast_mod/utils.cairo rename to packages/bn_legacy/src/math/fast_mod/utils.cairo diff --git a/src/math/fast_mod_tests.cairo b/packages/bn_legacy/src/math/fast_mod_tests.cairo similarity index 100% rename from src/math/fast_mod_tests.cairo rename to packages/bn_legacy/src/math/fast_mod_tests.cairo diff --git a/src/math/i257.cairo b/packages/bn_legacy/src/math/i257.cairo similarity index 100% rename from src/math/i257.cairo rename to packages/bn_legacy/src/math/i257.cairo diff --git a/src/playground.cairo b/packages/bn_legacy/src/playground.cairo similarity index 100% rename from src/playground.cairo rename to packages/bn_legacy/src/playground.cairo diff --git a/src/tests.cairo b/packages/bn_legacy/src/tests.cairo similarity index 100% rename from src/tests.cairo rename to packages/bn_legacy/src/tests.cairo diff --git a/src/tests_tate.cairo b/packages/bn_legacy/src/tests_tate.cairo similarity index 100% rename from src/tests_tate.cairo rename to packages/bn_legacy/src/tests_tate.cairo diff --git a/src/traits.cairo b/packages/bn_legacy/src/traits.cairo similarity index 100% rename from src/traits.cairo rename to packages/bn_legacy/src/traits.cairo diff --git a/scripts/residue_witness_bls381.py b/scripts/residue_witness_bls381.py new file mode 100644 index 0000000..14d2a07 --- /dev/null +++ b/scripts/residue_witness_bls381.py @@ -0,0 +1,249 @@ +# This script follows paper 'On Proving Pairings' - https://eprint.iacr.org/2024/640 +# to generate residue witness for the final exponentiation. + +# From 2.1 Eliminating the Final Exponentiation, +# Two elements x, y ∈ F are equivalent if there exists some c such that x * c**r = y +# Our optimization avoids this cost by instead providing c as auxiliary input and +# directly checking xcr = y. In this way we replace an exponentiation by (q**k − 1)/r +# with an exponentiation by r, which in general is much cheaper. + + +# from py_ecc import bn128, fields +# from py_ecc.bn128 import bn128_curve; +from py_ecc.fields import ( + bls12_381_FQ12 as FQ12, +) + + +def print_fq12(name: str, f: FQ12): + fq_hex = [hex(c) for c in direct_to_tower([c.__int__() for c in f.coeffs])] + print("\n{} fq12(\n\t{}\n)\n".format(name, ",\n\t".join(fq_hex))) + + +# The library we use here, py_ecc uses direct field extensions +# But Cairo implementation uses tower field extensions +# Utils for direct extension and tower extension conversions +# https://gist.github.com/feltroidprime/bd31ab8e0cbc0bf8cd952c8b8ed55bf5 +def tower_to_direct(x: list[int]): + p = q + res = 12 * [0] + res[0] = (x[0] - 9 * x[1]) % p + res[1] = (x[6] - 9 * x[7]) % p + res[2] = (x[2] - 9 * x[3]) % p + res[3] = (x[8] - 9 * x[9]) % p + res[4] = (x[4] - 9 * x[5]) % p + res[5] = (x[10] - 9 * x[11]) % p + res[6] = x[1] + res[7] = x[7] + res[8] = x[3] + res[9] = x[9] + res[10] = x[5] + res[11] = x[11] + return res + + +def direct_to_tower(x: list[int]): + p = q + res = 12 * [0] + res[0] = (x[0] + 9 * x[6]) % p + res[1] = x[6] + res[2] = (x[2] + 9 * x[8]) % p + res[3] = x[8] + res[4] = (x[4] + 9 * x[10]) % p + res[5] = x[10] + res[6] = (x[1] + 9 * x[7]) % p + res[7] = x[7] + res[8] = (x[3] + 9 * x[9]) % p + res[9] = x[9] + res[10] = (x[5] + 9 * x[11]) % p + res[11] = x[11] + return res + + +# Section 4.3 Computing Residue Witness for the BN254 curve + +# bn254 curve properties from https://hackmd.io/@jpw/bn254 +q = 21888242871839275222246405745257275088696311157297823662689037894645226208583 +x = 4965661367192848881 +r = 21888242871839275222246405745257275088548364400416034343698204186575808495617 +q12 = q**12 +# (q**12 - 1) is the exponent of the final exponentiation + +# Section 4.3.1 Parameters + +h = (q12 - 1) // r # = 3^3 · l # where gcd(l, 3) = 1 +l = h // (3**3) +λ = 6 * x + 2 + q - q**2 + q**3 +m = λ // r +d = 3 # = gcd(m, h) +m_dash = m // d # m' = m/d + +# equivalently, λ = 3rm′. +assert 3 * r * m_dash == λ, "incorrect parameters" # sanity check + +# precompute r' and m'' + +r_inv = 495819184011867778744231927046742333492451180917315223017345540833046880485481720031136878341141903241966521818658471092566752321606779256340158678675679238405722886654128392203338228575623261160538734808887996935946888297414610216445334190959815200956855428635568184508263913274453942864817234480763055154719338281461936129150171789463489422401982681230261920147923652438266934726901346095892093443898852488218812468761027620988447655860644584419583586883569984588067403598284748297179498734419889699245081714359110559679136004228878808158639412436468707589339209058958785568729925402190575720856279605832146553573981587948304340677613460685405477047119496887534881410757668344088436651291444274840864486870663164657544390995506448087189408281061890434467956047582679858345583941396130713046072603335601764495918026585155498301896749919393 +assert r_inv * r % h == 1, "r_inv should be the inverse of r" +m_d_inv = 17840267520054779749190587238017784600702972825655245554504342129614427201836516118803396948809179149954197175783449826546445899524065131269177708416982407215963288737761615699967145070776364294542559324079147363363059480104341231360692143673915822421222230661528586799190306058519400019024762424366780736540525310403098758015600523609594113357130678138304964034267260758692953579514899054295817541844330584721967571697039986079722203518034173581264955381924826388858518077894154909963532054519350571947910625755075099598588672669612434444513251495355121627496067454526862754597351094345783576387352673894873931328099247263766690688395096280633426669535619271711975898132416216382905928886703963310231865346128293216316379527200971959980873989485521004596686352787540034457467115536116148612884807380187255514888720048664139404687086409399 +assert m_d_inv * m_dash % h == 1, "r_inv should be the inverse of r" + +f = tower_to_direct( + [ + 0x1BF4E21820E6CC2B2DBC9453733A8D7C48F05E73F90ECC8BDD80505D2D3B1715, + 0x264F54F6B719920C4AC00AAFB3DF29CC8A9DDC25E264BDEE1ADE5E36077D58D7, + 0xDB269E3CD7ED27D825BCBAAEFB01023CF9B17BEED6092F7B96EAB87B571F3FE, + 0x25CE534442EE86A32C46B56D2BF289A0BE5F8703FB05C260B2CB820F2B253CF, + 0x33FC62C521F4FFDCB362B12220DB6C57F487906C0DAF4DC9BA736F882A420E1, + 0xE8B074995703E92A7B9568C90AE160E4D5B81AFFE628DC1D790241DE43D00D0, + 0x84E35BD0EEA3430B350041D235BB394E338E3A9ED2F0A9A1BA7FE786D391DE1, + 0x244D38253DA236F714CB763ABF68F7829EE631B4CC5EDE89B382E518D676D992, + 0x1EE0A098B62C76A9EBDF4D76C8DFC1586E3FCB6A01712CBDA8D10D07B32C5AF4, + 0xD23AEB23ACACF931F02ECA9ECEEE31EE9607EC003FF934694119A9C6CFFC4BD, + 0x16558217BB9B1BCDA995B123619808719CB8A282A190630E6D06D7D03E6333CA, + 0x14354C051802F8704939C9948EF91D89DB28FE9513AD7BBF58A4639AF347EA86, + ] +) +f = FQ12(f) + +# print("Should be one", f**h) + +# Section 4.3.2 Finding c +# find some u a cubic non-residue and c such that f = c**λ * u. + +# 1. Compute r-th root +# 2. Compute m′-th root +# 3. Compute cubic root + +unity = FQ12([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + +root_27th = FQ12( + tower_to_direct( + [ + 0, + 0, + 0, + 0, + 8204864362109909869166472767738877274689483185363591877943943203703805152849, + 17912368812864921115467448876996876278487602260484145953989158612875588124088, + 0, + 0, + 0, + 0, + 0, + 0, + ] + ) +) + +assert root_27th**27 == unity, "root_27th**27 should be one" +assert root_27th**9 != unity, "root_27th**9 should not be one" + + +def compute_exp_s(p: int) -> tuple[int, int]: + """ + Calculates the value of `s` given `p` such that `p - 1 = 3**r * s` and `3` does not divide `s`. + Input: + p: int - field size + + Output: + s, p: int, int + """ + s = p - 1 + r = 0 + while s % 3 == 0: + r += 1 + s //= 3 + return s, r + + +exp_s, exp_r = compute_exp_s(q12) +assert exp_s == 3**exp_r * l, "s should be 3**3 * l" + +exp = 0b1110001000001010101110000110000110011101100000001010110110111100110111000101011100001110111010110001010000111001001001010001100000011000110000000111000010110110110000111110000011010101011100101010100001001100010000100010001100110000100101101000101100000011000110001001110011010011000100010010100101000110001100110000100100101111010001101000101001011010011001100111110100111110101110101011101100001000110111001011010000001110001111111101111001010101111110100010010001011001111100100110010001011010000011110101001100010100000101110000110110101111001001000001110110111001110010001000110001110011101101101111010001010100000001111001100101101000011010111010001101110100010011110001010101101100101011111001001000110000011011101001010101100010110001011011010101001110010100100100000111011100001011110001000100101001111110110010100010100110010101111110000110001011101001111111110101101110100011101111000011101100111100110100100000101111001011001100000100100001101111010111001001100000110010110010000011001101100101110100001101011101010100011111001100101010110001110110101011101001010110001011100110011110110010100111001100111100101000100011110011001101111000111011001001001000000110011101110011101011000100111010100101110100111001000000011010010000110001100110111001001111001100000101001111000001110101110111000101010110111011110110110011101110000000001110000011101000010011110101001110101000100111100001010111101000010110010010110101001111100111101011000111100110001011001101000111011001000111100011110110011010010110110110010100100011111010100110011101100010001101111110100110001101001100010001110111000100000010001100001010000000000000011101100000010001001011001110001000011010100110111011100001001101100001110111101000001111000111110011001101010100100010101111110110111110011000101100010101011101000000101110010000111011001101101111101000101001011100111100011001110111010100110001110001111000110000000011110100111000110010110111001001111100011001111101111101101101111111110110010111100111000010000101011000000100010100101100001101110100111011001011100101000101111100000100001111100011011101010110110110111111101000010011001111001101010010111000001001010000000101000011001100101001000000011001110010000111001000110101010100111100011010010001010000000110110000000000101000001101101010100000001000001011101101001100011011000101110010100010111001010101011000111101100010001010101110111000101101100100011100110000111111100110101100000001110110111110101110100000111010111000001101001001101010100110111101010101100110111000000110000001011101001011101000111111100101011101110001100100011010010110010001001000100011010100100000111110010101111000101010001100001111101100000111110110010101110000000100110101001101011110001101100011111010100111001101111010100100101010101110111100011110010101111010100100000111100110101001000111101001110011110110001111011010101110011011101111110101100110110110010111101010001110100010011111100011010000110000111101101101111111100000100011100111110001110000111000100000010101000001101001100110001111010000110000111001011 +assert exp == exp_s, "exp incorrect" +print("EXP: ", exp_s, exp) + + +def pow_3_ord(a: FQ12): + t = 0 + while a != unity: + t += 1 + a = a**3 + return t + + +def find_cube_root(a: FQ12, w: FQ12) -> FQ12: + # Algorithm 4: Modified Tonelli-Shanks for cube roots + # Input: Cube residue a, cube non residue w and write p − 1 = 3^r · s such that 3 ∤ s + # Output: x such that x^3 = a + # 1 exp = (s + 1)/3 + a_inv = a.inv() # + # 2 x ← a^exp + x = a**exp + # 3 3^t ← ord((x^3)/a) + t = pow_3_ord(x**3 * a_inv) + # 4 while t != 0 do + while t != 0: + # 5 exp = (s + 1)/3 + # 6 x ← x · w^exp + x = x * w**exp + # 7 3^t ← ord(x^3/a) + t = pow_3_ord(x**3 * a_inv) + # 8 end + # 9 return x + return x + + +def find_c(f: FQ12, w: FQ12): + # Algorithm 5: Algorithm for computing λ residues over BN curve + # Input: Output of a Miller loop f and fixed 27-th root of unity w + # Output: (c, wi) such that c**λ = f · wi + # 1 s = 0 + s = 0 + exp = (q12 - 1) // 3 + # 2 if f**(q**k-1)/3 = 1 then + if f**exp == unity: + # 3 continue + # 4 end + # 5 else if (f · w)**(q**k-1)/3 = 1 then + c = f + elif (f * w) ** exp == unity: + # 6 s = 1 + s = 1 + # 7 f ← f · w + c = f * w + # 8 end + # 9 else + else: + # 10 s = 2 + s = 2 + # 11 f ← f · w**2 + c = f * w * w + # 12 end + # 13 c ← f**r′ + c = c**r_inv + # 14 c ← c**m′′ + c = c**m_d_inv + # 15 c ← c**1/3 (by using modified Tonelli-Shanks 4) + c = find_cube_root(c, w) + # 16 return (c, ws) + return c, w**s + + +if __name__ == "__main__": + print("Computing residue witness for f,") + + print_fq12("f =", f) + + c, wi = find_c(f, root_27th) + c_inv = c.inv() + + print("residue witness c,") + print_fq12("c =", c) + print_fq12("c_inverse =", c_inv) + print("witness scaling wi,") + print_fq12("wi = ", wi) + + assert c_inv**λ * f * wi == unity, "pairing not 1" + print_fq12("c_inv ** λ * f * wi (pairing) result:", c_inv**λ * f * wi) diff --git a/scripts/schzip.py b/scripts/schzip.py new file mode 100644 index 0000000..de60a1e --- /dev/null +++ b/scripts/schzip.py @@ -0,0 +1,3059 @@ +from schzip_runner import ( + fq12, + fq6, + f01234, + f034, + sz_print_coeffs, + sz_zero_bit, + sz_nz_bit, + sz_last_step, + sz_post_miller, + sz_residue_inv_verify, +) + +sz_zero_bit( + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), + f01234( + 0x93B29143F057F125C8B5E8D11986A4EC5C7CFEAC89B8580AE9A9D5830A19D4C, + 0x516B755FE3311C2B90AFCFCD0AB1FACB18C3CC8CDD0DDBFD6A2E685D16682F1, + 0x2E473DDCCED3F5A780549F16B4A7CB4652E9C772ED985C0A32118E83DE37389E, + 0x118CAFDEBCD59151735610932C49F81451723124F3523811E7641958D79007A, + 0x825DC9BF97BF4E6BFB4C02AFC096E5103490AFDE25B7278DFF3518AC1E0CDD0, + 0x2D46D338E907A3D3000BD23703B22114DAC7DCF262F53E65BBB9EC6D9538183D, + 0x18D61A2D2F1463E84E308689805E18E35B683FF6B590E69412A01FBD32E0C059, + 0x202944D77C6438D408678579A5A20FF5747F9EE8810FDF22C22B54B4B6487B10, + 0x1E323BC97AAE1789EF90B65D67DFA09EB495D53664A1E36B777AF4F53FFBED22, + 0x11F0E69D23129D28D5B870DB1751D6D8210ED4F05C5C4DE29C53F05D97E92A6C, + ), + f034( + 0x17B07937DB1F72B2B29E2DCF434668F0E938DBE0119C93EA7D4F109C1A0F45C4, + 0x25B8FA21453F00D01133A94A381FA8E2E438E5E4B6581DE60BD897964B732ECE, + 0x262FA9C6CF2C4599A834A0AB9941F0B3CD2FF6AC62B560E9D26033B238E10BA7, + 0x8D5574056E7E5A2567BE6A4004C39ABEF57222DDD94DF6BF514B8FD81AA0440, + ), +) +sz_nz_bit( + fq12( + 0x17B6F07867B2D8811B94054CB20E02D69E8696FBD8DFC30FC4DCC16AC3582B2B, + 0x1AD3085832F02DB30DAD3A38CF967C8948FABF90895BF5D0A407D0AA584BD32E, + 0xD2CAA0C3E9B8D955D6724E67DBAA7E9AB77879B818540303A5A5111C84D37E3, + 0x566102CDB5869B6F0B0C3342806346613FAC9CCE8B781A7307CDB9E672F312A, + 0xDD420D0FA4C4D927384E73BA7EE4A1B29ED49093C7EC79F97D82AF03C4BEF19, + 0x11A1A49C01D86EEAB6189B48BFBD9D9265E6A00C3C426FBCD88394692CBBB70C, + 0x27EAB2E8253C9DC314236D5CCE23FB4432CA392392996634F4BBA295475D0E41, + 0x7A161D713740C29CB8751DFDB0356B683840F804C630E626286C406E7FDCF3D, + 0x1DEFEA8B95AC737E4CD6B7DFBF81FA06BDFE78FA9D0F81310ADDE1230219DAC6, + 0x83A69098DE2B18EED6BD8EACBE4643EF5992E7C106E160425BE05E9D27C91E5, + 0x27A45554C37CDA23DB4D69FA803E87E97DFF43000C1C3142E2900EC51F71191F, + 0x2281F657560C385B4B012BC66C195B4EE12E7EAD34AF187701A56A60B1810BDE, + ), + f01234( + 0x222A977AA4FFA65D9C2EBC4A5FE2570A728EE4F9449F646813B7BE7D98C84DA2, + 0x1326C02005E2C7B7B0FBCA21A8CBA9D9B16CE7BF5E81D95CA2876F14049AB725, + 0x2BF3C77FCE69A8D248404B54D89B009E21E3121811D9F5EBFB4F17BCF35A7C, + 0x2F42EB9A435788F1E15C33CD75F178E59523F83CB7AA2C5579FDF489B8A67123, + 0x167A0706B99282449F6A66682740EBD01753ACC06BA06872CE823A70F6887EDF, + 0xCECF82AB7D6C7C0298CEB4F604AB94E210A40642D9C97A990377946A6C9275E, + 0x2519D8C37853E243809F854B29498B50CCB2F980393E0A950FB1CBF28FAD8069, + 0x70B275B879A44AB0632A2E013E4D0B546BB7B69B2642824DEEB07E675B2F00A, + 0x19EE31E0524CF51959A5DEFD812C2AAFBDBAE4B77266BACC6303EB16B64F2442, + 0x265A6DE3A0CBDF0DA331D43A013FBCB13E4E941769F2A8A1B8854588329549E8, + ), + f01234( + 0x4E5B09D9F4292665E16176AA067E2AC6314F5EE79AE6980E2EDCC951148CC0C, + 0xC27543DEBAC89C088F304429D31120D4B6BBC864390DFDBD50CCF4A3770661, + 0x14CF9ECB7A77BD64B08034EE2D3E616C572CFDEB0E1DE220AF8A0F92C31F3494, + 0x334D335A567E7CDED065DB12B5F45C705EE0D5F9184FEFBEE4F921E1AF668CB, + 0x2826A23E0B1CAC698575D38F2A1D79E6C500762A65615FEB0D041FEE6AA429DD, + 0x18F7727B98A1F6C8CD46B748FDBD69037E93B2DD49777A0260802E1563DF9C17, + 0x1ED91C464D54BFBC17E6680B057B7428BD9027FD1C98A5B113D347126E7B0C45, + 0x2839CE5EB72DF677A6E93C6CE86FFAE65272EE60D408562A03BCB6DB931B2DC3, + 0x23BBBD1F71FA0168651C042AD0074DDC2C398B44B80A3BCCF4EA902CBBC4D76F, + 0x1F43F6A87F038259260C4CBC14BF83675D973601C00507E37B283ECDF2F45F91, + ), + f01234( + 0x2084A503B31430C051A6B15C6979941A555AA90918120C701C2242594BE11763, + 0x48FBFF86C4C40B20CD67E253DABF168B96DB7C2DD401779F46964C720F6CFA3, + 0x1393A3287B1E7ED23EF75FE9D4ED92BFEB1746AFC652C476B53A4E09F8F533, + 0x1F001533923D64935DB3C6B2614A670BB5F9AAAA20E3C278A7663227B81F7599, + 0x27C02BF0115CAAAC8757CC7A2AF350F61C0D2E4042AD96E710FF278A3DF1EB2E, + 0x19C2F0012E9756C8FD43E14CEE1EFFF2B7E4C1E62AB267285422ABC3166FBBDC, + 0x1049D88F2A5D7476D01AF11A564D04F5F48EC9D3A4DE84701EFE36D1933A0897, + 0x2327863ACF38241771E114E5C1A0053815F974AE5F37432A32E7ED82950F6A89, + 0x22CCEAC6484622E8F8572901926BF3DD343AB0C09EC2BB913F28F86F014CE60B, + 0xAE45A230BE8239F4C73DACAD60F20CC3D099EA2A8FCB4E2042F0B16AE926580, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x1B61B596194AAC7A83BFDBB8D599CC3C880AFC7C15FDB101949D020545BC8216, + 0xDB072F0BD5B4F19FEE9F161789550F5E67742D736C0CD42564CD43C4C0FC072, + 0x13238EF7F9254AF170A434108699D895EF831ACDA6662B9FACC24448BDFA2C5, + 0x11894F9CEA1E134AFD42CC1B191930FB115E4D43242530E51DBEAB2BE1713BB8, + 0x1A1FC971816C2D57E5AEBAFC3E62921D9AE3644E2C86DD376BA58A0395BE174C, + 0x57C2ABB0843C42D30AB938B0A9A8F7C60D03F07D70CA255D346AAA566DC4726, + 0x55E6D6B635ED2C31081C8CDCFEEB7F7DEE5373705659AB1AD89ACFAF541B48B, + 0x24DCEF9C675A40F91DC402DA0D79BFD2751AB708E86BC0917E30574D827EC80, + 0x8681B2C40EF3DE21DB7356D3645D2F2058BB5F54FD801C3BD918B275BCB1F20, + 0x2C886EDAE25D33313B622C97379FFE6E02C707A0AA354D0E92849BF5C043A7CD, + 0xF9B2A15D2A4D93DE43EF3FB808B00F1F352A2C6C7FC704215DDD1AF8304B27A, + 0x22BD6E03C2F4EE6476BA66C28D2CDBE7C66D404B6C36EAAC33C274C0B34FF049, + ), + f01234( + 0x2B1B34CDD1F32F6EE7AEA5EAC4C9BB6DB7722ACC86EB2BF702B32AD8405D6990, + 0x2345672A8CCCB05B870D37D9B2CC77F5A53716C55E8CEEFF27060331A748A776, + 0x299FA7A81B70C97AB4B47B036207F39E04AFD788E1BE312D72A5FF15288E7BAD, + 0x20EC5E9EE39DDC4ECC7AD8E993288227239FC43D492A6D86F188E83791145A26, + 0x654E4037DEA18643CFDFE629F20F02A4B1C9632F981199576066BCC4069FE7D, + 0x1AB77397226C12444296D6C072DFE83E44382B96EB2AAFBADF262B32189168EC, + 0x8F9072ABEF1E8E95D34E43D367065B9440AFE6B663A602C4FF6E0E8867F4C51, + 0x1EF307C04596B0B9E36321AAA5714A5E93A27618029247197183D98D05F44F9B, + 0x2C2B78CAAD031D8CB5901F84083CC1BA62715CAF075CBEFBF469928DDC2AFDDE, + 0x490EF18F72ABD4B034324AA3700226264CFF1E142EFB88C7EB80C3090D3814B, + ), + f034( + 0x2FA9A43FCAB4B6B4A427DA1F3E979B0E1C18691985AD61B870D524E9A53267E2, + 0x2EE2668F4E31DAD0DC31860B1252183D66E87F1F578ADA5EC9158B4F493CA4DB, + 0x40A83F6A003107E72EA7101884D24B90D98D0C906A718C12E598863E1A12E8E, + 0x257496B38A693F6EB08C76E8D1EC51D7B6EDB4CEF268576F4C7680BA14ADD8B6, + ), +) +sz_nz_bit( + fq12( + 0x2F26D00F019C092ED7FEA1F46FD65A6B5719D56230748EC0DC238155B9616D56, + 0x28386356F2BB4C5986E19190A0B002905BED2AC41CC3A9D9D645AD85539772FD, + 0x2B706EB43A68FBFEF6D4277147839D632E63A63826209FD0498BB3AE13F1F6EC, + 0xD7112F3F96F7810FFCC733864D0EBBB7710E8969176B46FCA63A2970A7372, + 0x3028E0D61781C0860A572FF6C500503E02C6FCC2991FC6C16E1114EEC6A21BF5, + 0x1A6341909DEAD8722CD655F7EAE0CEB47032FCCDC1712A8AB0604D0ADF439F2E, + 0x298DC947F8481747E25969B971162F03598FD1D92896B051374DC7C5E722F26, + 0x118D61510C32D35245246CBF126130F00A55E766F797A6CD7D5CCBC93E8501DF, + 0x1A5EE42154A96D550DAC463038D2094CC7635866CED95A1AA368ECE90F3DB107, + 0x27EABB6F55C1F8308D6B4182C0565B45C695179D8C89DBF62CE027363F0855FE, + 0x29FC6A248E429B2E4ED080FBB0115D5862DFE2A78A9F77D3F0CE8FD2D2159954, + 0x232CD82BA0F9A834667402E00FFA6B91FE88A5EB48655A83FD3AD1C11434CD8B, + ), + f01234( + 0x24639475F77015F9A8B2D22A1B598E234F22DCB4FC943E597CB09F2D9C0118A, + 0x1C7C02BD84792280169F8647561E21FFE8E7187BB2E9CCDAFFAE649E508E4E33, + 0x2C9CA59A21E0DC1B41485CF5DCA1BBC032C5F461D2EA03A1EC8A7ECEDBA2BD53, + 0x2358255EA615EC51BE83FF4602249AC5600591E4FF61FDC4AABC812199B46C5D, + 0x183330830280D7E53E67F6B93926CD7CA884CE7D44520CA486E0071A6E53C7CE, + 0x14796696B0B33F03A5F8AA9BD140AE558FB04056B51F6AD93D8FB882DF3FFED2, + 0x4D9AF01509549CA2A07B1B16F738BCFFF97B7884A3AFD7CC6E6B099FEF3D05, + 0x2072C57C01F901775DAB6269BB3739BBA0C1E8C39394D9DD1C84EBE36DA3E737, + 0x246B60D21D2621A67A744FC540EFFDF00A596A225F7A072D840611D01704F769, + 0x14179FB06512B326C9A037B3DA05A431A98B8B185FF136BDA78D7B7F86715059, + ), + f01234( + 0x1ECDDC7EFBE76D08362ACB9C2A7D63ECFFA056FB535A0109CEFEC0DB4D345254, + 0x10FD52C239B43ADC83AFD11C90CDD51A7BE69CBD53A3F8247A1635F5785C506F, + 0x13E8DD53E9A992A888CF04048F3BE6B38A983BCC0BAEAD84FCEE780ECD4A27F5, + 0xB18407AA28FCAE46181F82F802043FBFF237FC5422A5446C3CB38C81D3F296A, + 0x1AEA62CA407255B536934159D3334456E53B3CAA7E49305D46032D65296738CA, + 0x24C4598F29607208BB684FD87BBB4FD371E97A280FDF0F7D0941F521038B8CA7, + 0xFE47FEFE97395D28872DB6BE2474EC01EACF89A8C11E924FAACD9080D1BB6F2, + 0x28F0F0ABB2EA991C15A2C684D9178B6CC4695F86BEDDA1D8FFC47590AE40DEA3, + 0x7C0CCCEE48F371588DC6CFE0A9883F572324A6C7EA932DFCF5ED6E46D27A934, + 0xF247A56C60B83881E0440D0C5F18E328E385CFBAED1FD2AE8C0B7A7FA88DD21, + ), + f01234( + 0x2C32062FA7BD6D012165F84AF9F5746FA02FDBB20354D3027555FEBBF0CB44DE, + 0x2EDB80DD1F5F81126DC900FB7C255DFED71E384813D1C73C3AFC2472A0D55A82, + 0x8B4352DF1A3F60799BFF39208962086AF67579F9E6CF9A6A23A03390001FD7D, + 0x303F13DCFAA90D1C3E9C03F057D6E56406F52E5C66B932E784BEB97E1D0AFD5F, + 0x21380BC3D6D0BDB27A5A842F8B5E333553283B959ADD7E848DA7AEA0EA0B0923, + 0x1E4C6E1D7B4C59061AB044DDF2BE46801C19F91872408F667628717DB3476129, + 0x2CFC3CCA0AE10AE4B7437D701054BFFC267A0FFFE0A7D25513593F7C24DE84C8, + 0x2964AA5400F4635628DDECE90181759EDA3B824BD91919D77F3343BCB2AA245D, + 0x12AE2EBC9FCAEA4A696535D5456CB73E82B3F21D777E7DC41F30A7B07814D299, + 0x13F00911928BBB7347390DBDE7776DD8BA6AA8548F91BA241AD62797F110D952, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0x27135C1AD2B32F5E0E57AF4845E7F89D0CE00F9B920BA049771D737C0CE05432, + 0xC9F88B839C7DE546C789553BA9A68491F8EFDDB6D7A527C4675BBA3861FDA56, + 0x2D9A4327BB386A849BF42D52784067F620D8A0104708A786709AB29EE41DCFE5, + 0x1C48AE8B00BACB3BEA6E05B94C73F19179703870C536346CE9E4C90A2B67E7CE, + 0x75296AD9CAB67C98C5F019BCD379B7A91864859BFE26C73A1857DEFE1995C4B, + 0x2C12E103F4CA37F7BFAC70A8460F56598C3999EC484DE8C6F6E822476F3CCFC9, + 0xE794677A2A9C03C24690C5FD5677392FE634F04C561BB613A37A2FB489EC71E, + 0x4B2D644C1B488713CB5E1EEB47BEB9FCEECDCB81E6D25843C14FA2B5B0CF317, + 0xDD096D5B74A143D8B1FCEB096DC2DFDF0E2271B8C51679B079A8D85D6967E64, + 0x28562AFBF1AB2AC4DBA510047B998C5B6506B8C17AAFC70FC673027540212F4C, + 0x3BC8953276409B0B89BBC4546F0D47D5968CC0A8C9D965635B009EE5B28614E, + 0x1850B167F0937F142B501528C84BCC44E96910599018029A02AF5C3A1C2557E5, + ), + f01234( + 0xD390A714EE8C571A577D657689B591236293185976F6936B95653C828DF368, + 0x11F7B91670289E67C1ABF6EDDE250F67BF634C32AA2B23D8CF98A67C942969F, + 0x301ABEE416BFAB9C64047C082897F01456A1471B3F9B967611A4F1BB3AEDC65D, + 0x215CEDD263F8B2D935EEEDDB8D5D7A40EEF14DAC6A08EFA97A9BA1812DE6C81B, + 0x29CAB27ED4F7F99DCB01BE902504CBA1524AD5EB238FD3E6B0AEC798EA79FCC1, + 0x131BF184DE111E726C6285ACA3C0F098A8BF1144D8289F7A61B41D37C75F0F58, + 0x5A0E23E57773736F9308B9AC4EB2D109A9ECB73195DB4DA32D4F231D9DD1D1, + 0x27DDB94A162CEEC23EAFDB471D65033EE74072DBFBA0095556D4A0F63B912A9A, + 0x8C21A71A7D770861BDA4C0041A689D6BFF05F21F78BE87C85B716E35EC78609, + 0x3020D7ECC85FA9869B983F01ACA7F35DCB78C37B2BD1ACBE8C29F514C2659B58, + ), + f034( + 0x6181B14750000077ADAFE29DE484A2DC644BFC6B36646D328D82AC37740769A, + 0x11A02B07B6FB1B777351B50D370FA586BF0A303BB8D5B42B2AAF7A3AF7FD5F6B, + 0x258A6CB5C4E1B59A02C899543E44816038A953273BC06FA65B21A5E8BAA6154A, + 0x19B8971E16BF092F86E2DD2C9374F3BB7A33B5507C2AA9F279FDFB59E258F325, + ), +) +sz_zero_bit( + fq12( + 0x355BDDA0A37B9D5FB75B033D1F100CF1707EC2723C116D6B2AF10979A7E20BB, + 0x2090B40B8FB7885F278DD753410811E369FCD7B71250BC72505BDC9A1A139514, + 0x12C76E0A0C08037388F1D58E36CFFFF4D521F1D2057529A03ECFA48D3114F1F0, + 0xEFBBE11B7BF5B7E0D75730DD421C9149F3160FD19F7A7864353AD54D9A1125C, + 0x6A8788F8ED9F4C2BFEE1EA21FF181DCD649CFAB13F844D0B73144CAA909FDC7, + 0x2D6F09187AB1CBD37431C02AFAF9A84A47F78FFA0541CE4165B3992343F56693, + 0x33CFCF50F468FB550D6A1D20CEA1D3CD57640A2A3EEB7F8F60DE6CDF4993436, + 0x1D3F2F995FEA435BEAFE3196374009E3B405D91F095E030838CFE5512715E56C, + 0x11B478912DC4890A1E8639D98577FA2F04866F31229D5274F71CDCC97A6B87CC, + 0x1E6E6194A4B964AA2B4F0DC0E5B64D6AF660470D8ACA71DF067490A1B1EAB165, + 0x2D6F4139B009F3500ED125136BC33CB937E86F1AA915CFB792C382981AABF98F, + 0x27A99AD2605DA5BDFF9337AB5C4BCB8256DEFC5BA2CAC57D394F694B97098DA0, + ), + f01234( + 0x3D08F4E067DA5DA0C770938FE9F2653C224A14ED8CE4086E536A9E91A3CA8FA, + 0x1EEE24238D9A4953251921642A061EC583B352DD559FDA1933EC08F9AEB4357B, + 0x2613A120F275798A2D35DAE81BF21F3A55C4A8AC70902064C370BD9955E12469, + 0x1C919967F51600E9899F7F47137343A684B1D6B0874BF46935BB3DF90C334B6E, + 0x1C75240DFC5E1154815558556D9A66EC320FF23B095C53DD6E1BE1C9837773FB, + 0x232C1006613B23236C99F106A4697D5A0852E9D1C3783D732BAF2DF397ADBF1F, + 0x15B9C25DEA7FA654F30A256B5C45A4710A30F14A0C3B4484BAC8ACB6CE48C8C4, + 0xD78C27A1B45D7913E4A22095C562F62F6B7A7D3F1CFB2AC5116EE790BCA31D2, + 0x24AF9922273AB9D4F53FBF066F4F9D004375EE35652C24ED8F4D44A4551FE8D3, + 0xEDF88834D159C757AC2859B62FBDABB148DEFD5231145C81AB03A8F485C26F4, + ), + f034( + 0x2B4AEAF9610A0061023E739F0D92DD1968FECCE0569E64D981B09AC458A97CC, + 0x201E6B79DFCC310D9085653B64EC4E8CF1AB1B2A4BC9C5D6DC802DC7BF80FE47, + 0x48E40627893CC61AA185331591978C80D3047F0A78557D6959141BFF45453DF, + 0xD50CE8009F40AEF610DADCBFDAB928A568D4EF0E7FC729D7FD32285E0E20A17, + ), +) +sz_zero_bit( + fq12( + 0x2014F7FF079B44C8B4DD9D0871F29507F55743B4A920F5E6442B0B74D59D0CB0, + 0x231EFD9C8C610DA016795AA966A226230D06208E5A8925D3EF51876084AF1234, + 0x1BFC0CB821527933A0E61C01B6596DB4FEAA27426BB9A7B1949A02533A55BE7D, + 0x1DEB79BDB1AC608BA40A9AF9618A6562970A107C3CD6FBCFAD1F70BAC45A7F9C, + 0x3019B8F426C7AD1AF2D55E269C0057B47879B37289ABD6CE94805EEAD92EFCA0, + 0x1C904803D1B3FE92B5B89D85EDBA3DC9D409900E65FD558A69B6777F8A3A992E, + 0x2E7CB94F95F5864929D6E5F0BF5B7319710CC07481B724A144036E80F184A6A8, + 0x208B48CB1E1E7C1148A91EBEED6E546803A2F936F19E4FC3916C921B89BB1D97, + 0x293CB44FBD347437D3790AE5FCE1B69EED50551100DFC9853F6FF71C9D1DD2B4, + 0x1323833FBE11F78B26BB6241C225E8F777F283FC294715AA8ED6EAA4F5D71442, + 0x4AFCF2D2F24105882AA596EAB39AFF31913C1D61D549ED93FEAC085D1AFAD70, + 0x2A632C21B06EE37511B98D88758FE1E6ABFF7083BE6FEAF89B4C909F918155D6, + ), + f01234( + 0x6C55FAF363E62C120DB4147DEFB75E2CB951C136DD5613B45B3E31C8AD3E0C3, + 0x4D445BA1EF3D4D247F1769FB67CEA2559A60138C87654C8FFA7458C3D4B3FEA, + 0x158CDDCFF164ECE4F8D85C75921C1320EC4883743306E50812DC8E0F2DBE165, + 0x12FCE1DDC738BCE1780829167CE12414E06E532D70AFB5AB59F2940517DDCC3B, + 0x146E188C662FC5672188EA7022AA308A67B9D9789C2D7B7C4B2CA05A5CB0A020, + 0x102787557FAE4CDC9ABBD73E3FA7F78AFD11AE5EDD64B104F232FFB5AA1B1810, + 0x1BA31C5616B97764C5062499966468F55410CE99038F159AFADCFC04F98E2483, + 0x18809A3E35828EF1A88A8A7D1398850850C84C332CC0FDCC8524191684DB5458, + 0x20530F8798E0F2A0B6069BA02E2886C9B04DF85C3870DCCD15DA33A0B285616, + 0x973EA89CA827C04166D9CA5BE771A32D4536ED2B0DEE03595D0729C002AD52D, + ), + f034( + 0x140BE302C4BD2EA09B822D35551F7BC02D9D5CA483C3F25B34FD3B6A114DA6E2, + 0x2B6664FA9EE86B720C07A563E990D6FAD1B1CF96DD511DAA717220FAC58BD40D, + 0x1272DE11517AC80F2E4F1D9F0A0490965BF49CF33163B4DA274F35D4E2E6F24A, + 0x625FBEAD5F0A5F0D07CBC47BD5466CE8529A2FC5041F2DF295958BA8F832882, + ), +) +sz_nz_bit( + fq12( + 0x1BE0A77DAC98A205C54220A1381031268C745046B0EEE07586798D7B9ADEA3D7, + 0x1BB5438040DFD1A108507B2B007BE615223649E3EBD31EB411B05A259275D7F3, + 0x1A90C8B1DF468C28E190932DC35751EAD50C70CB040768EA1CEE647880ECDEB1, + 0x2AC4BB1C128AFA199881B882A7EF2D7CC62C9DF527F5A8B48EFA215E28DBDEF2, + 0x2F2256FECE633E22AC07437B644266AE6B7CFB08C73C4336F0D4EE691999453C, + 0x235E95AC724F6B8EA90A1A42144E97B1A0D3E891239EB102B7315AFDA60A3560, + 0x236EB2274F69D7A6417C3053AAE995CEC160E78FE809F78D2ECDBB779B6273AC, + 0x79385E8DBDC12322DFF8DCA7824F759D84E6834D2304F6CF70A6F55DB490618, + 0x1D23228B63D10B1028D0451DABF94CAEB9F00749E05735ABE0E7C51123DF7AD9, + 0x1F6D6758453178FFDC7905A34C26053D8A0F6B5B0D062AC7566608E26E6969FE, + 0x19F56D4DC160A3B5128A66172B0403E0D3F8D7E897D65F6266176554EC97D26F, + 0x24BC2EFB0CF42B6D417E3F765D18C78EDC4F1749C53AC51AF5C8DA9F88C5E406, + ), + f01234( + 0x26240CCC21DE91EA4FB116666DA9E5CDF05A336BCBB3D4C27ABFD2158A73E347, + 0x1B232D7D3ACBF032F338F784EAC9C26168038C59F2BFE41B834185290F73B9F1, + 0x192E7B3703EAEC097DF43BCC333D739E7E125D1788438E877DB2428FD8C6F935, + 0x2F1B5863A8AC15927E0682D77774D974D2B8A49DD10EBD62D389EE1FD62E71B0, + 0x16188F2CD7322E3F4538D779A3C4BD96C1BB11713238967F8C209C7244236AFA, + 0x2215BC617157AB024F955A3A02D5DA99ADE8A07D4F812D29813FD31904B0429D, + 0xD34634DB799FD17D8CB72790A8F8D0A08D2A1D1BDC043DCDECAF86909C8F2B1, + 0x2D4EB7E63AC1DFC7F2A9508D5F54BB227BE4636E941CDF8E4F5A1CEEB34DC557, + 0x2FE685F9F6072EFAF254008DBCADFB81DC6A4D768FD00109B6B7EC110AB3F5EE, + 0x9AD6F5F1EEF8716A7A2258A330535A0BCD4743D520592B60E4DFB3361E71036, + ), + f01234( + 0x25ED42D77CC72DC0A407463DB727C9A02315D8222BC3965600D0BA2ED9FC0479, + 0x120E4EBE471B63730E93DD2C619747ECB54CD8D9DFE566543F8B9D5155EABE72, + 0x116D8FA0036C85127C2FB989F35E36F95EBD1F245C189278F896BE96F70267A5, + 0xE7ABD29F9A575A0EBC2C94F8B800907DAAABAAAD983E00144DB6276279DE268, + 0x2E60FD312F1A413C9DB790E2AC6030C2C6F6405233FBFED7197FEA72FB0030D1, + 0x1F8D1263660CD2B770C160EFD863121BF0378D5A9FAE695EC8C53D7FAA625616, + 0x2ACF626936010818388C67BB1A99D98BD1EFFAA9D20D543D4CBA3D3AA5DC329A, + 0x133CD51205118002A8F3247804FD1F894D13981FE8FFA1432AC5186CF90ABA7C, + 0x88B6AB7DBBD446C8273D26AE81D45DDAFC093A609BABC1FAD006B998A7D7016, + 0x2BAC117D1D7D99A585A1BD78EC73D86521DC370718629A0250E33C7ECFC0BEC1, + ), + f01234( + 0x124D1BB7C226E699531EEC06D6A6D7866B346936613B679811AE4B8DA34442D8, + 0x4625D7DA704A03C62EEF1CBFFE2E5BE43CFF7BCD43CB11BCEBD1F74B3717E5A, + 0x151347D2C3CCC180ACC36749DD692E92BC62473CDB5E42290B7AAB926B9D1978, + 0x13801D9215005D8BA105EEB205D35B929202072886491C819D01A178401D83FF, + 0x25691F3C379ECB2D7A5D9F9CFF906167DA942202041AC79196B3241CE69098B0, + 0x25BD566B30B2DB4AA1E4F2D3CF3D4997E3FB5B7B82257FDC8DE447D3E396B33C, + 0x1E602F71946BEE8E3861E769AE573BFDAE086F4DFA39EFE1DB2268C2C3FB4FB1, + 0x2EFB56CD43A92222C5D91F7B7DAD5FBD57985CDCD93B734243C826EB1753B6D2, + 0x18DD74673C5831B358F5272B4BF5E2DD29BA7CE6C316AEFF9F4E6A46A2005B91, + 0x4DCED45C5D31C698EE9EC059161CFC638F943C9745D3E9AD2C5F49C6495B4B9, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0xFC36CFBE3796C751874E52DE43B5946210C717167066DDC09A12885292481B6, + 0x94E86A2BF164595E4EB727ADED4E37FBC98C4E6CC2A6416C625810E991C4A8, + 0x18D6834301121091BC88F35EC76E03E50A420E3F03C2589E9DA2DB798E34677D, + 0x25A4B1822393D09EC2CC7CE11DAE1D749DFE32C960798BBB6A19B4E051C5EA36, + 0x2511931C2C2AA41A209660E884530342128FEED1E806163612D3CBDAC109B833, + 0x1741727BCD5964A9D3E9BB4347E983231CB1710EECFE7021FBF4A1E631A35F40, + 0x189CBF49D131237575C8CC15A93B210364BA2F2FACC32409F38396E7DF91B122, + 0x2AA384E5C560D2FFF76A4E8AF75D84ACD8A324CF48ACDB37FD0EA071311035D, + 0x69A8D8A0166603BAE88823D2F425FCE8F4CCB6BE366CE3837C8435C94ACEC76, + 0x275EDD20342AF5AE780BEC2520B71161F225672F615A4920A4C438CF2513A20A, + 0xD5D672009271EB1B22FE55DC46548EBCD174C0A54D6C821A7F4599D5848603A, + 0x64DBD7C1F98B2CDF50FD8EC1C1A37496900FBF2AB5C25AF5B846A4C4ACFF219, + ), + f01234( + 0x23FAF7DA8CE1F3D7996459216C5204139B72EC83E64E2A2DD264E2C3826F2C3C, + 0x2A1F8F149A33C641842EB2A3D2E29F1AE95403FC84411AA508D94718D147B972, + 0x846C1096F2073084AE442AE7D2DC46F1A3B7D4FDC99ABC0562EE01724FB5E18, + 0x118EA0873B28EC23DB350454CB855DB721EC226909EAA0242DF79AAD7701146, + 0x1B16297333F208D3114A5AE6F328745865F32998BAA9C0EAE1383F5348A6738D, + 0x20035CF0CA434B1D6A08646F7B7422967562E26D4446C5D52EDD5CB59F4FE4C1, + 0x20143477B5C6A9599F3BFCE405E6168C1C57153332526FC32CCFF0CB3A38F164, + 0x210F8C2499E4858AF9B406B328D40E9E0B54C34B700D3D9F2A8ECB47AFBDDD3F, + 0x1CD819A30C6EE7FFC2AD2506745FDAA73CF0D1169EAB43AC43979E259584F1F, + 0x1CF6D976111E9F16399614CF6DBCADFB7CDAAD640EB193ED7188862D9949698C, + ), + f034( + 0x139E9ED0C7D599074C51FC60DA4C020DE61C6D49FAD4B517D463702D70250482, + 0x2C3D1E65C4C0E7640BDE2AFC92ABBC74B27D4DB47C9322E8ECF1BD49F9F4D666, + 0x1DD3D5BAD733472E2A703A60882B96BB7FD0C5CE67DF1FF8B19A784FF4152046, + 0x5BAA7DEF5414122812AFD699F6AE16ED626A92FCF28FE9F329DD1B34EAA05, + ), +) +sz_nz_bit( + fq12( + 0x2D0B6367D39219FA7885384D9C4559ACC222A469D79F70AE8D902909B7194015, + 0x17107FCA320CD51AAF0C4DD0D70497DC80B330D4C0C8ECB19D0DB63F8AD50889, + 0x2F645B6E03AA4F3926B6344ECBDEEC6B9F249CAD6AAF573FDB268F47E3EA3695, + 0x37C47D2594FE6BEB2F29657831A05BE7FEE94E503B3658273D37E84FBDD382F, + 0x25CAB791AF2D62F1AB8489F395399FED8AEA43FAA15364ED0E78EFC395B43895, + 0x1DE2ADEE8A5A9192EE1EAD9ABCB02482241AB23AF9F19CCB5EEF633EF45C219D, + 0x280D5AF5A425E7B94AA5AFE7408BBC2B94E33B174933E44FAD31F9A9E1767596, + 0x1BBE1330DD1C1E0BDEB25679DF26CE070AA3262E65BD39CBCF9396B6464B4783, + 0x2CCAA75164801E8572A1FA8BD77B871C088833619A9E79C57AF3FC8D88E36AED, + 0x1D7BB3AFFC3C9FA89FAC2170111287B9F9E5643088DEFC502C36852CBC90EC49, + 0x2660CA368F9C2354D06C8148BB1B8BDC126EFFA8FE081872A17C319B804254D8, + 0x900810ED49A8ADC7B5B8D39F3B2F6822634EE8FC65B174E46D6253E74F551E3, + ), + f01234( + 0xB254AF74AD57D8FB4E7978A7FE86ACC08ACFB8DA5B8DE80EE1C78C6D7C5D99F, + 0xB228D18C3C3D5971742D4C9DF2CB3A312CAE5D0D1B3A1BCE3A7D445AD2E0982, + 0x2A003ED0BE36CFB8567D23059A5CCDD4D878B87C674634168FB6F0655D2DC442, + 0x2CEEEE13301BFC63385C77C515395FB68C8C4424BA1235B633626030FC285043, + 0x2FAF597744FAE07406F9488C09C771BE18A77A147F4394BCCF8A7D926B01262, + 0x7C8423DF659DF5B5ED6D2DEE3CE10D49118A7FD8D7880FC87F8FD7E48BD6A76, + 0xDB3450A07921CDDD3F2FA9238132E8CFF32ABDC4ABEF2490EB4C1E90D645198, + 0x2465EBE665DE9CDCF445865A8D4B8C5C4FDA54AF3683E9B529973D8C1C5DEC14, + 0x25C5AB16073CC8CA2C2A99B6EA914D02EA9EEC186FA711C2368A570260931E50, + 0x1F148AACE614638D33572CE6BB4EEBF00DF3B991F3DA85E9C2FEADB4DAB00477, + ), + f01234( + 0x2C0BDDA00EA1414BF93FA60A6C28B5C182AC94DBADB584FAC5BBA5FC27298897, + 0xB6D6E297A2B151475EE4107DA118A4CFDEF3A82CA88CD4064B65B2CE0CD053, + 0x16D4FA6406049CBA7E15AC31A6487030AE09A40D3CFF52C4838595D5FB9C388C, + 0x155AF8242934C5E2CAAB5073191186F1C9D34D78BAC39F91021E0C43A25DB1FB, + 0x602193325948BBCDB1C94160FF026DD276CEAA3E5F30060E4C28D784CA4921F, + 0xF9D108C867121982FB45CA0382872B3C4F3989A2767EF9D1C16954CB73E24DA, + 0x2B26F6210B89B051B71AF1CFB3FEA5C89C4D37C89BA212E335EEBF4E12F7D567, + 0x13B6A4B4DC8F0F46284E656FEAD4B7B47FAF928B84008139041245CCD4871CDB, + 0x20D6B5E740DCE35D93BA4C3BE17741209DC7762CB56221E341A6267BC343A309, + 0x5313191E50DDBC7619997F2323FD7C3D92824363A33DD130F3534C39138FF35, + ), + f01234( + 0x76F91AF1C47662DE4F6DB4D8646DB98A760DCA1143C1DCE0C51D6B35EA8A99B, + 0x161CC77ECC60CE904DC9B2831381621CAECB1F362ECDB90F4E7AF4E562C8EAB8, + 0x2FDFD4AAE2198EB990509332857C089F4E7EC39989EB6D44B1182F136A6966F0, + 0x18D9C61D3C299E92CED214BBA7E2FF01DAF0D5BFC25BA5915C007E9CC78D75B2, + 0xD2BF39F2261ACBB24CA88EF931E2681445B63E203FF6CF557B8D26C2E444390, + 0x2DC516D313010729848815151D252B193324819C20B3D89C065108E75A6962F8, + 0x2BB02A88EC0B5422703F499B2ADEDC42677111F53C1C14DFEDE0B1EA7944CE51, + 0x2215F616599DA2B40E0FACE8C2285BB7171B3DDCE662666014E8AAD273994C00, + 0x160AEA2ED6AAF19851CDF86F35E060679EB5725DD511E18E6A95378310AD2DFE, + 0xBE4B12E2D6812DEB2A3B7F987304A857D9DAD2584DC9680030EB05F15A6EB4C, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0xB18852E39DF969AD48331617A6A4BD2361FC49A0CE042E3BB6C236D0A6F25E6, + 0x2574F912E3D81523DC18B626074D7017745815457EA9FE8623E82E18283335A4, + 0x1CFFCA35BF85F6EB7CA2D0DC9E76C3E3CE8A1475B2F5BF0E5FDC9F6404A5B80, + 0xD9212EF700AD1218706E3066B9A6CAAC75F47ADEE2F1283664F511E30599EA2, + 0x1EA9E49778F3B7A35F125A055D7E31A361A6DC1E05539A9243E98095DD197D10, + 0xB83347EA3E411E026FE2F92C021B99E674CDA239177C8DE4F8E80E73C834747, + 0x1D6C0CCFDB05B11B6224844F4E40B0963CDFA12CB0865A0620A538EA21B029D1, + 0x36508930B11CF2D392DDCD7AECA75AE0DD9E16DB12D7F90ACEE0A5AE22E30DA, + 0x2C0E1DA6C1192EB369232A7E8A49FD27E6262E2C322CE074919180D9A09A62D8, + 0xA5EF425C0C608180C9CA8B84571AB2D50946A64D7DD0D78743FD99979084DCE, + 0x2AECF7F685BBF107E903B9CEC9F740F6CF220621A46C72EC50F863015F40905A, + 0x18E1329DBBF7F0FF3F1F8F9F47547EEA481990FC1B42CB9B497CD676B73FA5E5, + ), + f01234( + 0x1A2F6D1F3FB72527B863B8AD1AD3EE873FBC54D9C6C09210D7002E2122DC2462, + 0x14DAA2BB649C85AC7AF780FECCA9EC50B9DE509C4F516D583454633B89836EB7, + 0x123387D621E60F20DF1592BD9A81411DC360E1E71292D575CB8CFC613D79B0B0, + 0xA5ACC699E8D156C207D85FE3BE9BEB963DDDDC7258574E374BF2ECC0821CF60, + 0xE7F93331D7EF7FE3757C43419EA74D0DF3EA394B34731A0F57467888A28A5EE, + 0x255B25A8DB3023020947B5CA534513B9AAD98AA3EC2DF1704D2E72128BEE222D, + 0x2DAFADCAC8D6CFC605A758A155C3F2439025369649BC59C963A4F8117AA2A56F, + 0x16C24AB01843382C1CC63F6772BA34D94F6B72FBDA43243A7C10190E744392FF, + 0x1C3AC95342AFC64D79D92A93271F58C735946B751E249928C996163DEB782529, + 0xE08A4DAA8A8AA26E0F5F27FB12FC28982A825336F334E045FAEAAFC26730F6D, + ), + f034( + 0x188D5DF69D10ECEAC6C5F10B8FA079D687C9F5ECA309C563D30FDB29B777AF, + 0x1F7A4CB7C6832C76B4EBE33FD6713E55389FA8A7A0497B12C98165B9FA9FCCA0, + 0x2143E4B213CEBD8808B0BD5CE0F0C6CEDF97CF7E2166E648770831C4187DDB6D, + 0x2D141B35F3E2458F66639AF9A59A8BFBF929C276C237171489CC641F533DE43F, + ), +) +sz_zero_bit( + fq12( + 0x19DD165FD9F1D5EA3A8514B8DA4AFF1249E1C65D0EDCD512E97540C7C8A989DB, + 0x19BC64439232F38C3767C5B4009373C1743C7FA0EE0D2680A6C9EAFA57F84B50, + 0x25D924B0539AD59BB79C254723715F60B2E0E479C41F51FAF389DFD74065D3A1, + 0x84841FC1E7B27066A856C1D4DBB56A9AE8ABF946BA2A903BE1D079BACC98CF9, + 0x1BE9A0AD1AB583C033CABF40B8F65805DEC3ED020C1DEBB5FD38C8584A82838F, + 0x2473E90EDBB03A209AB1D9FD362A6249E9F2398EAE8BDB851686CAACFD0584D8, + 0x191D8C5E45F645C2AF9EBA5ABE8683784C1FD12634BC6908477588409CE8F8EB, + 0x243DEB38054C3C0FBB3171F702574EE1C8781C2D6866AF69DE83B14CE95DF54E, + 0x22586A04599A38F8DE41E7A6C88FDA16923F6BA9449DE73903C6BC511856CD97, + 0x1E265D7110C41B0709D90EA5C10F703F91863B4EB83A346CEC182172234D03C5, + 0x29486CD657E8FA472367780234B30FC7C6BD2C0CD6A116B3F41DA9710B5202A, + 0x15DCCB4A0FF089FA638C892704715DCC3BEB01E01F5BE239E0AC108D366FCB1B, + ), + f01234( + 0xEC852BFA3DB6A60B5EC2091270EBBD565A9634238D30CF88A9AB2E453512435, + 0x4F5EFD0C961FD905B81BA2A33524F51179776D2FC0239DF61D334EBA0829A3F, + 0x741B4C55899F19E44531E9DD08059690289A195408FF71E1D5DB8B92AB5BD40, + 0x215D3CC32D286CE780811FE219CD38196D2871E11DA688CEDC739832031FE75, + 0x138CF6AA3CCCCA3AE5250F4B8E1A60F4CA159F695D1F0836D193A6994FCFD4ED, + 0x3973F3FAB2E0B8170534C304F47C3304780564D526E2CCF1F4ADF0EA374790C, + 0x16E5301DA014365C918D5E4433338E21058BCB983C85D69469EB68C2658B42B8, + 0x10D173FE294F3210A7693FA5818E8835FB380E011A77808A92057A5AE76139E5, + 0x2239BBC49F5765D21754D7A543D544FF3C9C229241CFC46B9F85F59B90E3B4FE, + 0xE1415F206E79048A17FADD1DC3CF5A046FD4231BB5A59586BE833DB4DE65F90, + ), + f034( + 0x131D4D9E50C1CE61B5444A328179649070F1426817C8412433F3035DA4EA239B, + 0xFFC17279525B75382DA59C4F3FDD68FEE82EC8248ED6F1CE019EB79F19E15A2, + 0x2FEB083466F0D244933A636738CA17AA3F35AA22FD8A9B52398580BAD179514F, + 0x730F681F4E36F7E8A24814605CF8313C04BD8BE3E46881B8C82434CB61F078E, + ), +) +sz_zero_bit( + fq12( + 0x8579D94D45F2BA280A86FD8661C4F76240AF2A6C3C2EBC815F48AC2AD906037, + 0x1BD77F748BB090F5E09BC5B42D325205C3D2973BA0E97F7A2CE151836578392E, + 0x27F9662CCD4025355BA9C61F881BFE883A27C909A14F454573CB7A4AE0FD80C7, + 0xDF1671F4375297CD02FD35CCE762C629C3B548A3EF714CCB32B96E4100A6797, + 0x1D20068FD7486E598F265B71E2D14F9ADBB03CA928DDF38F0C1D5596D7B49CD5, + 0x20CAA6F72280A189A9B0CD48016BDFA7354847407E4B375D4364EB30A9E57ADF, + 0x2BC4DC0132DD3E81080510D3A135FC26BF533EEA008308CE1DF0C4EB58814782, + 0x95FA26E7A2D6C0025699E67D9AD62D34ABD536E72525AEAE088B3B7B9FFE1D, + 0x111DB8A60FEF4A4076FB1860CE4A7E6013EB6BABAF56F39F7DF133D2F380AD97, + 0x2F5D4F2D7B0449971E8AD00221DBC115BD9617B7F0C4FA1009FA8F3F460EF821, + 0x261272DB83CCCEAC0D21B8A499020CC94172D23AFDF014F0367ECE0D234D27CD, + 0x1E6FA3543509BED3BDDFB9FCA8F548BB62B6C220F3C17D8B602BD8FABDD70E6, + ), + f01234( + 0x4D016EEF2885845E628A731CFEA1BB067705D60942AC9121DC8A265E73A5F6A, + 0x2058CD3E4F734B6CCFEC38150D58A00F685D902FA9078820C88C571CC2BCEBEF, + 0x2912281BE33F510CC12191A8A7BA88AFB4194CE0220321D465FA6B0EA944DA90, + 0x1AD7CC4FCA1812B1E489831AF11E9963E4691EB39FC3F51B041E0DABAE8385FA, + 0x12247CB4C7225567703BEF57D3FF90D0735E8FBAFC1B5F009DCF98F9B118F8A7, + 0x2A0334975C397669DED633534EFA13A42E2A3F6F849A726D867E432150338CA6, + 0xD683D40D1D478A1DA1377E19FE2C65395E664C4C1B4CFBE8E6C35E28B70B7A, + 0x3F6C296A0F0CE4DDBF68C24C5F8CD2C8A042CDBBEBEE176998CDAE5CCD1B03E, + 0xF324824BC794A2E2D2526B135561763BA8D5F920435D9557E1A01350D01D724, + 0x1506B98E216FA471FE5FA2E1E619BA6D9949486D38CDEF198D123E4A6875FAC2, + ), + f034( + 0x89F45C180DCD0E5DDAFA9282316868E967579D167E61B2164A7C1A52EDF3A62, + 0x149EFC02387273B6DCA9AA4F6C0A400CE75BBFD91DDDBECF8F1D6603BF5BBED, + 0x2B93C2956E892972DC8CB4F60D692FF7BC58FCD06B2E634E6CA0F4BAE468A5E9, + 0x1D15C25AD0B4E82812C6A123157F5C40DE04673D1F9649993220BE2A6321DA7, + ), +) +sz_nz_bit( + fq12( + 0xD2FE54B2973D883208FAE149B88C4B6090ED84816B8E36880A5BEF2DE5C8CBB, + 0x1B5D488B9B836EADD547B6D170C1AF441283111824546F76A607D3F8E8686754, + 0x9C204A0E5547C15F4791270A82F09958C5D21C1AFB14ED00DFF10D97795D5F1, + 0x2885FDC94AD95E4E2EDF1D2F08DEE5F49904AFD73CD6973E6573BBECFC0FA872, + 0x7A8B35062EFDC75E9AF53207317046730B350CC6C43C55EB940820032FDFFA2, + 0x3046D79D06FB521D1341DA866A4292A33D5C11431C4CFCB91E281A0DF50B104F, + 0x165CE1C5052E133C9C5227B11E59E918D787B7AF539C256F044DCE6365623145, + 0x9780FD4C0185F086C007332C11A4B1192F6D7C10D867B46640011C96C0A2DA9, + 0x29A0A9484315BC2F5F5C58428580C63292A6ED6D64F7FB4CCA6A8D14C046EA81, + 0x168F89E7EC9FB9DD310225EEAD00564A261EBE042985964696AE988F714FB153, + 0x1A603E2A264527374C448EB423C59E24F12A02878A672C1C74174BA54044ECAE, + 0x15EE3F3D6F1E87269BF0ADCB052A61881DBD77AC9A6573C21C3A7B9E8A926642, + ), + f01234( + 0x1E4A7057A768FAB5DC49EAEC1BC0833483E3E9C39E7F8E5176ECFD2BFB8F477E, + 0x23F57D983A963DE1FCC36BC6A9475FFA9DFDC5C0CED0E0FE5B83B6BAB3EF54F3, + 0x1273E038A65C7A3A82EE7482395650E65949B473F780074661DCD9EED01DF8D9, + 0x1EC1DEAD3A671024B3EB91C5AA4127B2984F44AEFFD25A55BCF45A5899217E4D, + 0x17832439DE1DC6C5C9951874015783F57A938D0DAB024A3C77BA240B9E1974DD, + 0x2D665D0D184BD6DF280F76724D07E38276C43E647F5FBC820D995DF5F91EEFCE, + 0x2E6FDE8D855D2C2E50D2E61E44ED69240075D692C79C348E3B2FC1FD28E4E2, + 0x22CAB5860261ABC022F76568661A9F6BB02EBF989372C34382FF84A8A060F32B, + 0xEEF7A51F5C3F228B55C97F6723BE9E29580CAE1BB206B4D150CD42DB666C25D, + 0x1AE728371329F832707983B89FB288411682FAE80D3A75D36E45CDE2FCCDEA8D, + ), + f01234( + 0x2C2F9EB622808B0811741E7F2A3F3A913E385B789E6217B75C7EE7588264F95F, + 0x214F3811DB87FD4FEDD24026ED36B112205D4208F4EA154F5145003C4E2E3D37, + 0x1953EDA940021FB79751393E2DF1E49A348B7F298813D215152F1B64EEEA9DED, + 0xE90C550A5C7B80EECE51887F4F3B66068E920DBB3AD7E04A9B5CC959EDD0F42, + 0x28697BE4F612CC7E91711026F0E97BF3E5199CAFE835C8838AB9DB6EE91DEADC, + 0x25C69F71C5B1F0A62F83DF6E0AAB0D7C3CB3C44921A6D94166A4271AAD622025, + 0x29C103780DFE30E2334A12082207C8ACFC6F7822A89D499F59BC0DF19D79FF50, + 0x449EC7DEDCA64D35B9E47214BDB7F45529EB909D5FC3BDAECB7FD753350B0B6, + 0x152D252F2B8FE07699DC7F29169B2E80A6CED63F953F0E49F14DFE0F896F0851, + 0x2A7C479DDCDA4F78CDC490C6DEECA5C159D2668325C2FA9BEA4682D392404B46, + ), + f01234( + 0x788B5F4BA2D441F27FE8E9E906DA25BB8C866E75E8574E708EFEDB8DCDD5345, + 0x1D084376B45C89A8E0FFF46A188E85A216705B6E4C4CC194311F53455EDC4B0A, + 0x128D0E7D5EB4CA6771B9764A08FB04B79863DB5E8684FD351C0CE695119FC169, + 0x16402BFED8DB14EA40B2D7DB3C1561977890030284B321D2142D917BB129778D, + 0x2E9F05BEFED8A01E5F32E8DF111579D1644F82A7424C2D2AD9126F0FD931F735, + 0x2C4593646E2F9F546EDC87D54BBC053682D4823344BD9C48EB55654DDFB73BFF, + 0x256248C0A833F96A5869452821314A083A1D5AC9DE8E486FA3C8E3AC5ED67928, + 0x276B99101782AE9D9087483D2CD92D55BAAC304BA7A075CBF643C97BD4BA5938, + 0x232924BA4DC9D9BEB1E578DB269A67BBC31B17E58A989986BC3F4264FA0ABC7E, + 0x807845E3EFC5903CB18939D423643D13EF3B79B0A3A5EA5D6BD9C8ED63E86B6, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x6CA1C0CA7BCAE38618F4B33B03D5A66F7479885579028288EC65ABC75AEAC13, + 0x6638DC48404FE7090DC8DE2D6D92C2EB0DE7E542C0314EDEDDE8E983F578AF3, + 0x119B011F6856816DF3D690F7F1033794D54EAAB7AEECDA3C9FA7633A402FADDA, + 0xF6E3964C1D28BE1EB3CF808FD1F9F81AF61EDA09B0F5C14D28D097F98A1869F, + 0x2290CDA0CB334DB114EC1DE1F7E20C350031B6BBB06FE483F870A897397F60B7, + 0x111DDB06851F8B4BD2B2270A1630D060CE0B910321702B5CA5146518749FA02B, + 0x28F0C6ADFEE4D09A526B51B7D78CD97C283A7512DCB6660AA7A45E467CA192E8, + 0x11B42B132DF631A9ECD458E4CC9F534C0FE1D9EE5ACC8F5135E89A534FA6E288, + 0x1699EC10CC092B91139B797171022C99461D8E59850235A5D6CD6384DE2C818F, + 0x29E37AD4D1BCAB0CBF16855ECD8C9951B0486971B5BD3973A59B3A8D6CE9C757, + 0x12C20FF8A2783CF4BB820D5514D141744ABC7D845425CD7C6F67A47CF7DABEFD, + 0x1AFE11B42D60DDF50B333A61C5396421A4D3A0383CBD16442E712206A8E3C836, + ), + f01234( + 0x1D05DECB6B16977CD9202FE5E0A59595D348EA8E4D6AADFE129A1A9C92510368, + 0x16245C916DECAF41C5078499167CD7531E25EB7B1EAA5424F4A0325A5AE8851E, + 0x209E1D24BE56C9FA7C2CC09A24FBB0100D5981658FAD8C09B28E9A1F102B0BD0, + 0x1FBD704F4B388FF6A6C5C0D0A49E25992ED3BC8376C002C0BD579A3D47A4898B, + 0x2AD34DACB7AEE6E6493FC104E1B165F1B4AD8B415DE58DB35DA1267C753864EC, + 0x2A91233427C376CC02579ECE2A5AE348E8BA9250101B02A510B5EB198B139F0E, + 0x24EE611D04C0A12BCEE6E4A61F08272DFCC44D2CB09E51D910E15256EF5E0F77, + 0x14EF7D8A9EAE97E37802989F0CCCED278626D68E70A4746B3FAA5463B180DD06, + 0x634F818F4DC068AFA8CAB8424C99FA8E2239D3F50BB260A851E6A125AB3D5C1, + 0x27658DD4AEE25BD3665328FD46465ADD93B38192A56790E0A0F11B8497378B4B, + ), + f034( + 0x2C03D5D03ED435DCC29DD72E0CB179F6D0399D33F310AAF107F97FA060EAD517, + 0x103E82B4F33B11A7E9E4D91074A4B04A5269A0C2F7F6D3AD913EB83E59A83510, + 0x2A7324F62ADEFCA67110AF999CDD5014AEAA1DC823C7AFC67043C1C66464126C, + 0x987913E0B291B99F617760C3568735A28AB2E16261C095CA4B9741F3F2ACE6B, + ), +) +sz_nz_bit( + fq12( + 0x2C9EE2511C0BEA985FB431B2F8859C4ED9852191AA4EA5998BF95AF8E56C9AD4, + 0x274941B7D8D274E55D8911D9FE41B47BA0DB731A12E15982BA226E16546DBB87, + 0x29EF606537C6B888A7690F16CB3CBBA2807C3252CF4A3EAC5B7F18D536C685C4, + 0x15814EC5A629FD3B841386763F4C4D7AF17932BE484C9793211AADC3DC0F4926, + 0x2C2810114E82C7CDAD3A7393A5C86D37361CDC929BC45834E4452A86805ECFC1, + 0xFFBF6843FD2E9FC2DEC539AB2C3ABC0D73B36EB0A497AB43F94C94623A6EEC0, + 0x263EDCE4F11058D1CEF4238FC8312C73F36ABF5EFF39D7BC33DB4EF300942B57, + 0x22283002AC28F20A8910B74C953F8926EABD0C470E09A15B3FA8A3AD9BF59B3C, + 0x19219544B4A033C63B9DE93300602AE4A576D21E157D7D3EE29733257B128D3F, + 0x1B4E811C4866354D2C6F9886A2C8D60CBAB21862E5A4B539BE2F26412D0A8FF3, + 0x1A592D9F8CE66B56135B71F14C4116A03A48F8CE26C583D459812AA010326566, + 0x1126FAAAD936A35CC68EEAB4F4A6E11031F7EA57AA8C556B82D949C998601340, + ), + f01234( + 0x13B2C80553FF9B6A489BF1F56697E28D15C0192CDFFFC7D17D21151F0AF47C0C, + 0x3F398CB2C2CDC6919D46EA1D7BA945551D99DDE049C02BA63F8ED424C699C61, + 0xB8A66AF7DB20B68D3007E55A33F4338805C891086E9F4DC124EC449695C2079, + 0x8A5B43AB2BCF02266746656A72EE14D03B1050C1FBCBD705BC82D6692354FE7, + 0x1B9548184F34102EDC284D18EDE9D5C164A016F5AFA67C6BF0D83AE116D29976, + 0x2387FCD43C847178CB9C2B99ABE9F584E47A32F595D36930A343212CAEE3021A, + 0x4E857B1BC05C5358E06DDB38782EBE92FC70741DE90976BEBC716B58250B712, + 0xD58838E4481B05811940C127A36D7B4A7A36D835B88227524B65A25DC817B12, + 0x150EC9D2239E2FBE1E99CA32527EEFF13D1156D8C93A318FE2594F1AD5CD7B5D, + 0x3EB66EB1A70C55B4A07410A5D65AFC2E8741B03E3D0450883EFF6D10BC27907, + ), + f01234( + 0x1970C7B19736833738CAA13E337A9D1C90C0C5C50798C707BCA4597766AEC9DD, + 0x387636A3D24132D5FEFEB040FCC055B586E3E377023811A81EDFAF5D1EB8B06, + 0x7927BADD53BB89888E17991434CA3469045323B386C60EBBFAECFFBFC3D0FD7, + 0x70E35FC34DEF2305D6B60C0CF21F6205ABFC10EB05ED3EB1770015EDD224CF6, + 0x157667787A5189B3119867D521C249E41E4F0383B34DE5B5A0497E2A3E269670, + 0x40AF67B9A99E4C59A1B4F6C7ECD8948E480A5CBF5CF62C7987556D2068F3FE3, + 0x1EBC0A1081A42336FA93249C5659ED9777D12C9756B5CBEF2E28BF1204AEC8C9, + 0x122583EA65BFBEAE849CF63B94512E9CC82525323D81361C5FF73E17C09BBCF1, + 0x9CB36C6D8BBC7CF4E893ACC974407169BFA0B54B99AABE6D1A29EA1881997D5, + 0x1D3C44945CBC0A158503FC419AA43BA0E19836BEC4346E808D70B709A87F82F9, + ), + f01234( + 0x1842C77E644A9FC68FE202563708338EA6EBF8032B3F5FF183847D20D181DE84, + 0x247A503BC895D9358E9A105F17C095D539B9FEAE2C4BC322260EC451BA48AA15, + 0xCD26C047570E90409B11C56D8374050CDF0AC627213B18EDA0D414D698113CE, + 0x432E6624E4DBC9ADF6F68422A04E957C3FC6AE353472EFFDA7D51DF8C76855A, + 0x5E7670274E39B5A299147FB46EA6989EA6A7EF2B92A7626A1946D4FEB4B8B42, + 0x2C8DC69690923DEF0816E8291564D6D365C2C07AF0DDA99D5DC6181B0FBE419B, + 0x2E6782F08D5DFD1F0121E7A98FEEFE864A6B2206B981460BC703A8DA8FA570CB, + 0xFDB7A439F944E9ED8126F053494BD2854F8EF3FD5A365B383EDD4EE61E149E6, + 0x14D39E4C928641F735D3BEEC27B52B424DA43A610449DEA56EF904EDED6357E, + 0x281DE250E3B873D11F3984B00E2E804D2020EAD58D7EA725169FE6C9E8BC907E, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0x2A3C16A8C433F5FEE00ACC637C22891A066EA414EB7B2BAA24BC0105FE6D13D2, + 0x1265C9DCE5525FE4546C1E0EAA5A0FCAADC74A0310EE0AC4A24EF1BFC9AC026B, + 0x2A3EA14230BCB5FAE7B0E3A165C25C1D7EF2CD47285D2B7486847DE9FB664BCD, + 0xCA3208A48FB204D55968A4B1B84E1537E8F5A56A09EB7685A6077CE8FDDDA7A, + 0x1D33583864D804F7CAE61BCFD81D3258AF2929853E6BAA12AB479FDC50A2C734, + 0x48E46DEADABD3367822D23D9B40937C9C145D91D498BB73B07F3B2D1B00C413, + 0x53022C941B1C7DACB18ACEA97210E650C05DED5E733B381BB7A14CD25DC7402, + 0x5B6AB11431FB6D5B4C51F59B14532E84E66016154E8787575A61E9D6862C4A4, + 0x2A72EC3370E89EF4B7FF63C85DB96340C8BF0692DCB1F291EA8F9599DC1F5B57, + 0x2851CA1615471C54A54C2E471DBA82CE594568BE67BB64FFFC456E4048906947, + 0x183C345650E6406ED54897DF41FF7DCD0A029465218A5536E2E68B4D9E05763, + 0x1CDCBB68B93B5D6841151701E624008E33D7BD064ACEBC0A4642EA84705BE3D4, + ), + f01234( + 0x1B0704CFFAC568B595A67133D9660B2DBBD2FCF36A58A941EA8E01AFBA906E32, + 0x2AC9B112DE5AA216C8DF316804B417FE2E97EF1B66F78502FAB38BFB4F3C063D, + 0xC9E876CAA9A6B2DAB398B3ECDF08267E44A63A9F9F057F73A4D00C95FF7F8F6, + 0x1453F7DE28A4A77A819DED55E7D2EA39C20A6A175693A1719D1D471233EED3E1, + 0x80872E4D49B50BC0AB016629F14B5CE64B8C0AB9758B86F01204A270E95689F, + 0x18E7ECECC5BF79BBEF91EBCE01CA0A4012BCBB26013E11ABCC746080B0EBA33, + 0x293D943842085DDB40889E9C2A68F34596B9DEF24584CC896754B37C6E3F91FE, + 0x4B8857B4E6F3ABA5D4F51BFEA0582D91705590D1C0DA6C764233EA13BBA27C6, + 0xC9D84BB9763131F4B624761595A6C1BA831F327F880DFBBD9939BFA1D397E98, + 0x2B82DE8AE89209C7A9ECBD46D84FC588C83D901F9355C16D0D48594BEA40893, + ), + f034( + 0x1A03F61030CC8BA780F997485491A8326FD72FFC1AD3E1C4E07FFC866F859F39, + 0x50CDF5FB618EEAD909D8C2D31AAE8FD8357DFD31D7E3F257E6B7B9FF118089C, + 0x2556C0D25C3A85D2684AF7B68B08276F8696BD67EF806B5B41D0317D0FF652AB, + 0x27C697CD4A7F4ECCFB83ADFD7F9211705D4EBFB07930586A7415D63290E239C7, + ), +) +sz_nz_bit( + fq12( + 0x15D5FF80BC8247F2704D6C27D74A222BDB980116EE4FC6E387C332434089C78, + 0x1C03681BC08AA0450EFAF86F75FBB6C4CF85C07032D30BBADE76EB9FF2964BC9, + 0x10CEE53C45BD041C4612C24EF60604748369FC1949E392F66A03D34F8886554D, + 0x2E0BFA3B1EFE9A2D7E98938D5AA27D1C674E8D0C23D4D051CB5ACD5A245BCF6E, + 0xF5092141C8E49ED90E71B652AE569020619AA6DF756A5ABFE7FAA096C02AA66, + 0x20534CECB11B83C455CAE68D05F0A49A08D1519DD8DF934B63863E0B728C1C15, + 0x1D4208EAC7EE041A633ABB6695DEFBA60C6B8DB0E81C506A68E5ADD54A169A46, + 0x27D29C61CDE0D798551937DD2D52F66695F48269B8CCB5990781DA751D99FD50, + 0x2F70E90C0BBF40B274B759BAE90CE2F7FDE8C7F5051704C00FAF454AAA967982, + 0x476751EF7DED3D6AB0F379A28269C7CFB5DFD969F00380E352AB15F68EB23DA, + 0x11C8AEB49E422FA6502C68F85BC9FCFBB095EDE9C1C473285DD3BA8EA7C8B43B, + 0x1A89EDAC1EDA942B63FC8726E694E780E0008B64327F24DB687E4ABB31BA92ED, + ), + f01234( + 0x193D818DD249F8AD84B3E84CDCF89C66F47E0645A08711DA5E78F1ED1ABE8634, + 0x17EB23C5BA5AE236C7AC4225D5A00F9D94632D1547362A767058FB220AB0167E, + 0xF745BCAA0D46153441236E30637F1CE5D5CFF4EEFFA8BDD509FF9F8A5F6D94A, + 0x2DD7A20C1194E68EE248145E6E7B1695441E0D6045E2ADD4BDD26E8D74F7A6A, + 0x22ED36EDE574E47439AD88DD03E5D6CFBBDF911A32A6D0F89CE5F60C80378268, + 0x3016FE7F1BA62B00F8D16B900CA0F7058D5CECA423C12F6591DCDB562B0A007F, + 0x1A43BFE3005B9BA2FD778DE55151BCC3A96A49FC600FA49EEAD0D101B593B8FE, + 0x1228F3509EF32B91ECB7367707C252C63C3A1F5DF981252A56447F2570E64387, + 0x2504C1A19B507824935B8E1B8D1267EDDFF96D79876D80EA94CBB1F9603A11D5, + 0x20BAEA7571F1C0A1EDFCA6E1BBFDC9419E03D8FFB0E541F90B6DE2FC01AA9A2D, + ), + f01234( + 0x2D934F8BF0B020B5C2E571D1A04CC9E8EC38E9CA9E20B62FC213BAAA2631C9DC, + 0x2B13968BD3678260D9B7DEC04FCF4980F3E928813CCD642F565431EEDBEE126E, + 0x2657A9E87BB0071B89053B126558154689DF3E526B402CAA24A403C604297FDD, + 0x25768DCE51ED01C22EDD443B4F5356F01F6281D7471779F27C73075DD982A2E5, + 0x23F34C68EE777A85E203CCC9366D5043A80C9324150DC65C96C660F07DBC5EC9, + 0x377695D49787CA71710330BED5B67E1475101A0EDDA7CA6B8F1E8B04A056295, + 0x1D25964470E5F715C561AAF37456BBF0FA5FE514EA936E7A7C37F89BE3DE0366, + 0x643354A1B67C17E0DF47EF107941772BC72B9625638460D22D1FA4515ED1C06, + 0x1CAB2B8DEBD95056BDBE323196EEAF2E8C138B152D6A92968166B304B160B99E, + 0x752ECB0E11A32E7929A73EFAAFD4E7AD0A3D09D8B2925D3FF3D0D2B93A91E76, + ), + f01234( + 0x66C48FACD63E9FF0AB21ECCC599DD3A70BDE619D7ACE1DBEC1A8118521EC49E, + 0x13E0EE6B5E195AB2A94B7DFEFAFD5B2E3007BA5E913242D9D1290FCCA2197F3D, + 0x1F55024099AAFFC20970FEA3C7398E6CFA6837C26DF011325A5C48F428CD33AC, + 0x124E1B50CAE4E149B46751D610CCFB45E21DA5A4B6E9917769498A4D93BDDD9E, + 0x1D8FCC365032A4C63DACF1C8B3D9937CA360F077BDB14C0547CE2C201E81F5CA, + 0x2053BD3ED0DECB7BB79BB66D66E87AD20EFF8A3C4E00389FBE037D4BF85DF0F5, + 0xD3A50CD3287857597A19DCD12C7A1245123E1B9FB3F0B46BAD05176B3A50601, + 0xAF0ABA04A5568A06EE67CFAC9F883343692D76221DBDA34D168E58D39FDE58E, + 0x16C75F6F8B665AD6B39540BFD49A2DCB73DA37BF6D028676AEB9A78A35FDCAC6, + 0x22E32D0B00BC48601363CF2A4D2577DC98EFD0A2AAB64FB78AE9BBAB463B405B, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0xD8753FA0AFA511BE2285169469ED05B880184376EDF0AAD3D6F1E65AF78D91C, + 0xB57187E62EBFFF59D767ECFC209A90851F128EF33BA33E414D9C669BD470CC8, + 0x2BAA3436A1321F1C2DE7699DABF0DF58D65C6FED6DEACA69FA92614A038CBCFF, + 0x241086E904A696EFAF5318A6AFBD4E460B5BCD7556827C1F2E2953C80C4ED939, + 0x2E3CDE06B7AE7EDA17082094626094CA57F1A2D3D49E4ECA272801D6BDB3CA01, + 0x2F54A1E60074111A246708BFD4E30499A6FCEA118BBB6772139FEF84C216B03E, + 0x91A2A7EF51DF358E5101BE69219C1F97AF525C9F78B1EA39ED226CA029ED611, + 0x1CDED525C6892894A5792153AC7D6E0AF913155A027F135D50E20F55F6452ECD, + 0x7ABAD11CD18003D8809F68AEAEB244DD5CBDDCB316E3B5C4858E16A85B2941, + 0x2ACBA2C7E37D0BBD4C5B024AEFD11FABE4A4322BD60CF91EB93CEFDE0D152B09, + 0x6582243083319231AD3FFF0DB6F3D8AE917BCB167C01D7AA0C69A0AF2B53154, + 0x1E1E7DA5054F4226810A8847E6AFB20BB05EDBECAD830646301A4773C40231A2, + ), + f01234( + 0x5F92A1172BA3F0D07F0A6B27E73000AE405A8B1CF0BF4D56967B2A624A925A4, + 0x2BE05112437A61FED3367410F4A16FB5C68B8A60522D2627439F043776E7EDA7, + 0x1835CA78924DC0109A9A8A407051A58C1B951EBFBB8B70AE6515E30394EFC0A4, + 0x159D6C6A03A1F75B859E5DC238C269C4E54D12C9552BC6591716331668136B8F, + 0x1E1C4EF52A182BB0FD670B48EE27B873235BA0ECC5F5AB179FC43640630822EC, + 0xF35E8C74737812618E427D5D6B76CEB5DB5708174D662E4D0483BE1944B0755, + 0x188AB12BA85173588493D785A9A97EEDA7689A619F70B5E8895AEEB8BFD83622, + 0xA88200C5082D81433CFEBB7BE327A5BAB8B8F20804B99AEE2C0D0752A316DFF, + 0x4ECC78AF4357F976AD7399F0E85943D55DF1CC3C2F3D4C18D70EA05B6D226D6, + 0x1DBC368B54E151FD58314408DFB02EB516975757CF102DED804BBEE7B4CBBF35, + ), + f034( + 0x162BF806E47DB77E6175D50C7D86032950D64DAC6161626236EB47478E66B522, + 0x2B88D0DF9F378348B7CC508791535CA398D95691C8ACAF9D5EB6998C80DFC854, + 0x1E87A90CBFD7C53FEC602FBBB2C2CA08479811276A71E1D0B07CEE4A6829EBEE, + 0xFB4708B8CAC1813FFF977EA2A046A903C8132216A6D554D24283B4E43B0AAC2, + ), +) +sz_zero_bit( + fq12( + 0xA4ECF0DE772E7A6ECEDE8F73A09EE2D6D88217FE5C89FC40310919748EDE948, + 0x2E9D08037209B399204214DF8ACB1E6A91DF9FB340CCFBF1110DC82F22D3DE60, + 0xCE88C155FC9A0B68F2CBF0E5C8A8C977638EDC0D4005C447C5506B99F4BF8E5, + 0x14ACE046F7797F667156DE29A825806FD9D01B5621FA847C5B8494A070E427DB, + 0x2E17391CB90978EDF00158AB4E028295D4C7EDB84B4A06B07857061B8EEC2AD3, + 0x2BE08399F50F8D234751ECAD90B03FC5D1D2DF6DE5FE81212014D68B080AC7BC, + 0x1110627E225191342224161517D0946DBC5532D49787A868E33BF0CAE5CAF0BF, + 0x29E25C1B8C24C1E93FFEE60445A446DFFDE54010E6324477609E5ED9A6630C71, + 0x1E4605C8C703B5756DDD760837AEFE7F0A0A576CB25DFEF145D18AFA8419979D, + 0x1DA94671A1308D4604B45CF2F3FFC09D43974CBF5E24C5993A97A6CBB698F425, + 0xBDC578A9FAAAED59A4EC3F9419437B88C8C28928175ED612903486106EBE432, + 0xB1F33A8BA8448C206F1076C06EF484E771792208D9A71E5B847E7BE678E7A92, + ), + f01234( + 0x15AD5EE8CFDAA8826948EA937BD57BB62A5F7660EAF02E403028810CC1934E91, + 0xE76140EE55CFD418429646AD161750C0BB0432AB04C862E0465DE10BEAE5A8E, + 0x304C21F3BC70333D0332EF2D184B4C963A11B9056D7F6ECF0523B0E5BF72ECA9, + 0x20ECBBD8A6338D4F2441ACE3DA0889708F55ADA14470145E5494BA1DE9E3F5DD, + 0x1C78C7B27BD3360A8802F42D67421201BA064A7E1209A353A4B41B8F2AF2882A, + 0x149439C1D6AABE4242ABF2742C4054813B4BE13E91BA2C8E0F2DAEE466CDF35, + 0x2BD79E72F4B165CB27CC97AED7E07211B06431C7861AE6F0AEE4BE99A030BA51, + 0x158902A50A5872E72067596A1186BCC857857EF00AB5F797D918C8E9DDFB6B15, + 0x284146DB9692905CA2C51F8A0559CB3C8DFC4FF9BD467A08147C09CF0F90253B, + 0x2870211981C72311BF02C723A0A065035905AB446DF70C430871B23528400D7C, + ), + f034( + 0x164108764028856A0E72AD082029D085B4D294A232A5811DE497D5EF499D8415, + 0x2C181BFD241054320968CB23A0C3099575C0933B78E652D7A8102903BDBD8E25, + 0x26D6CEBBF64D682D746E779159F08E16134B729A8DFA8E0DCEDDE59EF341AD57, + 0x2D9C51DCA10D991B2D937760F35F2418F3F5CF5CE1B43CEED4FA592EEBB350D4, + ), +) +sz_nz_bit( + fq12( + 0x490C491CAA29A44C137C4CAEC1816BB4709C35685008BD4C904C43A93D3C5A, + 0x2B5C3FEA4723AD428D285A6494C6240FF111B8FAE03AB4E2F25F551693B27AEC, + 0x173094BB27C423D73D4B4D50FCD8EC1C132B4652347F18B452F59EE06473E1D8, + 0x208E2E23CA6749453962D2C83D542AFA620FE38D48BCF65FD8B281D3C7CF6012, + 0x3051322A8FD83B06F46AC1DE1AB4C58A402BCBC9CDFFA0FED725F103E8832D78, + 0xC5E84375FB96D5A120995A554C688D57664AAF0588547FC8F8948598DB53BC3, + 0xED0EF7E4C444E2CDB23C6D596BAB0B86BAF4EDD702EB981E9B18AEEEAD06E34, + 0x293005040CD255E49A1CE8E49D2A1ABB4E657E4DF1B52E0DB88E66FE6028B024, + 0x18B38178F83BB927C372D42C29C7938E605CE08DDD623876CCC87019D6769F50, + 0xD9726068F43680BE340BD87739E59D66E35F07198C789B3BEAADFECD4602172, + 0x34047D6EB8048F2077429268E1DB91AB8A16CE19E36D5AD059EAFDEF971E5FE, + 0x2AEEF3B62E540E4A8A2EBA52AACEB4417F47D3653C5C215B9D2839114B35E6F, + ), + f01234( + 0x10B3FBB020354940932CCD8F9814AB708EABDB59B1E8A05F978F92AADC8C59E7, + 0x208F5A467E3BB9ADAAD66CAB4728D3ABABF2945E0757DB57C5C83C52CFFFE1A9, + 0x7D0A3DC304BC13B61DF921025715A53BD257CECF2D8A4AB3ABBC4269596A845, + 0x2A2E7BEA8C5A88A81E61BB1A536E6778AEA347F4951FC4BE8AE684A6F153B25C, + 0x196B49DB6DF001EEDBD4976DD00893D7AD6B3FC08CFEA82859AFDB77ED211CE4, + 0x2BAAFDEF40AA19382A278657BB06BFAA83AFD9969B0360EE6E8F9AA0F404F00D, + 0xF2C5F400B88698FDC2B964FF63D419CFF7B0DC70D6554F9C9A1E001070C6718, + 0x2495970F6AF0C4F35DD0B62A584A2AF907CCCCAD87A43197DBE02747F7B2682E, + 0x2764BD36619BC3F8D15CCA38416374AF873266E697B1128EAF30C5999B8DDED2, + 0x14B076F2822AB3E8EF6DC00F2BC18F9CDBFAE015F17F60B2CF8C4C5E6C2E382C, + ), + f01234( + 0x2D667628CF681115F540779A12ABF09A45B8022D20803FE763263BEBFD8D06BE, + 0x1DD50359A30B8BCD1EF289B111642B03854C76A20CD6E80CF49A6260A3B2829A, + 0x247A4DF3A5CA517B61A3658F0F0EBB72FE14C0F54C4CF2314783BE625D8371B, + 0x1EB4B77278BE3E2918B5CDCB7CA566CFE8302221026116AFEFB18F04DC6AA3E8, + 0xBB70E8A6A27A2830A51FA07ED64969AC8570C182FCF7661A1655CC83614D56, + 0xD65389EC85B25367477C895AF642E2680EDA29CB5A303DAA3DD512ADA37EE26, + 0x2063187D42836BAA7885CBDF4F2A9B3423D3B6568BBED54419BABF9CED077AA4, + 0x2450D6FB19F052CD5951AF02ECB60C86E6EB0D60C036044A3193E520F297BC34, + 0x26E9F42E6DBF621A56865EEBDD25EEDD0C2D0167611A8FEF9DF88C0502BB6AF9, + 0x11EFE920C943614F343632FBC3E7E2338F9E9F65EACC73A43D63CED5C78710B5, + ), + f01234( + 0x12BE03DB566BD30C2845B7B14990A696754DCD031A03E10AC5808E9E34EB7164, + 0x15B70F111907722ED1A084C06D86F1F1C37737C8E2E5D7755507323C883CF35C, + 0xE8F53AEDC620FC8F7B62CFE6250988B103CBED663E0C20C087FBB82AE79532C, + 0x2E25946B47046B6905BDCE575447F56F4178A0F0537D8C37678C513ECB66DEFF, + 0x291AA167E541A56494C4AD6007FEB83716B7549FBFEDD8E14957472A7340DE79, + 0xD9274BA7A4F8627FC66E4F2C00AF588F69E45B236375B379365A4FA74824FB6, + 0xEF049C8EBC5FA204E1B66EF97A4EA89BE94AC3E1EDFFA5CEF92DD8CC4929970, + 0x12899EB4B31133EA06180226F141A50464ED3CA3B3E8FB1D684FC26EAB7D316A, + 0x19EC9AC765ADA09770C5E80711AB6B67830F659A99CFFFB73CA3FE0E79B0294E, + 0xB2077B6A0C3B4F2A7D303963A850252DC4D410CF27E82A3DE14FC3C3FF62F9D, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x161FD2E20CD70EB48C38A89794141C6D29E41A1B9BACCBF154655EFE24CB6496, + 0x1C0950567A65086594054F7BCAF0077D32F159BFFFCAA4AD35BC5A842BA514C4, + 0x2EF021C661F1446852DE8B53DE34DA5482914E40F16EA8DD7EDAD84F2E9DBF04, + 0x1DDDD6FF744EFF40B7E49FC9C79E6CA4D2ED06B0E025247CD9E6D406C084C245, + 0x3A59F16556BB4AF9CE93087CBA5221276888F46D23D959418297700D8B18A7D, + 0x21385A511E72D2DCB29D48D6B12E95C30588732D57EEC111E3BE5651CAEDDC14, + 0x1182C5B6ECB5406F3DE4C0EE55C50729B7A69DB342F2054C9BC029F27C01F7D0, + 0x1BE149979C09CA137BD47EACACF82FF1488C1A20C5840ABC7EF03FE6BCD10E69, + 0x1EDC064CDC090BB75F04905F3801B23B190568A34B0F85D2C4635E81CD5145B7, + 0x2234CAB1DDA4FE93F76C233F7DEBEC89012F2507195A4B0DFE9691CB568EC163, + 0x24C4E9D3F7AE66CCABE48CC5B6E3B51B6190D8E8198F258B7B1848040F90D88C, + 0x114167B6A864D079D73CF9255206B390D6B417E9A77F0078C08DCA198257F629, + ), + f01234( + 0x251D61ECDC81F7B59B83CF54496AC28F2C0F5D5CB46DB298953C9F5F8422828, + 0x164E61AD426DC626BA3FFBDAB1110313A5A3E2B054D8ABC55A73CEE53ECB71F7, + 0x303F1D03D0DBCC23A2993FA4366B4B54BD229FCDF1AF2A6B1A2A81312BC34886, + 0x2605419DEFD032FFBF882CEA48316C4585747F318810B5DD6A29688CC9977ED1, + 0x2AF8B500C06D1860916F28BA1FBD7AEB641CF41BA737BBF62F64D2A438DE4BCB, + 0x636918E2CDE506A744997A68CAC3BF7DF3EEEC10FB1C40E1B67E49138828293, + 0x2D1DEEDD65BFD5E4F9D7917FE32D694DEB48B38267E896894D2DBBB9849944AA, + 0x1767C87158890DE00C9E610BDF735ED21E72C275809E541C5B63D5BFA3D17F95, + 0x2045CAF0DFEA4F72713253541F5F27A672CD8B4755095652FD128F8E3D8EC17D, + 0x2F7C73BB6B550EE7653BEEF1B41DDCDA5B2007F8DFCFC89339884FA3621C6868, + ), + f034( + 0x1877021E0B015C6D98F0E8919974C5C8C5BEE281FA73B8E17C7F3B69BEE5FD6B, + 0x8DA23CF6129924FE986D3A4D462C43E35F9E2BFDCC0C91F75F9B119F8D3D283, + 0xE19AAD7E86134727B2D6CE0EDDBE21BE0C0BB2D398B3BCE8FA393046D2F5E60, + 0x16EC64160FA75ECDD8924605804DAD94D4B791ECB70F0CF762FB0A2CBFAF585C, + ), +) +sz_zero_bit( + fq12( + 0xE48F8194F34DF8C4C6B4BC63BBAB60451343B9A52EE8043305031572B13D9E1, + 0x2B106A6D348F4C9145BDD8DE625E838A1493A4D5C9509DC17A045457094EFE6B, + 0x2E8E02460EA915A41FD0199F2E9F2C40E795AF73B952B27365E686EA239C0EE3, + 0x2E35F13ACF675AAFE23B1C9DE095B4628DD51257408AC699C0C295670706EBD4, + 0x1FDC4BB09EA4AB0BCF549A2C03D91F73111F889564C6FEC71FF4ADCB83AD6F2A, + 0x8CFD5CB394DC5D91938178AEF35C0DF37530FCC02ABFE5DD29C73E7E35194B0, + 0xB6EF8A0DDC86CA6F7A0DE2B59B79229C5DD326DE8666AA127DF5DCB3F461DB9, + 0x3706F2FDAD22C24E00812C344445592D56EB816EDC1D91605B7CDB0A326C2C3, + 0x2E4BB5A3CAE5972DB356EEBCE333431BA35128D02BBB7A71A4189E14135D7000, + 0x1ED452023025003942DFE53F4495C9B91D5BF92FBD10ACCAF6C9EFE478D5CFBB, + 0xCDCABC537C98B92AE0FF9ACE6824E28D711FDEF4CE30CBCF6E84E5899B4EBBE, + 0x9E448DE8CC7C02C483776478D85E3AAE6B94036F6F603530BA23E70260E3720, + ), + f01234( + 0x2F1BE8F923FD221C3322B9FB996A5FF3613D2C7A1B1DF50748EB2094014E119C, + 0x166BD90E4BC857CAE7257DDECC5971EC8A98C4AD44C1CB07B12965ED48C79254, + 0x154D96E3CFD7A10E490741E6EAEE7A360281077E66030541E96E88D7F4D0C6A2, + 0x27E7228C08C85E47518A5F927D20C47B63381F4167B4B8CCFB49D515B825BE20, + 0x29417FFE12D50D66D54E4FD7109868B162099176A2872C9CDD377DE535DE6801, + 0x4E5ED89BDC5FADD550117BE718A2B0BFFADF6563F631EFB093CE526392A361, + 0x23057252988B47699E9660CC1184CA42B3914BEAE044EF55707E86C40D1FA2D7, + 0x150CFE9D1E9F38064401EBFF95DBF0E8529B2E6A51B0C3AADB1F3505653D9F56, + 0xC68E60A5D3FACBAC208EC60B42301D9C6A164D159B35CF6285BE7D63832DD4A, + 0x24E7A552B2492973572AA5339BE14EF40D110BBE62543B0211DF13EE2BD11880, + ), + f034( + 0x1A522DAAD4DECE58DB4EC2DCFCDFFC8EC52E4C283F7BA00AE24C31965C0D631D, + 0x12646A1EE43E9011D71A2A6CCA2907FF3F6DA50CE7733F7F4857CD4939B035B6, + 0x20275B11EC1D14BCBCAA4739802D90B9229516E63AF66B36697DD5880DB4C8E3, + 0x25EAEFFA31867D54BB276E85D17AB250D90A3C138D862BAF162CF2D0C4F1D5CE, + ), +) +sz_zero_bit( + fq12( + 0x2C3E8AEBC956A6544531A2DFC6C6DD806247187B1D6B2A962EC89C2CCDBD15F9, + 0x788CEE94FDBB882E905D73478ECA3321C35D057929632954843B5E4D7FB74A3, + 0x2E0ED1A32D9D22720E61AD6FCF5B9CA688C377B07ED6B57BC45D30001982A029, + 0x4CC6EC5206F515ED293163A35859545E004E86A4D5222D872267F3D16ABD5E6, + 0x1F402DBEA1C720C6302AD6684495E6F75ECB01F03CD47B346F3618B7027E2351, + 0x22F2E68369C4599F4F2BA5A232BC1CE317BA28A661082F167A1EF5EC1F20B65F, + 0x1329E2444347BFC4B3317E261580401A02ACDE718F83EEFB2B3C0F70CAD77E49, + 0x2A66802B998B7A0DFF32AEA04E3B4FBFAAA0CED979A5315755F22C6FEA7C709E, + 0x2556179508AAEA2BE908FCA7968A2DC2209B6F92091E4FD6DC147C1A607D7CCD, + 0x1D04B6FAD6556CAE629CE502ED5B705722B1C5E1E7C66438CC41769FA93FF230, + 0x9E93D8378B1409C009200FB144A9DCABC67C7AF431238FBBC78B26B34CD60AA, + 0x8B441878479966280F948F558F2F56EFFFECC66FCECC4571543E72ED2EA8A21, + ), + f01234( + 0x13B7E1BD04E657682E97F95257CFEBDD8F3C48B938246F5AFBED4BF40282A62A, + 0x7C7F5A556DB7F3C10EF0373B74F795062D7C8B5A2AD0E6FD303ACE6951E17DA, + 0x8DABE6838F832D56A11B12C4D4BBDEBBB6DA02F0C88C5047ED4881848D76A, + 0x3E3D225E625FFE08BD711916166BF99CDB42BAFD47847A9F18F5A76B6B2B1C2, + 0x9D9F6E6967D82DE3DB2EE029693952A714EDA5DD93F6B2F08930BA3A8A54C4E, + 0x1BC57C2730665991AB5EFB8CC1C946C0AB4D4D42447E6991159D11CB345ED855, + 0xFC0A44270D449066BF1114D0780EDE5E92D94112BA5465C07A60ED84B4D335E, + 0x25331E494338291CAF99AD5C72920E59245E27CC76662E5AA2459B98F2DED904, + 0x1F4B2BB5176C54484F936EE292C668B268B04AFC3B974F885A6DF324DF06C6C3, + 0x74DA024B43F948AF15604070A842AAC6488077C7B9B4D797AA4668210DF7386, + ), + f034( + 0x183C76343D5353A3CC02BED6E1BCF7674B33859EC423EB8C60E9FF85910E5B5D, + 0x287527D705D34A0113942E0E39C93FEEEFBCA0107B114DEBB5CFC76A1F477D32, + 0x1D51598674E4A99505E95A95175390E63BC33D1C257129D26B7B2774A813FA71, + 0xF2DB03F780925FE4C01F2E43D3C9A980C11AF75B04F949CF2E047F1E3580803, + ), +) +sz_zero_bit( + fq12( + 0x19EBE0B0CDC11AD046AA6FFC14FA0CF3E4C12280E1174DC9DCD8671309EAB43A, + 0x2CECDC675B154F832AC802DE865224F483625182C23CB737B64010B615E1DB9, + 0x1324A0AF249594B1BD5F7E95F83A8A3BD357D0381A2827B32F72508BAFF00514, + 0x16D4EEBA3F0B3C60190C8AECCA2BCB5A3453D450182B072306C1478C5A0AFAB3, + 0x1E18587C58C8902BB90B1FFC512027D87E5187C85BD0206D9222B81577D7CBFF, + 0x1F763D18C611B31F4C08D3346EC9EA9FF8E5AEB8BE4C6BEB039607AECF278FCF, + 0x28208BBA9AD6B72F2A64DEFB60C2D431A956F55AD78D32E75ACD77CE6CB83911, + 0x15BFDDFF0270264CAEEB31D96FD0DAF861B28C8382C1515ADBD6EC32862CA2D8, + 0x1B3248A481557910DC108B59267B985427D0397928B20439EFBCE8E0ADD5D133, + 0xD3E24A6CD3A2A6BCE5CB9C7739FC3F01063C1D1FE7822E67A645E9DD3C618DA, + 0x180747C4E3350DA2FFBE6F19538E85C4E46F64FBA8A3B08CDF381FF3478DE978, + 0x1AEDFDDC34AD172CD3480EC290A444D1FA1EC15327A0540DF75CB2F146BD7C0E, + ), + f01234( + 0x266AB8E38F97F5524C590108D3BD77A1BE69CD2D1C6F159CAB4CD2B05262B399, + 0x1223492BC36A3A6BD9D487A284D11AE0F2546F227582757BE4E11BF3D618D1F5, + 0x15463AB6E6D958AE2BB0EA8AC05071AE98EDAB05F1D85B25E686000E727CD5AB, + 0x27ABE4D8E22A496E8AC6D1477754D56555C226103FF1B5F120C95831E07CF643, + 0x2AF5D372446D1230864A147C0F346B3C3135A4721622BD54C57A05D00A92D83A, + 0x1D760B664484DC9665DABEB21A59AB591BCEB6C8722325E5F4E55A37DDABF38, + 0x7EBEAB7D987C5F2F2CFF94E69DA2D76D005C1271F6CB2A6B72FE869DD55E20C, + 0x145572FF5E3DD0764CB2892ABD2794B0A01883D47779A69669DC628554BC7373, + 0x749D8199A62599E97144D8B036DD85708045704FF1234F63B5BB5AD7ED046BA, + 0x12A8129E782B50E14A314D411B57AD5B82AA4C9EEFF826974B78A59F1B3BBF6E, + ), + f034( + 0x1D7B80D241431EE261716612016CA26090E836DA2725777C1D59DA657571E561, + 0x1CB15B7B6749AE7F039D5D20AEEA334D6863DD48C77498DD0082A9B22DDAC5B6, + 0xAFDA3CC412BB86E0380337C9EE03C3DC9A9F0738ED487BDD6EF4864334970AF, + 0x32F4F96764026F0853DD908916FE834255798AE0D0DCE5EAE41074503310F2B, + ), +) +sz_zero_bit( + fq12( + 0xD62FD457BE983EFBCB1D97B43CAEE2BB2FD71572E967FBA91E42C0BF2F30F23, + 0x2309A054260B388FCBF0E1F8113C54223C3D56E114F51EDEF0BF2006965299A8, + 0x219EF610809FC0DF24D0F9EF3AE51F46BCA8101B8003ED73FBB549A6129250B9, + 0x9DD0CD747A70640E79388EE59280A0BBEFF76D538450B931C2E4D950EC8F7F0, + 0x1A3F342C982CFC2F566D8AEB75A62EC1CE261E1DFB07B8A206F2E54CCAD7DED2, + 0x266BEDEC92EC2F8FC61B95A7AAB7F0F0BF9F321B0F0679D38A44E22271210B49, + 0x76AF100D125B877530B84271734C487D028859E3F7C4741DA194F3946593041, + 0x2BE3AD13DF633CC778A6D70D336F1945F98A62D4E759FB65513C6CB9197841EE, + 0x2149EDBED5B8EFAF4F697C77FA331A582F62BD0BE7F763C8978EC27C17F511E9, + 0x27A79C7749C93E4C5908F8B2113F04DE22C42C0D7042D510A8364CA79181280E, + 0xEED8148EC55B5DEA73CCA88E86563DDD44390D96B5A690580B0B5461F5FE3EC, + 0x152A531407928423E3EFDEEACA0E199161EFC9317C14F6B228FB3056BC2FE4D0, + ), + f01234( + 0x7061C1A20B798DCAA926AEA98E52BBC6DB0B4D7938BF96F4979754005149359, + 0x131E2A3720B78C061BFA5DCDFF37237EBDAE1B6EC820E074BC0BB8BAC5DBF1AD, + 0x6DBBCFE43914EBB4CEE1F8F1503E56725D293D24C5BE3A927FAE9A1CA0062, + 0x2011FB3CBBDA8ECD3D3CBE043017FEED916F68B0BB5E65186B01548D939C3FDE, + 0x25CF9CD9371DB78471DE462198217D46F8D63AF6974421ADFCF1B2E06070A2EF, + 0x16BC76AC3D7369B99AED7C5404ABACB96FB4394D4AE4079D30A2DFC496AD3016, + 0x1869F6E5853105601A576834F4FED8E82D3753DB60390889245B088C30D688A9, + 0x8A3ED719D128DF798D8D4D929CA7CF18F5BD082AD51BFB604D2FA95DF93A6A5, + 0x299AE547CCF6D9A75F620A86C67D8C230387860D15CC2239C05BC01C077A631, + 0x150CEBE493A2B5F35595B55EE73B1BD8CFDBB60D6D6E588DE3266157A988C4CC, + ), + f034( + 0x2BC06023075B24F6BABC90F4BE36B46DAB0476EAEF5477AE74BBC56F22E01CFC, + 0xF2DF59E3E06FEFE384E823B0FAD6B1C027CD460881B3F558607CFB2AC1BFE57, + 0x864EF90BACA5569F42AB8EB5DC1C6EADCDA0109A5537BE7EC267FB8B79CF53, + 0x1576A022D5E952B1BFA792C40F59892794BCD3B3C7BF5B251FE30EDA9A101081, + ), +) +sz_nz_bit( + fq12( + 0x10FC973AA50B7D904294A50637D4C520A4E0517D93C763AA2016EEC16AD7AF33, + 0x42584923DD40B821783A01425F4C1CDC456ADE065562578061BD7E01EA8F025, + 0x5E59103DB303D64EC79DB81809FF3168051B36D479530A33B6919458F820737, + 0x2B09662F9D302D245F5601EF61225621A0E968E27253DEF088017C8704744DDC, + 0x65561EC15BCE85BDF3F73155DCF22056FF37232F158EF725D703624A63BF2D4, + 0x1723A5E901E0E88B75910166CBBCA268B9391B05DD2E56D1D49A1DFFE29FE609, + 0x492BA731E3AF1B6DDA7C828B5E4666349FB76A89A74DFF5805FBCD2091E325D, + 0x1ECB9A92A27C47D086467A30FB6E64896BD69B1CADA152763B32670118ABDC56, + 0x1683420C4E170C49CD8FA9DCFE5108FBFD976290FFE1E82AB0BADCC1E60CC0BD, + 0x2AC5398555AFD1EBA3E95EC14F5C7A2917798439DEB36D75A6BD00BF6BE9E63D, + 0x915057D086FC106CC5A307F4F663631B3C95DE1AC83F26AC35AF48A94BC7933, + 0x74978099EC63F5384A7E552C3C7C1022E2A1AC67160ACE1808B8C324B144CB, + ), + f01234( + 0x239FC2BA37A8F2C97D633FF672B2FDB6E9AF40F45EDC3779A27F843E3C9E2CFD, + 0x28E85923EFB531792B54F2EF9DAD68F2AA2E3B602E0136CFABF88031FEFFC8C3, + 0x8D79253CD7A6C505C3CF6CEE6E628924FF21CB9E94D3008A46241DFEE55FFDB, + 0x161C1277DB0BAD885685FACDB5FB71EDF36ECC9A6FDB04C30417EEDF99312A4D, + 0x151CD2CDE7C7443FE62A1F87D4094898D9357CBE98187FE1A55CCB72686EADDE, + 0x20DEEC7610CD6994AB27F8516B8EFB5C8350B355F07B4EC4DC9C7E55B7363BF4, + 0x1CD4A6D857717FEC8D6681EBFB12ED4ED3C50E4C3C0767BAA3062F4AE1DF2E0, + 0xD56DBC117F78E67235DBA8ECC03D57F2CDF50BC15B6B34F0DCD450A7F2C8518, + 0x14A16E970D66736EA9E5F1EF64C674DA49D7A588920B7132CF7825F967922496, + 0x16088421DE07A254805B78898D01F37099E2E65A8FB4AE0399AF256EC559D20A, + ), + f01234( + 0x518FE07F739A53F137F28577F724CEAA393F3535D2FCAE5390AD1B646AF6A74, + 0x4F1DF1D3161DD309B027E8271373DB1FE2A2F1DA625DF08D7E7DFE50222BE25, + 0x13E9384C2940D32547824885FFF1C562F651D7273DC550F8C1F92801823EE143, + 0xA33975D59ED55ED64848F43B5FAEE76BD535B25F9F8C0FC93454D84F103A5F9, + 0x161D2C2F73D25E500B062F38C51BC3E6039893F2C19CF14B958602F69C19C364, + 0x10D256166ECA5FA8FF0A26CAB14E92DC5A2DAF4224B960B3C3701B7B421D22FB, + 0x2E75DE7D4A08864D80D28D4A9EC35F6C098ED05FA2EB0951AAE2E8ADC168FF86, + 0x2406EA19758AAFD8BB70321BED435F7D6B0D7583B5B1701E49A46E4C6431F692, + 0x1FD872DE320674F1EAD381A725D9219F17CD18D5320FEF13BFCDFA085AB63BD, + 0x48C96EF8E7BAC0081AAD6D1E08D74974FF95C13EF754558178DFCA9F1649DAF, + ), + f01234( + 0x10583CBAEF446BEB5AE7B3BB77EB83493D7AFFBB9B0C3AF3AA879C31FDA5B3CE, + 0x13D87C80425E643EFEBD5178652EBC173718A819BEF6CB490D12040FCA919C70, + 0x82FE202F3C2712CF09404D7822B5EFC306077CB30D6B5C7AF159C264A054B89, + 0x1FD038388E3159C655D55C3D2215E62D64F8B81E21F5D90B5DCF74A26B746D55, + 0x9CD22BA05143116904A3A9CA0C6545A49FE581BB780DC2C609557BD550A0A3E, + 0x18288BD07BB99CB9728B409C734E91CA301085657A50F2CFAAB218C1901AEEAA, + 0x64BFAC870B939EAD03A4CE5AA7D8C8D41C72D4311D4E493C0474F5E8DD7C8EC, + 0x1553A820F8CD4E030C4BF3B213E13D7B388DF8F93EC8545A67FF4990EF23A016, + 0x22A3D8394EDCF4C079C3CD1C1BA2330045D48DDA476F6E4993C91304AF5B37C7, + 0xB3EE450DD0E659783410270A04FC54BB7EB03DF506A873D6570679F7A9EDA6F, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0x18C6E443C84FDAB01F8915527FCC9133ABE7A620E046766166A25435B5AE58F2, + 0x20C5C394BE02E0AF2477374CD68E3396B9367191CB554E690D482EBD5930F775, + 0x2F1A582216580CCB9DF257ED52AE5E36CC5F06A2226B55C6AD85C0157A783194, + 0x18F191770339CC24723EB94B71F194815A370CC4545EB9C5F79BE44087E333E1, + 0x2269D902D8C7FC8A555A6D05A7F66DAE47AFA1BD52A9F91D243CA9C992F5EB5E, + 0x28BBA039E12B5B154EB1B24B1046D16FBB22CB1AD416C846426CBC600CB7799E, + 0x19D4BEE9F94BD33277D02B404F3F2BB0C6148FD34B257CA8E80CBEFD6FACD0E4, + 0x14A58198B71949154C5FE22892AE1E076BAF9BD00C2D44E406D36F97CD63E3E, + 0x3A62BFD31950A536522A220FA62F029200C3DB7ACB11DD74D669A6549F4AD52, + 0x95D8D0EB4D6D0F89EBC01B19D5A95165FE3F51B27FB17DB01DE100402B0B5EC, + 0x24FC04EBA9701B1096A78E5333B6E46D85DEF479DF2F1CBB0F7921E8F32578DE, + 0x2025759A9F6AAD09DDBE0ADC50C0FD3EA569890D72AB37FF5445FBA9B694A0AB, + ), + f01234( + 0x1B79B6B6D905CECBE7501B4A634756E487C1CBB81FF5EA9A8B02DE328C54AD95, + 0x12F50E62A33650879FDB6CDF0A0EA599CDABF1DFA32D6745EFD693FE8642C881, + 0x204FF78CACA2D73EBDEA82D7FD13C907EB28EBDDC160BFFA40546F88694390B7, + 0x25529DD18A373714304916C54D33B3E5ACA75FE4C3D2302A2E05C2A9811A0F1A, + 0x2A7278258685383D06E91447C56BE3294510E276B92718BC5EAAAB50620A6C67, + 0x13E04A325AAE556D30568D8B4D2C90BF158F04E7663DC339F002BA0F491C91B6, + 0x134F40DA4A960734FAFB4286DA22938DF6BCCFA6CF4007361254AB22E722463E, + 0x2E3E53A14C3CA8D66B6F332198BC1B984C06359DAFAA10BF90A32730C58C7FED, + 0x8A3FC9D83F411F6821F0A9F580E3904E20B4D055E12E202950F086B1DE38A8D, + 0xA2613BB78E29FB2C34DE4B06D76A900E87EECEC339A158A80B9FC0F61CA2082, + ), + f034( + 0x1E50EEDE2546ADA70AC844168356724911B0EEC320B45D1462598B073FDF9672, + 0x2710D7980E2E8DFB55C43B1167B4C556970CC6EEDD09CC85C4E0103FED5218BB, + 0x16FF214E66DC9468520D49AA1BA37C339FA215A51C4CEDE747B4B7F9108DFD59, + 0x1DB73F886AEBBF630307B59118DB40D21E6883BBB6344FE40D0A5C09AC8F72BB, + ), +) +sz_zero_bit( + fq12( + 0x14B48E4071FC8BC22A777CFC52859B641EF15C2CD436D789CC596072F0DA68E6, + 0x20BDB980C2B2EFF11FCFF505223515B6672B8C484D2F84211C40CE4D4317D386, + 0xC5C54CFDE1E5CF6CF5F597806790ACB159EF9975C15BA57FC3871A604635C25, + 0x17E86DCDED64D19C54DBC6297340204ECDC4F808BFE483CE27B549F6F0A5203A, + 0x25677340BB2303605C15B4E853EF9F8F9A8456B123043385E7E9E825B3EBB54A, + 0xE37E7AD4CD6B12CBAAFFFB65CEAE982AF09941A308AFFF03A711DCD821645D5, + 0x2AAAC619B1121736442F950194E40FD88D4A335BA0D5C417B12B97F935ABE07C, + 0x26F68CD1D652EA9606F6692AAB4715FC14790A2E5EC80404DDB8501629162339, + 0x270ACFCD313F7D5C85EF0724846D2DD39EAD286EF8549B499F61E22DD6FB6E5F, + 0x13F118A928595989AF8396C9F512BD119F76F1F4AB222804FDB048E429F606A6, + 0xE0652AD9E58E2BCBDF95D55034CA07488B99F3A22DC20C3FFF87A3A59E677C2, + 0x1D56E821EFFB243AEF7BD9669C0AAA80CE2D43947A53B9A8C557264963668975, + ), + f01234( + 0x2FEA11B67018C9CA52AF99195B80B9BE4E81548946B878BDA4DF073460A5D170, + 0x198EAE152022D2507433855BFB6C7A2A4B09F3EE13FB9ED5901B45F65EA7DDA5, + 0xDD3C66FA14064E50F1D4E6FAEFD249E7CDDA5EA33489A10C0BED5EF5037732, + 0x78A2D67A60140609EF7BAAB5E227D1018642D8DC83E7987D83C25B4FA39790B, + 0x308A6872D8A4001C90E57ABFAEFDF10F15CEA7874D07943B47558D88788B879, + 0x1EDEBAF1B397B69850BEA5F6BD1233BB32DF2F2C0421379E76DCEB0E26DBAFF2, + 0x2258CC9AFF91ADEA857F48874937AE71AA02DB794BD6DF00CB9CAFC3917E1D57, + 0x2F52ED754207F34A2C41D470241B1862BE7373299B91325324A2E5688C6D6C11, + 0x88A9ACFFE3128AE6675A4799BDE76818AECF80C7FA4ECB2FCA140056712D82B, + 0x101CC797BCBD07B56118958DC0AE890C1F0AE11A28C53A256517B8DF356EC7D6, + ), + f034( + 0x1EF6D39281F24E95C2799F4E1ED8F81267BAE861DDBA87CB166BC79A0285585B, + 0x1E980E82CE4AE52963B8ED05B544F609A7340847D12CD37BCA7A321163FE1024, + 0x2B510BB2FFD80F2A48FFE6A34E320A264BC7D058D7FACC481AB80E9AA84D972D, + 0x8366E9FA6AA174A96A61DBCCF20039ECE4C14E3DBE1E4A25E20DE5EC82970FF, + ), +) +sz_nz_bit( + fq12( + 0x1331CDF8014F57F0215157D0C8C68D756DFAC6B3A34673F6C43D14DC7C1DE412, + 0x19576F3A59EB536A76CA20B7BD178251324CF948F0F0C35F945D0D3570EF5F24, + 0x19AB0C9AD8DC39A2122C9CBD26BAE02132187739CE8DF2DE4928D09D73625B31, + 0xE350077B2EA69A645B8A0E890FF92BFAAA9077B7AC0E370FF1488519A3EE665, + 0x21237D2B14FA9C97A4B9E15DB5DAC813FC71EA8CC93BBE7E6D4A9847A9175D5C, + 0x1B81789F2DA6055AA77667A49790BEC2FFD63ACD91201CF12F1294072653BFE8, + 0x2AD785FF3E19FE63011770D0F795989AAFC58D067778AC0F886657DDE8C22CEF, + 0x2AC12C4433D751B2D2E6B62AF0AE8C084447982E3289E7584CB810609D443677, + 0x1811856125B62D9B8294F26D642F5D6705C1A59EB53577419F4F444A61A29666, + 0x75827CD1AB4EEB69D114F7449B1F02E6CEF8860A0C38C8EF672243234FD2EAF, + 0xDB0AC140300D066DC6FD5E8C184B59553CC3F4A4AD4A78BC9EDC92DDD1A8266, + 0x17E1B38FD36AFD5CDA5D107DE0C8B6301A62C1322F892815EFFCF31D0C0CCF, + ), + f01234( + 0x243E0EF904B5F0F33E735B281F377D934DA0942346ADC244393CD635FBE84B6E, + 0x256E5583912FEB1889BB3F8571FDC055A3D8DAB2292B0B2479DD8E71FA09BEE3, + 0x1EC4C62091390E3189D9E90763B696E972E8B1921BAF151EB87030C957DC933A, + 0x18DC079DDB7575E30A168D57CF9292144ECDEA807CB4192890ED2C55D3310C03, + 0x245DCF0EEB768BD9E366298C0CB393564487CF918C666D074FFE4D8F355A0892, + 0x75924B4CF2434F8262B43177298B386A608136F3C99F7B67B4E78D3D61A279C, + 0x28AEB9681B6D47C9BCAE085DB115EE32A02838BEBEA2918802ABD2317C66840E, + 0x10790E3160200BC1D1A96D5491756F3F4990877E84468405A5B23B9991989526, + 0x288B5384EB68F9D445BB96B8C08FA33E6C01E1905564B3DCDFC927720613C1FA, + 0xED0F29BF3661866EE6B07A05CD94C9D1671E77978D842A49D4EF6DF19D0F4F, + ), + f01234( + 0x11C2A1D34E08115C323932D6C86EE5AF1D080A39ED4F35D02C29853E7B91218, + 0x137A299486612883A68CA7DDD38F4C5791D43F235AA5473F5D09DD14D4504AA8, + 0xDEA7347E7FA7FDFFFCA7A990A83CC9E07A06B83D50DC2426CA5BBD0A83ABCA1, + 0x95C28B652EF4C5E4834325B942734DC6EE76DCBB9FB745A30296BE8446B7BB1, + 0x1E02E819E6368963215A03933C6B79BB4B612E3DB79B7759EEC57EA5C96DF694, + 0x1B56FE098CD901E5F605818CE007E04BAD95E50A8303EAB9198834D13BCCDEC3, + 0x508BCCAD52630C3CC664B7D8E0B06043C6A6F188B43625E5FD17BBBEC3A0DA2, + 0x115424D111E197026FDC49533218F54963F7E67BCBA85457CCFBBB876515A451, + 0x126EAB685C575F7899A3324CB3FB34A275772EE9E9CEA694AF410306E9718E57, + 0x2362173689FCBA9A6E3474E4CE37B102779C63523DD1DBF9EF4DEEA2336B615D, + ), + f01234( + 0x1C96E8C17D0DE95E38B1DA6E3AD4E6C2240D5B18DD22DF4B6ADC1DC7EE1CB183, + 0x2D7CBA92063CBC9E50252D0C4FEF348405F156AFE262CA3FAEFC1C28B14CB3A3, + 0x1DEBB1F54BD0EBF577A7D9F3A5145185EBC1625DEF7638FA7C71699905742161, + 0x2AEBCE5A0213CBD5C65B5F6C98A0ABF721A72BE453BA4FFC33B708CF60C090D4, + 0x13906449012C5AC9DA6A7EB5F37288804A6F7497113F04E6F315D6CB382C55A1, + 0x10943E601E8F4453B98477AB51E2F5C2C0CB2E6BFC6B190CBB7F36450112481E, + 0x2DA61CA5B9420B9134D0C787F2F0418ECFDE3281B4AF0BFC681ED3D338C8FC18, + 0x24C94B2733B9A7DCC5E11949A18AA146D79E3499A18EE42BE65B133BD8F6AE06, + 0xAE4CA01C187F602C9C12731C064BC7B61EFA6F48F1E903C024F4CCFB0C1A60C, + 0xAABB09A1921756C4E1DEAF34AE795AF30D80D93338B37614B6B7F61BFB45255, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0xF973ED83654A2ACCE865086895D331B07B16A1F990ED57271F0D9386A0D5E41, + 0x416476A0CA61873AD7109326E56DF781D6CFA4D79C6EA3F17BF1DC422AEADD9, + 0x11E9484EC6FE9C08EC1BECC1B4E89CD858AA7AA418B102F141B5C412C55DD6B6, + 0x219CE323D6C11583C6EECC8E24CA5AA2CDE29E3EA7D35B42C8085A3BC73DBE93, + 0x36EF36363AC8F3D7BBA56B2FA13087E0F648DA53BBAE32CF49BF08DEF1A632, + 0x4D8AE3C15ACE17A389EDBD1E21C0ACA9019FD04CAA1866E6052640216EA7C5F, + 0x1CE9D4E64C1D6E05170B04C99F5AA1060D9C957A716ACF197A55BE29E75C9459, + 0x53D12CCC97DB726D5B6BB2203ED1BFDA6BE22C94527BD28F0FB38300166AC9C, + 0x1195286A56BCC7DA5817A5D573F8392856C90961B07DA79B775921292CA31F98, + 0x13344AA486AA7B3617D0EBE2A4626BAC72194A225934F9757AF3848901DB0803, + 0x261FAD5A116A8A017FC23899839D4B217DBBD6C3F56CE39DBDA66354F9A1847E, + 0x2F8AAD55C3E76B63D616252695E5E3BC91966C766007AF5DAEE1012095C526DD, + ), + f01234( + 0x583CC2209A69CE3B7BF86653F6EC260341D591B2E1396DD476DBC6A706E269A, + 0x282159CA1C05EE3625889EEEE9F2BA0D4B31D4B170DD5ED517198FE4FC526035, + 0x229CB4DE35A67C8DD2FAFBD26E324A3CE0207F78D4A00E888DE231E2E71E2343, + 0x2474C7BB6AA21E5965EED4FB686ADD7A092FA4BDC2F5664CDF2DBBADBD1C52CD, + 0x26FE456A0D7A5B2C64D749C64D5AA217A2A538680F424840D2E88065F38BAA71, + 0x1E86EA8D290BEBDEB6FE4EBB6A4EF181B151C3BF9A1027D5A56387B7457C536, + 0x255632115B4C6F4888948656CFF76846215CD6546EBAA88A70B7A3D7C6A106D9, + 0x1215CD28CD0CE40C77D9D90B69071431E307974FD3C10F773A41AA7818E7C1DB, + 0x1022D3E2041CB865DE176BF5FFF07D2AE8AE016BB4A7B0D05A36B8AC0000FAC1, + 0x15865F45234A12CF781C47B96CBF3CC8ACE22619CEC8C591C47C7BD00E431D67, + ), + f034( + 0x3F2CE4B866271A856D20409693D23A3CFE73A39012F9B68A66D5AFD9C51E38, + 0x28E5664AC676E843F6966879004CCC1EB3E74E06F1A759AD470E986CED83A8D1, + 0xAA2093AA490F22D018F72CEE07B513CA2119C8EF4C81BFFA19CE4E6615109E6, + 0x58A3D8AA14D6E664C5AB32770AE11F5A177C0F248A6EFC9C0408A2E4B077D4B, + ), +) +sz_nz_bit( + fq12( + 0x2F64AAD936FEBC881A16720E229FF15B23C35417183294A63748EBE2ABBBC9E1, + 0xD3411657D046F794E79298CC07FE1990CF547EE9F7D6AFAA7B688F064A13D65, + 0x219C80E90DEEA2325868E485504D03285B7313D895361D9555D35FF6851E510F, + 0x869295EC7AE96C58E97CAC7113DBC0CC5CB4F11FEBB6C4E219FA0C7DCB1429D, + 0x141535E85F6894BEE315D8AF7DD7AF2707BE639BFF9D1061F9DF220FBB8BE482, + 0x177B46F45DB643D74A3B8DA8BCC0604D9A417DF2A33B0A2ACEAB2FFF87001EC3, + 0xF8082970D43A54511A9F204943C8451D6AC18B59BEF00C038BF20B84E1ED82B, + 0x229BC4094B1895D7189240C63376CFA8264B80F0B300680CE4FF5F3AD191A8A2, + 0x263BDB31A9EB2FE25DF9640898C2E6FD6D40D7DCF3DA39E48C1C7E6416537768, + 0x29968A400DD43C7732ED823CAFE830B2FF4650C7691A9C96C2A5535BC21B28E1, + 0x1A6A76F3C62E90841A628A679BBC33FB1D3E3D8D793F9F2EE0B50FE672F2F9AC, + 0x107E05CE14D0D095CD2EA0FE2021AAD1839AA48068080EE6F430A4092877CB5C, + ), + f01234( + 0x166286ADCE528D420B95A0AB20AA02FFE3960B99739927B4851AE1DF2D987E1A, + 0x1B8E931245D14FAAAD34114E4327891970F3D52EE1FAB18D8960B755E91FD3BF, + 0x221153181CD8392E41BAC85E0BA4F69CA9ACF17F8BB7A830C6BA262608163F25, + 0x1B8444EC9DFBAE0A0E43520E24B0FEFFB19E3D4A5B0EB4BC58731F6D43A82D66, + 0xE83B3949692F9BE3B1FF1DF5734A2CA31D2E2F1F509E00E1CDA68E4C8B42D68, + 0x1B8C9867508A73B460C97E2AA9ABE698E7D0FB16B7AD3F326CAE921BE4330300, + 0x2871724B3BC3B45F5E0E1D484BAD49AEC220E0D2DF111DC6B6A742356503FCC6, + 0xD787EBA84FD27EDA2AEC31D6B4DF3EC20AF64E89CC22FF863B09E37F407EC18, + 0x17C4905561551AD65DC205CC5399B4DF6B4BC2362B62639CF49A977DF2751DD6, + 0x28285D1399E2934E6E1AB4F537A87EDF2D7E5FB07532E8FA2C983B258F55F3DC, + ), + f01234( + 0x1482FB8440907E67EF33FF979D0B58E9DBF67DDA59BF659BCE6C6B0D1EF0D4E6, + 0x29B88203B1D5D867E1ECD6EDEA7118110BD379F9B06419083129DBD5A6A6C81C, + 0x501C99E0186D5EC71EC31F1A79FA93ABAAACC2B61BAD125ED860A9230484C7D, + 0x1658108A80D625272E24F9810F992DBA7C61408B9204955B3EC4F06700DCC4AA, + 0xC11D6AE25E47273C8C11164436DCA17FB99D5F2B37FF503FDAFD48D573D301A, + 0x14E45FAE7D589BA94B416ECDAC3ECFF7A8DB05651EBA2BB80E757BA4B79158A7, + 0x205F646CEDCACB9AE060502275582D88869FF3A5B9815788A98BD3AE83430A73, + 0x2137CCA43D6CF102BA93846A29E7D09117C7CC484ABDAB045B75D52B1BAE79D7, + 0xE956626DF21013768D91B15E71D746FDABA8B1C2B2B12FDDC8C52A8C9132CF0, + 0x13DAA3A91109E2B18F988EBEADF2B202814CE4F2090B677E78C88C92A42D60EB, + ), + f01234( + 0x1C67E6BE2439C2DB93129CE5E6F890A9C9B4B0B22757A4C04B0A97646B8AC38F, + 0x4F8BE05B7F855ED3941B5CF68748AA668A841E961C5010AE3C9B8FDF67424D8, + 0x16DFB122EE35E2C2E353BB31BB438C06A15873F56B97C0E673FBAD1CE3EB69F9, + 0x10772B8870AC0124AD75E01D5066420E678F1D9AF07644323680606BC22AC11A, + 0x2E6861BEC0ED31CF976C4C38BC77BD8D8C158F47FD9F4E1CEB87A8ECFCE4A991, + 0x23BEC66B398C145D104F6FFD831BD08134C88F292E3A9FEDF4D4D799A70BDEDB, + 0x2E44B5975D2960501C4816E3E82E1E88AF652BD76E97E6754A44100527818254, + 0x2D9C0E44830033E0F53453DDBC57E361E38AFF3B54D09B08993607F602FA03AC, + 0x1ED4801B27648D85AC2D2017C51E0784410425875C60D3664CBBB9142038F9BB, + 0x88A5F1C5F7B5A6D41FDF02C54958D17A813F9622A7AE497A78FECCD75A8B63B, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0x2EF8DD2CA940F6C93A997601A411885AEE1ACEE3C73BD2FD05E8ADE3678B8B82, + 0x1220F8F4757392FBF3B646A43CD380A2992EE817BA6A783EA27B4860F0458734, + 0x27A0646D68318B0148340645B533D7030F84E84433070E570AC3D448C2EE10EB, + 0x2557544521766CFF96F7BE43137CD8E6A1698334C1AD775BA800C0528D922514, + 0x234A2D0750E902F10268B4E6011C6B4515FF93C460EC5B9F5D8039F134DCA2A6, + 0x2203671736B32DCE27EE81CC108FEFB7EA0F4C36A37BBA7A8C589C92B3B0ADE8, + 0x16AB94E9C4589277F7D7A11D0F653F365939AAAF697453821DDC4D461A4A0E84, + 0x139529C7ABF16E7482DBA84E9C43DCB94952C042ADE5EFF817DB238FBE169B92, + 0x1A5EAE234BC29C2BCE1B559ACD3A671A875AA52B4E4CDCF9AFF7DFC4ADC1795F, + 0x63368C677B68CBD3F8814AE7A4313CE6383B653849549950EA8B5156653B402, + 0x5AB760D12EAEFF4190F19A13DB65D9816D7862C98B79C9AA700A00D2A75BF98, + 0x297402B80149F90941B8B3B6466DFCD2682D4999683FBB788A398947DC45DC54, + ), + f01234( + 0x2A091AAED65B7944EA11B1FE0F7F79C82A41D4EA39049E264591872F2CE61824, + 0x1C9F937295A772690316BA5F83ECDE05F5F2C9C6E1DE5B30FB255AE47EE16A59, + 0x2DA73C937B250BF8EA845E9C9A30127E7BEC67AD61FB48D2EF9570702A75F41, + 0x2A9A4581A53A6D1BDF9B9FFD865A6CCB37CD2417EA248FE992876FDAE2E09128, + 0x2789BD176CCD24837B3CCE2146248792700B3EFC2DD8474C349E91A6EF5E9B45, + 0x15018653B9B7430E46F96201C2A5E811CC44057C25A3CD00234848591214E40B, + 0xAFE04D6254212BE5C3F50E13BB6882C5A47B042199F465F8731944D21D12DF3, + 0x8EFFB4F15D64D2E596E54F07C8A0B1B20E94BA9400DC083152D84829F29565B, + 0x468415E9FCD69781C95B58634D47F42AF0166952F34D460F1642D7F1860EF3F, + 0x28D51B8D6ABC69C0997770C0D41F7B4E56D66548A36BA247268A7E79488AF74A, + ), + f034( + 0x1A84EF4448C54B36753FF8233E39CDFE1B9042C62015B6226F05D4E52AF99BC3, + 0x9E8A1D3D5F23CC74BB2D737A6FFCB4C975A20EF65FB56BEABE9626E80F9B1E7, + 0x2710E53C78338D72D6C7D38CFF85E6DBAF2B8C4B914BDBD58D3DDF2A830E18F5, + 0x12A3E7FCAE3899F57D2C15037DE8ABDEC9ABBC53E5ED14AE41653DA8CE8B8EA8, + ), +) +sz_zero_bit( + fq12( + 0x2BD142037852ECADA98BD40A0D7C98523212E69F7E0FCADC16E9DDE5D8E4DB5E, + 0x5281541958E567765DCD0EC40C9F1E168B6EC7B3B51D6B91C48CBD42C303D1A, + 0x1162CD406C6B1EAFD9D3D30F028B3E5C49A9BDA681F586134471978C5DDF049D, + 0x165A2F993D3E76C02A0593DF9655ECC3D0C54C61B7E0834864AC76DF19C9E7FF, + 0x207F61A2071D1333DE9A3C36AC5C2ED56084AE11A1EFD0B2E08EFD17C64213AA, + 0x16DA4FA12C1B9C57D9B0749B00D06785C5ADF1FD59EA99FD93E0688BE65162C, + 0x415DA7A10B5905AAEFA548AEFFC263A77472B9C5C1ED8154EB841C64A51233D, + 0x26E7860DA3601465434D2944E8A43BC429F850D6DC8918F2267691063791C936, + 0x22EBAD90DADA1737190B6DD3737B0A86BEFC30DF890C6F54A9CAC00F99DBD1C9, + 0x249DEC9F1448D539B184AC855DC4EF19F8ACE0A469F96E8EB3D00812D22621B1, + 0x57859C89D648EF0866D5ED78CBD03F1073B5695F27C756ADFF68DEA38B816DA, + 0x1782C84C3E2D6F4216D7387917E7B519DC351A738261AEF6204299333F73430, + ), + f01234( + 0x1D7C9A98D53E1B2F5974C21A5E41633CC775CDE08755A2C067F1EA6F93AB7B3C, + 0x2F24D56F09682690A8D455552056E1AAA6C4B55390B323E8CBC88D81EB1DF8F8, + 0x2D3CBF561CD92750DBBA903B6F7DE3B0457FEFB76509723021E2BD3E330A1CD0, + 0x20D20BEC4903F8DFFB858AFBC2119494408AAF7AD2A9746435E33413F1986475, + 0x139219B780EE15F969130B5E810E36D39B236CEC4D22AEFAB1F6418C16E13561, + 0x1DAE05BEA45AE4887A85B299C3E9392349A956CFD1288695B9381161BFA86608, + 0x175E9B804DB97D7969344C8DE047504DA0A90E18EEC86C8FA7570DC1BCAC2871, + 0x2E60785573F8E35172F59A3D84030CE026457B163CECCAA6344FCE1DEC903685, + 0xFE1DFCDD661BA014209B04CE71D6FDB877E9CB1D7B269D2041D99074CDC5232, + 0x1565B4A1ABD013B118A03661119C7CDE6214AB23A9BFE314BEFD7499CB92E88, + ), + f034( + 0x2253F15DEFE2B7C32D603A8983F2B7B74EC113C5940F6CF3D36E0969F88690F1, + 0x1BBFAD48194B8D95B8C2B277D18BF7FD65E38EB0899FBE6A6B53828CC4FDD548, + 0x5A1A8991145C814ABF4C70B90B46E72354E6CACB8CA7F890995F36C0BCB3F92, + 0x1F90158466E088953E7F973DCB084D729743A062997E07617B89CB1D3FFCB509, + ), +) +sz_nz_bit( + fq12( + 0x133AC3B089438BCDEE6F50EC7789AED6DCC01D0433AD34140FD7761ABC3FF114, + 0x238E8E22DD10C90D7ADAC641F676E6DE833BBA6925849EFA7EB4EF418467C0FF, + 0x2F518745D53154A1917E0CA0629A5D3ACE010CF556652B0A1306EC71B46BBE8F, + 0x1E59109C8665BACF83A5B70D50A0EF31D3D1DE2BF6961E651C8849165AF6C090, + 0x2F1E6C0BCD5C5F19D54FE81EAE051120EC3EFC903FA54293924E9EACA852F2A8, + 0xD2810329FBFE13DB485F5D8AE21D8F56D49D0F5F6609B9D7DFD990D846972E2, + 0x1B6523C57F2CB73FA52EDAB8E8B2FBABDAFC08DED7ACA19FF4887B4C23A7D570, + 0xA9A03B9A63D33717F91DA30A5415EBE068AD0E172C575680228BF477D9E6D7D, + 0x20897D02DB331520C48C65B2FD9E34957DE7367753DAA6A0C08AB8CCF346CB75, + 0x24792BE52E2EC96A647E123A1351012ACF4BA2323E2F51D79D44F8C14611F69A, + 0x14BBCB416EC560D579BF82C848B67404B044D0CAC6E4D8FBA3FD1889E22A4013, + 0x107C4EF82B44AA62EE11BE95AE9EF3B5FDE95E24BB7623D5EB1C8532F0911E5B, + ), + f01234( + 0xD1F9DE0811C7E82ECC2CEB1F584F4B067069203A8720835A7B01A790B66F7FF, + 0xD8CEE237488D85CA7F339B81D8F9A5F6745A720CCBDB59867423E6E31112EBD, + 0xA71C9D1D87B6E112707897C4C8818467FE0E252E9737393C26FFA13B1FD2C0B, + 0x258F76D18B079D272E58B13C6B78670D233B054044216CAE5A4DBB67FACE727A, + 0x1DBED4D70D6CED0F13AEC4FE22816733799FD23FE0F25205D81C98E3EF25948, + 0x1ED46AE374645E86EA049728A53DD04815A37215BEA2A63C680C16EAF9881858, + 0x186F8F6315DC64179B1E10ED699F0EFD3C68FAAB663E16B329C6DE3FB68B1A79, + 0x2A222AA1E093A1FD81402143E24A3E6383BE9FA72379A449332828183300EC91, + 0x21D7606971DD2601A12EAFAB607D5008202F6B15B4B2D57A6BC5D62DB96818D9, + 0x2B6A0E58BA7654E24FD8C1B77EEA735C3533C89130F8965D71BBBE9212EDDD23, + ), + f01234( + 0x287DE3CECF2B7564AF8A4D6A7C1071F6A41488B49FAF946DCE0B70E3B7D05971, + 0xC4E39E8A5A1FD2E54FA69E915A1D57C1C852D134C5D4F959C5F051126EEF833, + 0x14CD493CDDDE8690E241BC29C3E80D11776AC9C8E48418E435FD1C8E3D8BF4BF, + 0x1B2A4DDB3DE5E9D8F682C54AC81BE5A8A98CB6DD9FFAE174141CC6ADB5A49E0F, + 0x1768B60C02A6EF79F5DFEB9A34DEBC10250D6D3D31B7951F465A14F885A25DB7, + 0x17A4B17959C05E10B38482C8FEDBF88CEC736C0FA67BA0B65EA0B9509FFA1F35, + 0x29E300ACCA0079A0B51D385AA2473F8FBCFBECE882E62B0DC48A2463BD5A0EF3, + 0x3018CC84EA2743F2838CB1CA4C7D542E6A3E77604B3EEC4C5452ECDDDFFD8126, + 0x6E5DA66D4480366BB2A648E2E4E46FF10F084F753BC325E697DC921927E0892, + 0x4A4B8BD0E28E35860024E246CBBD7ABCA445DE87CB8408B89911BBB220CAA84, + ), + f01234( + 0x1AA8603BC4959E6D4931DAF10D8A193784C32DE5F236CCCA228F7080C3F79231, + 0xEAEDCDEE542C64AA020AC47EE5C040599A69FD3C9992A6A526C37D57200F054, + 0x2A67D1726BE376106613E8E01CDB20FE3CBC8ED5A3D8EA964FB005B3B89FBBA3, + 0xD0DD1301CE3E45D7313E1F0F75B43D14DE2CF095ACAD7DC456D548DF5B2A21C, + 0x245B71F4D33D1147665D4DF4B70852BB03F5A361AE0772A279A88E27A18CF629, + 0x1DF6E35D0715131F286D25BCE158390D6B560B261FF1E7D5DC0A3AF93AD293E5, + 0x2B9661F01843A9476E61C00F46F3589C674F179880DD2542D3BDFB2EDBFAF0E9, + 0x2C36E66F6354110168BB400C0911EB00DA17F9C2FD4F224461D238BBF3A96411, + 0x24E6A6E3F6FA1A845D11D1413383F8D5DF09B100A07B9D8D7AA770D088E1675B, + 0x159A5DA57108822198B52BFE3A4C3B9F7E722431581C767DBE118EE1ED492ACB, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x1E05D747CBC9EF7A6276535B1F9CC129A3107494D453D798D555A7BC82F03F63, + 0x2DCC96FA442E92F063B65EC47D530CCE02E82CEC9EEF9D1CAF75F8D65E4E1D23, + 0x218D35D0B029E034FC5B76F635A0CD03F040B6FD3B4160F2C205D4B0111E22F7, + 0x28337C8D744698970C9CBBCD1831BA32F6AE8BC5DCDF8C5B1BA25D4CD4797E45, + 0x48A219CE1A71F76FD0426689D7F13FFEF73061714462C028B0A2A342A312771, + 0x216168DF8AD406E251BE03BC1DC5E39AE7E60303535602EF9E5C8439215A4F61, + 0x127CC7217AE4B65492EB7AE0A572E002486AFD956AE9C36BDFDBCA8DCD3C8D6A, + 0x1CB03532F469D806CA1425450FE8D5151742733A03049E5472D8DF940FBC6218, + 0x1A2A24DBD02B6C6A5B648ADA1D8390ABD04DE670A3FA839D18B3E545F944DDD, + 0x203BE126C4E6A6CF47E3F082B24261300170F17ECB5A5E7907E66A3A8A4A8FA, + 0x7CA420FAB2860F0CC5B92C1A10B9FDCE054E2B9244386AD5699C9209A2142A7, + 0xC4D0AC790ABA7529B7513C6969A7CF51812505E689A97409EDD01651F3F2972, + ), + f01234( + 0x276CB2AC24497AAD8DB2F48441622F165E09F49D9A5E82909C72C3A55AFC562D, + 0x12D8F664C38FAC5ED4EA689C3B466CF1CEA14445117B7194D9A8959EBBED3AD3, + 0xE750809100A96EAA5250399D96957BE8A97E521E7D8172F2A06FDB4EBAA57DF, + 0x21CA40F972BFFCF5C27DD1A70A400CF118EA1C30D8A25DDC545C1EE120A0C79D, + 0x25C566B62B73E8BC256B01764819DEAD5993F6C2C5F672A7C348B07D7DF112F5, + 0x39A4AE58E9092DE6BCAF34B293038E8CF338963AB991C51087022B1E8CB78FD, + 0x2D4A3F4DEAD0903FDFAA004B6F4BF8F47861B22AC42BE1D0A72B8ADF4913404B, + 0x15E5882CCC10E7A96D2D1F65E4D54A14D9ACC6B3F500056A8AB3D6763196245C, + 0x22862C127194F4F43C2FB1C1593C172BBDAC3ADD6673E85AD6A26485BD2A8968, + 0x5B26AB30458EB60B767D5882A24A0CE61EEF9A7F644049609B16C1F96D02151, + ), + f034( + 0x1BDBF11FAACC053987CB94B53E965E374EC7B24616EC2CE05EB0F3B64D8DDF37, + 0x2A01EBA9C8E808D558A56076ABA87D11DCA462AB5EA2935688CF89D6DCF66F90, + 0x2A6C16FC8D979AA7F5474CAAC076B2CE8324D3AC232FCFCDFCB9AB0CF20B072F, + 0xF372943A4957EEC7CC3B24930F7FABF8A25B83C5774CAB58C06D329AF7609E9, + ), +) +sz_zero_bit( + fq12( + 0x1ADCC2533F3097EFC4CFD8FC001D7C8CA1C030E67ACCA2E1E868076783DAE915, + 0xE79959C14B531936F1382685D8C8CBF0178B444EE7411F62809844ACBD89962, + 0x13EFA10BCFD850E408ECA15616769BB9A9284EA7931BA5F9740265F864AECF7E, + 0x1A3DF73B5BED7D3B8072980CBBC352FB1580CD2D569475B996457ECD841D087B, + 0x22FD482C914B9E2CDE5874C7F3D5178B6F0DE78379B406870E5AE704D25E6E88, + 0x2E276F8F20CCBC65671EEF869EE62EF3A9BAFB73C7A04CB31C08CD3A48F16DC1, + 0x211A89F6305F4C8F09DA7DFDDA61296259CBE7D8130D481A018CAC8529A211A9, + 0x12AFF977F614F9479E9DC812F72C970FA1865AA85355EC245EDE8BA41E02D6, + 0x116994D57C50EB2B09AD035F67740B1AC7434D61B37FD413E208AC49837BFE98, + 0x1329ED6800A8844487FFE03B93962DDE543D8C2A909CD9D83F28E52390BAB760, + 0x2756869E98800F4663BB8114430EF3B3F753EA2FB7A24FD39529E366F4016DF1, + 0x27A1B5366474384F11038A3F7A9C27E71DC74B7070D8C8D79227422923100BEA, + ), + f01234( + 0x194770B42E7400005FAD682FA1C9B267255E1DA127BFAF4F2295EBA2E58D09C6, + 0x254B37247C5255138BE04B6FBAC7C678D584E5BA3335897559F3AE01A464C126, + 0x299BC04E98B548EF0DF7F7B76045DB9347A22CBDC2B2C7E30E882947EAA7BFF5, + 0x4CF32E5E7E6787C2D4BC61BD3EF5DCC196AAABDA3079F7541F28163162B2595, + 0x20ACB5FD7F55E48BC41C95160C3789AECC5E898B9DF55D774254AC24E55903E9, + 0x1BB37653480CD5EC9B34694202F46EFD90326BD8C152FDE5E0FB5BD973DDAE81, + 0x2236FB3E790B7AD22111F68577F468E17B5D3E7AA9B72E35D41A1294787629B, + 0x152CDF8D860970B14654B14F6A70D0FE86C60318ADB1E51D4F361DB7115052C3, + 0x1DF82952CFE6BE83FC27BE49671B6FD28491424C77D1F986294B82D0B375CE4D, + 0x22BAAE89D5F12DF9336257CF5C8CD47921359654DE6FE7655384C9D82D6FC5B9, + ), + f034( + 0x27C1F106AA6A4449E032A019542AD5F69B00683C2A268718B3A5F669F0DA2E06, + 0x1B53DC744884C3E5F2CCE2175AF45253A8CDD40C34A80EDD9E4E850B7673257, + 0x2FD38B95716DD0A5846F65B3D10CF8A52ED533BE97E4C39E5770954CE0D36D7F, + 0xE4C531C9D50934F23E1A5CF7A31CCA9C5F0EEC2A452F3FFD57AA4911E40F1CB, + ), +) +sz_zero_bit( + fq12( + 0x2A06E1C40DA002ECE18040001ADAECCD49E01589FFAF27C5C3D870A29E195794, + 0x1450EAF7F8CD14B58B36E60F84039268937143C3DCBEFC2E319D6A0111DD6BF9, + 0x24F98B0FD1555C7B71A673014806F9B58717C47F0FC19D57C40DF4356922D51C, + 0xA7AD7E733E7DF57AAED62A4DD2301D56022A554B441879115C43347CEB7DB8A, + 0x690A4F93E83BF27C9B5287DE1DC3208CD0ACC4B27299320BCB4B950B3B8E4BC, + 0x287A2897E9A69575EF2976AD9A948492792C463C7114B68DFF2AA5166179CBC2, + 0x19A137E1AAF388A932F53393957207BA4F8F4DFFF6FD351382D05F228676AC1C, + 0x2E723E5D466E3C0FD0EF35A9CDD6C1396904E8E990428A237F8186B3315504E1, + 0x1CD6FEE7F25CC35CB74FF8C00D364BD0AE8187763DEC48C4E8C17BED96978AA1, + 0x348043770203BCD1CF826FD959515CE4768D154D9CC2A14D0C852B3BEDDDF48, + 0x1A6B65CA51AABB1B0FA6F4126F233D3443D25F358DF892AE6E58534CB5C80130, + 0x2C41AF5E4B912CAE4376C70FD396FC3FA420BD1F358DCB7EE22AD1FBE3D568E8, + ), + f01234( + 0xA63172E11189195400A4F289DE0CFE56A1842094646989E31C18FECFEB8E71F, + 0xD6FF2F68B89DF61EAB5B66456B1EE7436E2F2E891D7B5F37421D4195A2822DF, + 0xD9AD88A4F8714D010E2CA71CBD4065A5FE2A7ED517E89F34013F0DE73BF5B, + 0xD59212A28C3A3BCADE02C1FE567E7D2D26B3D27DA428B2476E76260B30331FE, + 0x1D7EF043E721C491C8D3561BF5A2BAB5D8BADE4807D26A4430194B6F1E26A902, + 0xEAFEB1A35DADB55C64B3ABC8BE40412A1D69D9359207F830332F783ECD9B8C6, + 0x3A124D1A44C413179060FF51D2D7709BA0774395BE335EE56F30DA2528C5EE2, + 0xA48EA5D36A4F4C5C285D41F16FAB03E1334105DC18F8F0FD40A65F78522BAAF, + 0x2DEE90C97CCDFBD4E4B47A9094D9921D39A67399FCB891B9DDA23C6C856F40BD, + 0x468403926046CD9A68271029651F994BFF5E60A241561197D82560C029AC1CC, + ), + f034( + 0x1025837BFD7F16D55E790917E305818E447A391C005F362856AECDCC8516F4E5, + 0x192503F1AFB4D2E9F061AFAA25F011E54E3BB7BB52CED788AB2A9E3820FD4AEF, + 0x2200CA6502EF2760EFFC45DC11A8F5D5AE9F285879CC9C8A7258B4166C091F9E, + 0x4D3FFDCC5A99B495591B341240BEE8854397B890CA5354884DBE29E3840D968, + ), +) +sz_zero_bit( + fq12( + 0x20815F4BB7F18A7BBB59912D37FFB66A0E1C7B58EE19406383CB64A4CAC6ABD3, + 0x11A79F1CF9FFF6B81227CCAC1BB6A23CE7758E15AD8345BF5E12C323F74B2F67, + 0x1F8C1A40DFB12FD8195911936345FBDD127B0DDA5A093E781DC81C2AE691471, + 0xC26B6CA4A928055EE361A15465D65C6E549B73DD9F02F4BFA56D6FF8A624A49, + 0x1E6F8FAEC1931D91EC83D98DEC4C08B8C0246B5AA51050AD3F9BB470F79F8A06, + 0x18608E7B81ADA9E63278B53A574133ED58EEB506EA2D677803B9FC080084D799, + 0x2FBC69940451515F370660342FE4B9CE35BB517F4BCAA191063776CD064CEA04, + 0x297A789564B94369A19445DF9036F1F50A4CE9BF1442727DBD8E048F09C3C22F, + 0x9601E1D12826B73D36CD92B59C1AA62DA0264340238C59D75F9D01A2D579253, + 0xB884C4EA1BACFDBFE0720F1B53CC95B9808546459BC08A0577E039A972B5FB3, + 0xAAC484C536CB425EA1D722966029B3AEED43C5DAA0E7A850C4D16407979C12A, + 0x174988F1D15006B4ACFB79A96F8E37D67A3074EF903906A8A9C45697E2FE7745, + ), + f01234( + 0x286605F6C21012F9BCB83009920BB5791C0BD60A208173B80F7EF52D13CA6ACF, + 0x215B8C2B3BE1F622E500C34C0AF71BC0D16D39ED3E6B95D9D5AB137A340BC182, + 0x2F9A741FE844100F2E3C6BC20D1E61F0D4156F372A495382174929A92607F7A3, + 0x1CBDCA647EBC5BA8314C502B15341377235107986460687A88FC9291B459382F, + 0x1E1578BBA72AF9C8EE57CE8D016AC5D3D1DDDF525FC328C7EFF583814A3D0E99, + 0x1DB5385CFE671B656AC51152C1654D37607736EBC603FD808681F072DC0A3314, + 0x1865CB7F5042D945282DFEF7ADE66A9117BCF6B6AA33E850E685669BD8E2F487, + 0x1D4B493FD77E8CA11719E851EE36E258E4B1D3349E335E68F36D093CEA74B6F5, + 0x2F942EDFB02266F6A0071D015F77AB2C2CC88B95B9B3226E825385F4FB21C422, + 0xEA33A223F99E46AE77E286B5E7A17B727E3F55B64F62EE76217AEFDC74BFF3D, + ), + f034( + 0x4845D97CF7A3D7E8D98F4E4B7CBB5A7EA5CBB73C7B3807E9D58289969F1979D, + 0x7331BF20774AC1F4B15BE5CB520025CFC8A85FB2702A89F298BD646A6F8C608, + 0x399A00337777C5614FCF6B33D1292F35F14BD2E63090A6D4957FC558809F126, + 0x1988BE531A5E149CC1D511BFAF873BBA3AA9D37EF538160DFC2B284674DAEFEE, + ), +) +sz_nz_bit( + fq12( + 0x24AAE37B7AC66752F1454A7EF9B76672DCA921FABB1D5D593B5B444690E81784, + 0x1BE6EAEDA32BE69DBC4FE8045E43A2131EFD1E3A8CB344093CE9A599FE76DAC9, + 0x1611E078D800E0389AE49CDD2D0292292ADC6F4751E2079B9D6E25E8900AF6A9, + 0x1FBED99F66E5034FB584603BA2BFD57DEF929F1861B767F8B22A0CFB99108B84, + 0x15E1CDD13372B1F680CEE5CCA7C6F77CE70DDD5726C9CFA24577E4B972A1156, + 0x1BEBA3628E85178F637A171BCD786F4476B5F6AB19C7AAAE3B3F44BEF559351D, + 0x2558F5B465556989F815BCAFDE810888D465CCE2C3E36BD4779E6E49723D8C1A, + 0x2E9CB1DFED05324166FC9FD405F562DDAE0D61BA2EBCA979267AF0F51B1066E7, + 0xF21CE6288600A0EEBEBF30F9A0BF489F46D1EB59EA3CF8EA3C94040C11894DB, + 0x1DDF090964C448E33E538069EEE13AC57C7909B0C2B86EF50F579EF798D3A527, + 0x1818617404313E5C4963C091B0242FB8EDC6E2408D8F4087C090CE6A880E7940, + 0x27B7A5E50A41B32996BFE2A22B644CBCDAD303EDFBF1B3DB36583427726B08FA, + ), + f01234( + 0x2CDA5220EA785DFAB08664D51C902DD563C74BE6C0B2701AB6A528EDF887EB61, + 0x293514227A3B769526A26F153E30B3A55EB07C7B547AA15058244CCCB56E77C, + 0x2E300080A8804B4E7561A08E3CE8166E5D117F4E6897E9B922CBDB5F2D184583, + 0xD73C230ACFC58B7F47B12D7D85F901AF73053A6AD1437C95A30751B0BDDE3BD, + 0x197321B529D364F4B8D0EBB20118406082682429771B7184BA97E74AB891B9E, + 0x1AEC0D10CE512CFE13F35078E9DE12DA42E3398C75BB929D5EB6F50B3B2EE768, + 0x8E2B5955AD728E0475819DE9DE5984B8DD670E7968A7E5C63DA5B9057969182, + 0x7E243F99958543BEE022450AE2296B1D62D72B4F335C586502AAAF12CD4BC1F, + 0x2876EF8C90F5EC50D4117A5A972026A2143062726969BBB48ECC60669D276A8, + 0x14D8674D0F3C229C0874470D4F4C14CE7D2404934EB3D9B5D06D0F0D7A66F219, + ), + f01234( + 0x12410486BC084139E6E5E9CA341C8FECE5650BAD776C99EC34DA096149DA3B44, + 0x18BDE1DCAA02523ECCE04BCBCF3DEC378CBF79186151002D3A499B8E4477DC9C, + 0x1E4866B93BA6F62CCB9CC094B9DF97BDE7426802F42A850FCB32B7B1CA024DD5, + 0x23D9D58855BB9F2AA7A4610B13F872AF6E174D47C37129A6DF4CBC968F3C20F9, + 0xA5CDB0EA1005E9204B1CC90DE53D5893932D7DE2A52C2DC5E6FE02D34521B55, + 0x2AE2165B662B176629F7690530A7496129428A6300C6936E3A88ACA5CCE9C2B4, + 0x2FD11C810193AA9F4BA007B8BCA4C65FD0AA94FB786DEEB8389DBA248D234F9, + 0x2DA642A6651FF090E4D932D4338841F90E666F71661E2E2C32D73C6FD78CE402, + 0x28AA0C8E754A1A659E45DDB296125FD966ED010E6510D1CC60D40AAAA4B9D725, + 0x3031CEEDC78A19F485B71640BE4691CE5F661C60D806A4B70669A1E19B67EC3, + ), + f01234( + 0x1CFB20375B4FB9312E32D7D3F2D3EA0BEF0AC0057E6E5C2E6ACA53CF6D959FEE, + 0x2912E400CC6148B78888E972F7376BC3A267CEFA4D85BBEC6FCED64169AA5D27, + 0xC0A60A067A7FC7842D27CD83C3A9CFD69CE7F808D5ECB5BDC28656829A2F240, + 0x910B1188297263D1CAA60992B721779AEFD8FF0B1C2C4D9A2A659FC08CD664D, + 0xF7684A49C87B50470188FF2C52F1B04EEE1324263D08A72D740CEF828D967E7, + 0x29F7A0A65D847371972149FD15368161D12B59074A5781723F0A08371E4D8A2B, + 0x97DD26B23876F37988BD897D27C4A3F86757AC38EC3C093959105BBCD02D55F, + 0x8C6A5523F0AD9737AF3A2F8E080045D385337A472A5C3AE3BA712CD52253E0, + 0x1A60C4B28E1767E9CB3436A1B722FDF8BF8C56210C57537283D9F3C19073710C, + 0x28CC29EEF5C97DC9E0E4F22FF017B146944E362A27ADE35F06B7FCF9ED943A70, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x2A5C27B37E711D20A8A955BEB7F5705F2C5779CA5F70CA744138EC38048335AD, + 0xAD4215ABB3FEAF42BFCA3CC677AEE3ACFCD6E9F5296FF4B91ABEDC3E6FFBE5F, + 0x2E29D049F8CDB925BF4E19BAB7567D443022CAD31406951BF5FAD89C728916E8, + 0x15726A15DB7D789ADFBAA227B6FA500318892C0C109A540A288C7E6C6CF69ADC, + 0xBF4956EC6365DBA82073AB5D6D4106161F29BE0A04144126386C74B432551C1, + 0x19790529C54D94CF068D2E6DC1D66162805FFC7212A0FDC041EBF8A5B7C90866, + 0x249A2973F21BBDB1FA0CABD9C22271B9C91C9066E434B022F8DBD028C7658136, + 0x1BE1A3DA5DB217B9016D7E43C50B74AA2CC4D7D186D9865D5AA1FD78F3D4252, + 0x224EB36CF562E72602A3AFAFE2447C1EA7561B5789B7B2C095F3DB845B14C82F, + 0x49FAE1FAFB5604420C7984B2BB8A01E11C1F44C3ABAD941C84A8B63D2DE9C66, + 0x49F8C5CC8C930A72DD9377A62B2644A1CA5EE50FAB4628A166CBCE0260A17D2, + 0x235F36C1B86CED3C3E57FD146D48055554FF9F15C019FFE4AFC4FEBD797A4AA8, + ), + f01234( + 0x1421EC987BC0E07347F6D97688AE64F330D9D71BC16551F1E4531DFF6F960193, + 0x173B0BD9D1D56E4E67B40049D6FF6FA9758428483AF17510AF102EBB113AB885, + 0x297D35BDF68634C5025B908C438347786C5685987A3FF0B37D2BFE032CFC0147, + 0x25334353E4E7AF933EA71B11EEC7B19A251C48CAE074A0901F2C7D8319B1FBAD, + 0x2D9AA44B9CAC1B03A2490E281AF95F947D88232B707271089DA9CE328E8E53ED, + 0x2B501A7E9F3FCB6E30B235D0E14C484C53E3C2CE6E2AC16FE7BFD2434A7AAA63, + 0x1D62435394AD20C3776E63499D490E957E937ED9F65AA25CDACAF40390BB09D4, + 0x1338C271D0F1B64EE8F3D7E1B543BAA3C9AD07A931001A2243B83F7E193CB9C3, + 0x658DBEB0D74AA91663A999E4EAAD8FA8975065F9B3FDDF3D1A47D9DD1CADCF7, + 0x8A21AF391AC158540F72177866CB6E564A5A23FB965B1A6AED7CBBFCA45FAA0, + ), + f034( + 0x293F4D1B6AC9FC68A97759FE36D58BF022B128C2A63E074CBF121F43238CB3FE, + 0x47FB716D4BD5530485AA677607D58B89C0CDCEDE58DF21448AC2EF9384F5B32, + 0xAFCD985A5E05CD53CCD8D1705AB3EB511A9E57D3BD62F1860B1737A3815BE63, + 0x156AE3E60D744A0374D55CF21741D8C118F63E7847D74BBAB0A9AA903EF2D6AC, + ), +) +sz_nz_bit( + fq12( + 0x1B63B257DF64421EB3DE76BA17AB7DD56CAA06AAF80434D7E0803B4441BF9FA9, + 0xA2FBD355C647B7BBCA77798F2B0D7364A5F4BACA4186BDB11113B611797EB9A, + 0x2C93CF9067FE680D5F27B5C85E698079DA3887DB0EBED140ABDE68BB2668AE79, + 0x1A9879CA77D5456EB4E56EF620F0DF7825B3E259D82D6808F79C8BB8A4AD6F54, + 0x16BC401B019A07EEA33A43F7CCB3C602041C469E71D21F6C69089E6F24964073, + 0x9B53800795129426F92791180EB145A110A7E73DB25179439BB3D376AF545F8, + 0x106A77E95F53F3F38A403F0438B9FB042F1C8AE2A6EB0196EF50854ED7C9D48F, + 0x2EA3A878C33CB12AA33EE8D7CD6083ABB63664628099270E4C8E880F737864B6, + 0x222E8A568081BA1C309B80AF1E655991A0824D0185FB3741E23D930183A4C715, + 0x494964DD34F62D3B3CB218A6A82913ACB8EFDDDB6EBE5C2F8A14C00E6D803BF, + 0x253E52BA2E74C0928DA51ACEB6C8B332F134B1EAA3E934EB50D2EB05326C1997, + 0x67796733C41964C49E344B4C697FC5C5E737A7E5562509A76D74315A397CF49, + ), + f01234( + 0x1235E80539D6B9044C4F21EB66E4C7863994E6F57B0B009063F28BB22185CE09, + 0x128ADA04FADCBC6EECE1FDEA41342F93730000EECB6D29FC3B632E3F1DA29E75, + 0x155E5CB97F77744126707F0561E90C6F6F56B16C76AB7A7C0EFEDED15C703119, + 0x28CE8FFA8AA99809A27B66B043BBA85F1BE49C475259D156EDAA6DCC9B99B11E, + 0x13D40F4CF4AD24E145FA867CC8457F8866B7369B1160DF03DF5D28C980A3761F, + 0x288AD74D978EAA24FA6A74DBF197DC5C5CE645EFCE375F58AC28BF5B0F15B1FB, + 0x16DF035D856083C15663CD3D8F405B579A0DBC5E0B33153DB80925DB06F783B9, + 0x2464E5D4501DA94273E9C41030B49EA1FBAF9E6F559AD07CB3F5809D600FC3EF, + 0x14188B1ABF34AE82FF51FECD0225CB4E69FCECCE715A0F6F9E4ED85D2350CDAB, + 0x8C50400C13C3F5E7AAC1EE6C689D9F0C7BC4A2B29231FD80321E028CA49CA9A, + ), + f01234( + 0x1BD258A6FCC4B910158BAD87EF01B13AFBC19C9849C9687B5CC83F331330A48A, + 0x21A87A382F06DA5EC95B57AE1BF097F4C312C8FC554FAFE1DD5B8148933A94D7, + 0x52DA0D93ED2670EFA98684934E558F06B0CF932106D0D1965FB6BE13234553C, + 0x174A4901BFBD28BA9296AD4F09E4B18723E1972B26E65A98C939325FF3F4DA1, + 0x18C69BAA0AD5649F441628AF5019273DE19B0B01A5798E5749857CD764BB80F0, + 0x2BB217C6BF407CE1A65697E191ACEE4FB9646667550DCE3775BE23184081F8D9, + 0x114BF43EBD37AC2044BF03A454B0D5654EF4133C1ED3FC78DFCD1AAE5AA2E5ED, + 0x2D091E77B37458CAADDF77A50F86857617A2C7AB32B639E5834885A207F84578, + 0x14C70C2BA6A6590C6F933116C235203E1F5E3FF11D7F4BD2744BBA0B2CB31CE9, + 0xE867C970D894F27EBF6C51A4BB81E3B758CD28CC4A6223689634DF866F83BF5, + ), + f01234( + 0x1A10EA2CFC2D29658FB5543AD230A7281AAD65055D51E6E764891F8BA02D0FEB, + 0xCCFEB85F9106F75604C41F226655915786847E324D1226D2F7079788735CDC8, + 0x19F46A0F13DC5CD6F4AAD9EFDA1CB1BF3A9CF9AEB52553FF85BB057F60C0318D, + 0x17065DED554B767D2EDA64632E6C2546CC191CDF273D9D5C4EA2114A960536, + 0x2EC8A54396F61C1A014CF9B460A36FA4D1A95D2C3B42CA134951E07E08E3D846, + 0x574F7ADBDEB117835132F41B6288F977DD6049CB62F64B18DA295268A1E86E3, + 0x17163272066CC6F6BA0CD368CF451432CEA4265131AA25539E2182B6A5048B09, + 0x105583BDA7D3B2ABB67FE20FCC10F0AA8C6B6A0D1EA5ADE56A0DAA1EF07DC9AD, + 0x1E0454685A0C952FFAAAA29E6C579ACA9E2CE68984EF4F8CCD2790B5D955710C, + 0x3A60B9066502CA6ED1C6B096ECB0ADB33A2DBFD77A9882672202D87E8240F1D, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0x2CD5B85BC731A4E193E098C049CDB0D875300EF5039B327354CAEC2658EFD293, + 0x1B5C16E2ED28921E11FC87604236693EC0C7E0CEC1D0251BFAC7C5B0B4B04B2C, + 0x2DD4F9BA3C47D749D4A76E31886AA351D446265D00796BD3154E9F7776815F6E, + 0x73E02A4C5353ACD9599829A81C3E88533DF10D1043026F32B9FB7F3F8AEE3BB, + 0x1F12219BB11ECDB06E0A6D96B00BCDBA0D2C53ED24C582C33E563EA7C9FE9B4D, + 0x1CFF14FDA3F4D601F256731B02D6D97D80DC3F24DEBD827AAB212D5FF31A49A, + 0x2DBAEB454997DEBB1A0E295769A357A339065EA1B87E611CC74AB3BE2D40EEFC, + 0x190E4E7FBDF5B25943D14F116D092FC64C303F228037F423679EEA0A93A90E8E, + 0xFB9C77CCE3FD929577AB5FBF4B889C78DE466FDA9343DA327E21B5E1B336495, + 0x262ECE13764BB15ADBF6EBE80BFE04B68E0AA795CFF2407E2F15FBF4B12E9C2B, + 0x28378A7089E7E5E6A8950543717B1629E34C44D44DDFF1FC7290851B723ACB00, + 0x202B2926B9EDD2E52AA18088F516C70C079064A3F601659FF243C0A7442F01E3, + ), + f01234( + 0x1E68C5AD1CB163DC04B0313C2C1813B86879660813A5C270AC9A25DFDC777745, + 0x170CCF42A8EB5419E8D98F4EA773C74793C0851BDD425850E5254A2730A2B7FA, + 0x1BE7EC094D66E679A8DFF4959E680F4E9DAEC64A0719E76600A224DC698677AE, + 0x8AE39B4A8CFE1185C9005E75F79A1452C358B5B292D6061CA3096F8008B66D0, + 0x28F87C6CD697CB5CD2B4678408C69990B0CED4F35F4F6BAE83093D57301B1A87, + 0x1672D2ECCEF8765CC980CC501CDACD749A6C1CE2D6157160B73BEECC742B022D, + 0x1F1603E821CC2168B84CA3BB4A0C19CB63B85B7227B849713512CFEBD99FCBA3, + 0x1CBCFB8D0D7359C67C45112B23908449B05ECED2161C1F502B492692810AE657, + 0x151BCBB3D5FBAD756BBE525AE6F98C0DF215F4AF3E86F03F353642524200D42E, + 0x1BBB280D6566A39D91D8B8921E0FEFC96E61A651284308948123C3FB8D74FFC2, + ), + f034( + 0xB105453873713EB3CF25A570BE27D54FB8F7CEDBB5A3549E6EC9585021CCF3F, + 0x1F67A2A399B0C32E46D2141226DEA3BB243E839E675B5D0FAB7F4496DC4E14B, + 0x1ACAE2E084C6A55DA79136370B042F49B3D9778B68723DE8660936FD96D873D7, + 0x5C88C11015BE7DD10EA24025215A52B38C649F6DCBDC08A05DECE4A1EEDC35A, + ), +) +sz_zero_bit( + fq12( + 0x2D705D282F15191DFE828C4A509FC63FAB7B22A44519C4D35D3A86515F772829, + 0x2BC98DA3B70E71D950E2B2AEC626EFF71224DC8B67EEF6C2E5FAE6AD15C5E651, + 0x10BF733C8FD5271F72E91C74D0744983A7942213E84F2C58B28CC381081E5991, + 0x15D289AD23F1F21B1E536BA333D1601A1A28B5681803EBF13D40E296B3EE9FC6, + 0x18791E4C83FCB2AB31D8F63B091112D40A0395EE732B1C1AC17ECFAF470E3944, + 0x350F987ADEFBFF74E95C4E615A21B429A73AD4A80BC9A777F76BB8E1B3D89BE, + 0x166465D0C92959C367BB68D6BF200E6954E965C3DEAAB76F7DAE85B3798E425A, + 0x18E1844A5510699B072D5B1ED6A2FC993099208B9E4FF5BA5A63BAB60B0111DD, + 0x5554CEB59C32CC7C44869C3F6BCCC8B6EC8012B14F5919AE82CCD90B15A47EA, + 0x9D07EB146F3FB7810850EFA2DCAD8DA3EC14375D5C3B3853F59D9F79FFE055, + 0x1206892E0168D2AF56048B0D3431E4CDA9F62062B205DD288B74D9C8360044AE, + 0x1757B9579A046594DFE7DF4115C1626A33500ACF7F75E08A6BFE41EFEFE2AB76, + ), + f01234( + 0xA0614B134C0FDFF485133B88534E7A1F79C32C00733E08503DD5E5B67A84981, + 0x2D102381802CC21A36106B7D4625EF2F6BD8F06B9072F30F3118982881A56091, + 0x8AF0F00665B9A24925EAFBE3B66EFB67BA4CF00C24D149EFDB5CC5D03EF00C9, + 0x2D48E8E3F595FCD67CE167E4436EFF3E32C0903FFB2AC6CE9B0634178C344DB, + 0x2BF085DD2319F7FF1616298192CD9579F231E1B3921DA00A699406DB8E578DE3, + 0x10C197583238740EE412D5BA8356BE14A38924C00266410EA398B22BE81F6957, + 0x11C9E29CAD7741DF58FB7B328436A215C0F02DCC2400E13CE5947318A1872375, + 0x1A670D4E607573DD4CC1B7581A50DA1AB568481B8B5C8D4309BF69D95A3CDA1B, + 0x2F05BDF9F56C6AFF120C64179282CC18AB9DF7F10B8C66FB4678B8A13B7E3794, + 0x10B0B828F68F40E5BDA3F770009FDB0150ECAE8D77BD0CBA3C66BAE0A58E9296, + ), + f034( + 0x240BD54A5000B83BA2BDCAC9B3D72EDDF5C4658BB888CE3829999D997D9C11BB, + 0x1D8E8E0C8FE378E2995DA60611E1E8F77CA8C972E9D270116A1A5844117AF316, + 0x2484B3FFB12B378FE7299BD8D9610A18654E2CE5253ADE555DF43F05874161FD, + 0x1CCF29A59FF7A9C6C95962FB9A7659C5E34C82FDDE2BE92F268BAE2DC9F2B063, + ), +) +sz_zero_bit( + fq12( + 0x12A54D49356F638D0D95C74F35EECBE31246692E664668A7D0A574AB131EE37D, + 0xD1EBF36B15FC393318D3020EA0F3DF0CC6884503DB70216A69EB86537C4E9E5, + 0x1BE0C32C5D2EC895C5869A3A04604BE45815D0C390F280F32BB1C3B91DBDA884, + 0x1F2718C714A3001E98FC95187572366BB18620F5B3C5492A8EC2C3EB018B30F6, + 0x22FE4588CE251E94705CC99BA49177D6BA17E2697BCA27B3770F6A1817852752, + 0x18A75C213D6569F3DF57B16D99D2B619E45E3AF3CF5CCB32DAB1285D92F561AE, + 0x1C1C6C50B61A7F99879ECE2273B953BDE83C422B60738BE179FBEA031250DFE8, + 0xDF2068B30589E4E65374268410D83DCA5707727F61AF8308A4500AC2500425, + 0x26B476DDB910F466C131B970895DA372128CF39A0598E11B94E2C088ED86DBBF, + 0x1167AD357999598F9572AD6C20EC981EA04E1A8FDAD94B12ECBE087AB4A2A4E1, + 0x4666E1AC285526A0C5E7752D34C21BE4455B5EB33707B10E65978A949368558, + 0x1E6B19AAE274DDEECD10B18259E35DBAD63CA7316DAE75B6642834ED006962D6, + ), + f01234( + 0x1ADC04119CE6EF3F69ACF600D7733F2E63C7D619C163A625DD12C91F7A722BD, + 0x2976478278393FF87536673E6F21D8684B3C7D0C5D2D92544AC454E0B52EF98D, + 0x1B4D3EEA32866A6F2237C567EC57FF59DF8AB89E094883A78F5DB5A691EF0DBE, + 0x1515CC261DBDF3F029C29262A5C24A547EDD8F537D1DB6046C359476D14F2B7A, + 0xF1D35B380B572C44B3804B029B0DA79B93D7F80BBEA5B2EA434F6F8EF674097, + 0x2159E94ADD4684E87781581EACAA068F91585948396761C168E73D624BBE00C5, + 0x2973A891E1CDE95B4F4B75B51F674A016F441FE3BE128363035E2436E371D43A, + 0xF7EC558155ACC5F084DAB755A4B32FFC986DC9A9C3D808119A0F381CA09280F, + 0x27C5BB1B2ED0EF4A0F9E80DE3F94F840499E50FB5EA92431073057371DBC6D44, + 0x2BBA56E52430BE4743B58F8CEBAA5AC6CCD1AD7136278DE686F2A650BE4A63FD, + ), + f034( + 0xEA6BA9175BC603B29281BB90B6A7EBD839C7B3C918BE7275BC00250D148615E, + 0x21503062304742F10D0FD391A8C33AE321C8110AC6917AF2C78D2F77FA003EB3, + 0x14A5CB9B836251A50FDE9A82D7F79031CE0B074A6963E733D086CBBFAAD87859, + 0x363C47E09846AC23A129BFC2BA0C7170967B76B0114F75B7513268FD851F688, + ), +) +sz_nz_bit( + fq12( + 0x1EF7A91D6534830668BB8A708F0CB32866BFEB7BF1F2CFFDD9253E7A3A540FFB, + 0x168FD2CD79238490592D5943FF6634DF3B60FA0355C8A18BAB7751F1BBA483E3, + 0x1B1E426802593576B1B4FCC90EEFA7EB96F5BE1359B05AF1C965FDFE41CF7543, + 0x10EBC7C9262FB5D8ECF06C5B894AA6295471F1F45EA6BDE235EC1C6174E3C3FD, + 0x141C00385946E578CE9BEF5915D4B1B1B89E7DD02686715B1588F6D829FF95FF, + 0x7125165DC325C3F1AF9564EB0C22B299ACCF8DD01FE09A8E56840E2B5B6A106, + 0x2403FA4732E9FDCB1A4F077989BDFE83C349D137D4B3A012C859C75CBC8EC4D7, + 0xAAEA134ECFAB9305B0D04B5065DBC6DCB8B5A9B6FB5AF5963FF9127EAE0565B, + 0x20EE082B59BD7E5C61B4BC1FD6AC6F00B492199AC535839E42AE5CADA338D942, + 0x14E62409E54CE3DEBA05DDEA1A775516F5ED3BFE3F5AE797F77E098B0D7147CC, + 0x2FE097537C77DA517763E2441A9A2A9CB900669E09E7276F06DCC688DDBBE1B1, + 0x8FDFBB9D64A6CB71ED7361DEE31800963BB40C611743DB7558695FCC1EC5A5D, + ), + f01234( + 0x1910EB8748AA511FD66B0520DDCF6D0088E0AF3543FED81B0A8DC9FA932E3F40, + 0x19B6D7B6664BDF68502EE643ECF5BB391238B197C6F56F7630BB874510EF8312, + 0xDF7BFF1305B9C5FED4C3EE64716F83F50F63C6B928E8202B0F655D800B9D9DE, + 0x2B26285615ECB9073491F6CED9092D063A4B7765D077FE655BB7DE2805A9C9BB, + 0x21E8394644C12CB57960DD7DE9B67C95913A917ABFB03E72D1049F35C661730B, + 0x246899C4D62448CC8A1D3949034CC7E474C024FA0E3F14722D3FC4352C64EB97, + 0x23B4831AA7B8B47F517C5337A4858D5EE6BAA062DDC61D1C1E2771ED042948BD, + 0x6D9EC289104255A97B71E3B15AE59B95EC28399CE6C8CD8499BCB6CDB781BEE, + 0x77AAA568096438B5200F79F61D7E1B64E7C11890D7A0FB25AE66659A7627BD, + 0xECD054F2F2406F2137669C4BA12E718876EC1C8880F1FAF41267C21D2E5A0FC, + ), + f01234( + 0xAF09B9B0E2C31AF62AFBE87BDFC821BEB147CE581CAEEC24F7A2219243AD44B, + 0xF2B72B70A86EBE6A279265669694392506C179AC4E3EEF0594F840F7B34676C, + 0x1189FD52DFF406EF2CE8CB5B4240B2DDDBA2A742A55CD7B3A55F8BD695BBC386, + 0xCBBAD0E289134092FEA14D5D839F92A68CD5208436825D7363EBAFBFE1B053D, + 0x1DFCCCD42995232F99FD844CE53FC112A9CD498CF0BBDCBBCD4D58E3FFF2B598, + 0x2822F3485B0291C330AD8033DF69B98438FE284E45A8813ADE34580E043E5563, + 0x20C197FC2E1AC065BD370A3072C33ED605D0BC115B30672FCAB5E70813906268, + 0x1DB64E73A6DD6A492E07D0AA2F5CA9AD9B98F0A4765A8FF133898BF783236D2A, + 0x29384BE8AE8E3448313DDBB3451BF6045154D9AEDC5EA7ACA36B338C895D21C7, + 0x112D76F1D1FBD6BBB610DB99A01084A6E2926AA85C03AE7EE2926B54E0D2C433, + ), + f01234( + 0xF7EAE504BC9DD38B7AD1E4614F6E21F7E6CE5128DCD756FA106F4D74DF41E3B, + 0xF4BD4831F80C1FBF79BE1961A451D001EFE97B6B02404092E330C661266E207, + 0xB704C4A016E149C4655F622B0153BE0D858953FEDC8269901DCE49D56DBB392, + 0x28F379668C6FD573BC7222F4D83980801B860BD5189684245E1D38FEC809025D, + 0x25E8BE88E470FB3756B336F48C1A22839187300A91BDBBE8A4089986CF6745E1, + 0x7A66C84B5D89FA3FB2784596E0595D50A65E8D6B5035D77E08426ED2B0305B2, + 0x1509D0705EBC7D846A468A6B55E4FF0D44026A71502EE3A6358E6FB48B1F40A6, + 0x215F41E5A38083FCB029E9BF903B420048D730E158FD3F31EA0C269DF93F2B69, + 0x2E00E9338F48D5DF99B00B90FDE68F2D40FEA3F329B65EDE52976845741DCBB4, + 0xC129D07C944F28CCBBA83F7686BAB1C6905EF30E68D78A4BC9375B580F8559E, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x1AA054C68A27347D805B02BFDDC2F99C4CB363B97D18409E51D6760B10901AFF, + 0x2888CEE0B389778C42BB1F6916E65E98D494DBA34AC1B2D6A042B362C525FC07, + 0x16E6EB359434B4D9B8A55314F5FB608918228DEBAAC222636E30225826482B51, + 0x25E1D1F28F61A3D14ACF1C246D2FC775C698292A2284BD6EA5652F142126A83C, + 0x16F24289C4E27168E096F4271498C22AC496C3B5A297E21B21BB0296F1EDF2E5, + 0x125C46E1C9040CDFABDF5EFC6896262C454E129A66DC0F990C1733C812696CDD, + 0x2B17F45A4EBA1CC0F79A983A51F5BD7F19FBBAD831B59854D1BAD27524E9E6BA, + 0x2E5DC7CD569F0254408DC4C46EDC6F1E9E2D0EFA3638597EF84FAEE95090438B, + 0xDB82D9BF443A372D2F35715BBC8398FE4D9EFD6AEEF23DADA565DDDDD3413EF, + 0x29530F29F99E47F9639E92DD7D855346F4517D7388A01DAD1CD46E9083A11DD0, + 0x9D9F539C3834BC615B2A1AB88875A9ADD02BDBD44A858B12654B75F7557EF1, + 0x20666331EE197E5D9EB4D73163262AF8B912750B618C3D563898511B0100275C, + ), + f01234( + 0x25D1629DD82FBD35EB30795FDC9F25C7CD53ED2921CEF49BB40F25AEA93CB3F5, + 0x12E76CF7202997B7A7C3EDE29BFE399AD53BA4163D7292525A2B5FFC98208FB5, + 0x280A0A318EE9C4ED43A0F29CD7EFB9498EDABCA9575A670E0A9AF7E9629744E1, + 0x1A81E3ADD4534095AB31CCE9237644E0DB9EFB32B8B8867278738D3770E56AE5, + 0xD4B51B24D34505F44D4CB292954B513D2707401850929959B3B291CD0F6F5A3, + 0x287C9EF3DD5702DF9A840DDB374A6708F2619249ACA88FFDF22212F70E68822D, + 0x199D106CD7FB0BEDE6799550652519D9BD5C94DED0AE4CCCB4873CE85A46FF8A, + 0x2F828107607787B619CF926E990959BB70D365E889A1724A7B559CCFC98C99CE, + 0x1F5E99E05A5D23DCC212266391081DCA2879770C904A01A335AA48B5A0014E9F, + 0x2129EB58C7C45AA950929E2CB8FFB7B11B755FA16DD6A10F94357FBEDB31DC19, + ), + f034( + 0x95FB86314C0B4459C0DAEEF137CA5E7C327F7F5E11C77E471DAF88364DF934A, + 0x1310C53E9A4E601DB3BCE653337F9302C4A6CEA8EDB1751897105BF9682D1BCB, + 0x24FD78FD915AA1D0AF9E7689315F8CB96CF6091D3F237828E9CCF2E2B0DF5E9B, + 0x1F028381E83AB13B66D1C40AF960C83EF329E1EF40D8357937BC90E05B10EEC5, + ), +) +sz_nz_bit( + fq12( + 0x174BF8F0CCFDA5BD4B8B38E91E8D7213C41DEBB11892CBC48E188022528C77DD, + 0x1AF22B3CEFC1F62B85AEC3995635C730ACF64746FA955F63D71EAD3E39802384, + 0x1833B7181BDB3AC7FDD04C9DD6D887663D0AAC3DAE830EB24A929FD19C3CC268, + 0x11E7D451966F7CA6C276F3C198C2B023419908152C7AF50D1833A2CD108FFC4E, + 0x2FDBB2825426DF5CF7356D15017DE8E7776192363D2A5E6A335223CA26F4A691, + 0x2FC1B42E8793E7E547236E529706241104DFC4DEE2E9A9429EA604FD1564DD62, + 0x1BD87CBA16AB379C75FBF982F96FFCF18FF1B0F318DAAAEA85A0A5A4B7EDC293, + 0x5B0A4D729D48D975079F64B774B10DD56D5B0744F320B536A34D9E95875A794, + 0x2A4706E3466D58B54D5125F622B02961EF61DBBA8713F5D9C88FA6AEDAD8FC3D, + 0x19A8B6C1D8B494AA676A5025DDA9BD68C0749A83F942B43972A014C042A93067, + 0x1229D6DFA4B5C21B0AAF9325AE18F926ED377C9E3390ED474DC975F4AE27CEEC, + 0x21269191BEF0885F843FB9BB281A154064C71266495688E432BCE13BFAD4A9E7, + ), + f01234( + 0x23BB1A562338BEA45E7A650B2242098A09F03F51B30CD6391CCB43ED0F90F799, + 0x2090588331E6BE99D686C0529762843DF08592C832E53346135375CEA540EA55, + 0xE4ABD11ED2E5D6D99156C86D8EFD13ED1F64F68A9850CFCF0F1A8ED4F354811, + 0x25A2AC6E4284F36A9359F5B21197817901A67BC844D2E5E63BC82490F527A186, + 0xF3A43A0F8D307D8A96E7D32657DD29EDB512DDC3F8CE1E94293EB6062848FBD, + 0x13B45A5025315E9E7C9C1D5ED2BF1ED009E93DA7318771520325DD52F1DD0E19, + 0x127EEB56BB8F5F25C634F0F54703E92282C3B03F6E0C31897B4FA234FCE5E16A, + 0xA7F7D58579CA5D9382918414F632968E60ED1AEC5AE3E3B40FC62BCA8262AB3, + 0x2DAE35454BBB57DE152E5A73400E49D6340E88EC8FBB6CA2B125FC419DBF54F5, + 0x29CCEF73B3426074873970AEA822B9C73C28D1024035AF565C2ABEA89FEE4AAA, + ), + f01234( + 0x1C2691691BD40ED8634438AB4C02B27E305DB7EC2FF85C135A07479DD534D4AD, + 0x1B0483CA87F97D0ECFF6D69413ADB7732D028481DCD33C03C922C1D2D5887C57, + 0x15CC7400DE09582DD35D54629D7F902CCAED0534EB6DE2800B65BECECAD31429, + 0xA2DCFD0CEA07A91548B5D9A217B776D7966AEBCAE7E5CF4480DEC04CAE3D093, + 0x86BA6F91CF42A8164AB92EACC383C68E03A826C44C74605DFD4275B77157C2D, + 0x21F8E5E19D135F60FCCC4755A7F613EDF824F249BC2FC6A3C0907A9A3177C5CF, + 0x18B2E9F0A3E44E6F3E8A67A871D874FAECB55565791905C1213568B145593017, + 0x48717C981B31AADBA12FC236FCC850AF5B388B43B7A0A31651613F9BCA3234C, + 0x6848B1C1B58065F089DBA817087E48FA56D0AF1CCB0C84AA793960D09FE2F5B, + 0x23591B13432A57CB6D725C715FA92DAD0AA587DAB7A6F2F3DC7CDC8EDA16D078, + ), + f01234( + 0x1F00CE725F15BD6FCD0CEF04808A4978047FE72CD0C5B4020D72ECA9A81B4C7D, + 0xD298391E61F15DD16BDB6BCE2538CEFDC58AA6563A60128F49EDDA40F42B67C, + 0x181AED89D46CC640AAEEEB2C208EBF775D40CF5216220AB2B308BCDE9CA84C23, + 0x9F1A68220CD1F31872F365CA1DB56AE56B8F43EF6E35BA4C09D28CA77F82A99, + 0x93E7606448A18DB76767EA65F0509141E546E15C161FC718BD85C3DEC1825DC, + 0x2639643766042327418332A514289C04341C020A67204F331B150D54B7B05A8B, + 0x10FAE6D886E5FD287C26F9CE1D353FC1A2324004163269DB608C6BE144EB5400, + 0xBF3A435C0759C616423FEC37C280B186EB61BBDEEA25872E91BBE128F7123EF, + 0xB62B08968DA26761BC531E3D2D63B1AD58F5A532A6A3357C6CF0EBB93B744F7, + 0x2BEA459C21830AB47DED5941AA9368C8F883723D0AFA33894B79E14AE6EC79DD, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x1316B4EE3769C793A5B974F8908FAF67A0D0BAE0AF3F0F9023C71F27A30B5FD0, + 0x11891C66CF946AB7A99D2A342907B671AB4CA6D08DCDD5BC45E68D7E772B1B7E, + 0xC321DF705F3336FBDB8BFA4234CE3E865BDC3D82C95C73CAF56AFF3C9418ABD, + 0x15F6ADB5B93815AD252EF0AC000B88A8D719EC8D991C02F75580CB1582D2A0C8, + 0x1066124D7245A15042C0DBC8EEFC6FC545AE40E51C4C521E5227DF1605D12950, + 0x2EFF29957F405D49A980B8246141CFF030D06A1B34EA36EEE0FCDA13C1A2F1F9, + 0x101BCCFCAE004066CE24A75E6D6250579C89F6D923D33F86B01A9782CF08D08, + 0x373824FF053FC424467B35510F592193283074DB654F343FC9BF3D732DF87F5, + 0x4D9A33B7C082B93F7B18A39703F0DF76BB4229DA5FDC7B17973B3458B94CFD1, + 0x994D44C052E5EE321ADDA180339787D843C00FA71B60E796FB78184C1BE5D2F, + 0x853268FFB87B5074C4B8C6DF15A1D95A4758CE5A61B28492D56305C03A39B23, + 0xC606FCE85FE418B85B0D64BCE237A35E7CF0CB0119DAD20BE350576F27B6C8, + ), + f01234( + 0x2D30E879FD2482A4764BA7DBAAA972646FB44356D1F1F879A9C01338901B4A16, + 0x20FE41DABEB9C208B358AB7C31DFC5A19FF2881457BE809976789DFF1EC514E9, + 0xDCDF02366BC0F4052D6F1BBF95476CBEE6FAA78C6B2C918B5B08AC5B51CFD00, + 0x2007FA665830CC3E5F7C88C0BADDAB38A5996E1CB372A11895DA30375CF4DA4D, + 0x2FB542458FF9F39920F2A2DEAFF412F29645EC76718A5F5AD11E45264EFC6853, + 0x71D074F918A33D3F5E7828385FF1EC041B2B21DD2FE524627012614377E0F73, + 0x183AA434B0C117B2C295FA6BCB901C3D706B148B96B2ADF2C8B47BAB637AB140, + 0x2452F6BF560E1EDDF80A4032EEDFBC45D6B2BF103239B169A9D253DE1E0D3B47, + 0x21A799DFDA501A4C067CC7A7F2368C3719BB483408691AF5646EB11549904736, + 0x2DC8A2FC4B7C10898B9D3FA6A5048F286D79C18659267AE671EFEC5A0EE447D4, + ), + f034( + 0xAAA199215A076055DFDF7A2426E5F9589F69504DE492218377607279565C33C, + 0x14983B1D372AF0EDB56B46A3EA4990B602BEC402094F65EEC62DD5B42022D1E9, + 0x5F36888334D427E552892945DD1DBD9D305205079B4879B536E4E920E615E6, + 0x1B6E02C89D39C0E4F6AF9CD3E068A479C20A10B6E9084DF702FA1003CC320F0F, + ), +) +sz_zero_bit( + fq12( + 0x1C535D849917A724400DD109C672D3F8D57A34D64D1DEE93211216929C07BD96, + 0x5F52453627F833F3D9D4588012C25333ABE26CD81B7B6360EE6BD1252C1D54E, + 0x251A35EA7DAFFBECA9C34993B1C332869A2C704073F36F4993268C9F7D4F1190, + 0x294B5265C427AE1E8D4B8356FBA6B93802C66CDFC049744361FFC5FDB634402B, + 0x1F3DA37C3070300F1A7E57028F9471F5B2FCD50E123DFD938852AAF5D2CBB86E, + 0x19BC52FE20815A5B79DF10E2BD4EE2514275E9411999107643EE75C78228D0F6, + 0x2DB4C9DF28D973F9628021EABB576934E77773A67E2FD38A4D31DAFE2578260, + 0x5C2B851946B3A72156CD644326D4F4918D0EC784A80B19C8D8EBA700663D90, + 0x2F9AC188D813479DE6AC3B310F57ED482CAE480CAFCECA9700961ED77CB113FA, + 0x29A497CBB6B07CF28EAAB683D5FE507A51492016FEACA10B057AA8F158EB404, + 0x1B5342A35654C820A60C6BF31AFE49FC5A93737A29BE1E017DF2B2C4ADE54F9E, + 0x1CCA678DF15E39BEF86C7DC38C54295DC6942CFB51E641A93E60E292A1321622, + ), + f01234( + 0x1F2161D89F0D62DF8D1C4BF635541EF9D4353C908908350DFB0C561B0D09A677, + 0x1389E7CD8D640E0BCD9F54A6488580C8A48C9E9314827F308A41058C60616F4F, + 0x1D8E4039E7F445752030DD1489B8C278D47752F82E942D40F19FCD30840DE718, + 0x2A6142F2A3EAED6650D2C3121EEC2FF2FE643CC617E4E7CF741BBF9D3AC63C69, + 0x1D940C8787508E748D875314300054CD315A8B67AFB90D565396BBCEC744A9D5, + 0x2CD392D6C609938454FFBB166B25A3C5344DEF8997172EE1386EA532ACAE5D39, + 0x2E341D0549C74EF9A324C296ED36071D7451BEDF2EB0D55F2C020433C64F4AF7, + 0x12B698EED1F3CCC80854F97BD2182F53252CB143F3ED7FCF1A7FEAD73065333D, + 0x279930D869F42654E469932A2CAA6BAE2F01CC134DF31C1DD93138FBC78A0DBC, + 0x26B51AEA36DAB390BBB4E4BBF4EB7AA43B74CDDB989B05E91C9F9EB284711A20, + ), + f034( + 0x6BD319E5B380AC35D9E28E6B6522BEAE7FF26239D0E39C3956573815C9EFDED, + 0x2A5A040841C1B58C5F60F271158AAF91919FD5E0FA9FF84C81BCE5F1E16F53A1, + 0xDDD79068476BB2314AD4CC901FFAD76C916BF0E071DDA7DC4A9FA7977B24170, + 0xB86ADF57BCF75B1DFC5A126806ACFFFACA79617E3C91B758ADD77423E16D15F, + ), +) +sz_nz_bit( + fq12( + 0x2132255D6479F979733A79ECC718662A2E9234C98A0405DC965207717C18A10E, + 0x198CAD507965B41745F6C4BCC5E0FC26BD4476CD23819DBFCA1EDC8830DF9622, + 0x1E9C80AFDCA7FC3B2D2C559A2E85FFA396398D8343E489D2BCAACD3B5853CF10, + 0x7CACC7612EE49AFDC52A2DDD4FE91ADACFACB59229F3F641F2A174F174A154C, + 0x2804178696E2C68033AA3A023F6533126F82CDA7483734E81C90CE9653C26FB2, + 0x16185E9BBBD976732B0894B535E11FBDE6C3AE0DA6F65AF085D80DA0B19E49DF, + 0xCC457FFE9F63C6F5D9C4D2540B5CAD6B6D02DF0798ED8EEF1AED8CCE64E8294, + 0x8D0F6BCE4DAC3985F97BA085680A974D723B99F10845123C7FC26C3F91C35E8, + 0x418DEA30FC3F0085795A3DBDAFC145E5F681798173E07D9ABC6429A264F7D58, + 0x25F1BDE6778CEE17A8BCA03049DC4AA5D6F8AF67AB40ED9F02B8E6EF81838A46, + 0xFE6B8DD22FFB449239048D37652BBBB1E8D4CA92B9C0F0D437BEEDC5021C1F5, + 0x50B5B2F66583F3DDA3F91B4B447CE8E82BA8C13F99D58568902585C03A833ED, + ), + f01234( + 0x558D178B0FD84B88825D8E000151E2A1A312E609322BCBCCF398C13995A8790, + 0xEEFABACFCFAF2D6ABEBB247F8FE988B88DD0F6E4512D5F2C9EAD1C52F71C759, + 0x1A17C03987C8FC362DAF20B06D6459A95C40BF4F462C5C009A1C533F839CA8F6, + 0x1A9B3C5F567F7869C7BD1DD76F1F157D5FBDEFB5C776CF8D994B1A8FE738E0C1, + 0x11C895A19E554B62EFFE71540E8D50DBBFC36A203F3C1C5978E0FD215AF10197, + 0xE65F651DA4A407447F7005EBF0B684F458D42FA8D321873902F2D83E0606EC7, + 0x1E06D7BFAF309BE9DCE789312B968A26AB2B37ECB547832376C3A5C4150D811B, + 0x1CA4B50A74FEFEE9D765B4DB49A828D7D145F0A7CC8BBB5C36631A90C4BFFA8D, + 0xF141DA8E23811C9B14558F51DE20369E2E015110D874823C145ACDAA7F7D3F5, + 0x222C5A5A06CD59E44EEB39F303979D2D19A27144602003B56CA508414E5B2B47, + ), + f01234( + 0x253F451F32D4E33436FF7051E4289C70D64D5538B86A3A409C0B1A6932D535E6, + 0x10C20D7B8252ACD9F32997008D3A635734BD6D16A2E02E49E7AF929F7F5CD1E8, + 0x13267A6DC3CF4D747CDC5FB51CF66CB67474F90A546B959CC263CEB73F9551F8, + 0x135F3C77708F8FA557CCA1ED3896C653BDF1BE651DDAF364C48BB0ED1D9743C1, + 0x2F310FA025DFE985B76F63D8EDBC697FAD7939FD75CBD621F81C8B0A4E85BCBB, + 0x23DAD92D22D1FFC7CEAC2AE26F5081365AF986D4192D4A1DA4E590DE7F329314, + 0x9FC22038C9522851393F7969CA75A6425AE009A17422EC8B80C1961824641BB, + 0xC198755E8F84AFB297BEB1C7A02C689E3B88D8DE55123A952A53FA2B0A0F634, + 0x2FCA197180E2E950497D5A429606D6773A424DAAB98C17C3B1C63D18ED1955A5, + 0x2FF5AE5E4906FB986CA7880B783F77903C1798DCAB5E94CD56C7EA18AAF47D1B, + ), + f01234( + 0xCEB1B6546DBFB79342B6F2B5ABCEBFC9BA114C702AD2961CB1650D1AFA81D80, + 0x6A76A1EC0E55D27ECCF76DE61D54B0451B5681B5A968108269472410EFD54AD, + 0xC456F4ABA829B6523915EC0CC3D11C24F88DB144EC824F99BA870E21F778E91, + 0x2674DBA0ED35F176D73A5638C404AF50038008ADF2CFD9DD095C03F83D39894B, + 0x75B45A43B4E5AE14BAC8450F007189F8A23972E8D5BB021D2B0AC0E5B3419F4, + 0x1F877EDFBD1A897F8489D49EA1948E4FAE86E92F0DA45C57B08BC522D3F87160, + 0xD1B2DE16DF3D1203CF562E69B20C8DE93C60A85A8BE0FA1ABCAFF21F409FCF1, + 0xDE912B450695DCDF66A084864A7B942156ED897AFFC90F329F3A8B9F48B073F, + 0x144F3804EF81CA6264EB71F5908EF13158CB7B4F84078D6068165B8555C939D3, + 0x178C60FE2003AD8BAD939ABDFF86F61F9243450D2E64A479E8BA7393D9B9AFAC, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0x14905B050A55473CF18ED97FD24D75CAE75A4F71F94CEA21F053DF6FB98DD785, + 0x25C64D09FAD7C663F547F54D8C3CC62F6AF8937F38F9AB3EACB46E6C0E51C627, + 0x129E613249FA2E40A27D89D6DCF977DAAD34B9BC39EA5B2186EF1572A334D1F5, + 0x1D6A34E730E92673033ACD9596D77ED95FD68543AF5B53CC4214A02C5F5A640, + 0x233708E26D08F0E1AB8D65B13F7B6DB778B373BB9F81B44430B0CE1F48B8DC99, + 0x1CFA39B80BB8418B906317D429FFFBFF0DF7E31BF374A491AC8B23386527E1D1, + 0x6C6DE81E96104994DB6962DC7256BA8C3ED6FF7F20A0E78BC3608744AE39F07, + 0x1FE2714BFCFD96AF7745D61A8AB7B352AF80929C646B07B6C4EB17082C42AB3D, + 0x117D044D671F733247EAC9740FE9609A701C5539849668C474C9F8EEC0558AFB, + 0x1724933F073447C2E13E2FD3A19F6E08BD681AD08FA14B3A4F6CC2EAC9B33D85, + 0x11AD884156AF0621373CAB970D696E1029A2A72D11D67B64C9F8CB22FB9AD95E, + 0x3F0B8757C544B17D9CB37DADC9440B150393AED9220DB605C2E2226E5FEA652, + ), + f01234( + 0x1D610E8AF0E88EFABEC6ED5937812FA3AAACAC2B48DAC436A016F81E6D3A6B06, + 0x1B07EAFCAC1FF83B0A7739C831CB66A414F3B71C3695962DF5B75480F92DD12A, + 0x3D6E4D8AB5E1E7518C1270F9F857ACBDB7E7B5CA854AF14167F9EDD7EE693B4, + 0x9DFA48083E1D81E89C46A757A1EAF4E5F697F637623A59BCA2DC262615510FE, + 0xD67B964696BB993021A882A67695092628AB58B50CDB0DADBC723316749A4D7, + 0x8C79CFCF26787BD7457121FC81E5A9CB6D061653ED6A748F96800727B8DA3AF, + 0x2D1D1B9F37EC5B99351BDC1C47BB3D46FB11FD06C0426A6EFF399F440E2E52B4, + 0x4D1F1067BABC033A818D0EE57C406EA920B224CE9F02486D65324C8C9089B13, + 0x12289150FC4594607954BBD45E5244AE9F45F3137C9E30A242845BCA3F57288E, + 0x1B9536FFC2AA6A477E5B4B008025B97B3972863F41B2813D8CB9C37A0437BAE8, + ), + f034( + 0x23DF9B81DD94F0ECED3F0A4562D9131AE1C3416B2D2F331898A3725DBE45C835, + 0x776F3703E033CC17D13EEF523898FCB92EFE8CA9C99B43C5E2A89551033CAB1, + 0x5A22DCCE3758149339C6BF2A29E7C5DC87DFD631451C5A1EA2F503050D5507, + 0x133F0F159F4BD5C11A206353C7347158029CBA15BCBF6F8AEBA97490B8D4802C, + ), +) +sz_zero_bit( + fq12( + 0x19AD327379439F396DFE06E83DF5CDE33ED4616E5288DE52981EBAC8D3A684F8, + 0x1BABFF31AADF7F6AACBD68C8936C1A35C6846FE6E86BBB0C9DC8852CA6931477, + 0x26888845107FE02C5E907568CF34B5D1844B3F08BF50F0EEC9BECA1B18B4B5AD, + 0xC3D088386044E3CFEDD2932476CDBD1F48F219D2F6C31A69D42E56A1D43C765, + 0x183DC5F2E0AEB96AC2046276A53AF733CB8DB75C408ECEBC5D08B3EC31F23034, + 0x210F5EEB13643195B59638A2B3F31664E6579CCD496120CD906A5F906E8A1378, + 0x15F36697BD86B7A1652E0BB18F7E697FACC7A0733312C28D14EBFFA6EBD894ED, + 0x2B7246CB166D1C3CF04BA62BD9D50D39578F18A79F03BB80E260E7FB31655DA3, + 0xCE25786DB75584CC1BB24D7E7B5DBCD76A769C47F3411AF03F538E455AC7587, + 0x25CA760C6492C2E7C1B6E3604D48CB1C8F078511A2A5DD49708A473ED6902DF4, + 0x12757558CE449B95A784E77296616BF59EE4500E7100391FF1207CCFBE7DF9E2, + 0x7CD317DBA2785A85674AB6B6479A1415F0C607A1A70C56E5D702C8D76C42036, + ), + f01234( + 0x305F313D2D4F1F0E5FE08806D0755F6A704B8A605BE5F5FF80D673ED8C2C75AC, + 0xDE057A4C90F77F40075D00EE1902948143A979A368601EB3F3263974B38ABD, + 0x610F5C7B673C33BBAF57470AE9D1C8C83E00024555139B386502C4105497BE, + 0xC66BE165A0F23286EE2153DAB037D0151EDBA623C2EBF88B54275197A40EE2A, + 0xFF50A5926979B3A5073DFAEC922DD92FE28C655E80A1BCCEC39EA99372F24, + 0x8CC1654A84F68CCC9D1F693616064BC1DD094E6973975E45007F6A00DE37A72, + 0x194E3A2C0C1B9BB7AAC7E18B48CD3CFB3ED8E23D93D9501B68D7EE2B650BAF93, + 0x17D5533DCEA69470FAF7C566D2ED4CF0C2B7F298F3D575922B08137EB1F2EA21, + 0x28530EEFF30A41A3BCBA4ED88FC27361A3F07302414C9643EE7FBF8ADDA4EC84, + 0x17AFBB10D97671687ECC51CEE431D1E03AB72FD8FB8D5C8EE68B8625875EE076, + ), + f034( + 0x108254EA90A3FC4E0EC9A42CA35A30E5C21FC95CBB248D67F3F64421D6F7AB6F, + 0x51641D4AED7DFB934CDA4B49C0E3DD55CA45D9DE8E3931419E974E02FABDE95, + 0x188DDD8D710BF8C3FBFFAE59A5A8E5F2A65645FC521A6946E7BE9205E8FD9A43, + 0x1B233FDA8BFC44A5636C02B14CBFBA7E83E8D4A6CB2D0279314026ADB5DBC1D5, + ), +) +sz_zero_bit( + fq12( + 0xAE492EF3F4927D8C9FB1A13B5E74E1A5E053697BE89403ACAD25B5BDF79D0FB, + 0x58931921249CF3C0F34716243C3654392334B7648D7D41D24C3F926A4E1004C, + 0x2F4D661771904F417AACCB61F30B00B5029A8E14D858C69EC4A7545F6F303F8B, + 0x148BB8BBBED3D34A8664E4E62E2096929D9740B247259FF4375798F02F38829A, + 0xE689176890738E5E9BE0DF780F37589AFF61FBC9A55C4F6B4CDA826695EE949, + 0x2C000D3476064CCCE4FEBF236FBF0C45D5289C327FF38B23BA0FA4C49729B9E7, + 0x2E16BE10477EFF4DF847CCA83E149D5DE16BE9A9D1A66A1B5383D1EA545D9279, + 0x141F17C7052EB184DAB6CD6281D6B0A10C4249B9507FC2FF371065F875FB57D9, + 0x192247F6F6D052284F14D681E8792894B42BDCD5F0012A59F671350421F9E31, + 0x2BA1F6FBC6D265F57704543889DE1DFEFEED353525980CE52660386802E43724, + 0x29346D42E2361CB0871603F0A70EEC653569D79BC3A30F79D4B942BC512D88C4, + 0x28CFE25A8DDDBE94B73CC0A9CE174082F5DB984401D2873766160C9EE869DBF5, + ), + f01234( + 0xB4A2400DA2034419E31AF6294CF205F56D06020886E1423E939249F2B7CF6B6, + 0xC853E99469A3D7C1837A06FBAE776CCD539F7F985F748C6B2D1480E4351F0BF, + 0x1BF265C1633D11B4116BDDCE38E6F8F91083B95AA8C7E9C6164C3461490851E4, + 0x1EEBA6CB6E76DCC2E53FE4F4C20691A1A1E0D26B814D516D84413DD193037FEA, + 0x1114931CCA7820CFC84211A176AD65F2E8B6B38F402285DF6A35223C3B3C294F, + 0x559DDD1924AFA3314CDA12ECDD439662421A873CA6BF13D8A803CE6F6862E71, + 0x1FD7C8278679E2447EBFB5B6D50BE9B14131795CC794393069752D46A66ABEDF, + 0x28712E911C7722C74B25D8491689C85C05A91FC1CD33A2C2971D8865C155BE88, + 0x1EA83A4D9FAD11DD61EB3E21D2BEEA29775D153CDF9750D49380583A74F12321, + 0x11D6A50B610B54AA8E9B478C317A51549F449C4938E1DB935D30D1F74AF06E87, + ), + f034( + 0x2DE93077E24EA20B1FAFC831286AE6F7DD6645590105D220F68B70E3831AB05, + 0x1F66CEFC04902C56FF14BB7B8F9CBC5564638F9986A12EA378EF40F93332313F, + 0xCB10BEF7237E7AA639A5BCF912A07C7DFA1546FE116882C01202D85E5947FF, + 0x3CC0261814D74F4B6E41761C9145207B426083A33C54E1AB8CD14AF6D19C3E3, + ), +) +sz_nz_bit( + fq12( + 0x105188141805F152A77B2FCC94E417F771D10432CDBAC9E8472CE4E0CB712FC3, + 0x27862525978E7FF0E31435507A16001A67EC40925D4F6767851CA06E64E7166, + 0xE859128CA5CB3E1126CE76595D7A714F320F14F2D491CECD87033445FAFD8F9, + 0x44610E85721F08D561154952D400A88A7612B2E22BC6BE55E45B918E09D847B, + 0xE66CB1F7AEEFE4E2091219F030C2850CD945B0C4BBDBE1CD67BF2138F6D82DC, + 0x2CED8DC3FA5979A806CFEA36CA2339AE05EAF75BDD2959177DF0EA28E3791D56, + 0x432CB60B98EE3BE5F4C7603B6ACF693313BA46E09FA6997DAA47D8C14C7A731, + 0x2FD7B02455694E8B839CD1CDA21D77845DC15FC7B2A62871AEF9EB7C62FA1377, + 0x1F628C87449267E6BAE6B20BB663850F27A4F63AFDFCD730D515CFD7B8E08E7A, + 0x228420770B627DE6B1C29BCB87F4618C8A71FCEF3B00CA3787E550CE342BEB84, + 0x3A4770CC8C2F8B74178A5D936695E13D9FC4D21E57F74BC66B5FC675E0EDC47, + 0x1E048FC1CC82F7DF3437577181684CE9259B48635B9D3F47B65832F03F95AD74, + ), + f01234( + 0xC516F0AC32D2576EE96481A6CA3245F5D31D23B74A493043E19F79F8B87EB07, + 0xE9E36C9DA9D797D508E5AFB47E88BC27A05F425DE6E61025A6DBD97C3EF8385, + 0x2A300894CDD2D17D135EAE8E42C7463C239056A26F006B0227E4EF44A7EA63B, + 0x25756FC098CE3083BA459502939CCEA0661D00643AEBEEA6206788BB63C08960, + 0x2BDD11683E324958BBB2B74A63AFE2C0E2E303C582BBF24AAB71143623C017DA, + 0x14069354FA76F61937BA4871686F4689DDDB1D9CD00FE8499DE911D8548A1739, + 0x14220A104A3E825C43836C03212BA33FF06C674F02B4058B69FF6A3837B53770, + 0x2630E16D79D84396D9FE273930DF7D814E9B28A3E674C2510D8E8E2BAC8F6BF5, + 0x10E9C5B7F1600B8168A762A9F7B3F9C6F1C597EAE9C1560C2CA967830CD2A6BC, + 0x1FC1D3A16FCA93A7D006E62C2819E5BEDC298774B3685A03EC3A23CD0320C292, + ), + f01234( + 0x5C96CDA3C5B012A0D934BE037717CAFD9C523D0FCC16DDCF23AE984F7792264, + 0x12208274B45037A93E27F7DC458312D119958ADAAFB8317376A6026D03B445AC, + 0x2A4FB83CEFC374D1791493196BC3DD0E4242A7378612F7815EA5D18D2F7498FE, + 0x26123AAFC88C6C9F1356407132DCA8BDC49016502A0FED39E54613D553A86E4B, + 0x19BC55BDCB1E61F69C04643BC65F550058FE069B5629D094D57027A243B96BD2, + 0x1DC8C57FA86B780962F79D55AE5BFD4D6979326B34308625FC11434890E88865, + 0x1AFDC033E6B2B367BD31ED646BB6F181AB4306122071F0AA0DD8CABBD76A3B8C, + 0xF5019097FE2984C279A2091CC0ABF6BE233F3E5CB25E7250476BD35D1F032BC, + 0x1F7639976E5F4DC7CBC4EDB535E9D9E894B30E0181A109D805813A5611C758E7, + 0x2FC87CEC03114C8EEBE16F4994B30ECBF5E918FDA9A156714A7BDF7D945E1398, + ), + f01234( + 0x26DC90E2D4ABD8D21C5A37619211CC570395E8E5EFE92AC6048D5C42DDCEC1AA, + 0x21353C24DB49D2FEACD2A2A9CE819F85328187DA93169F3606E4B5C802D47DCD, + 0x2923866070CD26469F6FCCA1C8654D41541E0194F427A95F4B57E978F0B6AD11, + 0x32F71D608B920A45B19D2FA9BCC8262A9234E64BDE4CF41E3951D1B4E4AA955, + 0x221168CBA34D589DF0A467775C28465363DA19560FFFE1111347F0BA6B876870, + 0xA9827892DA54C20210878F6DF403F750FCC3C04655C32A2DF952C3CBC3ECE8A, + 0x3B2A54648AC55E3A8377D549E95D6F6D71A32B38BCDBB8753B967365F3BD216, + 0x54105A9AF581BCA2AE3236BBC10C844A17C11AA6BF217BA8C50E18152FDF2AF, + 0x1DF5764FE5B25B2817E1472B42CAE695995B6AE52AA5D6952213619F1A806933, + 0x13F80A5172A2B4AF200A03CBA0CA5954B01B9B3FD85D80F841B3098739863E20, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x23F492A82ADFD51EADA2868C6A59FD344A8712BFEFCE45A81487286408696D19, + 0x27DEB5D03C7F04469F2926C457F0A5DDD8B1C894B322262F11EE7631E195E9C0, + 0x29298A71B1A34CFA7A96170CBB73F776C62717BED95BCB22730152ACB88F048B, + 0xD30863567AA66BD719A7AB4874173BC30904253BF4925036E28752981039163, + 0x2EB81CE4EA8995F485145AFB67BEA37AB7CAD800B44BBF96AA28BF1110679631, + 0x1C867BEB3FDF3EBB6DFC392FB34D460AD5B0D3A65D6BF2D99981B3D343B6E563, + 0x13F64F484C0379423BD9A2B344EA9CA26FFF77FC952F40C4C5AB47BE4709C119, + 0x2366E9F85C7D22E9DED4394274C0D975B24E7031598C08C6567967187F508DFB, + 0x7EE60E9FD159AA13FEB21C1E265647A3082F2233BB17E924BDEAA0F8758CD9, + 0x2E1F299042A27605D50840BCFDBDDA95128FECC2B0FBB3D98BA69D5B2BC288F4, + 0x2B0E62B7CB56BEFCF0A4CDEC0E83423996AE0A2C7A6FB253EFA904B69D4BFB32, + 0x146EA1333F1402915A28D5AAD31E4EA8083BE4F13463770E481BDD6FFD8D96D9, + ), + f01234( + 0x1722FAFC0FF3E83D8007DC320BC3C8DC6A0F0F7694C94552559600D2DB4F329, + 0x29D2E7704FACF35F1C22243484F2194E5334438E86873343D94A36EC90C7B370, + 0x89980303434D09E14761C1BAEEE04ED443B23C6E2C3269ADD19CC1F1742CE23, + 0x2BCCFDB37FE517A0D769C8385EEBBC012A68477A228C4377A5B653FCD50966E, + 0x22821C7DBAF5F462331D8777E098B5F00131DC958930B1E6017CD16869E8A98A, + 0x265CEB703DCECBD0B390AFD94C212EB5B3F8DE7F0B473881647F3ADF3C74C170, + 0x2EA485D43DE1F59B70C2F5DFF2EC4F10DE05ED714643EF9FEFB9F1215816C6EC, + 0x1A19BDCA65FC75BCE136FA18540AB8C409652A00993EF8F589FD582DF9D27164, + 0xB98D6398DB648DF9044EEC95A39514A3C1EA30F1AA838028559EF1F1F3E06DD, + 0x2DA0D8A4F36B3819039E5654A39E4236E3429573E60552C579AD216C94DBDAC8, + ), + f034( + 0x2F92D66E70D32BE0CCF5F9A6840A6551EE8B3031B034A57EAC95BFE8208C4A7F, + 0x21A742B2E40BE0249BED5FC2FD7F9CEB27B60E3FEAAB584C3CE1446F004F0711, + 0x16CBFB9A5230C2D65C1523F8A0E35319BD14DBC717790B3702D22A65E0764B54, + 0xB1183F0C7DDE3001AA7C5C5FFCF519F3C0105DD5ED51A4D66E11920923EBBB2, + ), +) +sz_zero_bit( + fq12( + 0x2AF9F5AFD44FF0177C8134DA3FC21172C729CDD098A7534229A4F67031F58703, + 0xC79CA97CEE11BAB490D4C16DF7299D6194D2A2C83ABCEA41DF216C450F6003, + 0x36EE0B867856BE1DC51A6C04BFFD526DDD2AEBDB57D00D53D19D2B9E24F1CC6, + 0x110166229C4F51C2585EBDBECFBA177D6606A2C5E6A37564297A32C070F46D8A, + 0x171C5F80011DB3BBB6DD2DA9CE9F7FF2D140A02845CAB618DBD1D50B7E69E2FC, + 0x1CAE21D27D089D792B481DF3108B11463C1952C95AB9B6B70B0C93BA8CFAF251, + 0x233657F61DC386E6CFB0522F19E2CD23E9C0DAC428935B7D61BDCB016B6ACA1, + 0x2323370375940BF403EED3798608E7350A9DA710882B2A218FC42649678A16C2, + 0x2F41CA7DC7469B7C8B63C9481B1C26CDEADFB731AA2ADB04762294FB5F4D8911, + 0x2EDD58DFBDF7B6B54BDD578D050D3886FD05ADDDEB5E2EECF9137F98BE0F27DD, + 0xA48AF92CD24882CB6CB6A11AB757B10BA676426B74E97DADFCDBF49E9495C19, + 0x27819ACFFCF76B7D9017A437295448D7F860932A292CE20B38E0A090DC84007C, + ), + f01234( + 0xE3C60D5D921AB5B3EB04BAC31609E4A8ECE63D1D798FDF1C9463FDC38F29497, + 0x1E1EC91A1633E93858E46A0C6AEF799CDEF7E68E72246211A4E35493F3ECEBC4, + 0x2D167550285FA496A34E59D965372E5B473ECE20A08D8989DBB5B80B603DC758, + 0x1AB0B9B963B3AEB2B0852CB8517578F3324863EA07B3050CFC5155112930A1FB, + 0x1FC09D9C0EC4234452298A9BC53EF2F1EA5B0830CD8EF2C4072ECA8E1F1B1E54, + 0x294CCCC4FEB5A8411D674FB0731334F94EAB552A448E020CCEC6C028708D0022, + 0x2FA087524C5B8CAE5880CB2CE2D241D3E319D0BBCD55064F32C15E39FA4838BF, + 0x1358ECAADD9C73CC5B45C1B9822157B7365A85D5C2ADE8AF20ECFD6E70CE2948, + 0x1D35C4DA47E0363DACC16D08F354E2B94719B036B4D44CCB12922EE2DF4110ED, + 0x1BC774830B36C4B2B5347AC8CE1D5680D6739975F01CDCB0BE0917DF5094DC5A, + ), + f034( + 0x1CD737D7A579DE2CF7922A248E110D34102155E2CA9204CCC8FD06FB6C51D95E, + 0xC5139C6C072C14B5EF9FDBA88B805B0017447C84F39568DFDD85866FAFA042F, + 0xC467267916D26E153731F545A4171BD24FFE399BBE2AC0A27CC54EC2E7E8AD5, + 0x135EE8F8DA0AAAE811DA8BD476E086DD37D29ED4BB6687850D5561C5BA99074D, + ), +) +sz_nz_bit( + fq12( + 0xD0F985DA4CB9177D35A4A4C07C1CFF1D34B9BC89A084B22F32875ED17DD1E07, + 0x17CBA60B1D54C431CF61652600E788D27748D97C8C8750F03D2B5CBB3BD8A33D, + 0x613B627B20171144289EB7F35689271AAE807D8216D5A2692E621F13CCB8CA0, + 0x657172BC8E7CE4CA4F770AAC565261E52C9E282CF057A451191B9C4EEE30828, + 0x26C7CC47E76753CE0A8367A13948A056397B1399C741F9FC3CB193D887E088AA, + 0x1580894266B34797C6CF1C2D2E5C80EC7D5941A5AD3188B1077DE94798A76DD0, + 0x1830DD692BCF57CBD98019B6E4742FF1E57C87236EBFE95A2096D72204ED260A, + 0x2D6D80963E01029ABA9B5567E642A42419E2602F1FE6C18F7113DAC2B4220B7C, + 0x2EB088E78FCDE9004719166EE68A03998F8F98BCCA883823AD6497D3945C4D67, + 0xD81DDC3EA4DC4E3310F075EB658A2BFA9A360057E6956273DBD33121938B811, + 0x2790778860D8396A9272572C8C12CD99497A5C558505453DB3D614377FB34580, + 0x64DD5EE81261FC53E1B68669908839ADD2B26FB16F51E83DD3AAC98F1D1642C, + ), + f01234( + 0x2E17CCB6821574D7E464842EE5EDBB0BA968F115BBD8C9FC11C181D1822975EF, + 0x2F68EB0739A6DC9C4CC1F92DD0607D7AF0C5D3319EDE3941F2DE8C0F718ABBD8, + 0x376A5DAC6B815C547118135AA941737BEF3F7A7E4894154D69B941A473399C3, + 0x9E9629BE63CFE1D01B5CE1AE8991E97AC2A7A777570874A2B2256319F249F5E, + 0x25D49213DDAE20550E522D5787236B9BF29882C7F740C06636F43B37588AD0AD, + 0xBB8C4AE1CD9B2E1339CF355A4929F3ED3BE1BFE97565DD7CB7B989598CF50FE, + 0x1575304E9106D12ACC627146AED2EDE896B5C9198B78B0CC2D8AC85231E5EEF0, + 0x2D296BF2D56F2D0006D05E50E4E9CFF3C2024989F1BD3AEC80B12E0B78E5E9F6, + 0xD3381904A597886B708400565D6DDFE798CC5D8CF0A3A977090E4A4886EB18B, + 0x727202FFAE3828A05AC92986B294B783E0C8142C8CC6FE32B7D6EA9C145CA56, + ), + f01234( + 0x2A67F842A2B3202E5404CB0BAE3C0480B9E75B2EA9A8E2C1BC7BEE5B68F23F25, + 0x1A1941C176F00D2AA29C249DC85FB3019000B2FBB2AC67411B692FFB21D188C6, + 0x10F4ADB201176574A810CFFDAAEDE65F40409E6E3605A2D1FB838A5508EC1C55, + 0x51BBFCEBAB24ED56C76F91818FA46E2701854509E13260F0A60DA929B12B26C, + 0x7F1E03219DE1EAE74E3111EC9A75CD9EDD4EED6D37C3CC0FD6AAD772914D090, + 0x1C8E078C6D1033C510DDED8E5D51832F63C4985AD7D5FB43D391BAB48F33189A, + 0x18A78F48CD30DADF81F1A4600F7CC2F73D6C9021FE1749E6CCE61767B1A64FDE, + 0x197C142442655BF1F2B5E47A2BF02BAB8416B4CB93BF73B33091A56F2FD198AB, + 0x89B1317E88152AD00F17B45D9FCEEE66145938E8DB4D8AEA77635F988B96CDA, + 0x1FD068E821E86EBAAA39881105755D8444833F81ED5C92E2013E12EC89AEB43B, + ), + f01234( + 0x10006A3EB1CDA3DB40EB88F1F0C3875E5988C88355DC4CE7E6CB196F761B5476, + 0xE3460ED404098DC4DD39A151BE7638785307E1AC5D37E3C4F5F53A61CE3D6EE, + 0x734F4965CEDD1B59B874EAFE48C1358DA99055DF1FDD8710E3D44086E0BF74D, + 0x61BA1D7DE5E465C6B4003DB148EF5B027EB335029E5EEAC08335E9B385BFD6, + 0x1049CB10D9C1836EC31F9CB0B7112A1340EC0FFD38C4BD4291D05937CF221EBD, + 0x4BCC013E2AFD61A06BDA8AE8F718D2EEE1B28C3157184C6BAFFA05FC3E519E6, + 0x1775231B0EACC9AEA10E4C1ED7E23074ED86D6C534245C0148F5E0AB2484E9AD, + 0x144F08EB6E5AAE97FAF8AA6346084517E1718A2E75D1C5C384A6E9E71DACFBE6, + 0xC6B6DF1CF57F1FCD25057C0E9DC756D408A9C39F8042933C1F94E6E782FD51C, + 0x1170E208288237916723B1CE5B8C33291053C6BBF759EAEE0F692F5C4751871B, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_zero_bit( + fq12( + 0x2896C578221EE593C7C8FA061BBBDF1871FD2AC31DDD53B009127279D708D30C, + 0x2F5B773660A33347087A9775924919606917D117C132F637B8A176687CAE55F2, + 0x2905DAE9D5DCA1AD6D3CC90ADE80C829663E55E73F221A26B04BB70B67289356, + 0xCD48FC0DB0C9EEC93AA530F674507CE4AB866D9B5B07BAD841F1BD51E2A77BD, + 0xC5FE45935E1F2189BAD3957065C01DF9403BEF9705D68E5D8EAEF0E4E82FDF8, + 0x8830D94A72D7E49D2994101E2F4F89B2193DA24CD7A8C49BC2D2DBC9627A39A, + 0x3020F475E9D5CA0D1C6885CA456621D5D04E2FE2BA15443EA838588795BE5AC, + 0x2365EB368B8077CDEB126351B174B7E8EAA31DA6812A24365329320284B87D77, + 0x14D0579C19CB55E025464A5478CD980705E97A3B21CB30B49A360AA9FE4192DC, + 0x29B426B966312118789728BC3215C9EB5452D1EDAB5A342B73990BBCEF53DA6A, + 0x1EAB733AE1A04C338CE156D0DAC8D9E4BB3E392D89D08F0EC419CECE42EA9ACF, + 0x181523509E29400B96A2FCBE0230123A2CD1EDEE7F5252B3B739AF6799BDC5FE, + ), + f01234( + 0x225EE0600DA52890F396E06B6E388A56209FE94A0FD4E13076CAE33819C7D0D4, + 0x26C022C015C110A1C17AAFEBB56F95BF16F73E3E3A211DF7A9DDE98AF599363, + 0x19C8AF70B591DC7D7197696DEB1D81200F602DF7AB57D85970B89934521BEA6F, + 0x219A10D04B8E6A6453E249DF4F9C486671DC47205DAEE5824FAD10E03A585BBD, + 0x8AEB0408A604A3E0FD7381B44152BA0A54E3373497108CCB41EF2E30E3E8C5E, + 0x109B4F920FD9EE900ABAA5CF03F2D78BFAB5B7DC07EACC867624265830FEA11A, + 0x3109E2F9AD766192D2D18C7041C6884875D040D8BEFDE3B88248A455524C967, + 0x12F5F92119EFAB6A197AF79BBC845FE0C434FF3C94D049B85D3CD0B3BA092A00, + 0x1BCA1D59F4C5D83C4D32BF99AEBF8F405A0D4807543297C1D9D9F953E195A45, + 0x1FA904198F9B1FA7B5F70817B2DDE39246581D562994612209E805E221ECBCC2, + ), + f034( + 0x41545ABCFA583FCA4E33CF6F0B0170531C23DE4A6D93DC4FD75DA0BECBAB68B, + 0x2310549B6F149F5066FA83B09B2ABAC788488A372B682AD34B12FAC1C86A0C1, + 0x2ADA1B0D5152FCBF2D92F27CAD557C1A799E71F1C58FAE07A2DBB0784F450E25, + 0xEBC29B6C3DB8064B43F0FFB35B1661E1999AFB25B68673B837B1E34AF5F31E5, + ), +) +sz_nz_bit( + fq12( + 0x1817D0F20905508B89E5B8D77B21406E48062B1B343A58D9E170A2E403AAF7C2, + 0x1A484BCCC7BBA64E023387F8C106973A1B80667317C8082E271CA3CD3C7C8551, + 0x17A2AD23A6E7CC2203102100E17B965656FA2190FF39E35D318E0B50F7545601, + 0x1666A9939E28D1FA12A9478E68BFEBBA19842C7F84738B86873B20FFE89DFF4E, + 0x268C063E4B9287DB9AC43A4B26AFE8CC4AAC33ED9E1833F79EC11260DCBC294D, + 0x13380A59EDA7E57B3DE92A04CAF3AA8B5E26A4B598CCA5C48F3C926C6744468, + 0x12A19FB3CC5EC40413FF3C0807BD32E6C91DE7A756681AE493EC6E5D23122297, + 0xAFD672274FCE8679901500F20E82B30CE782DCDED2680100F4A47B9E7F8D0F4, + 0x14EE1DF5E6454E37520B2D15420D2E21F2C12B9FA331F17CDB6D1414F14A0597, + 0xCBFE9DD7C9AA681C80E0DAD9AAA2B3B2C451C1F87639A9E40B2C9F2D028CBEF, + 0xBBC2E6A93087E0FFCF96DACE354C4EC69C92A093EBCEC462BF645F39F2234A9, + 0x150B3BAF28D9AD063D1BD132586EFA2DED13CF65A35F14A8EF7AA87522FFF1D4, + ), + f01234( + 0x984A46EB06803ED84694BC0B4DB02963F7CFC301CEEE9FB298AA69E3F2FB3DB, + 0x2728495BDCE4C5DD680089FC737A6034C017D82A38A355C8508DE5BC11C1CAD1, + 0x94A33BFDB8012FECAE8F4F981037430171453C70E7CFFA4D421DF9035136AB4, + 0x2F9DFF23F23C3F3F1F64B5387C2F68B873A42C86F829087C026B9FBD9D1B660B, + 0x16F113C1B69A268354B2757C91B5599221A90079C7434385B361560D891A1479, + 0xEAFB58B9DD50ADC805B8F1A4BB0F80799288890B98279F17B60807970789993, + 0x14C92DF428E1027888110928B55080C607AA61C1FC7059DCB5281B075214693A, + 0x68B6D0A10C036E786E9E22A9FCC6C41C9251B8874AE9BDA3DD129114D448762, + 0x2062A34BE9DDD0F70CFB2E064AD2A4E388C747B32AB00BF083603C14A2ECED3F, + 0x26E555545DD779377C914461D8D665932312E5CC33A6D983DDE314E4E585745A, + ), + f01234( + 0x16F025BC3FC96AF7F29ACDAB38A3DA2A104AC2FEA3E680ABFAF94ED00866A0C6, + 0x1E230E1D4ABA8C1C759FB4FDBA4CB48296EE4A73D47234FF7170343F07FBD355, + 0x12408DC1DEE9328FF0CF8B5BACC0D8EBEA42331718F517BE51425403F9ADEB2D, + 0xE3FDD3C80F768BA5DC4AE97BA7757CE1928CA21CD3D088469A655B80238DCB4, + 0x173E139C9E96850A330F64AEADC74BF731743DB89CF6AAAF7DAB374069B6B9B9, + 0x239C341BA3D01821547ADC03DC7D9BC50458550022119558AC560F676C18874D, + 0x15B0BE4ACF858110F703A141A2EF88F0638262E80A7AD75DB6B8B71FA887CEE1, + 0xF459DA2AF8C3710363525DBAE26258ABEFD159D958AF93DB97E4C24F707C9C0, + 0x1E1B40D79AFA981AF423BB2D4537A175E2BD33864D783AF034973027E8C586F6, + 0x264ACD3588B584B7C4A67F15F2364A0033F4A287D8D8E8C107166C280873D771, + ), + f01234( + 0x255C2ECAD1C8C3EE6AC43F25D5B46F3BE3C1C35BAA6A66C50CC553533A149804, + 0x80BF55BF9588D4E391AA8780FF20DD7DFAA43EB0AEC65975BAFE9234FAC8B4F, + 0x2FC5450ACDC7B48F04B6A96E4970D5B46CE19F2830D7353D70D84F6C60305A09, + 0x2C0642F22C662DFE5ACDAE2915A45F5BB72A85D123FEB474D36429793B3BDDA9, + 0xC25D83361CF09A68A6F97611D74F09025E3CCD360D564ECFE78582CDC899B54, + 0x1268418F0AD5CB97493BB41A5AFB5FF54FA1B3CA30DDBBAE5593F7321B12A3BF, + 0x1D99BCCE7412C384412C26B0BC254C988448C6681807DCF3A950113B4A1A8764, + 0x16CD38886EC3B89B9D6B614AE5CA32338E487362471FAA6116130B876857397E, + 0xF545E24E8F9E75BE88A193E5BA8C2A574D4138E7C9C9706807F73DD81ADD791, + 0x232D66CD5587662EAD56C6B749F894E9A84F5F1416209E012AE2091950DCC5B6, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0x1F4C12BCA7AAC7EDEF87A9C147423F0E08597C86BB73E4A1535288EE1429FE99, + 0x15EAD5D253491539A7EF95BC47C9E1D1BA92A7A4B852A127ACF58221424B56E9, + 0x1544017B699A2E41E9A51DF84B89675C3188C596CE327CDEF97C9821FFC60CCC, + 0x1ED63C4C3430F0F7BF154D64683D0DB2B081C089E58C9184E30DAE64D15FB2AB, + 0x1E96AD622293DD7BDBE71332767B0B31EF699B33AE4F5CC2DE4B06577E651565, + 0x3056A037E685D837B414D1E7CF3FC1E7A2C0ADC44732B6C5A5D275DBC9102F06, + 0x113F0ACBA7294917C2056C693221432FC3E74EE823866E788A287DFFDCF5C2A7, + 0x21BE746D995802CBC21B01B493DDF2F8EC26038646E29E6F44AAC029B67062AE, + 0x1EBB8F45CECD4D2ACDDB47952899231A125EBD88ABDCAF07C5A6F9A83D5A136A, + 0x865F693275E3565432E0B64020CE3468ECBD3581C7E59CADB265C98E8DDA4D6, + 0x2D829C3AD9980A58526F9EC92F4D91E263AA9FA5168074289B76AED552098C30, + 0x21ACA72A7A70AC3C291C8E7870AE53D9EDF56468331E3B5671FF0EDA123D1288, + ), + f01234( + 0x2353038A9020CC664C9A4E3F2098577B2E1D51958C2F8395880E85322C5E310E, + 0x1DD94AAE68D5B14265803EFC117C0282EEA3E38B3F0427847D555AD7224D7CD, + 0x16CD5A810B17E97F5D781F6F999DFB7E49402D057D6EE270385079F7EF478265, + 0x51E2BD4338A566D902AB13850E0DEA18D5B870F78F339E891E1A2BEDF96AA9C, + 0x21FEA3BD3E6AF2FC8813E6D23231A2EB1414B42C3F9B216702F3F3DA1A05D2FD, + 0x6736615BE23E20AA29B46846F147E92F6794A8E43B0B8BA0AECF987355F7A61, + 0x12D5BBCE1B51BC44CB1F488B607958D46BE04CC3476FB1B5AB81947E190EC3EB, + 0x2CE339EC4D747E969DCD4504C3E9BB5B29E65D92BFDC14B22C4AC73678F37913, + 0x19A7D1DE498EDCE448DC1C2101A2614F89A5D39C2B714F0173873D21488AF870, + 0x10CC155341FF7CBC27D94167F862EFD94B9C220A0EC3B9BA29A80A99A9C289C3, + ), + f034( + 0x12CC65D5BE8D40B0542DF6863A84EB22A847E65787DFB2799C656A4DE9D5A8FC, + 0x2D41AC88CD76B00B106CA17DE0563A6D5D6126B7A7BF9ABE29604A5DBF73EAD7, + 0xCA5CA174A0CCCB95B56FAAD26E67AC36D72576C839C8E40DEAE042C1C968219, + 0x1EBC5F63CB97C91450D3FDFC0E1540A812AC0E856A140FF2A866F62936A8C72A, + ), +) +sz_nz_bit( + fq12( + 0xBFA7C1FCEA58E7B55DFA7D4E503D5C396944AF4BA22DC7B54DFAA22D10DEE5B, + 0x809166BD5CD5229A3A0B08DEEC996EAE4FE6B836905982EE6F07918CA1E2FF9, + 0x11CD4313CA8219489C3C35005ADA7FF8DB7369FE72B118ADA2F588C34BEBDBA4, + 0x18A134CDAFF097C84ABCDFEB9EB8020CF4585460F4E06B49613CC9FF3950FFAB, + 0x249DD011C58E6CE63BA25E60A551A80870FE8743191815D16C14F2473BAE5BA9, + 0x295C8148774A3E8CF37E241D63F33D3FF45769A6E7974FE2ACD432D0738C6940, + 0x829722EDF7442798E6D9CFAC9B289B8CAB080E7AA457AA99291D12A47BAEA70, + 0x476AE32443BA6265BFAABFC73B4F0A8A91368CE3F4DC62FBAF8BC6E034EDB74, + 0x1AC27486533C1EB9464EADE86F7103FCED2D7E65D110A8FB1823085A217F9B07, + 0x2377AF3517A9C34E55CE2BA96441303D9B5EFF16BA46FAADDEB98C4DC715381B, + 0x1662E0AE768C7F49F0CA4CD294B05A1D1C0204380B1A747EE265A90800B159A5, + 0x404208CE10B890070814E721128C97E750602B283B44C9D80A7A4C089101F3C, + ), + f01234( + 0x26F89C3D2EB44D23F49612F29041E9EFFAE81E7ED03069AA462431CAD86A478, + 0x222C52B1F76A92BF1B6D62510E55090115D00933D59E90BDDEBD2BAC962635D2, + 0x2C093C757300AF7619F15A4D7BC23CEF37AA013EBAB7A141602BF7D0BC0648EF, + 0x14550B21FCAC178181C1082DF447DA3E8B85BB152F2759387339EC0B0A1034A8, + 0x27C771B41E68B0564F9B3024060C08C6FCE17E57E3CF4E9AFE0DF6FEC9E8A721, + 0x18F775A9E8D37DE973EAA214ACF04B979FB0286979F9F1E47B728B01AF28391, + 0x1D104AED97F64EDE684EF5269819A94C7F6CAB3360E99E060860A58C213D4FAA, + 0x16F0CB7152FF06771BE13D4F0A06D5A45B0ABA5A33247D90E351D2A0FE960A3D, + 0x1D64895234C2D3DD3B845E2CBB5CB78DA62C036D7F622323C54BF496F575F7A4, + 0x2EECE508EB195BA0E1794E7573DD4C3508340077FFD1518114F2132FF4A95E15, + ), + f01234( + 0xA1DD1D4C6EF1D3382B1F375E65A5B36B0E25C095516EBA366C5D54A09D782E, + 0x1910CCC0548C1199CA837A2F1E7F8602A947C0284BCB22B816EA765EE33D751C, + 0x1E671B80B53DA2C0F26B81AD2C009DAAD0E562422B925599D6FC608295D9C29D, + 0x1F8055B14CB89EDFB47F87BC6304565AAAB19C8B52DE36E77E00FFF7B678D540, + 0x19864C110B3CA99A404A722E17D6EF3D69FABD06A6D97B9A8EFFB0601A6D8CCD, + 0x1F35B13B97B31CBB08D654BF06CB8A137C753F42576997E87A5A63A2481FC03D, + 0x21E5C84F67972DFF8AB1271C82EC7ABD4CC9EF74EF85401B5EAB83D45BBA87A2, + 0x3583948F68B664817EC66CD4E9E4519B97EC02BD54F483A6567B2231AA30B5C, + 0x1E2CEC36D6387E2CDC13842ECC8A9FB95B0602BB5B420C8FE6243C3693E41503, + 0x18BCB99DA9CF9A2BB9A6D611691641F6CA66579C91BCE4A03BC0E3FE586C99E6, + ), + f01234( + 0xEA25C742512F20C736065C3FB9D7F7D48D4937D27A7919393C0D874C3AB43E4, + 0x218AFF558B16675F9C9D208ABFE2DDF63DA70427FE3D45589D084D61AF6D2AC0, + 0x6C1533A7A45F9D2445B8513A72980FB4059A0F179C48EC123E48F4C1E8D1C32, + 0xA7B09EC0705A0ADBB78B42DCB107B29425B24CBC601232F442CB0473E73F5C4, + 0x249FB9AE10A9359754F3C7764B7FEFB9ED9E746942C52195D4CEB1D7A9CC6223, + 0xA4F576714264C044D0DB12BF819BF54E5B7E4B7E50A959AB75A1F811730471C, + 0x4E5B5118D3EAC8299686FAF678A5849DF767DDFB82E32B2B8504CE000791BAB, + 0x23E461823D4D200B7C98394C6756CD24A34E3EB48217882F2DE1A4F74F9F42FF, + 0x174EA35CAE0D19E02ED87932AFAE86584FA061EC54C27E5FF675894C168F15B9, + 0x13878C5363E673B3DC9DD9FE06E569BF83F1A7B698558F4A9EF0A479904467F8, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), +) +sz_zero_bit( + fq12( + 0xE86945B332C60BB6881741DC79E260278E0852BDBB5A7DE5173C50F2FB71838, + 0x7553B27F196C659DF064C26BB49A748961FBBCB16E5B7BDB17B7949CF827E06, + 0x23DD64B391387711D6CD7D7676489767CBFD3E651EA84F72B5955CB7F92C802B, + 0x1F87BD526D38825419B1F8816CC5FA6531A85AB4FD411DC208FC83877E6AB1CE, + 0xD5696A5B80667785794F2BD54654CAAE41F524D2A993F71B126CF5E141A8EC9, + 0x212BEB9C1F905542F20C61BD39D9F49672EF4F39A7F277C1FA6FB3F8D615F012, + 0x2A498D026F94A741DCE0FE8EB4DB7FA6680869D03167A982B920C612C6E9A917, + 0x18702BD7F93299EA9AF0EA96EF498037ADDB3092939145B362153F73EEA398BF, + 0x1827B1BAEA7B83E9E30105EAEBD4EFD90CB123D4AF7492A93A6A43A613EA66AE, + 0x103E275D34A00F6EDD5377E2B0BDBD00310712507465A7AB90ACBD72F20D5FEE, + 0x4CE49C342D528A1C0E53E6A0CCA4FA7913A8D358F3386C3A79D220E11BB79A9, + 0x422B3BCD3714FDCD8BE60EB02A7021D7AC4D7728AF31399E86FDEEF85DD2090, + ), + f01234( + 0x11234A4287FB1D90CDB9F579CD28DD4FCB4631B01E85324851CF43A2CE611EE7, + 0xA4AAD6886144E43C72B53A44393D7AB9BBBD8E792A4C669C33B41967722F03F, + 0x22AB4FA2915253F4091D89D27EE57A920BDA9930EEADCB2AF73A379ECC91FE23, + 0x22ACE9A04AD7CBDFBA765F869F8DB3893364AA5C0E80D691691A8B5B7611B315, + 0x256C1E4167D0C3DDC66E9A3F0808CA7441B5D2296D7328722119810880977E19, + 0x6373B829EDDE81E0147C4AE75DD9BE0E714D4E741474C62DDA3B069F4DAC, + 0x2DAEFD50DD352A84B7C0DD36E7BC30CAC3807C4688CF023BEB63C8C9D3BCAE3B, + 0x212414E0B08C50583CDE288C2663DAB2117C91CF7876A5989C19FB89E6E3A3DA, + 0x2EF9CA7FD53F62F4CCC1099DACD0DDA0F2E2E520CB529D1CF2B84C62F17C5F3C, + 0xBD7CB8B77020D2E16917D0DF47AF6A1BB24996088BB51E44F758E3C4DED0988, + ), + f034( + 0x158B433CF4F62C6C5DF4E9BCB435B1EEC851A93E9672CDB5BF23E9E03BE61385, + 0x2D65028EE1D297EC7CD10F5A83E4BE50D05AB08E5C9014A7356040355901BA47, + 0x15C2416ED0E70ABEE61C24F6FBBECD7CA687E9F080C7201BF675B41ED86E3B8, + 0x2D555B32FFC1A5F0CB0238121929A7D0160CC5EFFF2ACFE4BC56D636944FCA45, + ), +) +sz_zero_bit( + fq12( + 0x2A5865533F8DC4ED124E365CC9CF4696B43987318E35295C76F0F24A9CDBC5D7, + 0x28112E64982A266A9DEB41351AF09774A26ED6BCFDF44696EBABFD73B3FBB126, + 0x776DC495D511440536806E92EE2B478EE5E9FF1FC8DB6A6FA1D6A2D48C3C3A, + 0x14EAB3474740650E88BE6801121DCEE2B2C20E18616D4A26425F2AB7CDF5D9BB, + 0x2F5BFD472EB9427B41F265C58A0973F0D089E472CAE9F45CC9A2A0760B2A0CC6, + 0x2636F83A58B4A5E0C7B828A51290C8FE9BA1A6C3EA0F38F6BB9FDE7750BB483D, + 0xC5DD7BA88089DB1E463ACE9DB8CE644D878B926637591A0C66EB661AADDC9D4, + 0xB790A69FD17C533BB80EA3761A8C4E3037EAA447BBE9E6BC54E14CEEBA420AC, + 0x288EEA3845D90879B029FF861395E37F5EAC7E12181F2DC4C01B1CE8A2A5EF2C, + 0x373A7742DD3A31E16D4A361549B8F68E590DB51DF833434B859DDF5AF28CC21, + 0x214EEB4050418CC88A6ABEF026AF695CC769FF1AE0AAC73D97BC1002EC024256, + 0x9E6F6B4461DD0192D8D57635B46D84558EB28B187491E12EAAEB02DACF4DD97, + ), + f01234( + 0x998935B12A2E14269F12243757C2328348DDBDB3AC509A6078A3194A6FD9550, + 0x6D60F1DA2CB2CB7EFE6711F1739690395C25EB81AF90EAB9FDFEB2128934D25, + 0x6E4F1F6BE7F44C4882D058BE2D856A52F326A60970481F0B81A6E43DB4C0304, + 0x1F5455487E935FC319ED3652611971D95F843D482E61207035B4BBABD1F259D7, + 0x271BE2269EC49358DE10DA40133F1983562566823F80208C46CF1E570349169E, + 0x1832F8F2C77C84413E73B54C61C85353F5746158D9A971B7DF8FBF3684695415, + 0x20F65A0504E052C68073AB262F892306975A83F63B40101DA1428C2CC9031AEC, + 0xBD1B6EC28ED78782A6755AEF813015D2A154841147593D0CBBE6B54466BE66E, + 0x25C866BC199E70C737B8388E3C6FECCB70797CE6B7F7F8C2B2D88D5E5E4D11B9, + 0x2AEA83CE549D282583DD65C35C6C64A648609E9A571D9868B11004C852360D65, + ), + f034( + 0x2F656F0CF4641910C85828E71D67301F908D45C2EF052E42CEBD4F296965EAC3, + 0x75A9F0DACC1B96150AD3F2C87705C3E65FF9CB6CFD73C600729A630770BAE11, + 0x14DE82E2B7366C4483A749965D0B984DBEBEE6B9C9DFF1B6A52539C6CC421FD9, + 0x1035790E3416BE191710C14E7E586D2AADAA221F0AF13627DFE1CE7671F6027F, + ), +) +sz_zero_bit( + fq12( + 0x16D10A5C6CEA362108BA04847650AC26DE21618BBD7E3892BFF38B9679CA6E96, + 0x25F50BF371F91C0568A968604C7000F3C0ED5EE7E5B7D30B8307EF3F633A4D0E, + 0x2F5CF80DD76DA17F9DDB7B9132E220A252BCE4D0D28812A6854562CBDBEEDED8, + 0x2AF1D0C4C61619B351BFD17927F18910EC22C911C65F4CD45E0E1F9CA9BBD728, + 0x2D51722D60603AEDB9E66F91907E48B261FCCB0D30C0D6D2442C0F2FC63ABE0E, + 0x652438DD0AD1B38C454A33EE9497CAD0D0DB8109C73BA7BE915EC924A6E49BE, + 0x2EC429ABB6DBD61C8AD7378B5DDB3FA7BF53CEDBECDF742451D0F9FAC7C9A386, + 0xFEDEEF0B835C44F98520C12D729E6C3AA2880038BBE1098658D7719DF7C1A38, + 0x267F5A074B3B0EBAFD62DC7950A944A0908F78D4B62F7AF9BD2AE2E271E55424, + 0x8BA263D03F22ED794FEF8BD9BEF91BB3A5658431B38A326BA80A689AB91B98E, + 0x15E92B8C7149344DDE7D0DEAC5B8BE9D969F87927FDD2712DA35C990697F06F9, + 0xFAA0BBA2CDE4E5C802F41528E78D00E176FD4D73006248C724B1AC591171E6E, + ), + f01234( + 0x7927AB2EAE2972344E0F5B7A3848883047D7455B4298BCE2AC2F5AFAE4E0191, + 0x278A20313D545DD16D64F64630FF70A7C0F8ED193CC21C573DA42C65EF2441B2, + 0x18AA0EBAAD5CFB72D0DB2C3DF33C69C9A9806D02B3DD028EE8F0B4CFA44BCA9E, + 0x243865348E4C1B7D665E648EEAC0BBB1667D58AEAC29109E83DED39BCAA1B779, + 0x278B3549273429528C5B21DBE3B9EB0EB3721D2198D31C4959564B31EC3E14EF, + 0xCAE0B22D74FC59CDF49996550D590C6E784A7B884C935602740A3BA2C18DE54, + 0x24C32BD1E0168C19972E7B29881C62BCBE08BC363A6704732C58A4687CB372B3, + 0x1386E7CD30F116EE09213D8B73D11C7DA88A65DC2D2D0CE990EEF60AD8328F, + 0x139B82B4BBD99FAB8CCCE5EBCF076EC02C35E6204BE0A1A897D0C0EA0C08C0E4, + 0x174003C6A585A2A3F090DBDFCF3826E035F2501FB84C523C52B18B17C215F228, + ), + f034( + 0x1C9D660732A012C52999D527813117CB3AD8253E11C6D6BA3115A62BDAF78313, + 0x7EB252581DC64B9A8FE7E2BF61F7C327E5AF168D5F2418EBCA799950CF7B7C3, + 0x2DA1A73A02A61A563C299C2342E81FACA7B577A4B07D6744AC97C49C6FDF6BBC, + 0x195F0CE0CB745A6E06C3D7005D6D909CFCCC7F5C24D7F4AA5FAD142709B4A834, + ), +) +sz_last_step( + fq12( + 0x13C4D9C3066B99A1CB95288B7C2339B39F4D8DBDFF2DFFA6D4050D61CA5EBBDE, + 0x9DCA9720802636A30591A5415B98420A9D3AA8123D733989717A10082B3FB70, + 0x14E66FAF16FB330C223183A0AA08BC76CC618ABC8BA04C5BF6AF4D6D02EAF9C2, + 0x12104BD2AD92D2FA6DBECD5C705F31D5546DBF1E95F2360E8052D1CAF5783DC9, + 0x8BD0B7E7EE5E7F632D698385BBA0918EB78A0E51EBC32061B367ADBA6A1176A, + 0x1098C6A63CF5FA94A1453BC1ACF5D347303DB6C467B28FCCCB0DEDA37F1A817C, + 0x2EE147C2286E19463EA4E1F0A5F904949BF34EA7FDDA9430FE4D8509D93C5A04, + 0x105BAC6EB02607D51D493E07CE922594EF24F7C84B060824560430AABB162D9A, + 0x302691C3DE0E92A7B158642F87B84C9B7B8ACFC7E08F78FCD3F231ABAC46780A, + 0x164E95B44C8DDA9D841950E20244D91F913D215160779D681106762635BA90C9, + 0x1F107910D1CA77305D07EE00181276931C4C5BC14AC294A681E03FC1BCDFC3DB, + 0x10EB1B4B878ADADB751B4077BAD5A03D0B0E2941504DA8CB330D609042131AC2, + ), + f01234( + 0x274CF476672D0C2B668C204044DC02C3624BAA11ED2E3553A883F9204C606EF5, + 0x15984D746100474163CD8162751D470BC2E2CCC1DD522E62825594938417D443, + 0x8356479000C18930164C7F73BEF8A210483A3403121654F016F734A6FCF9DF5, + 0x69865F114B56AA1B98DB5218447482F95DBF34289351C01B8DD984EFD7C4878, + 0x2CE2F18B9E7904BEAA04990A88227008989AB2F06FC356A92982131509DA87BF, + 0x2659134FA61945A9A034C1E0EC48128366F93F0021F32DE63CC5F9AEC08A9E7D, + 0x26854D97A75F7D4E9E755FAC0B3E079DE1FB431D067A6226A55FA40E1D04C18C, + 0x21BB8AD65C7894D93034E84BAC7E829E7E5BFF63917FD6ADCC631D905F7ADDF9, + 0xFD7DEF2603D080B0B145D5735418AF73B20AD3651F11213DFEB6360A56DD2F8, + 0x971F4E2CA3DFC7C08C8499073057A2A8B923C9D6E4C9C0B5A894E8EB8D938ED, + ), + f01234( + 0x1DD5A72709BD2D7135ED58178FC580678699C6F4CFF97539342BD03A25A7680F, + 0x1567FEC5252E86D3B1CE1FAB97B9190EA0AF9C1C93948CFF08AF785479962DCE, + 0x2945E73D4965D225C04491A315B26D89581D7156EC16AF37D4D73EE48F8A3842, + 0x2D73635A15255EF596F10552CDE06C5DBE47CBE723025E4D88D226226885AD2D, + 0xBFF06C33B24010B5C39F0B325A2E828AF1BDB4836B4566219B87EC1EF91577, + 0x1FF48E011BFEAC511126E1F6DCD6282C3CA490DBA2D7F0C11EDC7867A9D62C6B, + 0x207CA1626AAD9C768895BE89FD22AC81D376E107BBC430045067D431C6EC0AC9, + 0x27028F1DE42DA335460CD30D12CF0EE138D96D5863236FCA2E227C4D6ACF00BD, + 0x6DC00EE0040EF198401D19716AEB6525857D3B09D8885AC1027CD6B757921F7, + 0x2EA6574452B69AD7FF9EB924F97F791FB66EB7FE3C9F5D9B5282083D8EC266CD, + ), + f01234( + 0xF9C9B6F57785197ABCDB6653BED74183E4A649230C211266B3AE604E877FFF0, + 0x2E790A0AC6BBC8D4236DAB59AB09FF381159322237464ABFFC85EB614A1650A2, + 0x20B808AAFE5F9F25D86914C3B2392677BC0F417BD437F7428F5EBE816050F4F6, + 0x1D1CFC5AD668B6CC8C78F3F83D7D9E5830AC3EC2002ED3B60C032FFE4D5C12EF, + 0x2F2AAC071A9E42CE7C3E1E171239361B76FC5B5768B9350E70F69373BEE044C, + 0x1DB89F32E6F8C5E66096ABAC4F64B4BCDD9A33075DCC210BF79257CC09ED483F, + 0x1D3ED22CE61A723C41BF3DDD44BC663FFB1452B7938FECD0D07895B9DA4ED24, + 0x2FC344ECC1CB5310F6EE8F91DCDEEA9C5DDDBE6AF998AAAA4B59C979263AD6E5, + 0x9E98B77F750E8257A0A697C9239A1C004B9DC11147199F7AE186FC1CEFEA209, + 0x2A13E0CF050039934C77CDE777D9564DA02226FFFC7D2C54CA3FF1D2284EE003, + ), +) +sz_residue_inv_verify( + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), +) +sz_post_miller( + fq12( + 0x239E7BB19672A897BD27EC622D5E2D4EBDA338111E96C31D648C2D4DFDA30291, + 0x2EB0A1B0B86EF38EC0C7D4009DCBEECC2BDD37E840202CF409FE998FF592189A, + 0x1719AB64AF3BB4B565273672D89AAD01716BFC9289A12529D0E84D282E22F6DF, + 0x1EE6BDAC2F9581E3EDAC54C0440CFE6B314EFF9CAE00C97DD87921B395EE815A, + 0x133D7CD7E64DB33C94638F3E7CC69364A51072483E4C19570268B7AF038B16D4, + 0x28BFA52ACF920F68C8550DA17719DB5D97B9AC55B8CABE3F6A55BC9BCA265324, + 0x16DB2532BB9B35B5E0CCF63E0611239D2D8A80AC40ED9A17C20601DCE5426378, + 0x65B55BA4325E5EA4D757A76743CD21281BD07BA280324512CF28FB4235702FA, + 0x230C62EB6DAD5FBE23D133626C60F74DF83477597BFDC314A7967FF65B24324A, + 0x1C91F5E3577081DE99BC8713ECBB5BCE19FE4542D2498EE22FE97128EB2709DB, + 0x2CD710F77517AA4779E33DD8D69FA84F7FA822993B8E4939CD5147BB1DBDE244, + 0x20DB36FBB4FAA64E1746C5B7C32CD8B2CAA0681F406D4F59EAF1873A9C99011E, + ), + fq12( + 0x27C20318505E03CEA84A04223B8679A6C84C1E55E83957A21E8986C1B8140510, + 0x104BB1B78F934618C94BA0290A964C58F1400E450E9E19680C39A8ACA6FA15F4, + 0x2E56F81476F8D79F0CAEF927AC110B77CEC88490D0860C746D82583440BB8919, + 0x1A814CB6D1FA262A5882E06C097FD68C05FDD1F27E2288F84726985DEA9706E, + 0x19BDC2CD81965796ABC4DD1AC13A5941CE94EAD67C26445A67CA63F07DEF54FA, + 0xE328B63E1F95C3E6208878E9CA68FA49960E71588C6302C244B428B2CF5AA6, + 0x159AD96D8A0F81D1E048379CB2DEE2671581CB84E58DE9CBF2D4EA8D11A5A262, + 0xF63CA25374F5B91BE7D57A067F1E5EC7A906BE473FB01F091D1793FD999B926, + 0x231B22B4C91411C1AEB9724839622ABF9D9297CAD863A0312452DF9F56E9872A, + 0x2CC3C64540E5E5AF46B3C583A7314A94FEDB672DA5DA977C6AC70927247C73BB, + 0xBD670107051399799978F2A70D7A08ED0BB130D1FA74638DCE3D81536701C96, + 0x221446E74EF53A921ABB7B8A0FA2AFEE56481780D136BC649916F1BEEB52AAA, + ), + fq6( + 0x0, + 0x0, + 0x25BA8E0531275A44594C4F53B44497BD8D7341FD41E5FAF337FA74DBBFF9FE1, + 0x10BD041A04B5422922463BD8B6519B59AF036109A228AA43FDB7F215226ECE12, + 0x0, + 0x0, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x20EEF5CC5E42D307E50692C958066CA5A3A8ED6FEE3160F6ABC64438080D40A, + 0x22B901CC05A276A352A5B2E4CDB0801F1090D7C3C00D2AEE133E58FA9A08166F, + 0x21EF1182C5982045BE5086E98B702B8E0A020B05DA08615B4C56898BBE7AD627, + 0x166EAB18F982D529D9716951CA8C8E8CF7B4D6C2A33842B1EFD2E91C51974C9C, + 0x8C971EE7EA3190056BBC580A3E30D71EF9CF0F366E413B66A934308B1886943, + 0x962D2942749B2BEE17E3DD2A4A816798AB7526991EF4468A2D609EFF8E3243E, + 0x1AE755CAD670294BAE38E1E0872ED365362CE44BF436B195C74307B1E70F8EB0, + 0x28686F32DCB94F6A1BEF9B430E2CE391AA94642EF1B5E3E17D9C550BA13CF604, + 0x1FCA3FF372CF4F024EDC0012FE4421C27DE8EA9E57B7B41E56B90F17253042A1, + 0x1FD2DA899094D7186E11DBBCE1945254ACCD99C25A18496E63C82D8575E53835, + 0x10EF17E4EB1A799E6520665B6E568135518530CF27E473403FE4DAE5B3ABB359, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x18DD43EA981DFD93157DBCEEDAF779FE595DC591D7B55399BBC5E47F5774B57A, + 0x1F537ED6F41E14535DBD02F9A5AF0AFC9C78DA96DD0D5D7484B839007937E68, + 0x4BA271695233F366E472A1C648D0510041758D9480D7FE6F6A4E44DF153A37, + 0x1F90E59A7A3D55FE7985237FEE00013683931CD744B16D404B5768484ABA36, + 0x62D7AC8EE4A4E5489932505F2885972FA3FD80858C41DDBE7BCEFD9314FB68D, + 0x20E7B3EC5432216AF93B6D014DECEE713B348509C387B2C5928E23CE9222EF13, + 0x2B341214025B845522176C00365DC13E7DBC5ECD0353014F4A32875061ADA1D0, + 0x1D58A967F3CF6D852FF56C9797E30DE26B7404AC75A2F23F590187CD2B77333D, + 0x1F3E350F37FAAABA1D67362947B40D26255F0E14B41CFE18990D23ED58B27918, + 0xCA343F03A5AAD483087E7C6F5826CB3E93CF2D4C93DA1A9C833CABFDB03D201, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x20EEF5CC5E42D307E50692C958066CA5A3A8ED6FEE3160F6ABC64438080D40A, + 0x2EFA89E47856A8F39D582FDE1312FF29A7AAE4AD63655041E01CF6D457345DEB, + 0x19CF56ADBFF74C0AD339512436BC207ADBE3B43F6CE4EF20576B1D0850ACDCF8, + 0x1D3542951E75687996BD1D838717C3CB9691CB50E26751389E7BA1FF5EF22C5A, + 0x20D75AA79FEBE682EF974AE30FC5549BA7C2F59ED89BF28421C1419E1776E408, + 0x2E8AF76D1B428356E369E25853B8DE1BB216E0D36375AD58B7BDB88E309DFEEA, + 0x24D25C217E024DBDA4702D65A478A50E480D73C92B391C6584715863E7F043D4, + 0x7FBDF40047850BF9C60AA73735474CBECED066276BBE6ABBE84370B37400743, + 0x109A0E7F6E625127697445A3833D369B19987FF310BA166EE5677CFFB34CBAA6, + 0x38804B1BD6745B6A9D6C78C0C99126A0ED3A44EBD22083E6C7EA8A5C05A0127, + 0x88A86135288468A418988363D1908045E6E8F5B15068DA601BA68E41384F5F2, + ), +) + +sz_print_coeffs() diff --git a/scripts/schzip_runner.py b/scripts/schzip_runner.py new file mode 100644 index 0000000..bb16be5 --- /dev/null +++ b/scripts/schzip_runner.py @@ -0,0 +1,286 @@ +import galois + +# Define the prime number q +field = 21888242871839275222246405745257275088696311157297823662689037894645226208583 + +r = 21888242871839275222246405745257275088548364400416034343698204186575808495617 +FQ = galois.GF(field) + +# Define the polynomial P +P12 = galois.Poly([1, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 82], field=FQ) + + +def tower_to_direct(x: list): + p = field + res = 12 * [0] + res[0] = (x[0] - 9 * x[1]) % p + res[1] = (x[6] - 9 * x[7]) % p + res[2] = (x[2] - 9 * x[3]) % p + res[3] = (x[8] - 9 * x[9]) % p + res[4] = (x[4] - 9 * x[5]) % p + res[5] = (x[10] - 9 * x[11]) % p + res[6] = x[1] + res[7] = x[7] + res[8] = x[3] + res[9] = x[9] + res[10] = x[5] + res[11] = x[11] + return res + + +def direct_to_tower(x: list): + n = 12 + fill = [0] * n + if len(x) < 12: + x = x + fill[len(x) :] + p = field + res = 12 * [0] + res[0] = (x[0] + 9 * x[6]) % p + res[1] = x[6] + res[2] = (x[2] + 9 * x[8]) % p + res[3] = x[8] + res[4] = (x[4] + 9 * x[10]) % p + res[5] = x[10] + res[6] = (x[1] + 9 * x[7]) % p + res[7] = x[7] + res[8] = (x[3] + 9 * x[9]) % p + res[9] = x[9] + res[10] = (x[5] + 9 * x[11]) % p + res[11] = x[11] + return res + + +def mul_qr(*polynomials): + # Compute the product of all input polynomials + product = polynomials[0] + for poly in polynomials[1:]: + product *= poly + # Perform polynomial division of product by P + Q, R = divmod(product, P12) + return Q, R + + +def poly(*coefficients) -> galois.Poly: + return galois.Poly(coefficients, order="asc", field=FQ) + + +def fq12(*coefficients) -> galois.Poly: + return poly(*tower_to_direct(coefficients)) + + +def f034(a1, a2, b1, b2) -> galois.Poly: + return fq12(1, 0, 0, 0, 0, 0, a1, a2, b1, b2, 0, 0) + + +def f01234(*coefficients) -> galois.Poly: + assert len(coefficients) == 10 + return fq12(*coefficients, 0, 0) + + +def to_tower(f: galois.Poly): + return direct_to_tower([int(c) for c in f.coefficients(order="asc")]) + + +def evaluate_poly(f: galois.Poly, x: int, field=field): + coeffs = [int(c) for c in f.coefficients(order="asc")] + sum = coeffs[0] + term_x_pow = x + for element in coeffs[1:]: + if isinstance(element, int): + sum = (sum + term_x_pow * element) % field + term_x_pow = (term_x_pow * x) % field + return sum + + +def print_poly_tower(name: str, f: galois.Poly): + fq_hex = [hex(c) for c in to_tower(f)] + print("\n{} fq12(\n\t{}\n)\n".format(name, ",\n\t".join(fq_hex))) + + +def print_poly(name: str, f: galois.Poly, compress: bool = False): + fq_hex = [hex(int(c)) for c in f.coefficients(order="asc")] + coeffs_glue = ",\n\t\t" + if compress: + coeffs_glue = ", " + print( + "\n{} Polynomial{{\n\tdegree: {},\n\tcoefficients: array![\n\t\t{}\n], }}\n".format( + name, len(fq_hex), coeffs_glue.join(fq_hex) + ) + ) + + +def test_case(name: str, qr: tuple[galois.Poly, galois.Poly]): + (q, r) = qr + print( + "----------------", + name, + "--", + len(q.coefficients()) + len(r.coefficients()), + "coeffs ---", + ) + print_poly("quotient =", q, True) + print_poly("result =", r, True) + print("//--------------", name, "//\n\n") + + +def test_mul(name: str, qr: tuple[galois.Poly, galois.Poly], expected: galois.Poly): + (q, r) = qr + assert r == expected, "incorrect " + name + " result" + print("correct " + name + " result") + # print_poly_tower("----------- " + name + " -- " + str( len(q.coefficients()) + len(r.coefficients()) ) + " coeffs\n", r) + # print("//--------------", name, "//\n\n") + + +# Schwartz Zippel steps + + +def schzip_op(*polynomials, acc: list): + (q, r) = mul_qr(*polynomials) + # qc = [hex(int(coeff)) for coeff in q.coefficients(order="asc")] + # rc = [hex(int(coeff)) for coeff in r.coefficients(order="asc")] + qc = [int(coeff) for coeff in q.coefficients(order="asc")] + rc = [int(coeff) for coeff in r.coefficients(order="asc")] + acc.extend(rc) + acc.extend(qc) + return q, r + + +all_coeffs = [] + + +# f12: Fq12 sqr multiplied with lines l1_2: F01234 and l_3: F034 +def sz_zero_bit(f12, l1_2, l3): + return schzip_op(f12, f12, l1_2, l3, acc=all_coeffs) + + +# f12: Fq12 sqr multiplied with lines l1, l2, l3: F01234 +def sz_nz_bit(f12, l1, l2, l3, witness): + return schzip_op(f12, f12, l1, l2, l3, witness, acc=all_coeffs) + + +# f12 multiplied with lines l1, l2, l3: F01234 +def sz_last_step(f12, l1, l2, l3): + return schzip_op(f12, l1, l2, l3, acc=all_coeffs) + + +def sz_post_miller(f12, l1, l2, l3): + return sz_last_step(f12, l1, l2, l3) + + +def sz_residue_inv_verify(f12, f12_inv): + return sz_last_step(f12, f12_inv) + + +def sz_print_coeffs(): + print("\n\t" + ",\n\t".join(all_coeffs)) + + +if __name__ == "__main__": + # Define the polynomials + last_len = len(all_coeffs) + sz_zero_bit( + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ), + f01234( + 0x93B29143F057F125C8B5E8D11986A4EC5C7CFEAC89B8580AE9A9D5830A19D4C, + 0x516B755FE3311C2B90AFCFCD0AB1FACB18C3CC8CDD0DDBFD6A2E685D16682F1, + 0x2E473DDCCED3F5A780549F16B4A7CB4652E9C772ED985C0A32118E83DE37389E, + 0x118CAFDEBCD59151735610932C49F81451723124F3523811E7641958D79007A, + 0x825DC9BF97BF4E6BFB4C02AFC096E5103490AFDE25B7278DFF3518AC1E0CDD0, + 0x2D46D338E907A3D3000BD23703B22114DAC7DCF262F53E65BBB9EC6D9538183D, + 0x18D61A2D2F1463E84E308689805E18E35B683FF6B590E69412A01FBD32E0C059, + 0x202944D77C6438D408678579A5A20FF5747F9EE8810FDF22C22B54B4B6487B10, + 0x1E323BC97AAE1789EF90B65D67DFA09EB495D53664A1E36B777AF4F53FFBED22, + 0x11F0E69D23129D28D5B870DB1751D6D8210ED4F05C5C4DE29C53F05D97E92A6C, + ), + f034( + 0x17B07937DB1F72B2B29E2DCF434668F0E938DBE0119C93EA7D4F109C1A0F45C4, + 0x25B8FA21453F00D01133A94A381FA8E2E438E5E4B6581DE60BD897964B732ECE, + 0x262FA9C6CF2C4599A834A0AB9941F0B3CD2FF6AC62B560E9D26033B238E10BA7, + 0x8D5574056E7E5A2567BE6A4004C39ABEF57222DDD94DF6BF514B8FD81AA0440, + ), + ) + print("sz_zero_bit", len(all_coeffs) - last_len) + sz_z_f = all_coeffs[::12] + print("\n " + "\n ".join(sz_z_f)) + + last_len = len(all_coeffs) + sz_nz_bit( + fq12( + 0x17B6F07867B2D8811B94054CB20E02D69E8696FBD8DFC30FC4DCC16AC3582B2B, + 0x1AD3085832F02DB30DAD3A38CF967C8948FABF90895BF5D0A407D0AA584BD32E, + 0xD2CAA0C3E9B8D955D6724E67DBAA7E9AB77879B818540303A5A5111C84D37E3, + 0x566102CDB5869B6F0B0C3342806346613FAC9CCE8B781A7307CDB9E672F312A, + 0xDD420D0FA4C4D927384E73BA7EE4A1B29ED49093C7EC79F97D82AF03C4BEF19, + 0x11A1A49C01D86EEAB6189B48BFBD9D9265E6A00C3C426FBCD88394692CBBB70C, + 0x27EAB2E8253C9DC314236D5CCE23FB4432CA392392996634F4BBA295475D0E41, + 0x7A161D713740C29CB8751DFDB0356B683840F804C630E626286C406E7FDCF3D, + 0x1DEFEA8B95AC737E4CD6B7DFBF81FA06BDFE78FA9D0F81310ADDE1230219DAC6, + 0x83A69098DE2B18EED6BD8EACBE4643EF5992E7C106E160425BE05E9D27C91E5, + 0x27A45554C37CDA23DB4D69FA803E87E97DFF43000C1C3142E2900EC51F71191F, + 0x2281F657560C385B4B012BC66C195B4EE12E7EAD34AF187701A56A60B1810BDE, + ), + f01234( + 0x222A977AA4FFA65D9C2EBC4A5FE2570A728EE4F9449F646813B7BE7D98C84DA2, + 0x1326C02005E2C7B7B0FBCA21A8CBA9D9B16CE7BF5E81D95CA2876F14049AB725, + 0x2BF3C77FCE69A8D248404B54D89B009E21E3121811D9F5EBFB4F17BCF35A7C, + 0x2F42EB9A435788F1E15C33CD75F178E59523F83CB7AA2C5579FDF489B8A67123, + 0x167A0706B99282449F6A66682740EBD01753ACC06BA06872CE823A70F6887EDF, + 0xCECF82AB7D6C7C0298CEB4F604AB94E210A40642D9C97A990377946A6C9275E, + 0x2519D8C37853E243809F854B29498B50CCB2F980393E0A950FB1CBF28FAD8069, + 0x70B275B879A44AB0632A2E013E4D0B546BB7B69B2642824DEEB07E675B2F00A, + 0x19EE31E0524CF51959A5DEFD812C2AAFBDBAE4B77266BACC6303EB16B64F2442, + 0x265A6DE3A0CBDF0DA331D43A013FBCB13E4E941769F2A8A1B8854588329549E8, + ), + f01234( + 0x4E5B09D9F4292665E16176AA067E2AC6314F5EE79AE6980E2EDCC951148CC0C, + 0xC27543DEBAC89C088F304429D31120D4B6BBC864390DFDBD50CCF4A3770661, + 0x14CF9ECB7A77BD64B08034EE2D3E616C572CFDEB0E1DE220AF8A0F92C31F3494, + 0x334D335A567E7CDED065DB12B5F45C705EE0D5F9184FEFBEE4F921E1AF668CB, + 0x2826A23E0B1CAC698575D38F2A1D79E6C500762A65615FEB0D041FEE6AA429DD, + 0x18F7727B98A1F6C8CD46B748FDBD69037E93B2DD49777A0260802E1563DF9C17, + 0x1ED91C464D54BFBC17E6680B057B7428BD9027FD1C98A5B113D347126E7B0C45, + 0x2839CE5EB72DF677A6E93C6CE86FFAE65272EE60D408562A03BCB6DB931B2DC3, + 0x23BBBD1F71FA0168651C042AD0074DDC2C398B44B80A3BCCF4EA902CBBC4D76F, + 0x1F43F6A87F038259260C4CBC14BF83675D973601C00507E37B283ECDF2F45F91, + ), + f01234( + 0x2084A503B31430C051A6B15C6979941A555AA90918120C701C2242594BE11763, + 0x48FBFF86C4C40B20CD67E253DABF168B96DB7C2DD401779F46964C720F6CFA3, + 0x1393A3287B1E7ED23EF75FE9D4ED92BFEB1746AFC652C476B53A4E09F8F533, + 0x1F001533923D64935DB3C6B2614A670BB5F9AAAA20E3C278A7663227B81F7599, + 0x27C02BF0115CAAAC8757CC7A2AF350F61C0D2E4042AD96E710FF278A3DF1EB2E, + 0x19C2F0012E9756C8FD43E14CEE1EFFF2B7E4C1E62AB267285422ABC3166FBBDC, + 0x1049D88F2A5D7476D01AF11A564D04F5F48EC9D3A4DE84701EFE36D1933A0897, + 0x2327863ACF38241771E114E5C1A0053815F974AE5F37432A32E7ED82950F6A89, + 0x22CCEAC6484622E8F8572901926BF3DD343AB0C09EC2BB913F28F86F014CE60B, + 0xAE45A230BE8239F4C73DACAD60F20CC3D099EA2A8FCB4E2042F0B16AE926580, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ), + ) + print("sz_nz_bit", len(all_coeffs) - last_len) From 7b8f1205e6251f614b322b33a4711b158790928a Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 2 Jul 2024 22:15:53 +0530 Subject: [PATCH 02/97] bn_ate package --- packages/bn_ate/Scarb.toml | 8 ++++++++ packages/bn_ate/src/lib.cairo | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 packages/bn_ate/Scarb.toml create mode 100644 packages/bn_ate/src/lib.cairo diff --git a/packages/bn_ate/Scarb.toml b/packages/bn_ate/Scarb.toml new file mode 100644 index 0000000..515f262 --- /dev/null +++ b/packages/bn_ate/Scarb.toml @@ -0,0 +1,8 @@ +[package] +name = "bn_ate" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] diff --git a/packages/bn_ate/src/lib.cairo b/packages/bn_ate/src/lib.cairo new file mode 100644 index 0000000..c55f19b --- /dev/null +++ b/packages/bn_ate/src/lib.cairo @@ -0,0 +1,25 @@ +fn main() -> u32 { + fib(16) +} + +fn fib(mut n: u32) -> u32 { + let mut a: u32 = 0; + let mut b: u32 = 1; + while n != 0 { + n = n - 1; + let temp = b; + b = a + b; + a = temp; + }; + a +} + +#[cfg(test)] +mod tests { + use super::fib; + + #[test] + fn it_works() { + assert(fib(16) == 987, 'it works!'); + } +} From 915727b4bf515a9fe348ebfcc71868a1c5780669 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 2 Jul 2024 22:42:20 +0530 Subject: [PATCH 03/97] minimal: bn ate loop --- Scarb.lock | 4 + packages/bn_ate/src/lib.cairo | 25 --- packages/{bn_ate => bn_ate_loop}/Scarb.toml | 2 +- packages/bn_ate_loop/src/lib.cairo | 178 ++++++++++++++++++++ packages/bn_ate_loop/src/test.cairo | 54 ++++++ 5 files changed, 237 insertions(+), 26 deletions(-) delete mode 100644 packages/bn_ate/src/lib.cairo rename packages/{bn_ate => bn_ate_loop}/Scarb.toml (88%) create mode 100644 packages/bn_ate_loop/src/lib.cairo create mode 100644 packages/bn_ate_loop/src/test.cairo diff --git a/Scarb.lock b/Scarb.lock index 85c0131..ba06804 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -5,6 +5,10 @@ version = 1 name = "bn" version = "0.1.0" +[[package]] +name = "bn_ate_loop" +version = "0.1.0" + [[package]] name = "bn_contracts" version = "0.1.0" diff --git a/packages/bn_ate/src/lib.cairo b/packages/bn_ate/src/lib.cairo deleted file mode 100644 index c55f19b..0000000 --- a/packages/bn_ate/src/lib.cairo +++ /dev/null @@ -1,25 +0,0 @@ -fn main() -> u32 { - fib(16) -} - -fn fib(mut n: u32) -> u32 { - let mut a: u32 = 0; - let mut b: u32 = 1; - while n != 0 { - n = n - 1; - let temp = b; - b = a + b; - a = temp; - }; - a -} - -#[cfg(test)] -mod tests { - use super::fib; - - #[test] - fn it_works() { - assert(fib(16) == 987, 'it works!'); - } -} diff --git a/packages/bn_ate/Scarb.toml b/packages/bn_ate_loop/Scarb.toml similarity index 88% rename from packages/bn_ate/Scarb.toml rename to packages/bn_ate_loop/Scarb.toml index 515f262..a099523 100644 --- a/packages/bn_ate/Scarb.toml +++ b/packages/bn_ate_loop/Scarb.toml @@ -1,5 +1,5 @@ [package] -name = "bn_ate" +name = "bn_ate_loop" version = "0.1.0" edition = "2023_11" diff --git a/packages/bn_ate_loop/src/lib.cairo b/packages/bn_ate_loop/src/lib.cairo new file mode 100644 index 0000000..9db0c8d --- /dev/null +++ b/packages/bn_ate_loop/src/lib.cairo @@ -0,0 +1,178 @@ +#[cfg(test)] +mod test; + +pub trait MillerRunner { + // Returns accumulator + fn accumulator(self: @TRunner) -> TAccumulator; + + // Square target group element + fn sqr_target(self: @TRunner, i: u32, ref acc: TAccumulator); + + // first and second step, O and N + fn bit_1st_2nd(self: @TRunner, i1: u32, i2: u32, ref acc: TAccumulator); + + // 0 bit + fn bit_o(self: @TRunner, i: u32, ref acc: TAccumulator); + + // 1 bit + fn bit_p(self: @TRunner, i: u32, ref acc: TAccumulator); + + // -1 bit + fn bit_n(self: @TRunner, i: u32, ref acc: TAccumulator); + + // last step + fn last(self: @TRunner, ref acc: TAccumulator); +} + +fn ate_miller_loop, +Drop>( + runner: TRunner +) -> TAccumulator { + core::gas::withdraw_gas().unwrap(); + core::internal::revoke_ap_tracking(); + + // Get accumulator from runner + let mut q_acc: TAccumulator = runner.accumulator(); + + ate_miller_loop_steps_first_half(@runner, ref q_acc); + ate_miller_loop_steps_second_half(@runner, ref q_acc); + q_acc +} + +fn ate_miller_loop_steps_first_half>( + runner: @TRunner, ref q_acc: TAccumulator +) { + // ate_loop[64] = O and ate_loop[63] = N + runner.bit_1st_2nd(64, 63, ref q_acc); + runner.sqr_target(62, ref q_acc); + runner.bit_o(62, ref q_acc); // ate_loop[62] = O + runner.sqr_target(61, ref q_acc); + runner.bit_p(61, ref q_acc); // ate_loop[61] = P + runner.sqr_target(60, ref q_acc); + runner.bit_o(60, ref q_acc); // ate_loop[60] = O + runner.sqr_target(59, ref q_acc); + runner.bit_o(59, ref q_acc); // ate_loop[59] = O + runner.sqr_target(58, ref q_acc); + runner.bit_o(58, ref q_acc); // ate_loop[58] = O + runner.sqr_target(57, ref q_acc); + runner.bit_n(57, ref q_acc); // ate_loop[57] = N + runner.sqr_target(56, ref q_acc); + runner.bit_o(56, ref q_acc); // ate_loop[56] = O + runner.sqr_target(55, ref q_acc); + runner.bit_n(55, ref q_acc); // ate_loop[55] = N + runner.sqr_target(54, ref q_acc); + runner.bit_o(54, ref q_acc); // ate_loop[54] = O + runner.sqr_target(53, ref q_acc); + runner.bit_o(53, ref q_acc); // ate_loop[53] = O + runner.sqr_target(52, ref q_acc); + runner.bit_o(52, ref q_acc); // ate_loop[52] = O + runner.sqr_target(51, ref q_acc); + runner.bit_n(51, ref q_acc); // ate_loop[51] = N + runner.sqr_target(50, ref q_acc); + runner.bit_o(50, ref q_acc); // ate_loop[50] = O + runner.sqr_target(49, ref q_acc); + runner.bit_p(49, ref q_acc); // ate_loop[49] = P + runner.sqr_target(48, ref q_acc); + runner.bit_o(48, ref q_acc); // ate_loop[48] = O + runner.sqr_target(47, ref q_acc); + runner.bit_n(47, ref q_acc); // ate_loop[47] = N + runner.sqr_target(46, ref q_acc); + runner.bit_o(46, ref q_acc); // ate_loop[46] = O + runner.sqr_target(45, ref q_acc); + runner.bit_o(45, ref q_acc); // ate_loop[45] = O + runner.sqr_target(44, ref q_acc); + runner.bit_n(44, ref q_acc); // ate_loop[44] = N + runner.sqr_target(43, ref q_acc); + runner.bit_o(43, ref q_acc); // ate_loop[43] = O + runner.sqr_target(42, ref q_acc); + runner.bit_o(42, ref q_acc); // ate_loop[42] = O + runner.sqr_target(41, ref q_acc); + runner.bit_o(41, ref q_acc); // ate_loop[41] = O + runner.sqr_target(40, ref q_acc); + runner.bit_o(40, ref q_acc); // ate_loop[40] = O + runner.sqr_target(39, ref q_acc); + runner.bit_o(39, ref q_acc); // ate_loop[39] = O + runner.sqr_target(38, ref q_acc); + runner.bit_p(38, ref q_acc); // ate_loop[38] = P + runner.sqr_target(37, ref q_acc); + runner.bit_o(37, ref q_acc); // ate_loop[37] = O + runner.sqr_target(36, ref q_acc); + runner.bit_o(36, ref q_acc); // ate_loop[36] = O + runner.sqr_target(35, ref q_acc); + runner.bit_n(35, ref q_acc); // ate_loop[35] = N + runner.sqr_target(34, ref q_acc); + runner.bit_o(34, ref q_acc); // ate_loop[34] = O + runner.sqr_target(33, ref q_acc); + runner.bit_p(33, ref q_acc); // ate_loop[33] = P + runner.sqr_target(32, ref q_acc); + runner.bit_o(32, ref q_acc); // ate_loop[32] = O + runner.sqr_target(31, ref q_acc); + runner.bit_o(31, ref q_acc); // ate_loop[31] = O +} + +fn ate_miller_loop_steps_second_half>( + runner: @TRunner, ref q_acc: TAccumulator +) { + runner.sqr_target(30, ref q_acc); + runner.bit_n(30, ref q_acc); // ate_loop[30] = N + runner.sqr_target(29, ref q_acc); + runner.bit_o(29, ref q_acc); // ate_loop[29] = O + runner.sqr_target(28, ref q_acc); + runner.bit_o(28, ref q_acc); // ate_loop[28] = O + runner.sqr_target(27, ref q_acc); + runner.bit_o(27, ref q_acc); // ate_loop[27] = O + runner.sqr_target(26, ref q_acc); + runner.bit_o(26, ref q_acc); // ate_loop[26] = O + runner.sqr_target(25, ref q_acc); + runner.bit_n(25, ref q_acc); // ate_loop[25] = N + runner.sqr_target(24, ref q_acc); + runner.bit_o(24, ref q_acc); // ate_loop[24] = O + runner.sqr_target(23, ref q_acc); + runner.bit_p(23, ref q_acc); // ate_loop[23] = P + runner.sqr_target(22, ref q_acc); + runner.bit_o(22, ref q_acc); // ate_loop[22] = O + runner.sqr_target(21, ref q_acc); + runner.bit_o(21, ref q_acc); // ate_loop[21] = O + runner.sqr_target(20, ref q_acc); + runner.bit_o(20, ref q_acc); // ate_loop[20] = O + runner.sqr_target(19, ref q_acc); + runner.bit_n(19, ref q_acc); // ate_loop[19] = N + runner.sqr_target(18, ref q_acc); + runner.bit_o(18, ref q_acc); // ate_loop[18] = O + runner.sqr_target(17, ref q_acc); + runner.bit_n(17, ref q_acc); // ate_loop[17] = N + runner.sqr_target(16, ref q_acc); + runner.bit_o(16, ref q_acc); // ate_loop[16] = O + runner.sqr_target(15, ref q_acc); + runner.bit_o(15, ref q_acc); // ate_loop[15] = O + runner.sqr_target(14, ref q_acc); + runner.bit_p(14, ref q_acc); // ate_loop[14] = P + runner.sqr_target(13, ref q_acc); + runner.bit_o(13, ref q_acc); // ate_loop[13] = O + runner.sqr_target(12, ref q_acc); + runner.bit_o(12, ref q_acc); // ate_loop[12] = O + runner.sqr_target(11, ref q_acc); + runner.bit_o(11, ref q_acc); // ate_loop[11] = O + runner.sqr_target(10, ref q_acc); + runner.bit_n(10, ref q_acc); // ate_loop[10] = N + runner.sqr_target(9, ref q_acc); + runner.bit_o(9, ref q_acc); // ate_loop[ 9] = O + runner.sqr_target(8, ref q_acc); + runner.bit_o(8, ref q_acc); // ate_loop[ 8] = O + runner.sqr_target(7, ref q_acc); + runner.bit_n(7, ref q_acc); // ate_loop[ 7] = N + runner.sqr_target(6, ref q_acc); + runner.bit_o(6, ref q_acc); // ate_loop[ 6] = O + runner.sqr_target(5, ref q_acc); + runner.bit_p(5, ref q_acc); // ate_loop[ 5] = P + runner.sqr_target(4, ref q_acc); + runner.bit_o(4, ref q_acc); // ate_loop[ 4] = O + runner.sqr_target(3, ref q_acc); + runner.bit_p(3, ref q_acc); // ate_loop[ 3] = P + runner.sqr_target(2, ref q_acc); + runner.bit_o(2, ref q_acc); // ate_loop[ 2] = O + runner.sqr_target(1, ref q_acc); + runner.bit_o(1, ref q_acc); // ate_loop[ 1] = O + runner.sqr_target(0, ref q_acc); + runner.bit_o(0, ref q_acc); // ate_loop[ 0] = O + runner.last(ref q_acc); +} diff --git a/packages/bn_ate_loop/src/test.cairo b/packages/bn_ate_loop/src/test.cairo new file mode 100644 index 0000000..e8a0b89 --- /dev/null +++ b/packages/bn_ate_loop/src/test.cairo @@ -0,0 +1,54 @@ +// [PASS] bn_ate::test::test_ate_miller_loop (gas: ~1) steps: 110 + +use super::{MillerRunner, ate_miller_loop}; + +#[derive(Drop)] +struct MockMillerRunner {} + +type MockAccumulator = felt252; + +impl Miller_u256 of MillerRunner { + // Returns accumulator + fn accumulator(self: @MockMillerRunner) -> MockAccumulator { + 1 + } + + // Square target group element + fn sqr_target(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // + acc = acc + acc; + } + + // first and second step, O and N + fn bit_1st_2nd(self: @MockMillerRunner, i1: u32, i2: u32, ref acc: MockAccumulator) { // + self.sqr_target(i1, ref acc); + self.bit_o(i1, ref acc); + self.sqr_target(i2, ref acc); + self.bit_n(i2, ref acc); + } + + // 0 bit + fn bit_o(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // + // do nothing + } + + // 1 bit + fn bit_p(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // + acc = acc + 1; + } + + // -1 bit + fn bit_n(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // + acc = acc - 1; + } + + // last step + fn last(self: @MockMillerRunner, ref acc: MockAccumulator) { // + // do nothing + } +} + +#[test] +fn test_ate_miller_loop() { + let res: MockAccumulator = ate_miller_loop(MockMillerRunner {}); + assert(res == 0x19d797039be763ba8, 'wrong value for 6u + 2'); +} From 20923a4183698733ac11b839263ce548a3284044 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 3 Jul 2024 12:23:47 +0530 Subject: [PATCH 04/97] minimal: fq tower types --- Scarb.lock | 4 ++ .../bn_legacy/src/fields/fq_12_direct.cairo | 4 +- packages/fq_types/Scarb.toml | 8 ++++ packages/fq_types/src/bn254.cairo | 38 ++++++++++++++++++ packages/fq_types/src/lib.cairo | 39 +++++++++++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 packages/fq_types/Scarb.toml create mode 100644 packages/fq_types/src/bn254.cairo create mode 100644 packages/fq_types/src/lib.cairo diff --git a/Scarb.lock b/Scarb.lock index ba06804..851dafb 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -15,3 +15,7 @@ version = "0.1.0" dependencies = [ "bn", ] + +[[package]] +name = "fq_types" +version = "0.1.0" diff --git a/packages/bn_legacy/src/fields/fq_12_direct.cairo b/packages/bn_legacy/src/fields/fq_12_direct.cairo index ca7c95c..366fade 100644 --- a/packages/bn_legacy/src/fields/fq_12_direct.cairo +++ b/packages/bn_legacy/src/fields/fq_12_direct.cairo @@ -30,7 +30,7 @@ pub fn fq12_from_fq( pub fn direct_to_tower(x: Fq12) -> Fq12 { let Fq12 { c0, c1 } = x; let Fq6 { c0: b0, c1: b1, c2: b2 } = c0; - let Fq6 { c0: b3, c1: b4, c2: b5 } = c1; // This should be c1 instead of c0 + let Fq6 { c0: b3, c1: b4, c2: b5 } = c1; let Fq2 { c0: a0, c1: a1 } = b0; let Fq2 { c0: a2, c1: a3 } = b1; let Fq2 { c0: a4, c1: a5 } = b2; @@ -66,7 +66,7 @@ impl Fq12IntoFq12Direct of Into { fn into(self: Fq12) -> Fq12Direct { let Fq12 { c0, c1 } = self; let Fq6 { c0: b0, c1: b1, c2: b2 } = c0; - let Fq6 { c0: b3, c1: b4, c2: b5 } = c1; // This should be c1 instead of c0 + let Fq6 { c0: b3, c1: b4, c2: b5 } = c1; let Fq2 { c0: a0, c1: a1 } = b0; let Fq2 { c0: a2, c1: a3 } = b1; let Fq2 { c0: a4, c1: a5 } = b2; diff --git a/packages/fq_types/Scarb.toml b/packages/fq_types/Scarb.toml new file mode 100644 index 0000000..99f61fd --- /dev/null +++ b/packages/fq_types/Scarb.toml @@ -0,0 +1,8 @@ +[package] +name = "fq_types" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] diff --git a/packages/fq_types/src/bn254.cairo b/packages/fq_types/src/bn254.cairo new file mode 100644 index 0000000..25f9456 --- /dev/null +++ b/packages/fq_types/src/bn254.cairo @@ -0,0 +1,38 @@ +use super::{Fq2, Fq6}; + +#[derive(Copy, Drop, Serde)] +struct Fq { + c0: u256, +} + +// Sparse Fq12 element containing only c3 and c4 Fq2 (c0 is 1) +// Equivalent to, +// Fq12{ +// c0: Fq6{c0: 1, c1: 0, c2: 0}, +// c1: Fq6{c0: c3, c1: c4, c2: 0}, +// } +#[derive(Copy, Drop, Serde)] +struct F12S034 { + pub c3: Fq, + pub c4: Fq, +} + +// Sparse Fq6 element containing c0 and c1 Fq2 +type F6S01 = Fq2>; + +// Sparse Fq12 element containing c0, c1, c2, c3 and c4 Fq2 +#[derive(Copy, Drop, Serde)] +struct F12S01234 { + pub c0: Fq6, + pub c1: F6S01, +} + +type Fq12Direct = (Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq); +type F12S01234Direct = ((Fq, Fq, Fq, Fq, Fq), (Fq, Fq, Fq, Fq, Fq)); + +struct F12S034Direct { + c1: Fq, + c3: Fq, + c7: Fq, + c9: Fq, +} diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo new file mode 100644 index 0000000..acbd623 --- /dev/null +++ b/packages/fq_types/src/lib.cairo @@ -0,0 +1,39 @@ +#[derive(Copy, Drop, Serde)] +pub struct Fq2 { + pub c0: T, + pub c1: T, +} + +#[derive(Copy, Drop, Serde)] +pub struct Fq3 { + pub c0: T, + pub c1: T, + pub c2: T, +} + +type Fq6 = Fq3>; +type Fq12 = Fq2>>; + +trait FieldOps { + fn add(self: TFq, rhs: TFq) -> TFq; + fn sub(self: TFq, rhs: TFq) -> TFq; + fn mul(self: TFq, rhs: TFq) -> TFq; + fn div(self: TFq, rhs: TFq) -> TFq; + fn sqr(self: TFq) -> TFq; + fn neg(self: TFq) -> TFq; + fn eq(lhs: @TFq, rhs: @TFq) -> bool; + fn inv(self: TFq, field_nz: NonZero) -> TFq; +} + +trait FieldOpsUnreduced { + fn u_add(self: TFq, rhs: TFq) -> TFq; + fn u_sub(self: TFq, rhs: TFq) -> TFq; + fn u_mul(self: TFq, rhs: TFq) -> TFqU512; + fn u_sqr(self: TFq) -> TFqU512; + fn u512_add_fq(self: TFqU512, rhs: TFq) -> TFqU512; + fn u512_sub_fq(self: TFqU512, rhs: TFq) -> TFqU512; + fn to_fq(self: TFqU512, field_nz: NonZero) -> TFq; + fn fix_mod(self: TFq) -> TFq; +} + +mod bn254; From b3abe27a1f8fff9ff9f84e96b7dfb5985083b0ba Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 3 Jul 2024 12:25:11 +0530 Subject: [PATCH 05/97] refactor: old code in legacy dir --- Scarb.toml | 1 + {packages => legacy}/bn_contracts/.gitignore | 0 {packages => legacy}/bn_contracts/Scarb.lock | 0 {packages => legacy}/bn_contracts/Scarb.toml | 0 {packages => legacy}/bn_contracts/src/bench_contract.cairo | 0 {packages => legacy}/bn_contracts/src/groth16_contract.cairo | 0 {packages => legacy}/bn_contracts/src/lib.cairo | 0 {packages => legacy}/bn_contracts/src/schzipv2_contract.cairo | 0 {packages => legacy}/bn_legacy/Scarb.toml | 0 {packages => legacy}/bn_legacy/src/bench.cairo | 0 {packages => legacy}/bn_legacy/src/bench/curve.cairo | 0 {packages => legacy}/bn_legacy/src/bench/fq01.cairo | 0 {packages => legacy}/bn_legacy/src/bench/fq02.cairo | 0 {packages => legacy}/bn_legacy/src/bench/fq06.cairo | 0 {packages => legacy}/bn_legacy/src/bench/fq12.cairo | 0 {packages => legacy}/bn_legacy/src/bench/sprs.cairo | 0 {packages => legacy}/bn_legacy/src/bench/u512.cairo | 0 {packages => legacy}/bn_legacy/src/curve.cairo | 0 {packages => legacy}/bn_legacy/src/curve/constants.cairo | 0 {packages => legacy}/bn_legacy/src/curve/groups.cairo | 0 {packages => legacy}/bn_legacy/src/curve/groups_tests.cairo | 0 {packages => legacy}/bn_legacy/src/curve/pairing/ate_tests.cairo | 0 .../bn_legacy/src/curve/pairing/miller_utils.cairo | 0 .../bn_legacy/src/curve/pairing/optimal_ate.cairo | 0 .../bn_legacy/src/curve/pairing/optimal_ate_impls.cairo | 0 .../bn_legacy/src/curve/pairing/optimal_ate_utils.cairo | 0 {packages => legacy}/bn_legacy/src/curve/pairing/tate_bkls.cairo | 0 {packages => legacy}/bn_legacy/src/curve/pairing/tests.cairo | 0 {packages => legacy}/bn_legacy/src/curve/residue_witness.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_1.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_12.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_12_direct.cairo | 0 .../bn_legacy/src/fields/fq_12_exponentiation.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_12_squaring.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_2.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_6.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_generics.cairo | 0 {packages => legacy}/bn_legacy/src/fields/fq_sparse.cairo | 0 {packages => legacy}/bn_legacy/src/fields/frobenius.cairo | 0 {packages => legacy}/bn_legacy/src/fields/print.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/fq.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/fq12.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/fq12_expo.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/fq2.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/fq6.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/fq_sparse.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/frobenius.cairo | 0 {packages => legacy}/bn_legacy/src/fields/tests/u512.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/fixture.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/fixture/groth16.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/fixture/lines.cairo | 0 .../bn_legacy/src/groth16/fixture/schzip_v1.cairo | 0 .../bn_legacy/src/groth16/fixture/schzip_v2.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/fixture/tests.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/schzip.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/schzip/base.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/schzip/eval.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/schzip/tests.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/schzip/utils.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/schzip/v1.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/setup.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/tests.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/utils.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/utils_line.cairo | 0 {packages => legacy}/bn_legacy/src/groth16/verifier.cairo | 0 {packages => legacy}/bn_legacy/src/lib.cairo | 0 {packages => legacy}/bn_legacy/src/math/fast_mod.cairo | 0 {packages => legacy}/bn_legacy/src/math/fast_mod/add_sub.cairo | 0 {packages => legacy}/bn_legacy/src/math/fast_mod/div_inv.cairo | 0 .../bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo | 0 {packages => legacy}/bn_legacy/src/math/fast_mod/u512_ops.cairo | 0 {packages => legacy}/bn_legacy/src/math/fast_mod/utils.cairo | 0 {packages => legacy}/bn_legacy/src/math/fast_mod_tests.cairo | 0 {packages => legacy}/bn_legacy/src/math/i257.cairo | 0 {packages => legacy}/bn_legacy/src/playground.cairo | 0 {packages => legacy}/bn_legacy/src/tests.cairo | 0 {packages => legacy}/bn_legacy/src/tests_tate.cairo | 0 {packages => legacy}/bn_legacy/src/traits.cairo | 0 78 files changed, 1 insertion(+) rename {packages => legacy}/bn_contracts/.gitignore (100%) rename {packages => legacy}/bn_contracts/Scarb.lock (100%) rename {packages => legacy}/bn_contracts/Scarb.toml (100%) rename {packages => legacy}/bn_contracts/src/bench_contract.cairo (100%) rename {packages => legacy}/bn_contracts/src/groth16_contract.cairo (100%) rename {packages => legacy}/bn_contracts/src/lib.cairo (100%) rename {packages => legacy}/bn_contracts/src/schzipv2_contract.cairo (100%) rename {packages => legacy}/bn_legacy/Scarb.toml (100%) rename {packages => legacy}/bn_legacy/src/bench.cairo (100%) rename {packages => legacy}/bn_legacy/src/bench/curve.cairo (100%) rename {packages => legacy}/bn_legacy/src/bench/fq01.cairo (100%) rename {packages => legacy}/bn_legacy/src/bench/fq02.cairo (100%) rename {packages => legacy}/bn_legacy/src/bench/fq06.cairo (100%) rename {packages => legacy}/bn_legacy/src/bench/fq12.cairo (100%) rename {packages => legacy}/bn_legacy/src/bench/sprs.cairo (100%) rename {packages => legacy}/bn_legacy/src/bench/u512.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/constants.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/groups.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/groups_tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/pairing/ate_tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/pairing/miller_utils.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/pairing/optimal_ate.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/pairing/optimal_ate_impls.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/pairing/tate_bkls.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/pairing/tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/curve/residue_witness.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_1.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_12.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_12_direct.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_12_exponentiation.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_12_squaring.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_2.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_6.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_generics.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/fq_sparse.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/frobenius.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/print.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/fq.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/fq12.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/fq12_expo.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/fq2.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/fq6.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/fq_sparse.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/frobenius.cairo (100%) rename {packages => legacy}/bn_legacy/src/fields/tests/u512.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/fixture.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/fixture/groth16.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/fixture/lines.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/fixture/schzip_v1.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/fixture/schzip_v2.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/fixture/tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/schzip.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/schzip/base.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/schzip/eval.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/schzip/tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/schzip/utils.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/schzip/v1.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/setup.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/utils.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/utils_line.cairo (100%) rename {packages => legacy}/bn_legacy/src/groth16/verifier.cairo (100%) rename {packages => legacy}/bn_legacy/src/lib.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/fast_mod.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/fast_mod/add_sub.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/fast_mod/div_inv.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/fast_mod/u512_ops.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/fast_mod/utils.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/fast_mod_tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/math/i257.cairo (100%) rename {packages => legacy}/bn_legacy/src/playground.cairo (100%) rename {packages => legacy}/bn_legacy/src/tests.cairo (100%) rename {packages => legacy}/bn_legacy/src/tests_tate.cairo (100%) rename {packages => legacy}/bn_legacy/src/traits.cairo (100%) diff --git a/Scarb.toml b/Scarb.toml index 28286d1..55c21b4 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,6 +1,7 @@ [workspace] members = [ "packages/*", + "legacy/*", ] [workspace.package] diff --git a/packages/bn_contracts/.gitignore b/legacy/bn_contracts/.gitignore similarity index 100% rename from packages/bn_contracts/.gitignore rename to legacy/bn_contracts/.gitignore diff --git a/packages/bn_contracts/Scarb.lock b/legacy/bn_contracts/Scarb.lock similarity index 100% rename from packages/bn_contracts/Scarb.lock rename to legacy/bn_contracts/Scarb.lock diff --git a/packages/bn_contracts/Scarb.toml b/legacy/bn_contracts/Scarb.toml similarity index 100% rename from packages/bn_contracts/Scarb.toml rename to legacy/bn_contracts/Scarb.toml diff --git a/packages/bn_contracts/src/bench_contract.cairo b/legacy/bn_contracts/src/bench_contract.cairo similarity index 100% rename from packages/bn_contracts/src/bench_contract.cairo rename to legacy/bn_contracts/src/bench_contract.cairo diff --git a/packages/bn_contracts/src/groth16_contract.cairo b/legacy/bn_contracts/src/groth16_contract.cairo similarity index 100% rename from packages/bn_contracts/src/groth16_contract.cairo rename to legacy/bn_contracts/src/groth16_contract.cairo diff --git a/packages/bn_contracts/src/lib.cairo b/legacy/bn_contracts/src/lib.cairo similarity index 100% rename from packages/bn_contracts/src/lib.cairo rename to legacy/bn_contracts/src/lib.cairo diff --git a/packages/bn_contracts/src/schzipv2_contract.cairo b/legacy/bn_contracts/src/schzipv2_contract.cairo similarity index 100% rename from packages/bn_contracts/src/schzipv2_contract.cairo rename to legacy/bn_contracts/src/schzipv2_contract.cairo diff --git a/packages/bn_legacy/Scarb.toml b/legacy/bn_legacy/Scarb.toml similarity index 100% rename from packages/bn_legacy/Scarb.toml rename to legacy/bn_legacy/Scarb.toml diff --git a/packages/bn_legacy/src/bench.cairo b/legacy/bn_legacy/src/bench.cairo similarity index 100% rename from packages/bn_legacy/src/bench.cairo rename to legacy/bn_legacy/src/bench.cairo diff --git a/packages/bn_legacy/src/bench/curve.cairo b/legacy/bn_legacy/src/bench/curve.cairo similarity index 100% rename from packages/bn_legacy/src/bench/curve.cairo rename to legacy/bn_legacy/src/bench/curve.cairo diff --git a/packages/bn_legacy/src/bench/fq01.cairo b/legacy/bn_legacy/src/bench/fq01.cairo similarity index 100% rename from packages/bn_legacy/src/bench/fq01.cairo rename to legacy/bn_legacy/src/bench/fq01.cairo diff --git a/packages/bn_legacy/src/bench/fq02.cairo b/legacy/bn_legacy/src/bench/fq02.cairo similarity index 100% rename from packages/bn_legacy/src/bench/fq02.cairo rename to legacy/bn_legacy/src/bench/fq02.cairo diff --git a/packages/bn_legacy/src/bench/fq06.cairo b/legacy/bn_legacy/src/bench/fq06.cairo similarity index 100% rename from packages/bn_legacy/src/bench/fq06.cairo rename to legacy/bn_legacy/src/bench/fq06.cairo diff --git a/packages/bn_legacy/src/bench/fq12.cairo b/legacy/bn_legacy/src/bench/fq12.cairo similarity index 100% rename from packages/bn_legacy/src/bench/fq12.cairo rename to legacy/bn_legacy/src/bench/fq12.cairo diff --git a/packages/bn_legacy/src/bench/sprs.cairo b/legacy/bn_legacy/src/bench/sprs.cairo similarity index 100% rename from packages/bn_legacy/src/bench/sprs.cairo rename to legacy/bn_legacy/src/bench/sprs.cairo diff --git a/packages/bn_legacy/src/bench/u512.cairo b/legacy/bn_legacy/src/bench/u512.cairo similarity index 100% rename from packages/bn_legacy/src/bench/u512.cairo rename to legacy/bn_legacy/src/bench/u512.cairo diff --git a/packages/bn_legacy/src/curve.cairo b/legacy/bn_legacy/src/curve.cairo similarity index 100% rename from packages/bn_legacy/src/curve.cairo rename to legacy/bn_legacy/src/curve.cairo diff --git a/packages/bn_legacy/src/curve/constants.cairo b/legacy/bn_legacy/src/curve/constants.cairo similarity index 100% rename from packages/bn_legacy/src/curve/constants.cairo rename to legacy/bn_legacy/src/curve/constants.cairo diff --git a/packages/bn_legacy/src/curve/groups.cairo b/legacy/bn_legacy/src/curve/groups.cairo similarity index 100% rename from packages/bn_legacy/src/curve/groups.cairo rename to legacy/bn_legacy/src/curve/groups.cairo diff --git a/packages/bn_legacy/src/curve/groups_tests.cairo b/legacy/bn_legacy/src/curve/groups_tests.cairo similarity index 100% rename from packages/bn_legacy/src/curve/groups_tests.cairo rename to legacy/bn_legacy/src/curve/groups_tests.cairo diff --git a/packages/bn_legacy/src/curve/pairing/ate_tests.cairo b/legacy/bn_legacy/src/curve/pairing/ate_tests.cairo similarity index 100% rename from packages/bn_legacy/src/curve/pairing/ate_tests.cairo rename to legacy/bn_legacy/src/curve/pairing/ate_tests.cairo diff --git a/packages/bn_legacy/src/curve/pairing/miller_utils.cairo b/legacy/bn_legacy/src/curve/pairing/miller_utils.cairo similarity index 100% rename from packages/bn_legacy/src/curve/pairing/miller_utils.cairo rename to legacy/bn_legacy/src/curve/pairing/miller_utils.cairo diff --git a/packages/bn_legacy/src/curve/pairing/optimal_ate.cairo b/legacy/bn_legacy/src/curve/pairing/optimal_ate.cairo similarity index 100% rename from packages/bn_legacy/src/curve/pairing/optimal_ate.cairo rename to legacy/bn_legacy/src/curve/pairing/optimal_ate.cairo diff --git a/packages/bn_legacy/src/curve/pairing/optimal_ate_impls.cairo b/legacy/bn_legacy/src/curve/pairing/optimal_ate_impls.cairo similarity index 100% rename from packages/bn_legacy/src/curve/pairing/optimal_ate_impls.cairo rename to legacy/bn_legacy/src/curve/pairing/optimal_ate_impls.cairo diff --git a/packages/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo b/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo similarity index 100% rename from packages/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo rename to legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo diff --git a/packages/bn_legacy/src/curve/pairing/tate_bkls.cairo b/legacy/bn_legacy/src/curve/pairing/tate_bkls.cairo similarity index 100% rename from packages/bn_legacy/src/curve/pairing/tate_bkls.cairo rename to legacy/bn_legacy/src/curve/pairing/tate_bkls.cairo diff --git a/packages/bn_legacy/src/curve/pairing/tests.cairo b/legacy/bn_legacy/src/curve/pairing/tests.cairo similarity index 100% rename from packages/bn_legacy/src/curve/pairing/tests.cairo rename to legacy/bn_legacy/src/curve/pairing/tests.cairo diff --git a/packages/bn_legacy/src/curve/residue_witness.cairo b/legacy/bn_legacy/src/curve/residue_witness.cairo similarity index 100% rename from packages/bn_legacy/src/curve/residue_witness.cairo rename to legacy/bn_legacy/src/curve/residue_witness.cairo diff --git a/packages/bn_legacy/src/fields/fq_1.cairo b/legacy/bn_legacy/src/fields/fq_1.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_1.cairo rename to legacy/bn_legacy/src/fields/fq_1.cairo diff --git a/packages/bn_legacy/src/fields/fq_12.cairo b/legacy/bn_legacy/src/fields/fq_12.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_12.cairo rename to legacy/bn_legacy/src/fields/fq_12.cairo diff --git a/packages/bn_legacy/src/fields/fq_12_direct.cairo b/legacy/bn_legacy/src/fields/fq_12_direct.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_12_direct.cairo rename to legacy/bn_legacy/src/fields/fq_12_direct.cairo diff --git a/packages/bn_legacy/src/fields/fq_12_exponentiation.cairo b/legacy/bn_legacy/src/fields/fq_12_exponentiation.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_12_exponentiation.cairo rename to legacy/bn_legacy/src/fields/fq_12_exponentiation.cairo diff --git a/packages/bn_legacy/src/fields/fq_12_squaring.cairo b/legacy/bn_legacy/src/fields/fq_12_squaring.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_12_squaring.cairo rename to legacy/bn_legacy/src/fields/fq_12_squaring.cairo diff --git a/packages/bn_legacy/src/fields/fq_2.cairo b/legacy/bn_legacy/src/fields/fq_2.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_2.cairo rename to legacy/bn_legacy/src/fields/fq_2.cairo diff --git a/packages/bn_legacy/src/fields/fq_6.cairo b/legacy/bn_legacy/src/fields/fq_6.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_6.cairo rename to legacy/bn_legacy/src/fields/fq_6.cairo diff --git a/packages/bn_legacy/src/fields/fq_generics.cairo b/legacy/bn_legacy/src/fields/fq_generics.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_generics.cairo rename to legacy/bn_legacy/src/fields/fq_generics.cairo diff --git a/packages/bn_legacy/src/fields/fq_sparse.cairo b/legacy/bn_legacy/src/fields/fq_sparse.cairo similarity index 100% rename from packages/bn_legacy/src/fields/fq_sparse.cairo rename to legacy/bn_legacy/src/fields/fq_sparse.cairo diff --git a/packages/bn_legacy/src/fields/frobenius.cairo b/legacy/bn_legacy/src/fields/frobenius.cairo similarity index 100% rename from packages/bn_legacy/src/fields/frobenius.cairo rename to legacy/bn_legacy/src/fields/frobenius.cairo diff --git a/packages/bn_legacy/src/fields/print.cairo b/legacy/bn_legacy/src/fields/print.cairo similarity index 100% rename from packages/bn_legacy/src/fields/print.cairo rename to legacy/bn_legacy/src/fields/print.cairo diff --git a/packages/bn_legacy/src/fields/tests/fq.cairo b/legacy/bn_legacy/src/fields/tests/fq.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/fq.cairo rename to legacy/bn_legacy/src/fields/tests/fq.cairo diff --git a/packages/bn_legacy/src/fields/tests/fq12.cairo b/legacy/bn_legacy/src/fields/tests/fq12.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/fq12.cairo rename to legacy/bn_legacy/src/fields/tests/fq12.cairo diff --git a/packages/bn_legacy/src/fields/tests/fq12_expo.cairo b/legacy/bn_legacy/src/fields/tests/fq12_expo.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/fq12_expo.cairo rename to legacy/bn_legacy/src/fields/tests/fq12_expo.cairo diff --git a/packages/bn_legacy/src/fields/tests/fq2.cairo b/legacy/bn_legacy/src/fields/tests/fq2.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/fq2.cairo rename to legacy/bn_legacy/src/fields/tests/fq2.cairo diff --git a/packages/bn_legacy/src/fields/tests/fq6.cairo b/legacy/bn_legacy/src/fields/tests/fq6.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/fq6.cairo rename to legacy/bn_legacy/src/fields/tests/fq6.cairo diff --git a/packages/bn_legacy/src/fields/tests/fq_sparse.cairo b/legacy/bn_legacy/src/fields/tests/fq_sparse.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/fq_sparse.cairo rename to legacy/bn_legacy/src/fields/tests/fq_sparse.cairo diff --git a/packages/bn_legacy/src/fields/tests/frobenius.cairo b/legacy/bn_legacy/src/fields/tests/frobenius.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/frobenius.cairo rename to legacy/bn_legacy/src/fields/tests/frobenius.cairo diff --git a/packages/bn_legacy/src/fields/tests/u512.cairo b/legacy/bn_legacy/src/fields/tests/u512.cairo similarity index 100% rename from packages/bn_legacy/src/fields/tests/u512.cairo rename to legacy/bn_legacy/src/fields/tests/u512.cairo diff --git a/packages/bn_legacy/src/groth16/fixture.cairo b/legacy/bn_legacy/src/groth16/fixture.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/fixture.cairo rename to legacy/bn_legacy/src/groth16/fixture.cairo diff --git a/packages/bn_legacy/src/groth16/fixture/groth16.cairo b/legacy/bn_legacy/src/groth16/fixture/groth16.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/fixture/groth16.cairo rename to legacy/bn_legacy/src/groth16/fixture/groth16.cairo diff --git a/packages/bn_legacy/src/groth16/fixture/lines.cairo b/legacy/bn_legacy/src/groth16/fixture/lines.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/fixture/lines.cairo rename to legacy/bn_legacy/src/groth16/fixture/lines.cairo diff --git a/packages/bn_legacy/src/groth16/fixture/schzip_v1.cairo b/legacy/bn_legacy/src/groth16/fixture/schzip_v1.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/fixture/schzip_v1.cairo rename to legacy/bn_legacy/src/groth16/fixture/schzip_v1.cairo diff --git a/packages/bn_legacy/src/groth16/fixture/schzip_v2.cairo b/legacy/bn_legacy/src/groth16/fixture/schzip_v2.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/fixture/schzip_v2.cairo rename to legacy/bn_legacy/src/groth16/fixture/schzip_v2.cairo diff --git a/packages/bn_legacy/src/groth16/fixture/tests.cairo b/legacy/bn_legacy/src/groth16/fixture/tests.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/fixture/tests.cairo rename to legacy/bn_legacy/src/groth16/fixture/tests.cairo diff --git a/packages/bn_legacy/src/groth16/schzip.cairo b/legacy/bn_legacy/src/groth16/schzip.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/schzip.cairo rename to legacy/bn_legacy/src/groth16/schzip.cairo diff --git a/packages/bn_legacy/src/groth16/schzip/base.cairo b/legacy/bn_legacy/src/groth16/schzip/base.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/schzip/base.cairo rename to legacy/bn_legacy/src/groth16/schzip/base.cairo diff --git a/packages/bn_legacy/src/groth16/schzip/eval.cairo b/legacy/bn_legacy/src/groth16/schzip/eval.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/schzip/eval.cairo rename to legacy/bn_legacy/src/groth16/schzip/eval.cairo diff --git a/packages/bn_legacy/src/groth16/schzip/tests.cairo b/legacy/bn_legacy/src/groth16/schzip/tests.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/schzip/tests.cairo rename to legacy/bn_legacy/src/groth16/schzip/tests.cairo diff --git a/packages/bn_legacy/src/groth16/schzip/utils.cairo b/legacy/bn_legacy/src/groth16/schzip/utils.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/schzip/utils.cairo rename to legacy/bn_legacy/src/groth16/schzip/utils.cairo diff --git a/packages/bn_legacy/src/groth16/schzip/v1.cairo b/legacy/bn_legacy/src/groth16/schzip/v1.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/schzip/v1.cairo rename to legacy/bn_legacy/src/groth16/schzip/v1.cairo diff --git a/packages/bn_legacy/src/groth16/setup.cairo b/legacy/bn_legacy/src/groth16/setup.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/setup.cairo rename to legacy/bn_legacy/src/groth16/setup.cairo diff --git a/packages/bn_legacy/src/groth16/tests.cairo b/legacy/bn_legacy/src/groth16/tests.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/tests.cairo rename to legacy/bn_legacy/src/groth16/tests.cairo diff --git a/packages/bn_legacy/src/groth16/utils.cairo b/legacy/bn_legacy/src/groth16/utils.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/utils.cairo rename to legacy/bn_legacy/src/groth16/utils.cairo diff --git a/packages/bn_legacy/src/groth16/utils_line.cairo b/legacy/bn_legacy/src/groth16/utils_line.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/utils_line.cairo rename to legacy/bn_legacy/src/groth16/utils_line.cairo diff --git a/packages/bn_legacy/src/groth16/verifier.cairo b/legacy/bn_legacy/src/groth16/verifier.cairo similarity index 100% rename from packages/bn_legacy/src/groth16/verifier.cairo rename to legacy/bn_legacy/src/groth16/verifier.cairo diff --git a/packages/bn_legacy/src/lib.cairo b/legacy/bn_legacy/src/lib.cairo similarity index 100% rename from packages/bn_legacy/src/lib.cairo rename to legacy/bn_legacy/src/lib.cairo diff --git a/packages/bn_legacy/src/math/fast_mod.cairo b/legacy/bn_legacy/src/math/fast_mod.cairo similarity index 100% rename from packages/bn_legacy/src/math/fast_mod.cairo rename to legacy/bn_legacy/src/math/fast_mod.cairo diff --git a/packages/bn_legacy/src/math/fast_mod/add_sub.cairo b/legacy/bn_legacy/src/math/fast_mod/add_sub.cairo similarity index 100% rename from packages/bn_legacy/src/math/fast_mod/add_sub.cairo rename to legacy/bn_legacy/src/math/fast_mod/add_sub.cairo diff --git a/packages/bn_legacy/src/math/fast_mod/div_inv.cairo b/legacy/bn_legacy/src/math/fast_mod/div_inv.cairo similarity index 100% rename from packages/bn_legacy/src/math/fast_mod/div_inv.cairo rename to legacy/bn_legacy/src/math/fast_mod/div_inv.cairo diff --git a/packages/bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo b/legacy/bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo similarity index 100% rename from packages/bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo rename to legacy/bn_legacy/src/math/fast_mod/mul_scale_sqr.cairo diff --git a/packages/bn_legacy/src/math/fast_mod/u512_ops.cairo b/legacy/bn_legacy/src/math/fast_mod/u512_ops.cairo similarity index 100% rename from packages/bn_legacy/src/math/fast_mod/u512_ops.cairo rename to legacy/bn_legacy/src/math/fast_mod/u512_ops.cairo diff --git a/packages/bn_legacy/src/math/fast_mod/utils.cairo b/legacy/bn_legacy/src/math/fast_mod/utils.cairo similarity index 100% rename from packages/bn_legacy/src/math/fast_mod/utils.cairo rename to legacy/bn_legacy/src/math/fast_mod/utils.cairo diff --git a/packages/bn_legacy/src/math/fast_mod_tests.cairo b/legacy/bn_legacy/src/math/fast_mod_tests.cairo similarity index 100% rename from packages/bn_legacy/src/math/fast_mod_tests.cairo rename to legacy/bn_legacy/src/math/fast_mod_tests.cairo diff --git a/packages/bn_legacy/src/math/i257.cairo b/legacy/bn_legacy/src/math/i257.cairo similarity index 100% rename from packages/bn_legacy/src/math/i257.cairo rename to legacy/bn_legacy/src/math/i257.cairo diff --git a/packages/bn_legacy/src/playground.cairo b/legacy/bn_legacy/src/playground.cairo similarity index 100% rename from packages/bn_legacy/src/playground.cairo rename to legacy/bn_legacy/src/playground.cairo diff --git a/packages/bn_legacy/src/tests.cairo b/legacy/bn_legacy/src/tests.cairo similarity index 100% rename from packages/bn_legacy/src/tests.cairo rename to legacy/bn_legacy/src/tests.cairo diff --git a/packages/bn_legacy/src/tests_tate.cairo b/legacy/bn_legacy/src/tests_tate.cairo similarity index 100% rename from packages/bn_legacy/src/tests_tate.cairo rename to legacy/bn_legacy/src/tests_tate.cairo diff --git a/packages/bn_legacy/src/traits.cairo b/legacy/bn_legacy/src/traits.cairo similarity index 100% rename from packages/bn_legacy/src/traits.cairo rename to legacy/bn_legacy/src/traits.cairo From 6c0217b7b1e0482c9d86878e98203f88498bf088 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 3 Jul 2024 12:57:19 +0530 Subject: [PATCH 06/97] workspace: fast mod operations --- Scarb.lock | 8 + Scarb.toml | 5 + .../bn_legacy/src/math/fast_mod/div_inv.cairo | 2 +- packages/fast_mod/Scarb.toml | 8 + packages/fast_mod/src/add_sub.cairo | 56 ++++ packages/fast_mod/src/div_inv.cairo | 26 ++ packages/fast_mod/src/lib.cairo | 44 +++ packages/fast_mod/src/mul_scale_sqr.cairo | 123 ++++++++ packages/fast_mod/src/tests.cairo | 289 ++++++++++++++++++ packages/fast_mod/src/u512_ops.cairo | 217 +++++++++++++ packages/fast_mod/src/utils.cairo | 189 ++++++++++++ 11 files changed, 966 insertions(+), 1 deletion(-) create mode 100644 packages/fast_mod/Scarb.toml create mode 100644 packages/fast_mod/src/add_sub.cairo create mode 100644 packages/fast_mod/src/div_inv.cairo create mode 100644 packages/fast_mod/src/lib.cairo create mode 100644 packages/fast_mod/src/mul_scale_sqr.cairo create mode 100644 packages/fast_mod/src/tests.cairo create mode 100644 packages/fast_mod/src/u512_ops.cairo create mode 100644 packages/fast_mod/src/utils.cairo diff --git a/Scarb.lock b/Scarb.lock index 851dafb..774c989 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -16,6 +16,14 @@ dependencies = [ "bn", ] +[[package]] +name = "fast_mod" +version = "0.1.0" + [[package]] name = "fq_types" version = "0.1.0" + +[[package]] +name = "pairing" +version = "0.1.0" diff --git a/Scarb.toml b/Scarb.toml index 55c21b4..7bb9f7b 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -8,9 +8,14 @@ members = [ version = "0.1.0" cairo-version = "2.6.2" +[package] +name = "pairing" +version.workspace = true + # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [scripts] +new = "scarb new --no-vcs packages/$1" addchain_gen_t = "addchain gen -tmpl addchain/tpl addchain/t" contracts = "scarb build -p bn_contracts" # Declares class for the contract diff --git a/legacy/bn_legacy/src/math/fast_mod/div_inv.cairo b/legacy/bn_legacy/src/math/fast_mod/div_inv.cairo index a64817f..05b1807 100644 --- a/legacy/bn_legacy/src/math/fast_mod/div_inv.cairo +++ b/legacy/bn_legacy/src/math/fast_mod/div_inv.cairo @@ -3,7 +3,7 @@ use super::{mul_u, mul_nz}; // Inversion #[inline(always)] fn inv(b: u256, modulo: NonZero) -> u256 { - math::u256_inv_mod(b, modulo).expect('inversion failed').into() + core::math::u256_inv_mod(b, modulo).expect('inversion failed').into() } // Division with Non Zero diff --git a/packages/fast_mod/Scarb.toml b/packages/fast_mod/Scarb.toml new file mode 100644 index 0000000..08379ca --- /dev/null +++ b/packages/fast_mod/Scarb.toml @@ -0,0 +1,8 @@ +[package] +name = "fast_mod" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] diff --git a/packages/fast_mod/src/add_sub.cairo b/packages/fast_mod/src/add_sub.cairo new file mode 100644 index 0000000..6399401 --- /dev/null +++ b/packages/fast_mod/src/add_sub.cairo @@ -0,0 +1,56 @@ +use core::result::{Result, ResultTrait}; +use super::{utils as u, reduce}; +use u::{u128_overflowing_add, u128_overflowing_sub, u256_overflow_sub, u256_wrapping_add}; +use core::integer::u512; +use core::panic_with_felt252; + +#[inline(always)] +pub fn neg(b: u256, modulo: u256) -> u256 { + modulo - b +} + +#[inline(always)] +pub fn add_u(lhs: u256, rhs: u256) -> u256 implicits(RangeCheck) { + let high = u::expect_u128(u128_overflowing_add(lhs.high, rhs.high), 'u256_add_u Overflow'); + match u128_overflowing_add(lhs.low, rhs.low) { + Result::Ok(low) => u256 { low, high }, + Result::Err(low) => { + let high = u::expect_u128(u128_overflowing_add(high, 1), 'u256_add_u Overflow'); + u256 { low, high } + }, + } +} + +#[inline(always)] +pub fn sub_u(lhs: u256, rhs: u256) -> u256 implicits(RangeCheck) { + let high = u::expect_u128(u128_overflowing_sub(lhs.high, rhs.high), 'u256_sub_u Overflow'); + match u128_overflowing_sub(lhs.low, rhs.low) { + Result::Ok(low) => u256 { low, high }, + Result::Err(low) => { + let high = u::expect_u128(u128_overflowing_sub(high, 1), 'u256_sub_u Overflow'); + u256 { low, high } + }, + } +} + +#[inline(always)] +pub fn add_nz(mut a: u256, mut b: u256, modulo: NonZero) -> u256 { + super::reduce(add_u(a, b), modulo) +} + +#[inline(always)] +pub fn add(mut a: u256, mut b: u256, modulo: u256) -> u256 { + let res = add_u(a, b); + match u256_overflow_sub(res, modulo) { + Result::Ok(v) => v, + Result::Err(_) => res + } +} + +#[inline(always)] +pub fn sub(mut a: u256, mut b: u256, modulo: u256) -> u256 { + match u256_overflow_sub(a, b) { + Result::Ok(v) => v, + Result::Err(v) => u256_wrapping_add(v, modulo) + } +} diff --git a/packages/fast_mod/src/div_inv.cairo b/packages/fast_mod/src/div_inv.cairo new file mode 100644 index 0000000..ea25129 --- /dev/null +++ b/packages/fast_mod/src/div_inv.cairo @@ -0,0 +1,26 @@ +use core::integer::u512; +use super::{mul_u, mul_nz}; +// Inversion +#[inline(always)] +pub fn inv(b: u256, modulo: NonZero) -> u256 { + core::math::u256_inv_mod(b, modulo).expect('inversion failed').into() +} + +// Division with Non Zero +#[inline(always)] +pub fn div_nz(a: u256, b: u256, modulo_nz: NonZero) -> u256 { + mul_nz(a, inv(b, modulo_nz), modulo_nz) +} + +// Division unreduced +#[inline(always)] +pub fn div_u(a: u256, b: u256, modulo_nz: NonZero) -> u512 { + mul_u(a, inv(b, modulo_nz)) +} + +// Division - Easy +#[inline(always)] +pub fn div(a: u256, b: u256, modulo: u256) -> u256 { + let modulo_nz = modulo.try_into().expect('0 modulo'); + div_nz(a, b, modulo_nz) +} diff --git a/packages/fast_mod/src/lib.cairo b/packages/fast_mod/src/lib.cairo new file mode 100644 index 0000000..fefa1ed --- /dev/null +++ b/packages/fast_mod/src/lib.cairo @@ -0,0 +1,44 @@ +// These mod functions are heavily optimised for < 255 bit numbers +// and may break for full 256 bit numbers + +use core::integer::u512; + +// util functions +mod utils; +use utils::{u256_overflow_add, u256_overflow_sub}; +use utils::{Tuple2Add, Tuple2Sub, Tuple3Add, Tuple3Sub, u512Display}; +// endregion util functions + +// u512_ops +mod u512_ops; + +use u512_ops::{u512_add, u512_add_overflow, u512_sub, u512_sub_overflow,}; +use u512_ops::{u512_high_add, u512_high_sub, u512_reduce, u512_add_u256, u512_sub_u256}; +// endregion u512_ops + +// region add/sub operation +mod add_sub; + +use add_sub::{neg, add, add_nz, add_u, sub, sub_u}; +// endregion add/sub operation + +// region mul operations +mod mul_scale_sqr; + +use mul_scale_sqr::{scl, scl_nz, scl_u, mul, mul_nz, mul_u, sqr, sqr_nz, sqr_u, u512_scl}; +// endregion mul operations + +// region div/inv operations +mod div_inv; +use div_inv::{inv, div, div_nz, div_u}; +// endregion div/inv operations + +#[inline(always)] +pub fn reduce(lhs: u256, modulo: NonZero) -> u256 { + let (_, r) = DivRem::div_rem(lhs, modulo); + r +} + +#[cfg(test)] +mod tests; + diff --git a/packages/fast_mod/src/mul_scale_sqr.cairo b/packages/fast_mod/src/mul_scale_sqr.cairo new file mode 100644 index 0000000..db8cef4 --- /dev/null +++ b/packages/fast_mod/src/mul_scale_sqr.cairo @@ -0,0 +1,123 @@ +use core::traits::TryInto; +pub use core::integer::{u512, u128_wide_mul,}; +use super::{utils as u, reduce, u512_reduce}; +// scale u512 by u128 (for smaller numbers) +// unreduced, returns u512 plus u128 (fifth limb) which needs handling +#[inline(always)] +pub fn u512_scl(a: u512, x: u128) -> (u512, u128) { + let u512 { limb0, limb1, limb2, limb3 } = a; + // (a1 + a2) * c + let (limb1_part1, limb0) = u128_wide_mul(limb0, x); + let (limb2_part1, limb1_part2) = u128_wide_mul(limb1, x); + let limb1 = u::u128_wrapping_add(limb1_part1, limb1_part2); + let (limb3_part1, limb2_part2) = u128_wide_mul(limb2, x); + let limb2 = u::u128_wrapping_add(limb2_part1, limb2_part2); + let (limb4, limb3_part2) = u128_wide_mul(limb3, x); + let limb3 = u::u128_wrapping_add(limb3_part1, limb3_part2); + (u512 { limb0, limb1, limb2, limb3 }, limb4) +} + +// scale u256 by u128 (for smaller numbers) +// unreduced, returns u512 +#[inline(always)] +pub fn scl_u(a: u256, b: u128) -> u512 { + // (a1 + a2) * c + let (limb1_part1, limb0) = u128_wide_mul(a.low, b); + let (limb2, limb1_part2) = u128_wide_mul(a.high, b); + let limb1 = u::u128_wrapping_add(limb1_part1, limb1_part2); + u512 { limb0, limb1, limb2, limb3: 0 } +} + +// scale u256 by u128 (for smaller numbers) +// takes non zero modulo +// returns modded u256 +#[inline(always)] +pub fn scl_nz(a: u256, b: u128, modulo: NonZero) -> u256 { + u512_reduce(scl_u(a, b), modulo) +} + +// scale u256 by u128 (for smaller numbers) +// returns modded u256 +#[inline(always)] +pub fn scl(a: u256, b: u128, modulo: NonZero) -> u256 { + scl_nz(a, b, modulo.try_into().unwrap()) +} + +// mul two u256 +// unreduced, returns u512 +// #[inline(always)] +pub fn mul_u(a: u256, b: u256) -> u512 { + let (limb1, limb0) = u128_wide_mul(a.low, b.low); + let (limb2, limb1_part) = u128_wide_mul(a.low, b.high); + let (limb1, limb1_overflow0) = u::u128_add_with_carry(limb1, limb1_part); + let (limb2_part, limb1_part) = u128_wide_mul(a.high, b.low); + let (limb1, limb1_overflow1) = u::u128_add_with_carry(limb1, limb1_part); + let (limb2, limb2_overflow) = u::u128_add_with_carry(limb2, limb2_part); + let (limb3, limb2_part) = u128_wide_mul(a.high, b.high); + // No overflow since no limb4. + let limb3 = u::u128_wrapping_add(limb3, limb2_overflow); + let (limb2, limb2_overflow) = u::u128_add_with_carry(limb2, limb2_part); + // No overflow since no limb4. + let limb3 = u::u128_wrapping_add(limb3, limb2_overflow); + // No overflow possible in this addition since both operands are 0/1. + let limb1_overflow = u::u128_wrapping_add(limb1_overflow0, limb1_overflow1); + let (limb2, limb2_overflow) = u::u128_add_with_carry(limb2, limb1_overflow); + // No overflow since no limb4. + let limb3 = u::u128_wrapping_add(limb3, limb2_overflow); + + u512 { limb0, limb1, limb2, limb3 } +} + +// mul two u256 +// takes non zero modulo +// returns modded u256 +#[inline(always)] +pub fn mul_nz(a: u256, b: u256, modulo: NonZero) -> u256 { + u512_reduce(mul_u(a, b), modulo) +} + +// mul two u256 +// returns modded u256 +#[inline(always)] +pub fn mul(a: u256, b: u256, modulo: u256) -> u256 { + mul_nz(a, b, modulo.try_into().unwrap()) +} + +// squares a u256 +// unreduced, returns u512 +// #[inline(always)] +pub fn sqr_u(a: u256) -> u512 { + let (limb1, limb0) = u128_wide_mul(a.low, a.low); + let (limb2, limb1_part) = u128_wide_mul(a.low, a.high); + let (limb1, limb1_overflow0) = u::u128_add_with_carry(limb1, limb1_part); + let (limb1, limb1_overflow1) = u::u128_add_with_carry(limb1, limb1_part); + let (limb2, limb2_overflow) = u::u128_add_with_carry(limb2, limb2); + let (limb3, limb2_part) = u128_wide_mul(a.high, a.high); + // No overflow since no limb4. + let limb3 = u::u128_wrapping_add(limb3, limb2_overflow); + let (limb2, limb2_overflow) = u::u128_add_with_carry(limb2, limb2_part); + // No overflow since no limb4. + let limb3 = u::u128_wrapping_add(limb3, limb2_overflow); + // No overflow possible in this addition since both operands are 0/1. + let limb1_overflow = u::u128_wrapping_add(limb1_overflow0, limb1_overflow1); + let (limb2, limb2_overflow) = u::u128_add_with_carry(limb2, limb1_overflow); + // No overflow since no limb4. + let limb3 = u::u128_wrapping_add(limb3, limb2_overflow); + u512 { limb0, limb1, limb2, limb3 } +} + +// squares a u256 +// takes non zero modulo +// returns modded u256 +#[inline(always)] +pub fn sqr_nz(a: u256, modulo: NonZero) -> u256 { + u512_reduce(sqr_u(a), modulo) +} + +// squares a u256 +// takes non zero modulo +// returns modded u256 +#[inline(always)] +pub fn sqr(a: u256, modulo: u256) -> u256 { + u512_reduce(sqr_u(a), modulo.try_into().unwrap()) +} diff --git a/packages/fast_mod/src/tests.cairo b/packages/fast_mod/src/tests.cairo new file mode 100644 index 0000000..e5ebf95 --- /dev/null +++ b/packages/fast_mod/src/tests.cairo @@ -0,0 +1,289 @@ +// test bn::math::fast_mod_tests::bench_plain::add ... ok (gas usage est.: 3530) +// test bn::math::fast_mod_tests::bench_plain::div ... ok (gas usage est.: 6950) +// test bn::math::fast_mod_tests::bench_plain::mul ... ok (gas usage est.: 15390) +// test bn::math::fast_mod_tests::bench_plain::rem ... ok (gas usage est.: 6950) +// test bn::math::fast_mod_tests::bench_plain::sub ... ok (gas usage est.: 3530) +// test bn::math::fast_mod_tests::bench::add ... ok (gas usage est.: 9060) +// test bn::math::fast_mod_tests::bench::add_u ... ok (gas usage est.: 3110) +// test bn::math::fast_mod_tests::bench::div ... ok (gas usage est.: 69700) +// test bn::math::fast_mod_tests::bench::div_u ... ok (gas usage est.: 48510) +// test bn::math::fast_mod_tests::bench::inv ... ok (gas usage est.: 28870) +// test bn::math::fast_mod_tests::bench::mul ... ok (gas usage est.: 41830) +// test bn::math::fast_mod_tests::bench::mul_u ... ok (gas usage est.: 20130) +// test bn::math::fast_mod_tests::bench::rdc ... ok (gas usage est.: 6950) +// test bn::math::fast_mod_tests::bench::scl ... ok (gas usage est.: 28430) +// test bn::math::fast_mod_tests::bench::scl_u ... ok (gas usage est.: 7140) +// test bn::math::fast_mod_tests::bench::sqr ... ok (gas usage est.: 38100) +// test bn::math::fast_mod_tests::bench::sqr_u ... ok (gas usage est.: 16900) +// test bn::math::fast_mod_tests::bench::sub ... ok (gas usage est.: 5240) +// test bn::math::fast_mod_tests::bench::sub_u ... ok (gas usage est.: 3110) +// test bn::math::fast_mod_tests::bench::u512_add ... ok (gas usage est.: 7980) +// test bn::math::fast_mod_tests::bench::u512_add_high ... ok (gas usage est.: 3420) +// test bn::math::fast_mod_tests::bench::u512_add_u256 ... ok (gas usage est.: 4960) +// test bn::math::fast_mod_tests::bench::u512_rdc ... ok (gas usage est.: 21390) +// test bn::math::fast_mod_tests::bench::u512_scl ... ok (gas usage est.: 14950) +// test bn::math::fast_mod_tests::bench::u512_sub ... ok (gas usage est.: 7980) +// test bn::math::fast_mod_tests::bench::u512_sub_high ... ok (gas usage est.: 3420) +// test bn::math::fast_mod_tests::bench::u512_sub_u256 ... ok (gas usage est.: 4960) +// test bn::math::fast_mod_tests::test_all_mod_ops ... ok (gas usage est.: 363770) + +use core::option::OptionTrait; +use core::traits::TryInto; +use super as f; +use f::{u512, u512Display}; + +const FIELD: u256 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; +const FIELD_NZ: NonZero = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; + +const a: u256 = 9099547013904003590785796930435194473319680151794113978918064868415326638035; +const b: u256 = 8021715850804026033197027745655159931503181100513576347155970296011118125764; + +#[inline(always)] +pub fn mu512(limb0: u128, limb1: u128, limb2: u128, limb3: u128) -> u512 { + u512 { limb0, limb1, limb2, limb3 } +} + +mod bench { + use core::option::OptionTrait; + use core::traits::TryInto; + use super::{mu512, f}; + use f::{u512}; + use super::{a, b, FIELD, FIELD_NZ}; + #[test] + #[available_gas(1000000)] + pub fn add() { + f::add(a, b, FIELD); + } + + #[test] + #[available_gas(1000000)] + pub fn sub() { + f::sub(a, b, FIELD); + } + + #[test] + #[available_gas(1000000)] + pub fn mul() { + f::mul(a, b, FIELD); + } + + #[test] + #[available_gas(1000000)] + pub fn scl() { + f::scl(a, b.low, FIELD_NZ); + } + + #[test] + #[available_gas(1000000)] + pub fn sqr() { + f::sqr_nz(a, FIELD_NZ); + } + + #[test] + #[available_gas(100000000)] + pub fn div() { + f::div(a, b, FIELD); + } + + #[test] + #[available_gas(100000000)] + pub fn inv() { + f::inv(a, FIELD_NZ); + } + + #[test] + #[available_gas(100000000)] + pub fn rdc() { + f::reduce(a, b.try_into().unwrap()); + } + + #[test] + #[available_gas(1000000)] + pub fn add_u() { + f::add_u(a, b); + } + + #[test] + #[available_gas(1000000)] + pub fn sub_u() { + f::sub_u(a, b); + } + + #[test] + #[available_gas(1000000)] + pub fn mul_u() { + f::mul_u(a, b); + } + + #[test] + #[available_gas(1000000)] + pub fn scl_u() { + f::scl_u(a, b.low); + } + + #[test] + #[available_gas(1000000)] + pub fn sqr_u() { + f::sqr_u(a); + } + + #[test] + #[available_gas(100000000)] + pub fn div_u() { + f::div_u(a, b, FIELD_NZ); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_add() { + f::u512_add(mu512(a.low, a.high, b.low, b.high), mu512(b.low, b.high, a.low, a.high)); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_add_high() { + f::u512_high_add(mu512(a.low, a.high, b.low, b.high), 5).unwrap(); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_add_u256() { + f::u512_add_u256(mu512(a.low, a.high, b.low, b.high), 5); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_sub() { + f::u512_sub(mu512(b.low, b.high, a.low, a.high), mu512(a.low, a.high, b.low, b.high)); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_sub_high() { + f::u512_high_sub(mu512(a.low, a.high, b.low, b.high), 5).unwrap(); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_sub_u256() { + f::u512_sub_u256(mu512(a.low, a.high, b.low, b.high), 5); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_rdc() { + f::u512_reduce(mu512(a.low, a.high, b.low, b.high), b.try_into().unwrap()); + } + + #[test] + #[available_gas(100000000)] + pub fn u512_scl() { + f::u512_scl(mu512(a.low, a.high, b.low, b.high), b.low); + } +} + +mod bench_plain { + use core::traits::TryInto; + use super::{a, b, FIELD}; + #[test] + #[available_gas(1000000)] + pub fn add() { + a + b; + } + + #[test] + #[available_gas(1000000)] + pub fn sub() { + a - b; + } + + #[test] + #[available_gas(1000000)] + pub fn mul() { + 7_u256 * 909954701390400359078579693043519447331968015179411397891806486841532663803; + } + + #[test] + #[available_gas(100000000)] + pub fn div() { + a / b; + } + + #[test] + #[available_gas(100000000)] + pub fn rem() { + a % b; + } +} + +#[test] +#[available_gas(100000000)] +pub fn test_all_mod_ops() { + let max_u128: u128 = 0xffffffffffffffffffffffffffffffff; + let add = f::add(a, b, FIELD); + assert( + add == 17121262864708029623982824676090354404822861252307690326074035164426444763799, + 'incorrect add' + ); + let sub = f::sub(a, b, FIELD); + assert( + sub == 1077831163099977557588769184780034541816499051280537631762094572404208512271, + 'incorrect sub' + ); + let mul = f::mul(a, b, FIELD); + assert( + mul == 6561477752769399547014183440960600095569924911855714080305417693732453755033, + 'incorrect mul' + ); + let div = f::div(a, b, FIELD); + assert( + div == 12819640619688655488085323601008678463608009668414428319642291645922931558321, + 'incorrect div' + ); + let sqr_mul = f::mul(a, a, FIELD); + let sqr = f::sqr_nz(a, FIELD_NZ); + assert(sqr == sqr_mul, 'incorrect square'); + + let scl_mul = f::mul(a, u256 { high: 0, low: b.low }, FIELD); + let scl = f::scl(a, b.low, FIELD_NZ); + assert(scl == scl_mul, 'incorrect square'); + + assert( + f::u512_add(mu512(max_u128, 1, 2, 3), mu512(4, 5, 6, 7)) == mu512(3, 7, 8, 10), + 'incorrect u512 add' + ); + assert( + f::u512_sub(mu512(4, 5, 6, 7), mu512(0, 1, 2, 3)) == mu512(4, 4, 4, 4), 'incorrect u512 sub' + ); + let (res, _) = f::u512_sub_overflow(mu512(4, 5, 6, 7), mu512(5, 1, 2, 3)); + assert(res == mu512(max_u128, 3, 4, 4), 'incorrect u512 sub'); + + let (scaled_u512, _) = f::u512_scl(mu512(4, 5, 6, 7), 9); + assert(scaled_u512.limb0 == 36, 'u512_scl incorrect limb0'); + assert(scaled_u512.limb1 == 45, 'u512_scl incorrect limb1'); + assert(scaled_u512.limb2 == 54, 'u512_scl incorrect limb2'); + assert(scaled_u512.limb3 == 63, 'u512_scl incorrect limb3'); + + let (scaled_u512, ovf) = f::u512_scl(mu512(1, 2, 3, 4), a.low); + let (alowx1_1, alowx1_0) = f::mul_scale_sqr::u128_wide_mul(a.low, 1); + assert(scaled_u512.limb0 == alowx1_0, 'u512_scl incorrect limb0'); + let (alowx2_1, alowx2_0) = f::mul_scale_sqr::u128_wide_mul(a.low, 2); + assert(scaled_u512.limb1 == alowx2_0 + alowx1_1, 'u512_scl incorrect limb1'); + let (alowx3_1, alowx3_0) = f::mul_scale_sqr::u128_wide_mul(a.low, 3); + assert(scaled_u512.limb2 == alowx2_1 + alowx3_0, 'u512_scl incorrect limb2'); + let (alowx4_1, alowx4_0) = f::mul_scale_sqr::u128_wide_mul(a.low, 4); + assert(scaled_u512.limb3 == alowx3_1 + alowx4_0, 'u512_scl incorrect limb3'); + assert(ovf == alowx4_1, 'u512_scl incorrect limb3'); + + let high_add_u512 = f::u512_high_add(mu512(4, 5, 6, 7), max_u128.into()).unwrap(); + assert(high_add_u512.limb0 == 4, 'u512_high_add incorrect limb0'); + assert(high_add_u512.limb1 == 5, 'u512_high_add incorrect limb1'); + assert(high_add_u512.limb2 == 5, 'u512_high_add incorrect limb2'); + assert(high_add_u512.limb3 == 8, 'u512_high_add incorrect limb3'); + + let high_sub_u512 = f::u512_high_sub(mu512(4, 5, 6, 7), 2).unwrap(); + assert(high_sub_u512.limb0 == 4, 'high_sub_u512 incorrect limb0'); + assert(high_sub_u512.limb1 == 5, 'high_sub_u512 incorrect limb1'); + assert(high_sub_u512.limb2 == 4, 'high_sub_u512 incorrect limb2'); + assert(high_sub_u512.limb3 == 7, 'high_sub_u512 incorrect limb3'); +} diff --git a/packages/fast_mod/src/u512_ops.cairo b/packages/fast_mod/src/u512_ops.cairo new file mode 100644 index 0000000..6112ee0 --- /dev/null +++ b/packages/fast_mod/src/u512_ops.cairo @@ -0,0 +1,217 @@ +use core::integer::u512; +use super::utils::{ + u256_wrapping_add, u256_overflow_add, u256_overflow_sub, u128_overflowing_add, + u256_wrapping_sub, u128_overflowing_sub, expect_u256, expect_u128 +}; + +#[derive(Copy, Drop, Hash, PartialEq, Serde)] +struct u256X2 { + low: u256, + high: u256, +} + +impl U512Intou256X2 of Into { + #[inline(always)] + fn into(self: u512) -> u256X2 { + let u512 { limb0: low, limb1: high, limb2, limb3 } = self; + u256X2 { low: u256 { low, high }, high: u256 { low: limb2, high: limb3 } } + } +} + +#[inline(always)] +pub fn u512_add(lhs: u512, rhs: u512) -> u512 { + let lhs: u256X2 = lhs.into(); + let rhs: u256X2 = rhs.into(); + + // No overflow allowed + let u256 { low: limb2, high: limb3 } = expect_u256( + u256_overflow_add(lhs.high, rhs.high), 'u512 add overflow' + ); + + match u256_overflow_add(lhs.low, rhs.low) { + Result::Ok(u256 { low: limb0, high: limb1 }) => { u512 { limb0, limb1, limb2, limb3 } }, + Result::Err(u256 { low: limb0, + high: limb1 }) => { + // Try to move overflow to limb2 + return match u128_overflowing_add(limb2, 1_u128) { + Result::Ok(limb2) => u512 { limb0, limb1, limb2, limb3 }, + Result::Err(limb2) => { + // Try to move overflow to limb3 + let limb3 = expect_u128( + u128_overflowing_add(limb3, 1_u128), 'u512 add overflow' + ); + u512 { limb0, limb1, limb2, limb3 } + }, + }; + }, + } +} + +#[inline(always)] +pub fn u512_add_overflow(lhs: u512, rhs: u512) -> (u512, bool) { + let lhs: u256X2 = lhs.into(); + let rhs: u256X2 = rhs.into(); + + let (u256 { low: limb2, high: limb3 }, overflow) = match u256_overflow_add(lhs.high, rhs.high) { + Result::Ok(v) => (v, false), + Result::Err(v) => (v, true) + }; + + match u256_overflow_add(lhs.low, rhs.low) { + Result::Ok(u256 { low: limb0, + high: limb1 }) => (u512 { limb0, limb1, limb2, limb3 }, overflow), + Result::Err(u256 { low: limb0, + high: limb1 }) => { + // Try to move overflow to limb2 + return match u128_overflowing_add(limb2, 1_u128) { + Result::Ok(limb2) => (u512 { limb0, limb1, limb2, limb3 }, overflow), + Result::Err(limb2) => { + // Try to move overflow to limb3 + match u128_overflowing_add(limb3, 1_u128) { + Result::Ok(limb3) => (u512 { limb0, limb1, limb2, limb3 }, overflow), + Result::Err(limb3) => (u512 { limb0, limb1, limb2, limb3 }, true) + } + }, + }; + }, + } +} + +#[inline(always)] +pub fn u512_sub(lhs: u512, rhs: u512) -> u512 { + let lhs: u256X2 = lhs.into(); + let rhs: u256X2 = rhs.into(); + + // No overflow allowed + let u256 { low: limb2, high: limb3 } = expect_u256( + u256_overflow_sub(lhs.high, rhs.high), 'u512 sub overflow' + ); + + match u256_overflow_sub(lhs.low, rhs.low) { + Result::Ok(u256 { low: limb0, high: limb1 }) => { u512 { limb0, limb1, limb2, limb3 } }, + Result::Err(u256 { low: limb0, + high: limb1 }) => { + // Try to move overflow to limb2 + return match u128_overflowing_sub(limb2, 1_u128) { + Result::Ok(limb2) => u512 { limb0, limb1, limb2, limb3 }, + Result::Err(limb2) => { + // Try to move overflow to limb3 + let limb3 = expect_u128( + u128_overflowing_sub(limb3, 1_u128), 'u512 sub overflow' + ); + u512 { limb0, limb1, limb2, limb3 } + }, + }; + }, + } +} + +#[inline(always)] +pub fn u512_add_u256(lhs: u512, rhs: u256) -> u512 { + let u256X2 { high, low }: u256X2 = lhs.into(); + let u256 { high: limb3, low: limb2 } = high; + + match u256_overflow_add(low, rhs) { + Result::Ok(u256 { low: limb0, high: limb1 }) => u512 { limb0, limb1, limb2, limb3 }, + Result::Err(limbs) => { + let u256 { low: limb0, high: limb1 } = limbs; + // Try to move overflow to limb2 + match u128_overflowing_add(limb2, 1) { + Result::Ok(limb2) => u512 { limb0, limb1, limb2, limb3 }, + Result::Err(limb2) => { + // Try to move overflow to limb3 + let limb3 = expect_u128( + u128_overflowing_add(limb3, 1), 'u512_add_u256 overflow' + ); + u512 { limb0, limb1, limb2, limb3 } + }, + } + }, + } +} + +#[inline(always)] +pub fn u512_sub_u256(lhs: u512, rhs: u256) -> u512 { + let u256X2 { high, low }: u256X2 = lhs.into(); + let u256 { high: limb3, low: limb2 } = high; + + match u256_overflow_sub(low, rhs) { + Result::Ok(u256 { low: limb0, high: limb1 }) => u512 { limb0, limb1, limb2, limb3 }, + Result::Err(limbs) => { + let u256 { low: limb0, high: limb1 } = limbs; + // Try to move overflow to limb2 + match u128_overflowing_sub(limb2, 1) { + Result::Ok(limb2) => u512 { limb0, limb1, limb2, limb3 }, + Result::Err(limb2) => { + // Try to move overflow to limb3 + let limb3 = expect_u128( + u128_overflowing_sub(limb3, 1), 'u512_sub_u256 overflow' + ); + u512 { limb0, limb1, limb2, limb3 } + }, + } + }, + } +} + +#[inline(always)] +pub fn u512_sub_overflow(lhs: u512, rhs: u512) -> (u512, bool) { + let lhs: u256X2 = lhs.into(); + let rhs: u256X2 = rhs.into(); + + // No overflow allowed + let (u256 { low: limb2, high: limb3 }, overflow) = match u256_overflow_sub(lhs.high, rhs.high) { + Result::Ok(v) => (v, false), + Result::Err(v) => (v, true) + }; + + match u256_overflow_sub(lhs.low, rhs.low) { + Result::Ok(u256 { low: limb0, + high: limb1 }) => (u512 { limb0, limb1, limb2, limb3 }, overflow), + Result::Err(u256 { low: limb0, + high: limb1 }) => { + // Try to move overflow to limb2 + return match u128_overflowing_sub(limb2, 1_u128) { + Result::Ok(limb2) => (u512 { limb0, limb1, limb2, limb3 }, overflow), + Result::Err(limb2) => { + // Try to move overflow to limb3 + match u128_overflowing_sub(limb3, 1_u128) { + Result::Ok(limb3) => (u512 { limb0, limb1, limb2, limb3 }, overflow), + Result::Err(limb3) => (u512 { limb0, limb1, limb2, limb3 }, true) + } + }, + }; + }, + } +} + +// add a u256 to high limbs of u512 +// this beautiful beautiful function converts a `-x mod 2**512` to `x mod rhs` +#[inline(always)] +pub fn u512_high_add(lhs: u512, rhs: u256) -> Result { + let u512 { limb0, limb1, limb2: low, limb3: high } = lhs; + let lhs = u256 { low, high }; + match u256_overflow_add(lhs, rhs) { + Result::Ok(res) => Result::Ok(u512 { limb0, limb1, limb2: res.low, limb3: res.high }), + Result::Err(res) => Result::Err(u512 { limb0, limb1, limb2: res.low, limb3: res.high }) + } +} + +// subtracts u256 from high limbs of u512 +// this beautiful beautiful function can convert an overflown `2**512 + x mod rhs` to equivalent `y mod rhs` +#[inline(always)] +pub fn u512_high_sub(lhs: u512, rhs: u256) -> Result { + let u512 { limb0, limb1, limb2: low, limb3: high } = lhs; + let lhs = u256 { low, high }; + match u256_overflow_sub(lhs, rhs) { + Result::Ok(res) => Result::Ok(u512 { limb0, limb1, limb2: res.low, limb3: res.high }), + Result::Err(res) => Result::Err(u512 { limb0, limb1, limb2: res.low, limb3: res.high }) + } +} + +#[inline(always)] +pub fn u512_reduce(a: u512, modulo: NonZero) -> u256 { + let (_, rem_u256) = core::integer::u512_safe_div_rem_by_u256(a, modulo); + rem_u256 +} + diff --git a/packages/fast_mod/src/utils.cairo b/packages/fast_mod/src/utils.cairo new file mode 100644 index 0000000..f32f13a --- /dev/null +++ b/packages/fast_mod/src/utils.cairo @@ -0,0 +1,189 @@ +pub use core::integer::{u128_overflowing_add, u128_overflowing_sub, u512}; +pub use core::panic_with_felt252; + +#[inline(always)] +pub fn u128_wrapping_add(lhs: u128, rhs: u128) -> u128 implicits(RangeCheck) nopanic { + match u128_overflowing_add(lhs, rhs) { + Result::Ok(x) => x, + Result::Err(x) => x, + } +} + +#[inline(always)] +pub fn u128_add_with_carry(a: u128, b: u128) -> (u128, u128) nopanic { + match u128_overflowing_add(a, b) { + Result::Ok(v) => (v, 0), + Result::Err(v) => (v, 1), + } +} + +#[inline(always)] +pub fn u128_wrapping_sub(lhs: u128, rhs: u128) -> u128 implicits(RangeCheck) nopanic { + match u128_overflowing_sub(lhs, rhs) { + Result::Ok(x) => x, + Result::Err(x) => x, + } +} + +#[inline(always)] +pub fn u256_overflow_add(lhs: u256, rhs: u256) -> Result implicits(RangeCheck) nopanic { + let (high, overflow) = match u128_overflowing_add(lhs.high, rhs.high) { + Result::Ok(high) => (high, false), + Result::Err(high) => (high, true), + }; + match u128_overflowing_add(lhs.low, rhs.low) { + Result::Ok(low) => if overflow { + Result::Err(u256 { low, high }) + } else { + Result::Ok(u256 { low, high }) + }, + Result::Err(low) => { + match u128_overflowing_add(high, 1_u128) { + Result::Ok(high) => if overflow { + Result::Err(u256 { low, high }) + } else { + Result::Ok(u256 { low, high }) + }, + Result::Err(high) => Result::Err(u256 { low, high }), + } + }, + } +} + +#[inline(always)] +pub fn u256_overflow_sub(lhs: u256, rhs: u256) -> Result implicits(RangeCheck) nopanic { + let (high, overflow) = match u128_overflowing_sub(lhs.high, rhs.high) { + Result::Ok(high) => (high, false), + Result::Err(high) => (high, true), + }; + match u128_overflowing_sub(lhs.low, rhs.low) { + Result::Ok(low) => if overflow { + Result::Err(u256 { low, high }) + } else { + Result::Ok(u256 { low, high }) + }, + Result::Err(low) => { + match u128_overflowing_sub(high, 1_u128) { + Result::Ok(high) => if overflow { + Result::Err(u256 { low, high }) + } else { + Result::Ok(u256 { low, high }) + }, + Result::Err(high) => Result::Err(u256 { low, high }), + } + }, + } +} + +#[inline(always)] +pub fn u256_wrapping_add(lhs: u256, rhs: u256) -> u256 implicits(RangeCheck) nopanic { + let high = match u128_overflowing_add(lhs.high, rhs.high) { + Result::Ok(high) => high, + Result::Err(high) => high, + }; + match u128_overflowing_add(lhs.low, rhs.low) { + Result::Ok(low) => u256 { low, high }, + Result::Err(low) => { + match u128_overflowing_add(high, 1_u128) { + Result::Ok(high) => u256 { low, high }, + Result::Err(high) => u256 { low, high }, + } + }, + } +} + +#[inline(always)] +pub fn u256_wrapping_sub(lhs: u256, rhs: u256) -> u256 implicits(RangeCheck) nopanic { + let high = match u128_overflowing_sub(lhs.high, rhs.high) { + Result::Ok(high) => high, + Result::Err(high) => high, + }; + match u128_overflowing_sub(lhs.low, rhs.low) { + Result::Ok(low) => u256 { low, high }, + Result::Err(low) => { + match u128_overflowing_sub(high, 1_u128) { + Result::Ok(high) => u256 { low, high }, + Result::Err(high) => u256 { low, high }, + } + }, + } +} + +#[inline(always)] +pub fn expect_u256(result: Result, panic_msg: felt252) -> u256 { + match result { + Result::Ok(value) => value, + Result::Err(value) => { + panic_with_felt252(panic_msg); + value + }, + } +} + +#[inline(always)] +pub fn expect_u128(result: Result, panic_msg: felt252) -> u128 { + match result { + Result::Ok(value) => value, + Result::Err(value) => { + panic_with_felt252(panic_msg); + value + }, + } +} + +use core::to_byte_array::AppendFormattedToByteArray; +use core::fmt::{Display, Formatter, Error}; + +pub impl u512Display of Display { + fn fmt(self: @u512, ref f: Formatter) -> Result<(), Error> { + let base = 16_u256.try_into().unwrap(); + write!(f, "\n0x").unwrap(); + u256 { high: *self.limb3, low: *self.limb2 } + .append_formatted_to_byte_array(ref f.buffer, base); + write!(f, ",0x").unwrap(); + u256 { high: *self.limb1, low: *self.limb0 } + .append_formatted_to_byte_array(ref f.buffer, base); + Result::Ok(()) + } +} + +pub impl Tuple2Add, +Add, +Drop, +Drop> of Add<(T1, T2)> { + #[inline(always)] + fn add(lhs: (T1, T2), rhs: (T1, T2)) -> (T1, T2) { + let (a0, a1) = lhs; + let (b0, b1) = rhs; + (a0 + b0, a1 + b1) + } +} + +pub impl Tuple2Sub, +Sub, +Drop, +Drop> of Sub<(T1, T2)> { + #[inline(always)] + fn sub(lhs: (T1, T2), rhs: (T1, T2)) -> (T1, T2) { + let (a0, a1) = lhs; + let (b0, b1) = rhs; + (a0 - b0, a1 - b1) + } +} + +pub impl Tuple3Add< + T1, T2, T3, +Add, +Add, +Add, +Drop, +Drop, +Drop, +> of Add<(T1, T2, T3)> { + #[inline(always)] + fn add(lhs: (T1, T2, T3), rhs: (T1, T2, T3)) -> (T1, T2, T3) { + let (a0, a1, a2) = lhs; + let (b0, b1, b2) = rhs; + (a0 + b0, a1 + b1, a2 + b2) + } +} + +pub impl Tuple3Sub< + T1, T2, T3, +Sub, +Sub, +Sub, +Drop, +Drop, +Drop, +> of Sub<(T1, T2, T3)> { + #[inline(always)] + fn sub(lhs: (T1, T2, T3), rhs: (T1, T2, T3)) -> (T1, T2, T3) { + let (a0, a1, a2) = lhs; + let (b0, b1, b2) = rhs; + (a0 - b0, a1 - b1, a2 - b2) + } +} + From 7242638f3d32cdf6abc8ac2564fd6c9a2911f046 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 3 Jul 2024 12:58:30 +0530 Subject: [PATCH 07/97] workspace: versions --- legacy/bn_contracts/Scarb.lock | 4 ++-- legacy/bn_contracts/Scarb.toml | 2 +- legacy/bn_legacy/Scarb.toml | 2 +- packages/bn_ate_loop/Scarb.toml | 2 +- packages/fast_mod/Scarb.toml | 2 +- packages/fq_types/Scarb.toml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/legacy/bn_contracts/Scarb.lock b/legacy/bn_contracts/Scarb.lock index 85c0131..63bee35 100644 --- a/legacy/bn_contracts/Scarb.lock +++ b/legacy/bn_contracts/Scarb.lock @@ -3,11 +3,11 @@ version = 1 [[package]] name = "bn" -version = "0.1.0" +version.workspace = true [[package]] name = "bn_contracts" -version = "0.1.0" +version.workspace = true dependencies = [ "bn", ] diff --git a/legacy/bn_contracts/Scarb.toml b/legacy/bn_contracts/Scarb.toml index 77910eb..fa1299b 100644 --- a/legacy/bn_contracts/Scarb.toml +++ b/legacy/bn_contracts/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "bn_contracts" -version = "0.1.0" +version.workspace = true [dependencies] bn = { path = "../bn_legacy" } diff --git a/legacy/bn_legacy/Scarb.toml b/legacy/bn_legacy/Scarb.toml index 7182cfd..7a77eee 100644 --- a/legacy/bn_legacy/Scarb.toml +++ b/legacy/bn_legacy/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "bn" -version = "0.1.0" +version.workspace = true # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html diff --git a/packages/bn_ate_loop/Scarb.toml b/packages/bn_ate_loop/Scarb.toml index a099523..c25a0f4 100644 --- a/packages/bn_ate_loop/Scarb.toml +++ b/packages/bn_ate_loop/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "bn_ate_loop" -version = "0.1.0" +version.workspace = true edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html diff --git a/packages/fast_mod/Scarb.toml b/packages/fast_mod/Scarb.toml index 08379ca..a299bb6 100644 --- a/packages/fast_mod/Scarb.toml +++ b/packages/fast_mod/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "fast_mod" -version = "0.1.0" +version.workspace = true edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html diff --git a/packages/fq_types/Scarb.toml b/packages/fq_types/Scarb.toml index 99f61fd..faed47b 100644 --- a/packages/fq_types/Scarb.toml +++ b/packages/fq_types/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "fq_types" -version = "0.1.0" +version.workspace = true edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html From cdb3e6d7c5bf8b3857e87a5ee7d52cfcbf9bf792 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 3 Jul 2024 13:07:33 +0530 Subject: [PATCH 08/97] fix fast_mod tests --- packages/fast_mod/src/tests.cairo | 126 ++++++++++++++++++------------ 1 file changed, 76 insertions(+), 50 deletions(-) diff --git a/packages/fast_mod/src/tests.cairo b/packages/fast_mod/src/tests.cairo index e5ebf95..e068397 100644 --- a/packages/fast_mod/src/tests.cairo +++ b/packages/fast_mod/src/tests.cairo @@ -32,14 +32,14 @@ use core::traits::TryInto; use super as f; use f::{u512, u512Display}; -const FIELD: u256 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; -const FIELD_NZ: NonZero = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; +const PRIME: u256 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; +const PRIME_NZ: NonZero = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; const a: u256 = 9099547013904003590785796930435194473319680151794113978918064868415326638035; const b: u256 = 8021715850804026033197027745655159931503181100513576347155970296011118125764; #[inline(always)] -pub fn mu512(limb0: u128, limb1: u128, limb2: u128, limb3: u128) -> u512 { +fn mu512(limb0: u128, limb1: u128, limb2: u128, limb3: u128) -> u512 { u512 { limb0, limb1, limb2, limb3 } } @@ -48,204 +48,230 @@ mod bench { use core::traits::TryInto; use super::{mu512, f}; use f::{u512}; - use super::{a, b, FIELD, FIELD_NZ}; + use super::{a, b, PRIME, PRIME_NZ}; #[test] #[available_gas(1000000)] - pub fn add() { - f::add(a, b, FIELD); + fn add() { + f::add(a, b, PRIME); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn sub() { - f::sub(a, b, FIELD); + fn sub() { + f::sub(a, b, PRIME); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn mul() { - f::mul(a, b, FIELD); + fn mul() { + f::mul(a, b, PRIME); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn scl() { - f::scl(a, b.low, FIELD_NZ); + fn scl() { + f::scl(a, b.low, PRIME_NZ); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn sqr() { - f::sqr_nz(a, FIELD_NZ); + fn sqr() { + f::sqr_nz(a, PRIME_NZ); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn div() { - f::div(a, b, FIELD); + fn div() { + f::div(a, b, PRIME); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn inv() { - f::inv(a, FIELD_NZ); + fn inv() { + f::inv(a, PRIME_NZ); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn rdc() { + fn rdc() { f::reduce(a, b.try_into().unwrap()); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn add_u() { + fn add_u() { f::add_u(a, b); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn sub_u() { + fn sub_u() { f::sub_u(a, b); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn mul_u() { + fn mul_u() { f::mul_u(a, b); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn scl_u() { + fn scl_u() { f::scl_u(a, b.low); + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn sqr_u() { + fn sqr_u() { f::sqr_u(a); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn div_u() { - f::div_u(a, b, FIELD_NZ); + fn div_u() { + f::div_u(a, b, PRIME_NZ); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_add() { + fn u512_add() { f::u512_add(mu512(a.low, a.high, b.low, b.high), mu512(b.low, b.high, a.low, a.high)); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_add_high() { + fn u512_add_high() { f::u512_high_add(mu512(a.low, a.high, b.low, b.high), 5).unwrap(); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_add_u256() { + fn u512_add_u256() { f::u512_add_u256(mu512(a.low, a.high, b.low, b.high), 5); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_sub() { + fn u512_sub() { f::u512_sub(mu512(b.low, b.high, a.low, a.high), mu512(a.low, a.high, b.low, b.high)); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_sub_high() { + fn u512_sub_high() { f::u512_high_sub(mu512(a.low, a.high, b.low, b.high), 5).unwrap(); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_sub_u256() { + fn u512_sub_u256() { f::u512_sub_u256(mu512(a.low, a.high, b.low, b.high), 5); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_rdc() { + fn u512_rdc() { f::u512_reduce(mu512(a.low, a.high, b.low, b.high), b.try_into().unwrap()); + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn u512_scl() { + fn u512_scl() { f::u512_scl(mu512(a.low, a.high, b.low, b.high), b.low); + assert(true, 'for snforge tests'); } } mod bench_plain { use core::traits::TryInto; - use super::{a, b, FIELD}; + use super::{a, b, PRIME}; #[test] #[available_gas(1000000)] - pub fn add() { + fn add() { a + b; + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn sub() { + fn sub() { a - b; + assert(true, 'for snforge tests'); } #[test] #[available_gas(1000000)] - pub fn mul() { + fn mul() { 7_u256 * 909954701390400359078579693043519447331968015179411397891806486841532663803; + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn div() { + fn div() { a / b; + assert(true, 'for snforge tests'); } #[test] #[available_gas(100000000)] - pub fn rem() { + fn rem() { a % b; + assert(true, 'for snforge tests'); } } - #[test] #[available_gas(100000000)] -pub fn test_all_mod_ops() { +fn test_all_mod_ops() { let max_u128: u128 = 0xffffffffffffffffffffffffffffffff; - let add = f::add(a, b, FIELD); + let add = f::add(a, b, PRIME); assert( add == 17121262864708029623982824676090354404822861252307690326074035164426444763799, 'incorrect add' ); - let sub = f::sub(a, b, FIELD); + let sub = f::sub(a, b, PRIME); assert( sub == 1077831163099977557588769184780034541816499051280537631762094572404208512271, 'incorrect sub' ); - let mul = f::mul(a, b, FIELD); + let mul = f::mul(a, b, PRIME); assert( mul == 6561477752769399547014183440960600095569924911855714080305417693732453755033, 'incorrect mul' ); - let div = f::div(a, b, FIELD); + let div = f::div(a, b, PRIME); assert( div == 12819640619688655488085323601008678463608009668414428319642291645922931558321, 'incorrect div' ); - let sqr_mul = f::mul(a, a, FIELD); - let sqr = f::sqr_nz(a, FIELD_NZ); + let sqr_mul = f::mul(a, a, PRIME); + let sqr = f::sqr_nz(a, PRIME_NZ); assert(sqr == sqr_mul, 'incorrect square'); - let scl_mul = f::mul(a, u256 { high: 0, low: b.low }, FIELD); - let scl = f::scl(a, b.low, FIELD_NZ); + let scl_mul = f::mul(a, u256 { high: 0, low: b.low }, PRIME); + let scl = f::scl(a, b.low, PRIME_NZ); assert(scl == scl_mul, 'incorrect square'); assert( From dd49e7e5e84d102a725ce11c238ec736e3df14ec Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 3 Jul 2024 13:58:51 +0530 Subject: [PATCH 09/97] fix workspace scripts --- Scarb.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 7bb9f7b..2228b66 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -15,16 +15,16 @@ version.workspace = true # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [scripts] -new = "scarb new --no-vcs packages/$1" +new = "scarb new --no-vcs" addchain_gen_t = "addchain gen -tmpl addchain/tpl addchain/t" contracts = "scarb build -p bn_contracts" # Declares class for the contract ktn_declare = "starkli declare target/dev/bn_contracts_BN_Pairing.contract_class.json --account katana --rpc=http://localhost:5050" # Deploys the contract for input classhash -ktn_deploy = "starkli deploy $1 --account katana --rpc=http://localhost:5050" +ktn_deploy = "starkli deploy --account katana --rpc=http://localhost:5050" # Invokes final_exponentiation_bench on input contract address -ktn_expo = "starkli invoke $1 final_exponentiation_bench --account katana --rpc=http://localhost:5050" +ktn_expo = "starkli invoke final_exponentiation_bench --account katana --rpc=http://localhost:5050" # Invokes miller_bench on input contract address -ktn_miller = "starkli invoke $1 miller_bench --account katana --rpc=http://localhost:5050" +ktn_miller = "starkli invoke miller_bench --account katana --rpc=http://localhost:5050" # Invokes pairing_bench on input contract address -ktn_pair = "starkli invoke $1 pairing_bench --account katana --rpc=http://localhost:5050" +ktn_pair = "starkli invoke pairing_bench --account katana --rpc=http://localhost:5050" From 79c72970fadc5c1372a527b567920eb9532cd46f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 3 Jul 2024 19:01:22 +0530 Subject: [PATCH 10/97] refactor: fq types, common fq ops --- packages/fq_types/src/bn254.cairo | 38 ------------------------ packages/fq_types/src/common.cairo | 45 ++++++++++++++++++++++++++++ packages/fq_types/src/lib.cairo | 47 ++++++++++++++++++++++-------- 3 files changed, 80 insertions(+), 50 deletions(-) delete mode 100644 packages/fq_types/src/bn254.cairo create mode 100644 packages/fq_types/src/common.cairo diff --git a/packages/fq_types/src/bn254.cairo b/packages/fq_types/src/bn254.cairo deleted file mode 100644 index 25f9456..0000000 --- a/packages/fq_types/src/bn254.cairo +++ /dev/null @@ -1,38 +0,0 @@ -use super::{Fq2, Fq6}; - -#[derive(Copy, Drop, Serde)] -struct Fq { - c0: u256, -} - -// Sparse Fq12 element containing only c3 and c4 Fq2 (c0 is 1) -// Equivalent to, -// Fq12{ -// c0: Fq6{c0: 1, c1: 0, c2: 0}, -// c1: Fq6{c0: c3, c1: c4, c2: 0}, -// } -#[derive(Copy, Drop, Serde)] -struct F12S034 { - pub c3: Fq, - pub c4: Fq, -} - -// Sparse Fq6 element containing c0 and c1 Fq2 -type F6S01 = Fq2>; - -// Sparse Fq12 element containing c0, c1, c2, c3 and c4 Fq2 -#[derive(Copy, Drop, Serde)] -struct F12S01234 { - pub c0: Fq6, - pub c1: F6S01, -} - -type Fq12Direct = (Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq, Fq); -type F12S01234Direct = ((Fq, Fq, Fq, Fq, Fq), (Fq, Fq, Fq, Fq, Fq)); - -struct F12S034Direct { - c1: Fq, - c3: Fq, - c7: Fq, - c9: Fq, -} diff --git a/packages/fq_types/src/common.cairo b/packages/fq_types/src/common.cairo new file mode 100644 index 0000000..a5d8fba --- /dev/null +++ b/packages/fq_types/src/common.cairo @@ -0,0 +1,45 @@ +use super::{Fq2, Fq3, FieldCommonOps, FieldOps, FieldOpsUnreduced}; + +pub impl Fq2CommonOps, +Drop> of FieldCommonOps> { + #[inline(always)] + fn add(self: Fq2, rhs: Fq2) -> Fq2 { + Fq2 { c0: self.c0.add(rhs.c0), c1: self.c1.add(rhs.c1), } + } + + #[inline(always)] + fn sub(self: Fq2, rhs: Fq2) -> Fq2 { + Fq2 { c0: self.c0.sub(rhs.c0), c1: self.c1.sub(rhs.c1), } + } + + #[inline(always)] + fn neg(self: Fq2) -> Fq2 { + Fq2 { c0: self.c0.neg(), c1: self.c1.neg(), } + } + + #[inline(always)] + fn eq(self: @Fq2, rhs: @Fq2) -> bool { + self.c0.eq(rhs.c0) && self.c1.eq(rhs.c1) + } +} + +pub impl Fq3CommonOps, +Drop> of FieldCommonOps> { + #[inline(always)] + fn add(self: Fq3, rhs: Fq3) -> Fq3 { + Fq3 { c0: self.c0.add(rhs.c0), c1: self.c1.add(rhs.c1), c2: self.c2.add(rhs.c2), } + } + + #[inline(always)] + fn sub(self: Fq3, rhs: Fq3) -> Fq3 { + Fq3 { c0: self.c0.sub(rhs.c0), c1: self.c1.sub(rhs.c1), c2: self.c2.sub(rhs.c2), } + } + + #[inline(always)] + fn neg(self: Fq3) -> Fq3 { + Fq3 { c0: self.c0.neg(), c1: self.c1.neg(), c2: self.c2.neg(), } + } + + #[inline(always)] + fn eq(self: @Fq3, rhs: @Fq3) -> bool { + self.c0.eq(rhs.c0) && self.c1.eq(rhs.c1) && self.c2.eq(rhs.c2) + } +} diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index acbd623..0b0c1cf 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -1,3 +1,5 @@ +pub mod common; + #[derive(Copy, Drop, Serde)] pub struct Fq2 { pub c0: T, @@ -11,29 +13,50 @@ pub struct Fq3 { pub c2: T, } -type Fq6 = Fq3>; -type Fq12 = Fq2>>; +// Sparse Fq12 element containing only c3 and c4 Fq2 (c0 is 1) +// Equivalent to, +// Fq12{ +// c0: Fq6{c0: 1, c1: 0, c2: 0}, +// c1: Fq6{c0: c3, c1: c4, c2: 0}, +// } +#[derive(Copy, Drop, Serde)] +struct F12S034 { + pub c3: T, + pub c4: T, +} + +// Sparse Fq12 element containing c0, c1, c2, c3 and c4 Fq2 +#[derive(Copy, Drop, Serde)] +struct F12S01234 { + pub c0: T, + pub c1: T, + pub c2: T, + pub c3: T, + pub c4: T, +} -trait FieldOps { +pub trait FieldCommonOps { fn add(self: TFq, rhs: TFq) -> TFq; fn sub(self: TFq, rhs: TFq) -> TFq; + // fn scl(self: TFq, rhs: TFqChildren) -> TFq; + fn neg(self: TFq) -> TFq; + fn eq(self: @TFq, rhs: @TFq) -> bool; +} + +pub trait FieldOps { + fn scl(self: TFq, rhs: TFqChildren) -> TFq; fn mul(self: TFq, rhs: TFq) -> TFq; fn div(self: TFq, rhs: TFq) -> TFq; fn sqr(self: TFq) -> TFq; - fn neg(self: TFq) -> TFq; - fn eq(lhs: @TFq, rhs: @TFq) -> bool; fn inv(self: TFq, field_nz: NonZero) -> TFq; -} - -trait FieldOpsUnreduced { - fn u_add(self: TFq, rhs: TFq) -> TFq; - fn u_sub(self: TFq, rhs: TFq) -> TFq; fn u_mul(self: TFq, rhs: TFq) -> TFqU512; fn u_sqr(self: TFq) -> TFqU512; fn u512_add_fq(self: TFqU512, rhs: TFq) -> TFqU512; fn u512_sub_fq(self: TFqU512, rhs: TFq) -> TFqU512; fn to_fq(self: TFqU512, field_nz: NonZero) -> TFq; - fn fix_mod(self: TFq) -> TFq; } -mod bn254; +type Fq12Direct = (T, T, T, T, T, T, T, T, T, T, T, T); +type F12S01234Direct = ((T, T, T, T, T), (T, T, T, T, T)); + +pub use common::{Fq2CommonOps, Fq3CommonOps}; From 897fbc6b67edc6df658f133be63eb1fadbadad2f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 4 Jul 2024 01:28:20 +0530 Subject: [PATCH 11/97] fq types tweak --- packages/fq_types/src/lib.cairo | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index 0b0c1cf..f91e820 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -43,12 +43,15 @@ pub trait FieldCommonOps { fn eq(self: @TFq, rhs: @TFq) -> bool; } -pub trait FieldOps { - fn scl(self: TFq, rhs: TFqChildren) -> TFq; +pub trait FieldOps { fn mul(self: TFq, rhs: TFq) -> TFq; fn div(self: TFq, rhs: TFq) -> TFq; fn sqr(self: TFq) -> TFq; fn inv(self: TFq, field_nz: NonZero) -> TFq; +} + +pub trait FieldOpsExtended { + fn scl(self: TFq, rhs: TFqChildren) -> TFq; fn u_mul(self: TFq, rhs: TFq) -> TFqU512; fn u_sqr(self: TFq) -> TFqU512; fn u512_add_fq(self: TFqU512, rhs: TFq) -> TFqU512; From 80329135c5f5212fd563fe1565af941dff3e37a8 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 4 Jul 2024 01:28:30 +0530 Subject: [PATCH 12/97] bn groups --- packages/bn_groups/Scarb.toml | 8 +++ packages/bn_groups/src/lib.cairo | 114 +++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 packages/bn_groups/Scarb.toml create mode 100644 packages/bn_groups/src/lib.cairo diff --git a/packages/bn_groups/Scarb.toml b/packages/bn_groups/Scarb.toml new file mode 100644 index 0000000..186e353 --- /dev/null +++ b/packages/bn_groups/Scarb.toml @@ -0,0 +1,8 @@ +[package] +name = "bn_groups" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] diff --git a/packages/bn_groups/src/lib.cairo b/packages/bn_groups/src/lib.cairo new file mode 100644 index 0000000..d96af70 --- /dev/null +++ b/packages/bn_groups/src/lib.cairo @@ -0,0 +1,114 @@ +use fq_types::{FieldCommonOps, FieldOps}; +use bn::fields::print::{FqPrintImpl, Fq2PrintImpl}; +use core::num::traits::One; + +#[derive(Copy, Drop, Serde)] +struct Affine { + x: T, + y: T +} + +trait ECOperations { + fn x_on_slope(self: @Affine, slope: TCoord, x2: TCoord) -> TCoord; + fn y_on_slope(self: @Affine, slope: TCoord, x: TCoord) -> TCoord; + fn pt_on_slope(self: @Affine, slope: TCoord, x2: TCoord) -> Affine; + fn chord(self: @Affine, rhs: Affine) -> TCoord; + fn add(self: @Affine, rhs: Affine) -> Affine; + fn tangent(self: @Affine) -> TCoord; + fn double(self: @Affine) -> Affine; + fn multiply(self: @Affine, multiplier: u256) -> Affine; + fn neg(self: @Affine) -> Affine; +} + +impl AffinePartialEq> of PartialEq> { + fn eq(lhs: @Affine, rhs: @Affine) -> bool { + lhs.x == rhs.x && lhs.y == rhs.y + } + fn ne(lhs: @Affine, rhs: @Affine) -> bool { + lhs.x == rhs.x && lhs.y == rhs.y + } +} + +impl AffineOps< + T, +FieldOps, +FieldCommonOps, +Copy, +Drop, +One> +> of ECOperations { + #[inline(always)] + fn x_on_slope(self: @Affine, slope: T, x2: T) -> T { + // x = λ^2 - x1 - x2 + slope.sqr().sub(*self.x).sub(x2) + } + + #[inline(always)] + fn y_on_slope(self: @Affine, slope: T, x: T) -> T { + // y = λ(x1 - x) - y1 + slope.mul((*self.x).sub(x)).sub(*self.y) + } + + fn pt_on_slope(self: @Affine, slope: T, x2: T) -> Affine { + let x = self.x_on_slope(slope, x2); + let y = self.y_on_slope(slope, x); + Affine { x, y } + } + + #[inline(always)] + fn chord(self: @Affine, rhs: Affine) -> T { + let Affine { x: x1, y: y1 } = *self; + let Affine { x: x2, y: y2 } = rhs; + // λ = (y2-y1) / (x2-x1) + y2.sub(y1).div(x2.sub(x1)) + } + + fn add(self: @Affine, rhs: Affine) -> Affine { + self.pt_on_slope(self.chord(rhs), rhs.x) + } + + fn tangent(self: @Affine) -> T { + let Affine { x, y } = *self; + + // λ = (3x^2 + a) / 2y + // But BN curve has a == 0 so that's one less addition + // λ = 3x^2 / 2y + let x_2 = x.sqr(); + (x_2.add(x_2).add(x_2)).div(y.add(y)) + } + + fn double(self: @Affine) -> Affine { + self.pt_on_slope(self.tangent(), *self.x) + } + + fn multiply(self: @Affine, mut multiplier: u256) -> Affine { + let nz2: NonZero = 2_u256.try_into().unwrap(); + let mut dbl_step = *self; + let mut result = One::>::one(); + let mut first_add_done = false; + + // TODO: optimise with u128 ops + // Replace u256 multiplier loop with 2x u128 loops + loop { + let (q, r) = DivRem::div_rem(multiplier, nz2); + + if r == 1 { + result = + if !first_add_done { + first_add_done = true; + // self is zero, return rhs + dbl_step + } else { + result.add(dbl_step) + } + } + + if q == 0 { + break; + } + dbl_step = dbl_step.double(); + multiplier = q; + }; + result + } + + #[inline(always)] + fn neg(self: @Affine) -> Affine { + Affine { x: *self.x, y: (*self.y).neg() } + } +} From 8604b591c2e58a2314c7b294dce5a8876188d7a4 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 4 Jul 2024 14:22:30 +0530 Subject: [PATCH 13/97] fq_types: fq2/3 op traits --- packages/fq_types/src/common.cairo | 220 ++++++++++++++++++++++++++--- packages/fq_types/src/lib.cairo | 50 ++++--- 2 files changed, 228 insertions(+), 42 deletions(-) diff --git a/packages/fq_types/src/common.cairo b/packages/fq_types/src/common.cairo index a5d8fba..a007d82 100644 --- a/packages/fq_types/src/common.cairo +++ b/packages/fq_types/src/common.cairo @@ -1,45 +1,227 @@ -use super::{Fq2, Fq3, FieldCommonOps, FieldOps, FieldOpsUnreduced}; +use super::{Fq2, Fq3, FieldOps, FieldUtils}; -pub impl Fq2CommonOps, +Drop> of FieldCommonOps> { +pub impl Fq2Ops< + TCurve, + TFq, + impl FqUtils: FieldUtils, + impl FqOps: FieldOps, + +Drop, + +Copy +> of FieldOps> { #[inline(always)] - fn add(self: Fq2, rhs: Fq2) -> Fq2 { - Fq2 { c0: self.c0.add(rhs.c0), c1: self.c1.add(rhs.c1), } + fn add(ref self: TCurve, lhs: Fq2, rhs: Fq2) -> Fq2 { + lhs.c0; + Fq2 { c0: FqOps::add(ref self, lhs.c0, rhs.c0), c1: FqOps::add(ref self, lhs.c1, rhs.c1), } } #[inline(always)] - fn sub(self: Fq2, rhs: Fq2) -> Fq2 { - Fq2 { c0: self.c0.sub(rhs.c0), c1: self.c1.sub(rhs.c1), } + fn sub(ref self: TCurve, lhs: Fq2, rhs: Fq2) -> Fq2 { + Fq2 { c0: FqOps::sub(ref self, lhs.c0, rhs.c0), c1: FqOps::sub(ref self, lhs.c1, rhs.c1), } } #[inline(always)] - fn neg(self: Fq2) -> Fq2 { - Fq2 { c0: self.c0.neg(), c1: self.c1.neg(), } + fn neg(ref self: TCurve, lhs: Fq2) -> Fq2 { + Fq2 { c0: FqOps::neg(ref self, lhs.c0,), c1: FqOps::neg(ref self, lhs.c1,), } } #[inline(always)] - fn eq(self: @Fq2, rhs: @Fq2) -> bool { - self.c0.eq(rhs.c0) && self.c1.eq(rhs.c1) + fn eq(self: @TCurve, lhs: @Fq2, rhs: @Fq2) -> bool { + self.eq(lhs.c0, rhs.c0) && self.eq(lhs.c1, rhs.c1) + } + + fn mul(ref self: TCurve, lhs: Fq2, rhs: Fq2) -> Fq2 { + // Karatsuba multiplication + let Fq2 { c0: a0, c1: a1 } = lhs; + let Fq2 { c0: b0, c1: b1 } = rhs; + let v0 = self.mul(a0, b0); + let v1 = self.mul(a1, b1); + // v0 + βv1 + let c0 = self.add(v0, self.mul_by_nonresidue(v1)); + // (a0 + a1) * (b0 + b1) - v0 - v1 + let t0 = self.add(a0, a1); // a0 + a1 + let t1 = self.add(b0, b1); // b0 + b1 + let t2 = self.mul(t0, t1); // (a0 + a1) * (b0 + b1) + let t3 = self.sub(t2, v0); // (a0 + a1) * (b0 + b1) - v0 + let c1 = self.sub(t3, v1); // (a0 + a1) * (b0 + b1) - v0 - v1 + Fq2 { c0, c1 } + } + + fn div(ref self: TCurve, lhs: Fq2, rhs: Fq2) -> Fq2 { + self.mul(lhs, self.inv(rhs)) + } + + fn sqr(ref self: TCurve, lhs: Fq2) -> Fq2 { + // Complex squaring + let Fq2 { c0: a0, c1: a1 } = lhs; + // v = a0 * a1; + let v = FqOps::mul(ref self, a0, a1); // a0 * a1 + + // (a0 + a1) * (a0 + βa1) - v - βv + let t0 = FqOps::add(ref self, a0, a1); // a0 + a1 + let a1_nr = self.mul_by_nonresidue(a1); // βa1 + let t1 = FqOps::add(ref self, a0, a1_nr); // a0 + βa1 + let t2 = FqOps::mul(ref self, t0, t1); // (a0 + a1) * (a0 + βa1) + let v_nr = self.mul_by_nonresidue(v); // βv + let c0 = FqOps::sub(ref self, t2, v_nr); // (a0 + a1) * (a0 + βa1) - v - βv + // c1 = v + v; + let c1 = FqOps::add(ref self, v, v); // 2v + Fq2 { c0, c1 } + } + + fn inv(ref self: TCurve, lhs: Fq2) -> Fq2 { + let Fq2 { c0, c1 } = lhs; + // let t = (c0.sqr() - (c1.sqr().mul_by_nonresidue())).inv(); + let t0 = self.sqr(c0); // c0.sqr() + let t1 = self.sqr(c1); // c1.sqr() + let t2 = self.mul_by_nonresidue(t1); // c1.sqr().mul_by_nonresidue() + let t3 = self.sub(t0, t2); // c0.sqr() - c1.sqr().mul_by_nonresidue() + let t = self.inv(t3); // (c0.sqr() - c1.sqr().mul_by_nonresidue()).inv() + + let new_c0 = self.mul(c0, t); // c0 * t + let neg_t = self.neg(t); // -t + let new_c1 = self.mul(c1, neg_t); // c1 * -t + Fq2 { c0: new_c0, c1: new_c1 } } } -pub impl Fq3CommonOps, +Drop> of FieldCommonOps> { +pub impl Fq3Ops< + TCurve, + TFq, + impl FqUtils: FieldUtils, + impl FqOps: FieldOps, + +Drop, + +Copy +> of FieldOps> { #[inline(always)] - fn add(self: Fq3, rhs: Fq3) -> Fq3 { - Fq3 { c0: self.c0.add(rhs.c0), c1: self.c1.add(rhs.c1), c2: self.c2.add(rhs.c2), } + fn add(ref self: TCurve, lhs: Fq3, rhs: Fq3) -> Fq3 { + Fq3 { + c0: FqOps::add(ref self, lhs.c0, rhs.c0), + c1: FqOps::add(ref self, lhs.c1, rhs.c1), + c2: FqOps::add(ref self, lhs.c2, rhs.c2), + } } #[inline(always)] - fn sub(self: Fq3, rhs: Fq3) -> Fq3 { - Fq3 { c0: self.c0.sub(rhs.c0), c1: self.c1.sub(rhs.c1), c2: self.c2.sub(rhs.c2), } + fn sub(ref self: TCurve, lhs: Fq3, rhs: Fq3) -> Fq3 { + Fq3 { + c0: FqOps::sub(ref self, lhs.c0, rhs.c0), + c1: FqOps::sub(ref self, lhs.c1, rhs.c1), + c2: FqOps::sub(ref self, lhs.c2, rhs.c2), + } } #[inline(always)] - fn neg(self: Fq3) -> Fq3 { - Fq3 { c0: self.c0.neg(), c1: self.c1.neg(), c2: self.c2.neg(), } + fn neg(ref self: TCurve, lhs: Fq3) -> Fq3 { + Fq3 { + c0: FqOps::neg(ref self, lhs.c0,), + c1: FqOps::neg(ref self, lhs.c1,), + c2: FqOps::neg(ref self, lhs.c2,), + } } #[inline(always)] - fn eq(self: @Fq3, rhs: @Fq3) -> bool { - self.c0.eq(rhs.c0) && self.c1.eq(rhs.c1) && self.c2.eq(rhs.c2) + fn eq(self: @TCurve, lhs: @Fq3, rhs: @Fq3) -> bool { + FqOps::eq(self, lhs.c0, rhs.c0) + && FqOps::eq(self, lhs.c1, rhs.c1) + && FqOps::eq(self, lhs.c2, rhs.c2) + } + fn mul(ref self: TCurve, lhs: Fq3, rhs: Fq3) -> Fq3 { // + let Fq3 { c0: a0, c1: a1, c2: a2 } = lhs; + let Fq3 { c0: b0, c1: b1, c2: b2 } = rhs; + + let v0 = FqOps::mul(ref self, a0, b0); // a0 * b0 + let v1 = FqOps::mul(ref self, a1, b1); // a1 * b1 + let v2 = FqOps::mul(ref self, a2, b2); // a2 * b2 + + let t0 = FqOps::add(ref self, a1, a2); // a1 + a2 + let t1 = FqOps::add(ref self, b1, b2); // b1 + b2 + let t2 = FqOps::mul(ref self, t0, t1); // (a1 + a2) * (b1 + b2) + let t3 = FqOps::sub(ref self, t2, v1); // (a1 + a2) * (b1 + b2) - v1 + let t4 = FqOps::sub(ref self, t3, v2); // (a1 + a2) * (b1 + b2) - v1 - v2 + let t5 = FqUtils::mul_by_nonresidue(ref self, t4); // ξ((a1 + a2) * (b1 + b2) - v1 - v2) + let c0 = FqOps::add(ref self, v0, t5); // v0 + ξ((a1 + a2) * (b1 + b2) - v1 - v2) + + let t6 = FqOps::add(ref self, a0, a1); // a0 + a1 + let t7 = FqOps::add(ref self, b0, b1); // b0 + b1 + let t8 = FqOps::mul(ref self, t6, t7); // (a0 + a1) * (b0 + b1) + let t9 = FqOps::sub(ref self, t8, v0); // (a0 + a1) * (b0 + b1) - v0 + let t10 = FqOps::sub(ref self, t9, v1); // (a0 + a1) * (b0 + b1) - v0 - v1 + let t11 = FqUtils::mul_by_nonresidue(ref self, v2); // ξv2 + let c1 = FqOps::add(ref self, t10, t11); // (a0 + a1) * (b0 + b1) - v0 - v1 + ξv2 + + let t12 = FqOps::add(ref self, a0, a2); // a0 + a2 + let t13 = FqOps::add(ref self, b0, b2); // b0 + b2 + let t14 = FqOps::mul(ref self, t12, t13); // (a0 + a2) * (b0 + b2) + let t15 = FqOps::sub(ref self, t14, v0); // (a0 + a2) * (b0 + b2) - v0 + let t16 = FqOps::add(ref self, t15, v1); // (a0 + a2) * (b0 + b2) - v0 + v1 + let c2 = FqOps::sub(ref self, t16, v2); // (a0 + a2) * (b0 + b2) - v0 + v1 - v2 + + Fq3 { c0, c1, c2 } + } + + fn div(ref self: TCurve, lhs: Fq3, rhs: Fq3) -> Fq3 { // + self.mul(lhs, self.inv(rhs)) + } + fn sqr(ref self: TCurve, lhs: Fq3) -> Fq3 { // + let Fq3 { c0, c1, c2 } = lhs; + + let s0 = FqOps::sqr(ref self, c0); // c0.sqr() + let ab = FqOps::mul(ref self, c0, c1); // c0 * c1 + let s1 = FqOps::add(ref self, ab, ab); // ab + ab + + let t0 = FqOps::add(ref self, c0, c2); // c0 + c2 + let t1 = FqOps::sub(ref self, t0, c1); // c0 + c2 - c1 + let s2 = FqOps::sqr(ref self, t1); // (c0 + c2 - c1).sqr() + + let bc = FqOps::mul(ref self, c1, c2); // c1 * c2 + + let s3 = FqOps::add(ref self, bc, bc); // bc + bc + + let s4 = FqOps::sqr(ref self, c2); // c2.sqr() + + let s3_nonresidue = FqUtils::mul_by_nonresidue(ref self, s3); // s3ξ + let new_c0 = FqOps::add(ref self, s0, s3_nonresidue); // s0 + s3ξ + + let s4_nonresidue = FqUtils::mul_by_nonresidue(ref self, s4); // s4ξ + let new_c1 = FqOps::add(ref self, s1, s4_nonresidue); // s1 + s4ξ + + let t2 = FqOps::add(ref self, s1, s2); // s1 + s2 + let t3 = FqOps::add(ref self, t2, s3); // s1 + s2 + s3 + let t4 = FqOps::sub(ref self, t3, s0); // s1 + s2 + s3 - s0 + let new_c2 = FqOps::sub(ref self, t4, s4); // s1 + s2 + s3 - s0 - s4 + + Fq3 { c0: new_c0, c1: new_c1, c2: new_c2 } + } + + fn inv(ref self: TCurve, lhs: Fq3) -> Fq3 { // + let Fq3 { c0, c1, c2 } = lhs; + + let c0_sq = FqOps::sqr(ref self, c0); // c0.sqr() + let c2_nr = FqUtils::mul_by_nonresidue(ref self, c2); // c2ξ + let c1_c2_nr = FqOps::mul(ref self, c1, c2_nr); // c1 * c2ξ + let v0 = FqOps::sub(ref self, c0_sq, c1_c2_nr); // c0.sqr() - c1 * c2ξ + + let c2_sq = FqOps::sqr(ref self, c2); // c2.sqr() + let c0_c1 = FqOps::mul(ref self, c0, c1); // c0 * c1 + let c2_sq_nr = FqUtils::mul_by_nonresidue(ref self, c2_sq); + let v1 = FqOps::sub(ref self, c2_sq_nr, c0_c1); // c2.sqr()ξ - c0 * c1 + + let c1_sq = FqOps::sqr(ref self, c1); // c1.sqr() + let c0_c2 = FqOps::mul(ref self, c0, c2); // c0 * c2 + let v2 = FqOps::sub(ref self, c1_sq, c0_c2); // c1.sqr() - c0 * c2 + + let t0 = FqOps::mul(ref self, c2, v1); // c2 * v1 + let t1 = FqOps::mul(ref self, c1, v2); // c1 * v2 + let t2 = FqOps::add(ref self, t0, t1); // c2 * v1 + c1 * v2 + let t3 = FqUtils::mul_by_nonresidue(ref self, t2); // (c2 * v1 + c1 * v2)ξ + let t4 = FqOps::mul(ref self, c0, v0); // c0 * v0 + let t5 = FqOps::add(ref self, t3, t4); // (c2 * v1 + c1 * v2)ξ + c0 * v0 + let t = FqOps::inv(ref self, t5); // ((c2 * v1 + c1 * v2)ξ + c0 * v0).inv() + + let new_c0 = FqOps::mul(ref self, t, v0); // t * v0 + let new_c1 = FqOps::mul(ref self, t, v1); // t * v1 + let new_c2 = FqOps::mul(ref self, t, v2); // t * v2 + + Fq3 { c0: new_c0, c1: new_c1, c2: new_c2 } } } diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index f91e820..69fc643 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -20,14 +20,14 @@ pub struct Fq3 { // c1: Fq6{c0: c3, c1: c4, c2: 0}, // } #[derive(Copy, Drop, Serde)] -struct F12S034 { +pub struct F12S034 { pub c3: T, pub c4: T, } // Sparse Fq12 element containing c0, c1, c2, c3 and c4 Fq2 #[derive(Copy, Drop, Serde)] -struct F12S01234 { +pub struct F12S01234 { pub c0: T, pub c1: T, pub c2: T, @@ -35,31 +35,35 @@ struct F12S01234 { pub c4: T, } -pub trait FieldCommonOps { - fn add(self: TFq, rhs: TFq) -> TFq; - fn sub(self: TFq, rhs: TFq) -> TFq; - // fn scl(self: TFq, rhs: TFqChildren) -> TFq; - fn neg(self: TFq) -> TFq; - fn eq(self: @TFq, rhs: @TFq) -> bool; +pub trait FieldOps { + fn add(ref self: TCurve, lhs: TFq, rhs: TFq) -> TFq; + fn sub(ref self: TCurve, lhs: TFq, rhs: TFq) -> TFq; + fn neg(ref self: TCurve, lhs: TFq) -> TFq; + fn eq(self: @TCurve, lhs: @TFq, rhs: @TFq) -> bool; + fn mul(ref self: TCurve, lhs: TFq, rhs: TFq) -> TFq; + fn div(ref self: TCurve, lhs: TFq, rhs: TFq) -> TFq; + fn sqr(ref self: TCurve, lhs: TFq) -> TFq; + fn inv(ref self: TCurve, lhs: TFq) -> TFq; } -pub trait FieldOps { - fn mul(self: TFq, rhs: TFq) -> TFq; - fn div(self: TFq, rhs: TFq) -> TFq; - fn sqr(self: TFq) -> TFq; - fn inv(self: TFq, field_nz: NonZero) -> TFq; +pub trait FieldUtils { + fn one(ref self: TCurve) -> TFq; + fn zero(ref self: TCurve) -> TFq; + fn conjugate(ref self: TCurve, el: TFq) -> TFq; + fn mul_by_nonresidue(ref self: TCurve, el: TFq,) -> TFq; + fn frobenius_map(ref self: TCurve, el: TFq, power: usize) -> TFq; } -pub trait FieldOpsExtended { - fn scl(self: TFq, rhs: TFqChildren) -> TFq; - fn u_mul(self: TFq, rhs: TFq) -> TFqU512; - fn u_sqr(self: TFq) -> TFqU512; - fn u512_add_fq(self: TFqU512, rhs: TFq) -> TFqU512; - fn u512_sub_fq(self: TFqU512, rhs: TFq) -> TFqU512; - fn to_fq(self: TFqU512, field_nz: NonZero) -> TFq; +pub trait FieldOpsExtended { + fn scl(ref self: TCurve, lhs: TFq, rhs: TFqChildren) -> TFq; + fn u_mul(ref self: TCurve, lhs: TFq, rhs: TFq) -> TFqU512; + fn u_sqr(ref self: TCurve, lhs: TFq) -> TFqU512; + fn u512_add_fq(ref self: TCurve, lhs: TFqU512, rhs: TFq) -> TFqU512; + fn u512_sub_fq(ref self: TCurve, lhs: TFqU512, rhs: TFq) -> TFqU512; + fn to_fq(ref self: TCurve, lhs: TFqU512) -> TFq; } -type Fq12Direct = (T, T, T, T, T, T, T, T, T, T, T, T); -type F12S01234Direct = ((T, T, T, T, T), (T, T, T, T, T)); +pub type Fq12Direct = (T, T, T, T, T, T, T, T, T, T, T, T); +pub type F12S01234Direct = ((T, T, T, T, T), (T, T, T, T, T)); -pub use common::{Fq2CommonOps, Fq3CommonOps}; +pub use common::{Fq2Ops, Fq3Ops}; From 1e17a86a920a0a32cb3608073b5a149d3759c4d5 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 4 Jul 2024 18:43:23 +0530 Subject: [PATCH 14/97] fast mod: pub use for shortcuts --- packages/fast_mod/src/lib.cairo | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/fast_mod/src/lib.cairo b/packages/fast_mod/src/lib.cairo index fefa1ed..c2d336a 100644 --- a/packages/fast_mod/src/lib.cairo +++ b/packages/fast_mod/src/lib.cairo @@ -1,36 +1,36 @@ // These mod functions are heavily optimised for < 255 bit numbers // and may break for full 256 bit numbers -use core::integer::u512; +pub use core::integer::u512; // util functions -mod utils; -use utils::{u256_overflow_add, u256_overflow_sub}; -use utils::{Tuple2Add, Tuple2Sub, Tuple3Add, Tuple3Sub, u512Display}; +pub mod utils; +pub use utils::{u256_overflow_add, u256_overflow_sub}; +pub use utils::{Tuple2Add, Tuple2Sub, Tuple3Add, Tuple3Sub, u512Display}; // endregion util functions // u512_ops -mod u512_ops; +pub mod u512_ops; -use u512_ops::{u512_add, u512_add_overflow, u512_sub, u512_sub_overflow,}; -use u512_ops::{u512_high_add, u512_high_sub, u512_reduce, u512_add_u256, u512_sub_u256}; +pub use u512_ops::{u512_add, u512_add_overflow, u512_sub, u512_sub_overflow,}; +pub use u512_ops::{u512_high_add, u512_high_sub, u512_reduce, u512_add_u256, u512_sub_u256}; // endregion u512_ops // region add/sub operation -mod add_sub; +pub mod add_sub; -use add_sub::{neg, add, add_nz, add_u, sub, sub_u}; +pub use add_sub::{neg, add, add_nz, add_u, sub, sub_u}; // endregion add/sub operation // region mul operations -mod mul_scale_sqr; +pub mod mul_scale_sqr; -use mul_scale_sqr::{scl, scl_nz, scl_u, mul, mul_nz, mul_u, sqr, sqr_nz, sqr_u, u512_scl}; +pub use mul_scale_sqr::{scl, scl_nz, scl_u, mul, mul_nz, mul_u, sqr, sqr_nz, sqr_u, u512_scl}; // endregion mul operations // region div/inv operations -mod div_inv; -use div_inv::{inv, div, div_nz, div_u}; +pub mod div_inv; +pub use div_inv::{inv, div, div_nz, div_u}; // endregion div/inv operations #[inline(always)] @@ -40,5 +40,5 @@ pub fn reduce(lhs: u256, modulo: NonZero) -> u256 { } #[cfg(test)] -mod tests; +pub mod tests; From 2abfef801d38adf945f95a32d3e49bbafa911727 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 4 Jul 2024 18:44:09 +0530 Subject: [PATCH 15/97] bn_groups: stateful ec operations --- packages/bn_groups/src/lib.cairo | 45 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/packages/bn_groups/src/lib.cairo b/packages/bn_groups/src/lib.cairo index d96af70..195a4d6 100644 --- a/packages/bn_groups/src/lib.cairo +++ b/packages/bn_groups/src/lib.cairo @@ -1,4 +1,4 @@ -use fq_types::{FieldCommonOps, FieldOps}; +use fq_types::{FieldOps}; use bn::fields::print::{FqPrintImpl, Fq2PrintImpl}; use core::num::traits::One; @@ -8,16 +8,16 @@ struct Affine { y: T } -trait ECOperations { - fn x_on_slope(self: @Affine, slope: TCoord, x2: TCoord) -> TCoord; - fn y_on_slope(self: @Affine, slope: TCoord, x: TCoord) -> TCoord; - fn pt_on_slope(self: @Affine, slope: TCoord, x2: TCoord) -> Affine; - fn chord(self: @Affine, rhs: Affine) -> TCoord; - fn add(self: @Affine, rhs: Affine) -> Affine; - fn tangent(self: @Affine) -> TCoord; - fn double(self: @Affine) -> Affine; - fn multiply(self: @Affine, multiplier: u256) -> Affine; - fn neg(self: @Affine) -> Affine; +trait ECOperations { + fn x_on_slope(ref self: TCurve, pt: @Affine, slope: TCoord, x2: TCoord) -> TCoord; + fn y_on_slope(ref self: TCurve, pt: @Affine, slope: TCoord, x: TCoord) -> TCoord; + fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: TCoord, x2: TCoord) -> Affine; + fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> TCoord; + fn add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine; + fn tangent(ref self: TCurve, pt: @Affine) -> TCoord; + fn double(ref self: TCurve, pt: @Affine) -> Affine; + fn multiply(ref self: TCurve, pt: @Affine, multiplier: u256) -> Affine; + fn neg(ref self: TCurve, pt: @Affine) -> Affine; } impl AffinePartialEq> of PartialEq> { @@ -30,40 +30,41 @@ impl AffinePartialEq> of PartialEq> { } impl AffineOps< - T, +FieldOps, +FieldCommonOps, +Copy, +Drop, +One> -> of ECOperations { + T, TCurve, +FieldOps, +Copy, +Drop, +One> +> of ECOperations { #[inline(always)] - fn x_on_slope(self: @Affine, slope: T, x2: T) -> T { + fn x_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> T { // x = λ^2 - x1 - x2 slope.sqr().sub(*self.x).sub(x2) + self.sub(self.sub(self.sqr(slope), pt.x), x2) } #[inline(always)] - fn y_on_slope(self: @Affine, slope: T, x: T) -> T { + fn y_on_slope(ref self: TCurve, pt: @Affine, slope: T, x: T) -> T { // y = λ(x1 - x) - y1 slope.mul((*self.x).sub(x)).sub(*self.y) } - fn pt_on_slope(self: @Affine, slope: T, x2: T) -> Affine { let x = self.x_on_slope(slope, x2); let y = self.y_on_slope(slope, x); + fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> Affine { Affine { x, y } } #[inline(always)] - fn chord(self: @Affine, rhs: Affine) -> T { let Affine { x: x1, y: y1 } = *self; + fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> T { let Affine { x: x2, y: y2 } = rhs; // λ = (y2-y1) / (x2-x1) y2.sub(y1).div(x2.sub(x1)) } - fn add(self: @Affine, rhs: Affine) -> Affine { self.pt_on_slope(self.chord(rhs), rhs.x) + fn add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine { } - fn tangent(self: @Affine) -> T { let Affine { x, y } = *self; + fn tangent(ref self: TCurve, pt: @Affine) -> T { // λ = (3x^2 + a) / 2y // But BN curve has a == 0 so that's one less addition @@ -72,11 +73,11 @@ impl AffineOps< (x_2.add(x_2).add(x_2)).div(y.add(y)) } - fn double(self: @Affine) -> Affine { self.pt_on_slope(self.tangent(), *self.x) + fn double(ref self: TCurve, pt: @Affine) -> Affine { } - fn multiply(self: @Affine, mut multiplier: u256) -> Affine { + fn multiply(ref self: TCurve, pt: @Affine, mut multiplier: u256) -> Affine { let nz2: NonZero = 2_u256.try_into().unwrap(); let mut dbl_step = *self; let mut result = One::>::one(); @@ -108,7 +109,7 @@ impl AffineOps< } #[inline(always)] - fn neg(self: @Affine) -> Affine { Affine { x: *self.x, y: (*self.y).neg() } + fn neg(ref self: TCurve, pt: @Affine) -> Affine { } } From 51f080412a0447ed1a424b5acb0188d7dda2fea2 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 4 Jul 2024 23:30:27 +0530 Subject: [PATCH 16/97] bn_groups: ec operations --- packages/bn_groups/Scarb.toml | 1 + packages/bn_groups/src/lib.cairo | 69 +++++++++++++++--------------- packages/fq_types/src/common.cairo | 2 + 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/packages/bn_groups/Scarb.toml b/packages/bn_groups/Scarb.toml index 186e353..c63c171 100644 --- a/packages/bn_groups/Scarb.toml +++ b/packages/bn_groups/Scarb.toml @@ -6,3 +6,4 @@ edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] +fq_types = { path = "../fq_types" } \ No newline at end of file diff --git a/packages/bn_groups/src/lib.cairo b/packages/bn_groups/src/lib.cairo index 195a4d6..f2aad75 100644 --- a/packages/bn_groups/src/lib.cairo +++ b/packages/bn_groups/src/lib.cairo @@ -1,5 +1,4 @@ use fq_types::{FieldOps}; -use bn::fields::print::{FqPrintImpl, Fq2PrintImpl}; use core::num::traits::One; #[derive(Copy, Drop, Serde)] @@ -8,16 +7,16 @@ struct Affine { y: T } -trait ECOperations { - fn x_on_slope(ref self: TCurve, pt: @Affine, slope: TCoord, x2: TCoord) -> TCoord; - fn y_on_slope(ref self: TCurve, pt: @Affine, slope: TCoord, x: TCoord) -> TCoord; - fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: TCoord, x2: TCoord) -> Affine; - fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> TCoord; - fn add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine; - fn tangent(ref self: TCurve, pt: @Affine) -> TCoord; - fn double(ref self: TCurve, pt: @Affine) -> Affine; - fn multiply(ref self: TCurve, pt: @Affine, multiplier: u256) -> Affine; - fn neg(ref self: TCurve, pt: @Affine) -> Affine; +trait ECOperations { + fn x_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> TFq; + fn y_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x: TFq) -> TFq; + fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> Affine; + fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> TFq; + fn tangent(ref self: TCurve, pt: @Affine) -> TFq; + fn pt_add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine; + fn pt_dbl(ref self: TCurve, pt: @Affine) -> Affine; + fn pt_mul(ref self: TCurve, pt: @Affine, multiplier: u256) -> Affine; + fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine; } impl AffinePartialEq> of PartialEq> { @@ -30,56 +29,56 @@ impl AffinePartialEq> of PartialEq> { } impl AffineOps< - T, TCurve, +FieldOps, +Copy, +Drop, +One> + T, TCurve, +FieldOps, +Copy, +Drop, +Drop, +One> > of ECOperations { #[inline(always)] fn x_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> T { // x = λ^2 - x1 - x2 - slope.sqr().sub(*self.x).sub(x2) - self.sub(self.sub(self.sqr(slope), pt.x), x2) + self.sub(self.sub(self.sqr(slope), *pt.x), x2) } #[inline(always)] fn y_on_slope(ref self: TCurve, pt: @Affine, slope: T, x: T) -> T { // y = λ(x1 - x) - y1 - slope.mul((*self.x).sub(x)).sub(*self.y) + self.sub(self.mul(slope, self.sub(*pt.x, x)), *pt.y) } - let x = self.x_on_slope(slope, x2); - let y = self.y_on_slope(slope, x); fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> Affine { + let x = self.x_on_slope(pt, slope, x2); + let y = self.y_on_slope(pt, slope, x); Affine { x, y } } #[inline(always)] - let Affine { x: x1, y: y1 } = *self; fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> T { + let Affine { x: x1, y: y1 } = pt; let Affine { x: x2, y: y2 } = rhs; // λ = (y2-y1) / (x2-x1) - y2.sub(y1).div(x2.sub(x1)) + self.div(self.sub(y2, *y1), self.sub(x2, *x1)) } - - self.pt_on_slope(self.chord(rhs), rhs.x) - fn add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine { - } - - let Affine { x, y } = *self; fn tangent(ref self: TCurve, pt: @Affine) -> T { + let Affine { x, y } = pt; // λ = (3x^2 + a) / 2y // But BN curve has a == 0 so that's one less addition // λ = 3x^2 / 2y - let x_2 = x.sqr(); - (x_2.add(x_2).add(x_2)).div(y.add(y)) + let x_2 = self.sqr(*x); + self.div(self.add(self.add(x_2, x_2), x_2), self.add(*y, *y)) } - self.pt_on_slope(self.tangent(), *self.x) - fn double(ref self: TCurve, pt: @Affine) -> Affine { + #[inline(always)] + fn pt_add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine { + self.pt_on_slope(pt, self.chord(pt, rhs), rhs.x) + } + + + fn pt_dbl(ref self: TCurve, pt: @Affine) -> Affine { + self.pt_on_slope(pt, self.tangent(pt), *pt.x) } - fn multiply(ref self: TCurve, pt: @Affine, mut multiplier: u256) -> Affine { + fn pt_mul(ref self: TCurve, pt: @Affine, mut multiplier: u256) -> Affine { let nz2: NonZero = 2_u256.try_into().unwrap(); - let mut dbl_step = *self; + let mut dbl_step = *pt; let mut result = One::>::one(); let mut first_add_done = false; @@ -95,21 +94,21 @@ impl AffineOps< // self is zero, return rhs dbl_step } else { - result.add(dbl_step) + self.pt_add(@result, dbl_step) } } if q == 0 { break; } - dbl_step = dbl_step.double(); + dbl_step = self.pt_dbl(@dbl_step); multiplier = q; }; result } #[inline(always)] - Affine { x: *self.x, y: (*self.y).neg() } - fn neg(ref self: TCurve, pt: @Affine) -> Affine { + fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine { + Affine { x: *pt.x, y: self.neg(*pt.y) } } } diff --git a/packages/fq_types/src/common.cairo b/packages/fq_types/src/common.cairo index a007d82..93c8ce7 100644 --- a/packages/fq_types/src/common.cairo +++ b/packages/fq_types/src/common.cairo @@ -125,6 +125,7 @@ pub impl Fq3Ops< && FqOps::eq(self, lhs.c1, rhs.c1) && FqOps::eq(self, lhs.c2, rhs.c2) } + fn mul(ref self: TCurve, lhs: Fq3, rhs: Fq3) -> Fq3 { // let Fq3 { c0: a0, c1: a1, c2: a2 } = lhs; let Fq3 { c0: b0, c1: b1, c2: b2 } = rhs; @@ -162,6 +163,7 @@ pub impl Fq3Ops< fn div(ref self: TCurve, lhs: Fq3, rhs: Fq3) -> Fq3 { // self.mul(lhs, self.inv(rhs)) } + fn sqr(ref self: TCurve, lhs: Fq3) -> Fq3 { // let Fq3 { c0, c1, c2 } = lhs; From 7cf8b60d26ce01c3921dc8b7801e79ffcc89b49b Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Mon, 8 Jul 2024 22:49:51 +0530 Subject: [PATCH 17/97] bn_groups: refactor --- packages/bn_groups/src/bn.cairo | 85 +++++++++++++++++++++++ packages/bn_groups/src/lib.cairo | 111 ++++++------------------------- 2 files changed, 106 insertions(+), 90 deletions(-) create mode 100644 packages/bn_groups/src/bn.cairo diff --git a/packages/bn_groups/src/bn.cairo b/packages/bn_groups/src/bn.cairo new file mode 100644 index 0000000..144b535 --- /dev/null +++ b/packages/bn_groups/src/bn.cairo @@ -0,0 +1,85 @@ +use super::{Affine, ECOperations, FieldOps, One}; +pub impl AffineOpsBn< + T, TCurve, +FieldOps, +Copy, +Drop, +Drop, +One> +> of ECOperations { + #[inline(always)] + fn x_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> T { + // x = λ^2 - x1 - x2 + self.sub(self.sub(self.sqr(slope), *pt.x), x2) + } + + #[inline(always)] + fn y_on_slope(ref self: TCurve, pt: @Affine, slope: T, x: T) -> T { + // y = λ(x1 - x) - y1 + self.sub(self.mul(slope, self.sub(*pt.x, x)), *pt.y) + } + + fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> Affine { + let x = self.x_on_slope(pt, slope, x2); + let y = self.y_on_slope(pt, slope, x); + Affine { x, y } + } + + #[inline(always)] + fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> T { + let Affine { x: x1, y: y1 } = pt; + let Affine { x: x2, y: y2 } = rhs; + // λ = (y2-y1) / (x2-x1) + self.div(self.sub(y2, *y1), self.sub(x2, *x1)) + } + fn tangent(ref self: TCurve, pt: @Affine) -> T { + let Affine { x, y } = pt; + + // λ = (3x^2 + a) / 2y + // But BN curve has a == 0 so that's one less addition + // λ = 3x^2 / 2y + let x_2 = self.sqr(*x); + self.div(self.add(self.add(x_2, x_2), x_2), self.add(*y, *y)) + } + + #[inline(always)] + fn pt_add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine { + self.pt_on_slope(pt, self.chord(pt, rhs), rhs.x) + } + + + fn pt_dbl(ref self: TCurve, pt: @Affine) -> Affine { + self.pt_on_slope(pt, self.tangent(pt), *pt.x) + } + + fn pt_mul(ref self: TCurve, pt: @Affine, mut multiplier: u256) -> Affine { + let nz2: NonZero = 2_u256.try_into().unwrap(); + let mut dbl_step = *pt; + let mut result = One::>::one(); + let mut first_add_done = false; + + // TODO: optimise with u128 ops + // Replace u256 multiplier loop with 2x u128 loops + loop { + let (q, r) = DivRem::div_rem(multiplier, nz2); + + if r == 1 { + result = + if !first_add_done { + first_add_done = true; + // self is zero, return rhs + dbl_step + } else { + self.pt_add(@result, dbl_step) + } + } + + if q == 0 { + break; + } + dbl_step = self.pt_dbl(@dbl_step); + multiplier = q; + }; + result + } + + #[inline(always)] + fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine { + Affine { x: *pt.x, y: self.neg(*pt.y) } + } +} diff --git a/packages/bn_groups/src/lib.cairo b/packages/bn_groups/src/lib.cairo index f2aad75..f64e3bf 100644 --- a/packages/bn_groups/src/lib.cairo +++ b/packages/bn_groups/src/lib.cairo @@ -1,13 +1,29 @@ +pub mod bn; use fq_types::{FieldOps}; use core::num::traits::One; +pub use bn::AffineOpsBn; #[derive(Copy, Drop, Serde)] -struct Affine { - x: T, - y: T +pub struct Affine { + pub x: T, + pub y: T } -trait ECOperations { +#[derive(Copy, Drop)] +pub struct Groth16MillerG1 { // Points in G1 + pi_a: Affine, + pi_c: Affine, + k: Affine, +} + +#[derive(Copy, Drop)] +pub struct Groth16MillerG2 { // Points in + pi_b: Affine, + delta: Affine, + gamma: Affine, +} + +pub trait ECOperations { fn x_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> TFq; fn y_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x: TFq) -> TFq; fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> Affine; @@ -19,7 +35,7 @@ trait ECOperations { fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine; } -impl AffinePartialEq> of PartialEq> { +pub impl AffinePartialEq> of PartialEq> { fn eq(lhs: @Affine, rhs: @Affine) -> bool { lhs.x == rhs.x && lhs.y == rhs.y } @@ -27,88 +43,3 @@ impl AffinePartialEq> of PartialEq> { lhs.x == rhs.x && lhs.y == rhs.y } } - -impl AffineOps< - T, TCurve, +FieldOps, +Copy, +Drop, +Drop, +One> -> of ECOperations { - #[inline(always)] - fn x_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> T { - // x = λ^2 - x1 - x2 - self.sub(self.sub(self.sqr(slope), *pt.x), x2) - } - - #[inline(always)] - fn y_on_slope(ref self: TCurve, pt: @Affine, slope: T, x: T) -> T { - // y = λ(x1 - x) - y1 - self.sub(self.mul(slope, self.sub(*pt.x, x)), *pt.y) - } - - fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> Affine { - let x = self.x_on_slope(pt, slope, x2); - let y = self.y_on_slope(pt, slope, x); - Affine { x, y } - } - - #[inline(always)] - fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> T { - let Affine { x: x1, y: y1 } = pt; - let Affine { x: x2, y: y2 } = rhs; - // λ = (y2-y1) / (x2-x1) - self.div(self.sub(y2, *y1), self.sub(x2, *x1)) - } - fn tangent(ref self: TCurve, pt: @Affine) -> T { - let Affine { x, y } = pt; - - // λ = (3x^2 + a) / 2y - // But BN curve has a == 0 so that's one less addition - // λ = 3x^2 / 2y - let x_2 = self.sqr(*x); - self.div(self.add(self.add(x_2, x_2), x_2), self.add(*y, *y)) - } - - #[inline(always)] - fn pt_add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine { - self.pt_on_slope(pt, self.chord(pt, rhs), rhs.x) - } - - - fn pt_dbl(ref self: TCurve, pt: @Affine) -> Affine { - self.pt_on_slope(pt, self.tangent(pt), *pt.x) - } - - fn pt_mul(ref self: TCurve, pt: @Affine, mut multiplier: u256) -> Affine { - let nz2: NonZero = 2_u256.try_into().unwrap(); - let mut dbl_step = *pt; - let mut result = One::>::one(); - let mut first_add_done = false; - - // TODO: optimise with u128 ops - // Replace u256 multiplier loop with 2x u128 loops - loop { - let (q, r) = DivRem::div_rem(multiplier, nz2); - - if r == 1 { - result = - if !first_add_done { - first_add_done = true; - // self is zero, return rhs - dbl_step - } else { - self.pt_add(@result, dbl_step) - } - } - - if q == 0 { - break; - } - dbl_step = self.pt_dbl(@dbl_step); - multiplier = q; - }; - result - } - - #[inline(always)] - fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine { - Affine { x: *pt.x, y: self.neg(*pt.y) } - } -} From be3533591bc988e0132c976971bb24d8c5bfa51d Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Mon, 8 Jul 2024 22:51:05 +0530 Subject: [PATCH 18/97] bn_groups -> ec_groups --- packages/{bn_groups => ec_groups}/Scarb.toml | 2 +- packages/{bn_groups => ec_groups}/src/bn.cairo | 0 packages/{bn_groups => ec_groups}/src/lib.cairo | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename packages/{bn_groups => ec_groups}/Scarb.toml (91%) rename packages/{bn_groups => ec_groups}/src/bn.cairo (100%) rename packages/{bn_groups => ec_groups}/src/lib.cairo (100%) diff --git a/packages/bn_groups/Scarb.toml b/packages/ec_groups/Scarb.toml similarity index 91% rename from packages/bn_groups/Scarb.toml rename to packages/ec_groups/Scarb.toml index c63c171..d1b0d85 100644 --- a/packages/bn_groups/Scarb.toml +++ b/packages/ec_groups/Scarb.toml @@ -1,5 +1,5 @@ [package] -name = "bn_groups" +name = "ec_groups" version = "0.1.0" edition = "2023_11" diff --git a/packages/bn_groups/src/bn.cairo b/packages/ec_groups/src/bn.cairo similarity index 100% rename from packages/bn_groups/src/bn.cairo rename to packages/ec_groups/src/bn.cairo diff --git a/packages/bn_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo similarity index 100% rename from packages/bn_groups/src/lib.cairo rename to packages/ec_groups/src/lib.cairo From e15156e81be7d133116b6273bcced789462e3aa8 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Mon, 8 Jul 2024 23:10:53 +0530 Subject: [PATCH 19/97] bn ate loop refactor --- packages/bn_ate_loop/src/ate_loop.cairo | 175 +++++++++++++++++++++++ packages/bn_ate_loop/src/lib.cairo | 180 +----------------------- 2 files changed, 179 insertions(+), 176 deletions(-) create mode 100644 packages/bn_ate_loop/src/ate_loop.cairo diff --git a/packages/bn_ate_loop/src/ate_loop.cairo b/packages/bn_ate_loop/src/ate_loop.cairo new file mode 100644 index 0000000..f169db7 --- /dev/null +++ b/packages/bn_ate_loop/src/ate_loop.cairo @@ -0,0 +1,175 @@ +pub trait MillerRunner { + // Returns accumulator + fn accumulator(self: @TRunner) -> TAccumulator; + + // Square target group element + fn sqr_target(self: @TRunner, i: u32, ref acc: TAccumulator); + + // first and second step, O and N + fn bit_1st_2nd(self: @TRunner, i1: u32, i2: u32, ref acc: TAccumulator); + + // 0 bit + fn bit_o(self: @TRunner, i: u32, ref acc: TAccumulator); + + // 1 bit + fn bit_p(self: @TRunner, i: u32, ref acc: TAccumulator); + + // -1 bit + fn bit_n(self: @TRunner, i: u32, ref acc: TAccumulator); + + // last step + fn last(self: @TRunner, ref acc: TAccumulator); +} + +pub fn ate_miller_loop, +Drop>( + runner: TRunner +) -> TAccumulator { + core::gas::withdraw_gas().unwrap(); + core::internal::revoke_ap_tracking(); + + // Get accumulator from runner + let mut q_acc: TAccumulator = runner.accumulator(); + + _loop_inner_1_of_2(@runner, ref q_acc); + _loop_inner_2_of_2(@runner, ref q_acc); + q_acc +} + +pub fn _loop_inner_1_of_2>( + runner: @TRunner, ref q_acc: TAccumulator +) { + // ate_loop[64] = O and ate_loop[63] = N + runner.bit_1st_2nd(64, 63, ref q_acc); + runner.sqr_target(62, ref q_acc); + runner.bit_o(62, ref q_acc); // ate_loop[62] = O + runner.sqr_target(61, ref q_acc); + runner.bit_p(61, ref q_acc); // ate_loop[61] = P + runner.sqr_target(60, ref q_acc); + runner.bit_o(60, ref q_acc); // ate_loop[60] = O + runner.sqr_target(59, ref q_acc); + runner.bit_o(59, ref q_acc); // ate_loop[59] = O + runner.sqr_target(58, ref q_acc); + runner.bit_o(58, ref q_acc); // ate_loop[58] = O + runner.sqr_target(57, ref q_acc); + runner.bit_n(57, ref q_acc); // ate_loop[57] = N + runner.sqr_target(56, ref q_acc); + runner.bit_o(56, ref q_acc); // ate_loop[56] = O + runner.sqr_target(55, ref q_acc); + runner.bit_n(55, ref q_acc); // ate_loop[55] = N + runner.sqr_target(54, ref q_acc); + runner.bit_o(54, ref q_acc); // ate_loop[54] = O + runner.sqr_target(53, ref q_acc); + runner.bit_o(53, ref q_acc); // ate_loop[53] = O + runner.sqr_target(52, ref q_acc); + runner.bit_o(52, ref q_acc); // ate_loop[52] = O + runner.sqr_target(51, ref q_acc); + runner.bit_n(51, ref q_acc); // ate_loop[51] = N + runner.sqr_target(50, ref q_acc); + runner.bit_o(50, ref q_acc); // ate_loop[50] = O + runner.sqr_target(49, ref q_acc); + runner.bit_p(49, ref q_acc); // ate_loop[49] = P + runner.sqr_target(48, ref q_acc); + runner.bit_o(48, ref q_acc); // ate_loop[48] = O + runner.sqr_target(47, ref q_acc); + runner.bit_n(47, ref q_acc); // ate_loop[47] = N + runner.sqr_target(46, ref q_acc); + runner.bit_o(46, ref q_acc); // ate_loop[46] = O + runner.sqr_target(45, ref q_acc); + runner.bit_o(45, ref q_acc); // ate_loop[45] = O + runner.sqr_target(44, ref q_acc); + runner.bit_n(44, ref q_acc); // ate_loop[44] = N + runner.sqr_target(43, ref q_acc); + runner.bit_o(43, ref q_acc); // ate_loop[43] = O + runner.sqr_target(42, ref q_acc); + runner.bit_o(42, ref q_acc); // ate_loop[42] = O + runner.sqr_target(41, ref q_acc); + runner.bit_o(41, ref q_acc); // ate_loop[41] = O + runner.sqr_target(40, ref q_acc); + runner.bit_o(40, ref q_acc); // ate_loop[40] = O + runner.sqr_target(39, ref q_acc); + runner.bit_o(39, ref q_acc); // ate_loop[39] = O + runner.sqr_target(38, ref q_acc); + runner.bit_p(38, ref q_acc); // ate_loop[38] = P + runner.sqr_target(37, ref q_acc); + runner.bit_o(37, ref q_acc); // ate_loop[37] = O + runner.sqr_target(36, ref q_acc); + runner.bit_o(36, ref q_acc); // ate_loop[36] = O + runner.sqr_target(35, ref q_acc); + runner.bit_n(35, ref q_acc); // ate_loop[35] = N + runner.sqr_target(34, ref q_acc); + runner.bit_o(34, ref q_acc); // ate_loop[34] = O + runner.sqr_target(33, ref q_acc); + runner.bit_p(33, ref q_acc); // ate_loop[33] = P + runner.sqr_target(32, ref q_acc); + runner.bit_o(32, ref q_acc); // ate_loop[32] = O + runner.sqr_target(31, ref q_acc); + runner.bit_o(31, ref q_acc); // ate_loop[31] = O +} + +pub fn _loop_inner_2_of_2>( + runner: @TRunner, ref q_acc: TAccumulator +) { + runner.sqr_target(30, ref q_acc); + runner.bit_n(30, ref q_acc); // ate_loop[30] = N + runner.sqr_target(29, ref q_acc); + runner.bit_o(29, ref q_acc); // ate_loop[29] = O + runner.sqr_target(28, ref q_acc); + runner.bit_o(28, ref q_acc); // ate_loop[28] = O + runner.sqr_target(27, ref q_acc); + runner.bit_o(27, ref q_acc); // ate_loop[27] = O + runner.sqr_target(26, ref q_acc); + runner.bit_o(26, ref q_acc); // ate_loop[26] = O + runner.sqr_target(25, ref q_acc); + runner.bit_n(25, ref q_acc); // ate_loop[25] = N + runner.sqr_target(24, ref q_acc); + runner.bit_o(24, ref q_acc); // ate_loop[24] = O + runner.sqr_target(23, ref q_acc); + runner.bit_p(23, ref q_acc); // ate_loop[23] = P + runner.sqr_target(22, ref q_acc); + runner.bit_o(22, ref q_acc); // ate_loop[22] = O + runner.sqr_target(21, ref q_acc); + runner.bit_o(21, ref q_acc); // ate_loop[21] = O + runner.sqr_target(20, ref q_acc); + runner.bit_o(20, ref q_acc); // ate_loop[20] = O + runner.sqr_target(19, ref q_acc); + runner.bit_n(19, ref q_acc); // ate_loop[19] = N + runner.sqr_target(18, ref q_acc); + runner.bit_o(18, ref q_acc); // ate_loop[18] = O + runner.sqr_target(17, ref q_acc); + runner.bit_n(17, ref q_acc); // ate_loop[17] = N + runner.sqr_target(16, ref q_acc); + runner.bit_o(16, ref q_acc); // ate_loop[16] = O + runner.sqr_target(15, ref q_acc); + runner.bit_o(15, ref q_acc); // ate_loop[15] = O + runner.sqr_target(14, ref q_acc); + runner.bit_p(14, ref q_acc); // ate_loop[14] = P + runner.sqr_target(13, ref q_acc); + runner.bit_o(13, ref q_acc); // ate_loop[13] = O + runner.sqr_target(12, ref q_acc); + runner.bit_o(12, ref q_acc); // ate_loop[12] = O + runner.sqr_target(11, ref q_acc); + runner.bit_o(11, ref q_acc); // ate_loop[11] = O + runner.sqr_target(10, ref q_acc); + runner.bit_n(10, ref q_acc); // ate_loop[10] = N + runner.sqr_target(9, ref q_acc); + runner.bit_o(9, ref q_acc); // ate_loop[ 9] = O + runner.sqr_target(8, ref q_acc); + runner.bit_o(8, ref q_acc); // ate_loop[ 8] = O + runner.sqr_target(7, ref q_acc); + runner.bit_n(7, ref q_acc); // ate_loop[ 7] = N + runner.sqr_target(6, ref q_acc); + runner.bit_o(6, ref q_acc); // ate_loop[ 6] = O + runner.sqr_target(5, ref q_acc); + runner.bit_p(5, ref q_acc); // ate_loop[ 5] = P + runner.sqr_target(4, ref q_acc); + runner.bit_o(4, ref q_acc); // ate_loop[ 4] = O + runner.sqr_target(3, ref q_acc); + runner.bit_p(3, ref q_acc); // ate_loop[ 3] = P + runner.sqr_target(2, ref q_acc); + runner.bit_o(2, ref q_acc); // ate_loop[ 2] = O + runner.sqr_target(1, ref q_acc); + runner.bit_o(1, ref q_acc); // ate_loop[ 1] = O + runner.sqr_target(0, ref q_acc); + runner.bit_o(0, ref q_acc); // ate_loop[ 0] = O + runner.last(ref q_acc); +} diff --git a/packages/bn_ate_loop/src/lib.cairo b/packages/bn_ate_loop/src/lib.cairo index 9db0c8d..c7b118b 100644 --- a/packages/bn_ate_loop/src/lib.cairo +++ b/packages/bn_ate_loop/src/lib.cairo @@ -1,178 +1,6 @@ -#[cfg(test)] -mod test; - -pub trait MillerRunner { - // Returns accumulator - fn accumulator(self: @TRunner) -> TAccumulator; - - // Square target group element - fn sqr_target(self: @TRunner, i: u32, ref acc: TAccumulator); - - // first and second step, O and N - fn bit_1st_2nd(self: @TRunner, i1: u32, i2: u32, ref acc: TAccumulator); - - // 0 bit - fn bit_o(self: @TRunner, i: u32, ref acc: TAccumulator); - - // 1 bit - fn bit_p(self: @TRunner, i: u32, ref acc: TAccumulator); +pub mod ate_loop; - // -1 bit - fn bit_n(self: @TRunner, i: u32, ref acc: TAccumulator); +pub use ate_loop::{MillerRunner, ate_miller_loop, _loop_inner_1_of_2, _loop_inner_2_of_2}; - // last step - fn last(self: @TRunner, ref acc: TAccumulator); -} - -fn ate_miller_loop, +Drop>( - runner: TRunner -) -> TAccumulator { - core::gas::withdraw_gas().unwrap(); - core::internal::revoke_ap_tracking(); - - // Get accumulator from runner - let mut q_acc: TAccumulator = runner.accumulator(); - - ate_miller_loop_steps_first_half(@runner, ref q_acc); - ate_miller_loop_steps_second_half(@runner, ref q_acc); - q_acc -} - -fn ate_miller_loop_steps_first_half>( - runner: @TRunner, ref q_acc: TAccumulator -) { - // ate_loop[64] = O and ate_loop[63] = N - runner.bit_1st_2nd(64, 63, ref q_acc); - runner.sqr_target(62, ref q_acc); - runner.bit_o(62, ref q_acc); // ate_loop[62] = O - runner.sqr_target(61, ref q_acc); - runner.bit_p(61, ref q_acc); // ate_loop[61] = P - runner.sqr_target(60, ref q_acc); - runner.bit_o(60, ref q_acc); // ate_loop[60] = O - runner.sqr_target(59, ref q_acc); - runner.bit_o(59, ref q_acc); // ate_loop[59] = O - runner.sqr_target(58, ref q_acc); - runner.bit_o(58, ref q_acc); // ate_loop[58] = O - runner.sqr_target(57, ref q_acc); - runner.bit_n(57, ref q_acc); // ate_loop[57] = N - runner.sqr_target(56, ref q_acc); - runner.bit_o(56, ref q_acc); // ate_loop[56] = O - runner.sqr_target(55, ref q_acc); - runner.bit_n(55, ref q_acc); // ate_loop[55] = N - runner.sqr_target(54, ref q_acc); - runner.bit_o(54, ref q_acc); // ate_loop[54] = O - runner.sqr_target(53, ref q_acc); - runner.bit_o(53, ref q_acc); // ate_loop[53] = O - runner.sqr_target(52, ref q_acc); - runner.bit_o(52, ref q_acc); // ate_loop[52] = O - runner.sqr_target(51, ref q_acc); - runner.bit_n(51, ref q_acc); // ate_loop[51] = N - runner.sqr_target(50, ref q_acc); - runner.bit_o(50, ref q_acc); // ate_loop[50] = O - runner.sqr_target(49, ref q_acc); - runner.bit_p(49, ref q_acc); // ate_loop[49] = P - runner.sqr_target(48, ref q_acc); - runner.bit_o(48, ref q_acc); // ate_loop[48] = O - runner.sqr_target(47, ref q_acc); - runner.bit_n(47, ref q_acc); // ate_loop[47] = N - runner.sqr_target(46, ref q_acc); - runner.bit_o(46, ref q_acc); // ate_loop[46] = O - runner.sqr_target(45, ref q_acc); - runner.bit_o(45, ref q_acc); // ate_loop[45] = O - runner.sqr_target(44, ref q_acc); - runner.bit_n(44, ref q_acc); // ate_loop[44] = N - runner.sqr_target(43, ref q_acc); - runner.bit_o(43, ref q_acc); // ate_loop[43] = O - runner.sqr_target(42, ref q_acc); - runner.bit_o(42, ref q_acc); // ate_loop[42] = O - runner.sqr_target(41, ref q_acc); - runner.bit_o(41, ref q_acc); // ate_loop[41] = O - runner.sqr_target(40, ref q_acc); - runner.bit_o(40, ref q_acc); // ate_loop[40] = O - runner.sqr_target(39, ref q_acc); - runner.bit_o(39, ref q_acc); // ate_loop[39] = O - runner.sqr_target(38, ref q_acc); - runner.bit_p(38, ref q_acc); // ate_loop[38] = P - runner.sqr_target(37, ref q_acc); - runner.bit_o(37, ref q_acc); // ate_loop[37] = O - runner.sqr_target(36, ref q_acc); - runner.bit_o(36, ref q_acc); // ate_loop[36] = O - runner.sqr_target(35, ref q_acc); - runner.bit_n(35, ref q_acc); // ate_loop[35] = N - runner.sqr_target(34, ref q_acc); - runner.bit_o(34, ref q_acc); // ate_loop[34] = O - runner.sqr_target(33, ref q_acc); - runner.bit_p(33, ref q_acc); // ate_loop[33] = P - runner.sqr_target(32, ref q_acc); - runner.bit_o(32, ref q_acc); // ate_loop[32] = O - runner.sqr_target(31, ref q_acc); - runner.bit_o(31, ref q_acc); // ate_loop[31] = O -} - -fn ate_miller_loop_steps_second_half>( - runner: @TRunner, ref q_acc: TAccumulator -) { - runner.sqr_target(30, ref q_acc); - runner.bit_n(30, ref q_acc); // ate_loop[30] = N - runner.sqr_target(29, ref q_acc); - runner.bit_o(29, ref q_acc); // ate_loop[29] = O - runner.sqr_target(28, ref q_acc); - runner.bit_o(28, ref q_acc); // ate_loop[28] = O - runner.sqr_target(27, ref q_acc); - runner.bit_o(27, ref q_acc); // ate_loop[27] = O - runner.sqr_target(26, ref q_acc); - runner.bit_o(26, ref q_acc); // ate_loop[26] = O - runner.sqr_target(25, ref q_acc); - runner.bit_n(25, ref q_acc); // ate_loop[25] = N - runner.sqr_target(24, ref q_acc); - runner.bit_o(24, ref q_acc); // ate_loop[24] = O - runner.sqr_target(23, ref q_acc); - runner.bit_p(23, ref q_acc); // ate_loop[23] = P - runner.sqr_target(22, ref q_acc); - runner.bit_o(22, ref q_acc); // ate_loop[22] = O - runner.sqr_target(21, ref q_acc); - runner.bit_o(21, ref q_acc); // ate_loop[21] = O - runner.sqr_target(20, ref q_acc); - runner.bit_o(20, ref q_acc); // ate_loop[20] = O - runner.sqr_target(19, ref q_acc); - runner.bit_n(19, ref q_acc); // ate_loop[19] = N - runner.sqr_target(18, ref q_acc); - runner.bit_o(18, ref q_acc); // ate_loop[18] = O - runner.sqr_target(17, ref q_acc); - runner.bit_n(17, ref q_acc); // ate_loop[17] = N - runner.sqr_target(16, ref q_acc); - runner.bit_o(16, ref q_acc); // ate_loop[16] = O - runner.sqr_target(15, ref q_acc); - runner.bit_o(15, ref q_acc); // ate_loop[15] = O - runner.sqr_target(14, ref q_acc); - runner.bit_p(14, ref q_acc); // ate_loop[14] = P - runner.sqr_target(13, ref q_acc); - runner.bit_o(13, ref q_acc); // ate_loop[13] = O - runner.sqr_target(12, ref q_acc); - runner.bit_o(12, ref q_acc); // ate_loop[12] = O - runner.sqr_target(11, ref q_acc); - runner.bit_o(11, ref q_acc); // ate_loop[11] = O - runner.sqr_target(10, ref q_acc); - runner.bit_n(10, ref q_acc); // ate_loop[10] = N - runner.sqr_target(9, ref q_acc); - runner.bit_o(9, ref q_acc); // ate_loop[ 9] = O - runner.sqr_target(8, ref q_acc); - runner.bit_o(8, ref q_acc); // ate_loop[ 8] = O - runner.sqr_target(7, ref q_acc); - runner.bit_n(7, ref q_acc); // ate_loop[ 7] = N - runner.sqr_target(6, ref q_acc); - runner.bit_o(6, ref q_acc); // ate_loop[ 6] = O - runner.sqr_target(5, ref q_acc); - runner.bit_p(5, ref q_acc); // ate_loop[ 5] = P - runner.sqr_target(4, ref q_acc); - runner.bit_o(4, ref q_acc); // ate_loop[ 4] = O - runner.sqr_target(3, ref q_acc); - runner.bit_p(3, ref q_acc); // ate_loop[ 3] = P - runner.sqr_target(2, ref q_acc); - runner.bit_o(2, ref q_acc); // ate_loop[ 2] = O - runner.sqr_target(1, ref q_acc); - runner.bit_o(1, ref q_acc); // ate_loop[ 1] = O - runner.sqr_target(0, ref q_acc); - runner.bit_o(0, ref q_acc); // ate_loop[ 0] = O - runner.last(ref q_acc); -} +#[cfg(test)] +mod test; From 1f424b692372ff5d9a8b149b8a201f09bad15b71 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 9 Jul 2024 00:23:40 +0530 Subject: [PATCH 20/97] bn_ate_loop: groth16 types --- packages/bn_ate_loop/Scarb.toml | 2 ++ packages/bn_ate_loop/src/groth16.cairo | 45 ++++++++++++++++++++++++++ packages/bn_ate_loop/src/lib.cairo | 2 ++ 3 files changed, 49 insertions(+) create mode 100644 packages/bn_ate_loop/src/groth16.cairo diff --git a/packages/bn_ate_loop/Scarb.toml b/packages/bn_ate_loop/Scarb.toml index c25a0f4..c68bc8f 100644 --- a/packages/bn_ate_loop/Scarb.toml +++ b/packages/bn_ate_loop/Scarb.toml @@ -6,3 +6,5 @@ edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] +ec_groups = { path = "../ec_groups" } +fq_types = { path = "../fq_types" } \ No newline at end of file diff --git a/packages/bn_ate_loop/src/groth16.cairo b/packages/bn_ate_loop/src/groth16.cairo new file mode 100644 index 0000000..1f93817 --- /dev/null +++ b/packages/bn_ate_loop/src/groth16.cairo @@ -0,0 +1,45 @@ +use ec_groups::Affine; +use fq_types::{Fq2, Fq3}; + +#[derive(Copy, Drop, Serde)] +pub struct PPrecompute { + neg_x_over_y: TFq, + y_inv: TFq, +} + +#[derive(Drop, Serde)] +pub struct Groth16Circuit { + alpha_beta: TFq12, + gamma: TPtG2, + gamma_neg: TPtG2, + delta: TPtG2, + delta_neg: TPtG2, + lines: TLines, + ic: TIC, +} + +#[derive(Copy, Drop, Serde)] +pub struct Groth16MillerG1 { // Points in G1 + pi_a: PtG1, + pi_c: PtG1, + k: PtG1, +} + +#[derive(Copy, Drop, Serde)] +pub struct Groth16MillerG2 { // Points in G2 + pi_b: PtG2, + delta: PtG2, + gamma: PtG2, +} + +#[derive(Copy, Drop, Serde)] +pub struct Groth16PreCompute { + p: TG1Pts, + q: TG2Pts, + ppc: TG1Pts, + neg_q: TG2Pts, + lines: TLines, + residue_witness: TFq12, + residue_witness_inv: TFq12, + field_nz: NonZero, +} diff --git a/packages/bn_ate_loop/src/lib.cairo b/packages/bn_ate_loop/src/lib.cairo index c7b118b..231dd39 100644 --- a/packages/bn_ate_loop/src/lib.cairo +++ b/packages/bn_ate_loop/src/lib.cairo @@ -1,6 +1,8 @@ pub mod ate_loop; +pub mod groth16; pub use ate_loop::{MillerRunner, ate_miller_loop, _loop_inner_1_of_2, _loop_inner_2_of_2}; +pub use groth16::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; #[cfg(test)] mod test; From 9e13648ef14ec1f7eb563d0d29078df79df86518 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 9 Jul 2024 05:01:14 +0530 Subject: [PATCH 21/97] ec_group: lines --- packages/ec_groups/src/lib.cairo | 3 +++ packages/ec_groups/src/lines.cairo | 37 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 packages/ec_groups/src/lines.cairo diff --git a/packages/ec_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo index f64e3bf..4b8b263 100644 --- a/packages/ec_groups/src/lib.cairo +++ b/packages/ec_groups/src/lib.cairo @@ -1,7 +1,9 @@ pub mod bn; +pub mod lines; use fq_types::{FieldOps}; use core::num::traits::One; pub use bn::AffineOpsBn; +pub use lines::{LineFn, StepLinesGet, LinesArray, LinesArrayGet}; #[derive(Copy, Drop, Serde)] pub struct Affine { @@ -23,6 +25,7 @@ pub struct Groth16MillerG2 { // Points in gamma: Affine, } + pub trait ECOperations { fn x_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> TFq; fn y_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x: TFq) -> TFq; diff --git a/packages/ec_groups/src/lines.cairo b/packages/ec_groups/src/lines.cairo new file mode 100644 index 0000000..dc36392 --- /dev/null +++ b/packages/ec_groups/src/lines.cairo @@ -0,0 +1,37 @@ +#[derive(Copy, Drop, Serde)] +pub struct LineFn { + pub slope: TFq, + pub c: TFq, +} + +pub trait StepLinesGet { + fn get_gamma_line(self: @T, step: u32, line_index: u32) -> TLnFn; + fn get_delta_line(self: @T, step: u32, line_index: u32) -> TLnFn; + fn get_gamma_lines(self: @T, step: u32, line_index: u32) -> (TLnFn, TLnFn); + fn get_delta_lines(self: @T, step: u32, line_index: u32) -> (TLnFn, TLnFn); +} + +#[derive(Drop)] +pub struct LinesArray { + gamma: Array, + delta: Array, +} + +pub impl LinesArrayGet< + TLnFn, +Copy, +Drop +> of StepLinesGet, TLnFn> { + fn get_gamma_line(self: @LinesArray, step: u32, line_index: u32) -> TLnFn { + // let l1: LineFn = *self.gamma[line_index]; + // println!("Get {}.{} {}", step, line_index, l1.slope.c0.c0.low); + *self.gamma[line_index] + } + fn get_delta_line(self: @LinesArray, step: u32, line_index: u32) -> TLnFn { + *self.delta[line_index] + } + fn get_gamma_lines(self: @LinesArray, step: u32, line_index: u32) -> (TLnFn, TLnFn) { + (*self.gamma[line_index], *self.gamma[line_index + 1]) + } + fn get_delta_lines(self: @LinesArray, step: u32, line_index: u32) -> (TLnFn, TLnFn) { + (*self.delta[line_index], *self.delta[line_index + 1]) + } +} From 8bffdbcb019c134bfc84757159d54fff0fe79df5 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 10 Jul 2024 04:22:07 +0530 Subject: [PATCH 22/97] ate loop: add curve --- packages/bn_ate_loop/src/ate_loop.cairo | 239 +++++++++--------------- packages/bn_ate_loop/src/test.cairo | 34 ++-- packages/ec_groups/src/lib.cairo | 1 - 3 files changed, 108 insertions(+), 166 deletions(-) diff --git a/packages/bn_ate_loop/src/ate_loop.cairo b/packages/bn_ate_loop/src/ate_loop.cairo index f169db7..52eb01f 100644 --- a/packages/bn_ate_loop/src/ate_loop.cairo +++ b/packages/bn_ate_loop/src/ate_loop.cairo @@ -1,175 +1,120 @@ -pub trait MillerRunner { +pub trait MillerRunner { // Returns accumulator - fn accumulator(self: @TRunner) -> TAccumulator; - - // Square target group element - fn sqr_target(self: @TRunner, i: u32, ref acc: TAccumulator); + fn accumulator(self: @TRunner, ref curve: TCurve) -> TAccumulator; // first and second step, O and N - fn bit_1st_2nd(self: @TRunner, i1: u32, i2: u32, ref acc: TAccumulator); + fn bit_1st_2nd(self: @TRunner, ref curve: TCurve, i1: u32, i2: u32, ref acc: TAccumulator); // 0 bit - fn bit_o(self: @TRunner, i: u32, ref acc: TAccumulator); + fn bit_o(self: @TRunner, ref curve: TCurve, i: u32, ref acc: TAccumulator); // 1 bit - fn bit_p(self: @TRunner, i: u32, ref acc: TAccumulator); + fn bit_p(self: @TRunner, ref curve: TCurve, i: u32, ref acc: TAccumulator); // -1 bit - fn bit_n(self: @TRunner, i: u32, ref acc: TAccumulator); + fn bit_n(self: @TRunner, ref curve: TCurve, i: u32, ref acc: TAccumulator); // last step - fn last(self: @TRunner, ref acc: TAccumulator); + fn last(self: @TRunner, ref curve: TCurve, ref acc: TAccumulator); } -pub fn ate_miller_loop, +Drop>( - runner: TRunner +pub fn ate_miller_loop< + TCurve, + TRunner, + TAccumulator, + +MillerRunner, + +Drop, + +Drop +>( + ref curve: TCurve, runner: TRunner ) -> TAccumulator { core::gas::withdraw_gas().unwrap(); core::internal::revoke_ap_tracking(); // Get accumulator from runner - let mut q_acc: TAccumulator = runner.accumulator(); + let mut q_acc: TAccumulator = runner.accumulator(ref curve); - _loop_inner_1_of_2(@runner, ref q_acc); - _loop_inner_2_of_2(@runner, ref q_acc); + _loop_inner_1_of_2(@runner, ref curve, ref q_acc); + _loop_inner_2_of_2(@runner, ref curve, ref q_acc); q_acc } -pub fn _loop_inner_1_of_2>( - runner: @TRunner, ref q_acc: TAccumulator +pub fn _loop_inner_1_of_2< + TCurve, TRunner, TAccumulator, +MillerRunner +>( + runner: @TRunner, ref curve: TCurve, ref q_acc: TAccumulator ) { // ate_loop[64] = O and ate_loop[63] = N - runner.bit_1st_2nd(64, 63, ref q_acc); - runner.sqr_target(62, ref q_acc); - runner.bit_o(62, ref q_acc); // ate_loop[62] = O - runner.sqr_target(61, ref q_acc); - runner.bit_p(61, ref q_acc); // ate_loop[61] = P - runner.sqr_target(60, ref q_acc); - runner.bit_o(60, ref q_acc); // ate_loop[60] = O - runner.sqr_target(59, ref q_acc); - runner.bit_o(59, ref q_acc); // ate_loop[59] = O - runner.sqr_target(58, ref q_acc); - runner.bit_o(58, ref q_acc); // ate_loop[58] = O - runner.sqr_target(57, ref q_acc); - runner.bit_n(57, ref q_acc); // ate_loop[57] = N - runner.sqr_target(56, ref q_acc); - runner.bit_o(56, ref q_acc); // ate_loop[56] = O - runner.sqr_target(55, ref q_acc); - runner.bit_n(55, ref q_acc); // ate_loop[55] = N - runner.sqr_target(54, ref q_acc); - runner.bit_o(54, ref q_acc); // ate_loop[54] = O - runner.sqr_target(53, ref q_acc); - runner.bit_o(53, ref q_acc); // ate_loop[53] = O - runner.sqr_target(52, ref q_acc); - runner.bit_o(52, ref q_acc); // ate_loop[52] = O - runner.sqr_target(51, ref q_acc); - runner.bit_n(51, ref q_acc); // ate_loop[51] = N - runner.sqr_target(50, ref q_acc); - runner.bit_o(50, ref q_acc); // ate_loop[50] = O - runner.sqr_target(49, ref q_acc); - runner.bit_p(49, ref q_acc); // ate_loop[49] = P - runner.sqr_target(48, ref q_acc); - runner.bit_o(48, ref q_acc); // ate_loop[48] = O - runner.sqr_target(47, ref q_acc); - runner.bit_n(47, ref q_acc); // ate_loop[47] = N - runner.sqr_target(46, ref q_acc); - runner.bit_o(46, ref q_acc); // ate_loop[46] = O - runner.sqr_target(45, ref q_acc); - runner.bit_o(45, ref q_acc); // ate_loop[45] = O - runner.sqr_target(44, ref q_acc); - runner.bit_n(44, ref q_acc); // ate_loop[44] = N - runner.sqr_target(43, ref q_acc); - runner.bit_o(43, ref q_acc); // ate_loop[43] = O - runner.sqr_target(42, ref q_acc); - runner.bit_o(42, ref q_acc); // ate_loop[42] = O - runner.sqr_target(41, ref q_acc); - runner.bit_o(41, ref q_acc); // ate_loop[41] = O - runner.sqr_target(40, ref q_acc); - runner.bit_o(40, ref q_acc); // ate_loop[40] = O - runner.sqr_target(39, ref q_acc); - runner.bit_o(39, ref q_acc); // ate_loop[39] = O - runner.sqr_target(38, ref q_acc); - runner.bit_p(38, ref q_acc); // ate_loop[38] = P - runner.sqr_target(37, ref q_acc); - runner.bit_o(37, ref q_acc); // ate_loop[37] = O - runner.sqr_target(36, ref q_acc); - runner.bit_o(36, ref q_acc); // ate_loop[36] = O - runner.sqr_target(35, ref q_acc); - runner.bit_n(35, ref q_acc); // ate_loop[35] = N - runner.sqr_target(34, ref q_acc); - runner.bit_o(34, ref q_acc); // ate_loop[34] = O - runner.sqr_target(33, ref q_acc); - runner.bit_p(33, ref q_acc); // ate_loop[33] = P - runner.sqr_target(32, ref q_acc); - runner.bit_o(32, ref q_acc); // ate_loop[32] = O - runner.sqr_target(31, ref q_acc); - runner.bit_o(31, ref q_acc); // ate_loop[31] = O + runner.bit_1st_2nd(ref curve, 64, 63, ref q_acc); + runner.bit_o(ref curve, 62, ref q_acc); // ate_loop[62] = O + runner.bit_p(ref curve, 61, ref q_acc); // ate_loop[61] = P + runner.bit_o(ref curve, 60, ref q_acc); // ate_loop[60] = O + runner.bit_o(ref curve, 59, ref q_acc); // ate_loop[59] = O + runner.bit_o(ref curve, 58, ref q_acc); // ate_loop[58] = O + runner.bit_n(ref curve, 57, ref q_acc); // ate_loop[57] = N + runner.bit_o(ref curve, 56, ref q_acc); // ate_loop[56] = O + runner.bit_n(ref curve, 55, ref q_acc); // ate_loop[55] = N + runner.bit_o(ref curve, 54, ref q_acc); // ate_loop[54] = O + runner.bit_o(ref curve, 53, ref q_acc); // ate_loop[53] = O + runner.bit_o(ref curve, 52, ref q_acc); // ate_loop[52] = O + runner.bit_n(ref curve, 51, ref q_acc); // ate_loop[51] = N + runner.bit_o(ref curve, 50, ref q_acc); // ate_loop[50] = O + runner.bit_p(ref curve, 49, ref q_acc); // ate_loop[49] = P + runner.bit_o(ref curve, 48, ref q_acc); // ate_loop[48] = O + runner.bit_n(ref curve, 47, ref q_acc); // ate_loop[47] = N + runner.bit_o(ref curve, 46, ref q_acc); // ate_loop[46] = O + runner.bit_o(ref curve, 45, ref q_acc); // ate_loop[45] = O + runner.bit_n(ref curve, 44, ref q_acc); // ate_loop[44] = N + runner.bit_o(ref curve, 43, ref q_acc); // ate_loop[43] = O + runner.bit_o(ref curve, 42, ref q_acc); // ate_loop[42] = O + runner.bit_o(ref curve, 41, ref q_acc); // ate_loop[41] = O + runner.bit_o(ref curve, 40, ref q_acc); // ate_loop[40] = O + runner.bit_o(ref curve, 39, ref q_acc); // ate_loop[39] = O + runner.bit_p(ref curve, 38, ref q_acc); // ate_loop[38] = P + runner.bit_o(ref curve, 37, ref q_acc); // ate_loop[37] = O + runner.bit_o(ref curve, 36, ref q_acc); // ate_loop[36] = O + runner.bit_n(ref curve, 35, ref q_acc); // ate_loop[35] = N + runner.bit_o(ref curve, 34, ref q_acc); // ate_loop[34] = O + runner.bit_p(ref curve, 33, ref q_acc); // ate_loop[33] = P + runner.bit_o(ref curve, 32, ref q_acc); // ate_loop[32] = O + runner.bit_o(ref curve, 31, ref q_acc); // ate_loop[31] = O } -pub fn _loop_inner_2_of_2>( - runner: @TRunner, ref q_acc: TAccumulator +pub fn _loop_inner_2_of_2< + TCurve, TRunner, TAccumulator, +MillerRunner +>( + runner: @TRunner, ref curve: TCurve, ref q_acc: TAccumulator ) { - runner.sqr_target(30, ref q_acc); - runner.bit_n(30, ref q_acc); // ate_loop[30] = N - runner.sqr_target(29, ref q_acc); - runner.bit_o(29, ref q_acc); // ate_loop[29] = O - runner.sqr_target(28, ref q_acc); - runner.bit_o(28, ref q_acc); // ate_loop[28] = O - runner.sqr_target(27, ref q_acc); - runner.bit_o(27, ref q_acc); // ate_loop[27] = O - runner.sqr_target(26, ref q_acc); - runner.bit_o(26, ref q_acc); // ate_loop[26] = O - runner.sqr_target(25, ref q_acc); - runner.bit_n(25, ref q_acc); // ate_loop[25] = N - runner.sqr_target(24, ref q_acc); - runner.bit_o(24, ref q_acc); // ate_loop[24] = O - runner.sqr_target(23, ref q_acc); - runner.bit_p(23, ref q_acc); // ate_loop[23] = P - runner.sqr_target(22, ref q_acc); - runner.bit_o(22, ref q_acc); // ate_loop[22] = O - runner.sqr_target(21, ref q_acc); - runner.bit_o(21, ref q_acc); // ate_loop[21] = O - runner.sqr_target(20, ref q_acc); - runner.bit_o(20, ref q_acc); // ate_loop[20] = O - runner.sqr_target(19, ref q_acc); - runner.bit_n(19, ref q_acc); // ate_loop[19] = N - runner.sqr_target(18, ref q_acc); - runner.bit_o(18, ref q_acc); // ate_loop[18] = O - runner.sqr_target(17, ref q_acc); - runner.bit_n(17, ref q_acc); // ate_loop[17] = N - runner.sqr_target(16, ref q_acc); - runner.bit_o(16, ref q_acc); // ate_loop[16] = O - runner.sqr_target(15, ref q_acc); - runner.bit_o(15, ref q_acc); // ate_loop[15] = O - runner.sqr_target(14, ref q_acc); - runner.bit_p(14, ref q_acc); // ate_loop[14] = P - runner.sqr_target(13, ref q_acc); - runner.bit_o(13, ref q_acc); // ate_loop[13] = O - runner.sqr_target(12, ref q_acc); - runner.bit_o(12, ref q_acc); // ate_loop[12] = O - runner.sqr_target(11, ref q_acc); - runner.bit_o(11, ref q_acc); // ate_loop[11] = O - runner.sqr_target(10, ref q_acc); - runner.bit_n(10, ref q_acc); // ate_loop[10] = N - runner.sqr_target(9, ref q_acc); - runner.bit_o(9, ref q_acc); // ate_loop[ 9] = O - runner.sqr_target(8, ref q_acc); - runner.bit_o(8, ref q_acc); // ate_loop[ 8] = O - runner.sqr_target(7, ref q_acc); - runner.bit_n(7, ref q_acc); // ate_loop[ 7] = N - runner.sqr_target(6, ref q_acc); - runner.bit_o(6, ref q_acc); // ate_loop[ 6] = O - runner.sqr_target(5, ref q_acc); - runner.bit_p(5, ref q_acc); // ate_loop[ 5] = P - runner.sqr_target(4, ref q_acc); - runner.bit_o(4, ref q_acc); // ate_loop[ 4] = O - runner.sqr_target(3, ref q_acc); - runner.bit_p(3, ref q_acc); // ate_loop[ 3] = P - runner.sqr_target(2, ref q_acc); - runner.bit_o(2, ref q_acc); // ate_loop[ 2] = O - runner.sqr_target(1, ref q_acc); - runner.bit_o(1, ref q_acc); // ate_loop[ 1] = O - runner.sqr_target(0, ref q_acc); - runner.bit_o(0, ref q_acc); // ate_loop[ 0] = O - runner.last(ref q_acc); + runner.bit_n(ref curve, 30, ref q_acc); // ate_loop[30] = N + runner.bit_o(ref curve, 29, ref q_acc); // ate_loop[29] = O + runner.bit_o(ref curve, 28, ref q_acc); // ate_loop[28] = O + runner.bit_o(ref curve, 27, ref q_acc); // ate_loop[27] = O + runner.bit_o(ref curve, 26, ref q_acc); // ate_loop[26] = O + runner.bit_n(ref curve, 25, ref q_acc); // ate_loop[25] = N + runner.bit_o(ref curve, 24, ref q_acc); // ate_loop[24] = O + runner.bit_p(ref curve, 23, ref q_acc); // ate_loop[23] = P + runner.bit_o(ref curve, 22, ref q_acc); // ate_loop[22] = O + runner.bit_o(ref curve, 21, ref q_acc); // ate_loop[21] = O + runner.bit_o(ref curve, 20, ref q_acc); // ate_loop[20] = O + runner.bit_n(ref curve, 19, ref q_acc); // ate_loop[19] = N + runner.bit_o(ref curve, 18, ref q_acc); // ate_loop[18] = O + runner.bit_n(ref curve, 17, ref q_acc); // ate_loop[17] = N + runner.bit_o(ref curve, 16, ref q_acc); // ate_loop[16] = O + runner.bit_o(ref curve, 15, ref q_acc); // ate_loop[15] = O + runner.bit_p(ref curve, 14, ref q_acc); // ate_loop[14] = P + runner.bit_o(ref curve, 13, ref q_acc); // ate_loop[13] = O + runner.bit_o(ref curve, 12, ref q_acc); // ate_loop[12] = O + runner.bit_o(ref curve, 11, ref q_acc); // ate_loop[11] = O + runner.bit_n(ref curve, 10, ref q_acc); // ate_loop[10] = N + runner.bit_o(ref curve, 9, ref q_acc); // ate_loop[ 9] = O + runner.bit_o(ref curve, 8, ref q_acc); // ate_loop[ 8] = O + runner.bit_n(ref curve, 7, ref q_acc); // ate_loop[ 7] = N + runner.bit_o(ref curve, 6, ref q_acc); // ate_loop[ 6] = O + runner.bit_p(ref curve, 5, ref q_acc); // ate_loop[ 5] = P + runner.bit_o(ref curve, 4, ref q_acc); // ate_loop[ 4] = O + runner.bit_p(ref curve, 3, ref q_acc); // ate_loop[ 3] = P + runner.bit_o(ref curve, 2, ref q_acc); // ate_loop[ 2] = O + runner.bit_o(ref curve, 1, ref q_acc); // ate_loop[ 1] = O + runner.bit_o(ref curve, 0, ref q_acc); // ate_loop[ 0] = O + runner.last(ref curve, ref q_acc); } diff --git a/packages/bn_ate_loop/src/test.cairo b/packages/bn_ate_loop/src/test.cairo index e8a0b89..1cf9559 100644 --- a/packages/bn_ate_loop/src/test.cairo +++ b/packages/bn_ate_loop/src/test.cairo @@ -7,48 +7,46 @@ struct MockMillerRunner {} type MockAccumulator = felt252; -impl Miller_u256 of MillerRunner { +impl Miller_u256 of MillerRunner<(), MockMillerRunner, MockAccumulator> { // Returns accumulator - fn accumulator(self: @MockMillerRunner) -> MockAccumulator { + fn accumulator(self: @MockMillerRunner, ref curve: ()) -> MockAccumulator { 1 } - // Square target group element - fn sqr_target(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // - acc = acc + acc; - } - // first and second step, O and N - fn bit_1st_2nd(self: @MockMillerRunner, i1: u32, i2: u32, ref acc: MockAccumulator) { // - self.sqr_target(i1, ref acc); - self.bit_o(i1, ref acc); - self.sqr_target(i2, ref acc); - self.bit_n(i2, ref acc); + fn bit_1st_2nd( + self: @MockMillerRunner, ref curve: (), i1: u32, i2: u32, ref acc: MockAccumulator + ) { // + self.bit_o(ref curve, i1, ref acc); + self.bit_n(ref curve, i2, ref acc); } // 0 bit - fn bit_o(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // - // do nothing + fn bit_o(self: @MockMillerRunner, ref curve: (), i: u32, ref acc: MockAccumulator) { // + acc = acc + acc; } // 1 bit - fn bit_p(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // + fn bit_p(self: @MockMillerRunner, ref curve: (), i: u32, ref acc: MockAccumulator) { // + acc = acc + acc; acc = acc + 1; } // -1 bit - fn bit_n(self: @MockMillerRunner, i: u32, ref acc: MockAccumulator) { // + fn bit_n(self: @MockMillerRunner, ref curve: (), i: u32, ref acc: MockAccumulator) { // + acc = acc + acc; acc = acc - 1; } // last step - fn last(self: @MockMillerRunner, ref acc: MockAccumulator) { // + fn last(self: @MockMillerRunner, ref curve: (), ref acc: MockAccumulator) { // // do nothing } } #[test] fn test_ate_miller_loop() { - let res: MockAccumulator = ate_miller_loop(MockMillerRunner {}); + let mut curve = (); + let res: MockAccumulator = ate_miller_loop(ref curve, MockMillerRunner {}); assert(res == 0x19d797039be763ba8, 'wrong value for 6u + 2'); } diff --git a/packages/ec_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo index 4b8b263..163da89 100644 --- a/packages/ec_groups/src/lib.cairo +++ b/packages/ec_groups/src/lib.cairo @@ -25,7 +25,6 @@ pub struct Groth16MillerG2 { // Points in gamma: Affine, } - pub trait ECOperations { fn x_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> TFq; fn y_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x: TFq) -> TFq; From 44070b0e25569498015eed2018aee7130eba752d Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 11:55:34 +0530 Subject: [PATCH 23/97] ec groups: group utils trait --- packages/ec_groups/src/bn.cairo | 8 +++++--- packages/ec_groups/src/lib.cairo | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/ec_groups/src/bn.cairo b/packages/ec_groups/src/bn.cairo index 144b535..55d50df 100644 --- a/packages/ec_groups/src/bn.cairo +++ b/packages/ec_groups/src/bn.cairo @@ -1,6 +1,7 @@ -use super::{Affine, ECOperations, FieldOps, One}; +use super::{Affine, ECOperations, ECGroupUtils, FieldOps, One}; + pub impl AffineOpsBn< - T, TCurve, +FieldOps, +Copy, +Drop, +Drop, +One> + T, TCurve, +FieldOps, +Copy, +Drop, +Drop, +ECGroupUtils > of ECOperations { #[inline(always)] fn x_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> T { @@ -50,7 +51,7 @@ pub impl AffineOpsBn< fn pt_mul(ref self: TCurve, pt: @Affine, mut multiplier: u256) -> Affine { let nz2: NonZero = 2_u256.try_into().unwrap(); let mut dbl_step = *pt; - let mut result = One::>::one(); + let mut result: Affine = self.pt_one(); let mut first_add_done = false; // TODO: optimise with u128 ops @@ -83,3 +84,4 @@ pub impl AffineOpsBn< Affine { x: *pt.x, y: self.neg(*pt.y) } } } + diff --git a/packages/ec_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo index 163da89..b1392e5 100644 --- a/packages/ec_groups/src/lib.cairo +++ b/packages/ec_groups/src/lib.cairo @@ -37,6 +37,10 @@ pub trait ECOperations { fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine; } +pub trait ECGroupUtils { + fn pt_one(ref self: TCurve) -> Affine; +} + pub impl AffinePartialEq> of PartialEq> { fn eq(lhs: @Affine, rhs: @Affine) -> bool { lhs.x == rhs.x && lhs.y == rhs.y From a816e8cb8dc2b42a0f5719ed3c6a222d05d8590e Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 17:04:45 +0530 Subject: [PATCH 24/97] ec groups and types: minor tweaks --- packages/bn_ate_loop/src/groth16.cairo | 46 +++++++++++++------------- packages/ec_groups/src/bn.cairo | 41 ++++++++++++----------- packages/ec_groups/src/lib.cairo | 18 +++++----- packages/fq_types/src/lib.cairo | 8 +++++ 4 files changed, 61 insertions(+), 52 deletions(-) diff --git a/packages/bn_ate_loop/src/groth16.cairo b/packages/bn_ate_loop/src/groth16.cairo index 1f93817..258b922 100644 --- a/packages/bn_ate_loop/src/groth16.cairo +++ b/packages/bn_ate_loop/src/groth16.cairo @@ -3,43 +3,43 @@ use fq_types::{Fq2, Fq3}; #[derive(Copy, Drop, Serde)] pub struct PPrecompute { - neg_x_over_y: TFq, - y_inv: TFq, + pub neg_x_over_y: TFq, + pub y_inv: TFq, } #[derive(Drop, Serde)] pub struct Groth16Circuit { - alpha_beta: TFq12, - gamma: TPtG2, - gamma_neg: TPtG2, - delta: TPtG2, - delta_neg: TPtG2, - lines: TLines, - ic: TIC, + pub alpha_beta: TFq12, + pub gamma: TPtG2, + pub gamma_neg: TPtG2, + pub delta: TPtG2, + pub delta_neg: TPtG2, + pub lines: TLines, + pub ic: TIC, } #[derive(Copy, Drop, Serde)] pub struct Groth16MillerG1 { // Points in G1 - pi_a: PtG1, - pi_c: PtG1, - k: PtG1, + pub pi_a: PtG1, + pub pi_c: PtG1, + pub k: PtG1, } #[derive(Copy, Drop, Serde)] pub struct Groth16MillerG2 { // Points in G2 - pi_b: PtG2, - delta: PtG2, - gamma: PtG2, + pub pi_b: PtG2, + pub delta: PtG2, + pub gamma: PtG2, } #[derive(Copy, Drop, Serde)] pub struct Groth16PreCompute { - p: TG1Pts, - q: TG2Pts, - ppc: TG1Pts, - neg_q: TG2Pts, - lines: TLines, - residue_witness: TFq12, - residue_witness_inv: TFq12, - field_nz: NonZero, + pub p: TG1Pts, + pub q: TG2Pts, + pub ppc: TG1Pts, + pub neg_q: TG2Pts, + pub lines: TLines, + pub residue_witness: TFq12, + pub residue_witness_inv: TFq12, + pub field_nz: NonZero, } diff --git a/packages/ec_groups/src/bn.cairo b/packages/ec_groups/src/bn.cairo index 55d50df..bfb502e 100644 --- a/packages/ec_groups/src/bn.cairo +++ b/packages/ec_groups/src/bn.cairo @@ -1,56 +1,57 @@ use super::{Affine, ECOperations, ECGroupUtils, FieldOps, One}; pub impl AffineOpsBn< - T, TCurve, +FieldOps, +Copy, +Drop, +Drop, +ECGroupUtils + TCurve, T, +FieldOps, +Copy, +Drop, +Drop, +ECGroupUtils > of ECOperations { #[inline(always)] - fn x_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> T { + fn x_on_slope(ref self: TCurve, pt: Affine, slope: T, x2: T) -> T { // x = λ^2 - x1 - x2 - self.sub(self.sub(self.sqr(slope), *pt.x), x2) + self.sub(self.sub(self.sqr(slope), pt.x), x2) } #[inline(always)] - fn y_on_slope(ref self: TCurve, pt: @Affine, slope: T, x: T) -> T { + fn y_on_slope(ref self: TCurve, pt: Affine, slope: T, x: T) -> T { // y = λ(x1 - x) - y1 - self.sub(self.mul(slope, self.sub(*pt.x, x)), *pt.y) + self.sub(self.mul(slope, self.sub(pt.x, x)), pt.y) } - fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: T, x2: T) -> Affine { + fn pt_on_slope(ref self: TCurve, pt: Affine, slope: T, x2: T) -> Affine { let x = self.x_on_slope(pt, slope, x2); let y = self.y_on_slope(pt, slope, x); Affine { x, y } } #[inline(always)] - fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> T { + fn chord(ref self: TCurve, pt: Affine, rhs: Affine) -> T { let Affine { x: x1, y: y1 } = pt; let Affine { x: x2, y: y2 } = rhs; // λ = (y2-y1) / (x2-x1) - self.div(self.sub(y2, *y1), self.sub(x2, *x1)) + self.div(self.sub(y2, y1), self.sub(x2, x1)) } - fn tangent(ref self: TCurve, pt: @Affine) -> T { + fn tangent(ref self: TCurve, pt: Affine) -> T { let Affine { x, y } = pt; // λ = (3x^2 + a) / 2y // But BN curve has a == 0 so that's one less addition // λ = 3x^2 / 2y - let x_2 = self.sqr(*x); - self.div(self.add(self.add(x_2, x_2), x_2), self.add(*y, *y)) + let x_2 = self.sqr(x); + let three_x2 = self.add(self.add(x_2, x_2), x_2); + self.div(three_x2, self.add(y, y)) } #[inline(always)] - fn pt_add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine { + fn pt_add(ref self: TCurve, pt: Affine, rhs: Affine) -> Affine { self.pt_on_slope(pt, self.chord(pt, rhs), rhs.x) } - fn pt_dbl(ref self: TCurve, pt: @Affine) -> Affine { - self.pt_on_slope(pt, self.tangent(pt), *pt.x) + fn pt_dbl(ref self: TCurve, pt: Affine) -> Affine { + self.pt_on_slope(pt, self.tangent(pt), pt.x) } - fn pt_mul(ref self: TCurve, pt: @Affine, mut multiplier: u256) -> Affine { + fn pt_mul(ref self: TCurve, pt: Affine, mut multiplier: u256) -> Affine { let nz2: NonZero = 2_u256.try_into().unwrap(); - let mut dbl_step = *pt; + let mut dbl_step = pt; let mut result: Affine = self.pt_one(); let mut first_add_done = false; @@ -66,22 +67,22 @@ pub impl AffineOpsBn< // self is zero, return rhs dbl_step } else { - self.pt_add(@result, dbl_step) + self.pt_add(result, dbl_step) } } if q == 0 { break; } - dbl_step = self.pt_dbl(@dbl_step); + dbl_step = self.pt_dbl(dbl_step); multiplier = q; }; result } #[inline(always)] - fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine { - Affine { x: *pt.x, y: self.neg(*pt.y) } + fn pt_neg(ref self: TCurve, pt: Affine) -> Affine { + Affine { x: pt.x, y: self.neg(pt.y) } } } diff --git a/packages/ec_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo index b1392e5..4fb92bb 100644 --- a/packages/ec_groups/src/lib.cairo +++ b/packages/ec_groups/src/lib.cairo @@ -26,15 +26,15 @@ pub struct Groth16MillerG2 { // Points in } pub trait ECOperations { - fn x_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> TFq; - fn y_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x: TFq) -> TFq; - fn pt_on_slope(ref self: TCurve, pt: @Affine, slope: TFq, x2: TFq) -> Affine; - fn chord(ref self: TCurve, pt: @Affine, rhs: Affine) -> TFq; - fn tangent(ref self: TCurve, pt: @Affine) -> TFq; - fn pt_add(ref self: TCurve, pt: @Affine, rhs: Affine) -> Affine; - fn pt_dbl(ref self: TCurve, pt: @Affine) -> Affine; - fn pt_mul(ref self: TCurve, pt: @Affine, multiplier: u256) -> Affine; - fn pt_neg(ref self: TCurve, pt: @Affine) -> Affine; + fn x_on_slope(ref self: TCurve, pt: Affine, slope: TFq, x2: TFq) -> TFq; + fn y_on_slope(ref self: TCurve, pt: Affine, slope: TFq, x: TFq) -> TFq; + fn pt_on_slope(ref self: TCurve, pt: Affine, slope: TFq, x2: TFq) -> Affine; + fn chord(ref self: TCurve, pt: Affine, rhs: Affine) -> TFq; + fn tangent(ref self: TCurve, pt: Affine) -> TFq; + fn pt_add(ref self: TCurve, pt: Affine, rhs: Affine) -> Affine; + fn pt_dbl(ref self: TCurve, pt: Affine) -> Affine; + fn pt_mul(ref self: TCurve, pt: Affine, multiplier: u256) -> Affine; + fn pt_neg(ref self: TCurve, pt: Affine) -> Affine; } pub trait ECGroupUtils { diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index 69fc643..3d1ae0f 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -13,6 +13,14 @@ pub struct Fq3 { pub c2: T, } +pub fn fq2(c0: T, c1: T) -> Fq2 { + Fq2 { c0, c1 } +} + +pub fn fq3(c0: T, c1: T, c2: T) -> Fq3 { + Fq3 { c0, c1, c2 } +} + // Sparse Fq12 element containing only c3 and c4 Fq2 (c0 is 1) // Equivalent to, // Fq12{ From 67c8bfc9e62473cc280580b773fda5e6fddfa79a Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 17:08:11 +0530 Subject: [PATCH 25/97] bn254 u256 field element and extensions --- packages/bn254_u256/src/fq_1.cairo | 69 ++++++++++++++++++++++++++++++ packages/bn254_u256/src/lib.cairo | 9 ++++ 2 files changed, 78 insertions(+) create mode 100644 packages/bn254_u256/src/fq_1.cairo create mode 100644 packages/bn254_u256/src/lib.cairo diff --git a/packages/bn254_u256/src/fq_1.cairo b/packages/bn254_u256/src/fq_1.cairo new file mode 100644 index 0000000..7505f32 --- /dev/null +++ b/packages/bn254_u256/src/fq_1.cairo @@ -0,0 +1,69 @@ +pub use fq_types::{FieldOps, FieldOpsExtended, FieldUtils}; +pub use fast_mod::{add, sub, mul_nz, sqr_nz, div_nz, inv, neg, scl_nz}; +pub use bn254_u256::Bn254U256Curve; + +#[derive(Copy, Drop, Serde, Debug)] +pub struct Fq { + c0: u256, +} + +pub impl U256IntoFq of Into { + #[inline(always)] + fn into(self: u256) -> Fq { + Fq { c0: self } + } +} + +#[inline(always)] +pub fn scale_9(ref self: Bn254U256Curve, a: Fq) -> Fq { + let a2 = self.add(a, a); // 2a + let a4 = self.add(a2, a2); // 4a + self.add(self.add(a4, a4), a) // 8a + a +} + +pub impl Bn254FqOps of FieldOps { + fn add(ref self: Bn254U256Curve, lhs: Fq, rhs: Fq) -> Fq { + add(lhs.c0, rhs.c0, self.q).into() + } + fn sub(ref self: Bn254U256Curve, lhs: Fq, rhs: Fq) -> Fq { + sub(lhs.c0, rhs.c0, self.q).into() + } + fn neg(ref self: Bn254U256Curve, lhs: Fq) -> Fq { + neg(lhs.c0, self.q).into() + } + fn eq(self: @Bn254U256Curve, lhs: @Fq, rhs: @Fq) -> bool { + lhs.c0 == rhs.c0 + } + fn mul(ref self: Bn254U256Curve, lhs: Fq, rhs: Fq) -> Fq { + mul_nz(lhs.c0, rhs.c0, self.qnz).into() + } + fn div(ref self: Bn254U256Curve, lhs: Fq, rhs: Fq) -> Fq { + div_nz(lhs.c0, rhs.c0, self.qnz).into() + } + fn sqr(ref self: Bn254U256Curve, lhs: Fq) -> Fq { + sqr_nz(lhs.c0, self.qnz).into() + } + fn inv(ref self: Bn254U256Curve, lhs: Fq) -> Fq { + inv(lhs.c0, self.qnz).into() + } +} + +pub impl Bn254FqUtils of FieldUtils { + fn one(ref self: Bn254U256Curve) -> Fq { + Fq { c0: 1 } + } + fn zero(ref self: Bn254U256Curve) -> Fq { + Fq { c0: 0 } + } + fn conjugate(ref self: Bn254U256Curve, el: Fq) -> Fq { + core::panic_with_felt252('no_impl: fq conjugate'); + el + } + fn mul_by_nonresidue(ref self: Bn254U256Curve, el: Fq) -> Fq { + self.neg(el) + } + fn frobenius_map(ref self: Bn254U256Curve, el: Fq, power: usize) -> Fq { + core::panic_with_felt252('no_impl: fq frobenius_map'); + el + } +} diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo new file mode 100644 index 0000000..6597571 --- /dev/null +++ b/packages/bn254_u256/src/lib.cairo @@ -0,0 +1,9 @@ +use fq_types::{Fq2 as Fq2Gen, fq2, Fq3 as Fq3Gen, fq3,}; +pub mod fq_1; +pub use fq_1::{scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}; +pub use fq_1::{U256IntoFq, Bn254FqOps, Bn254FqUtils}; + +pub type Fq2 = Fq2Gen; +pub type Fq6 = Fq3Gen>; +pub type Fq12 = Fq2Gen; + From f96a0e0343b1f6743deed33ed9d5c338955ec34b Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 17:23:54 +0530 Subject: [PATCH 26/97] bn254 u256 curve --- packages/bn254_u256/src/curve.cairo | 41 +++++++++++++++++++++++++++++ packages/bn254_u256/src/lib.cairo | 3 +++ packages/ec_groups/src/lib.cairo | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 packages/bn254_u256/src/curve.cairo diff --git a/packages/bn254_u256/src/curve.cairo b/packages/bn254_u256/src/curve.cairo new file mode 100644 index 0000000..c0b4e4e --- /dev/null +++ b/packages/bn254_u256/src/curve.cairo @@ -0,0 +1,41 @@ +use bn254_u256::{Fq, U256IntoFq, Fq2, fq2, fq3, Bn254FqOps, Bn254FqUtils}; +use ec_groups::{Affine, ECGroupUtils}; +pub use ec_groups::AffineOpsBn; + +#[derive(Drop, Serde)] +pub struct Bn254U256Curve { + pub q: u256, + pub qnz: NonZero, +} + +pub type PtG1 = Affine; +pub type PtG2 = Affine; + +impl PtG1One of ECGroupUtils { + fn pt_one(ref self: Bn254U256Curve) -> PtG1 { + Affine { x: 1_u256.into(), y: 2_u256.into() } + } +} + +impl PtG2One of ECGroupUtils { + fn pt_one(ref self: Bn254U256Curve) -> PtG2 { + Affine { + x: fq2::< + Fq + >( + 10857046999023057135944570762232829481370756359578518086990519993285655852781_u256 + .into(), + 11559732032986387107991004021392285783925812861821192530917403151452391805634_u256 + .into(), + ), + y: fq2::< + Fq + >( + 8495653923123431417604973247489272438418190587263600148770280649306958101930_u256 + .into(), + 4082367875863433681332203403145435568316851327593401208105741076214120093531_u256 + .into(), + ) + } + } +} diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 6597571..78017e8 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -1,5 +1,8 @@ use fq_types::{Fq2 as Fq2Gen, fq2, Fq3 as Fq3Gen, fq3,}; +pub mod curve; pub mod fq_1; + +pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn}; pub use fq_1::{scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}; pub use fq_1::{U256IntoFq, Bn254FqOps, Bn254FqUtils}; diff --git a/packages/ec_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo index 4fb92bb..804041f 100644 --- a/packages/ec_groups/src/lib.cairo +++ b/packages/ec_groups/src/lib.cairo @@ -19,7 +19,7 @@ pub struct Groth16MillerG1 { // Points in G1 } #[derive(Copy, Drop)] -pub struct Groth16MillerG2 { // Points in +pub struct Groth16MillerG2 { // Points in G2 pi_b: Affine, delta: Affine, gamma: Affine, From 0f0aaac4a8c1e4a8bc6d8406a24bfe66cab67422 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 17:24:17 +0530 Subject: [PATCH 27/97] input constraint functions --- packages/bn254_u256/src/lib.cairo | 3 ++ packages/bn254_u256/src/pairing/utils.cairo | 39 +++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 packages/bn254_u256/src/pairing/utils.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 78017e8..ca23512 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -10,3 +10,6 @@ pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3Gen>; pub type Fq12 = Fq2Gen; +mod pairing { + mod utils; +} diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo new file mode 100644 index 0000000..7e8c2cc --- /dev/null +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -0,0 +1,39 @@ +use ec_groups::ECOperations; +use bn_ate_loop::{PPrecompute}; +use bn254_u256::{Fq, Fq2, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; +use bn254_u256::Bn254U256Curve; + +// Generic Input constraints processing +trait ICProcess { + fn process_inputs_and_ic(ref self: TIC, inputs: TInputs, ref curve: TCurve) -> TG1; +} + +// Input constraints processing for array of IC paramters +impl ICArrayInput of ICProcess, Array, PtG1> { + fn process_inputs_and_ic( + ref self: Array, mut inputs: Array, ref curve: Bn254U256Curve + ) -> PtG1 { + // First element is the initial point + let mut ic_point = self.pop_front().unwrap(); + + assert(inputs.len() == self.len(), 'incorrect input length'); + + if inputs.len() == 0 { + return ic_point; + } + + loop { + match self.pop_front() { + Option::Some(point) => { // + match inputs.pop_front() { + Option::Some(in) => { + ic_point = curve.pt_add(ic_point, curve.pt_mul(point, in)); + }, + Option::None => {} // This wouldn't happen + } + }, + Option::None => { break ic_point; } + } + } + } +} From fd271448629ab75291f91367ce5abb592823f25e Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 18:56:37 +0530 Subject: [PATCH 28/97] bn ate loop types and fn tweaks --- packages/bn_ate_loop/src/ate_loop.cairo | 9 +-------- packages/bn_ate_loop/src/groth16.cairo | 12 ++++++++++-- packages/bn_ate_loop/src/lib.cairo | 4 +++- packages/bn_ate_loop/src/test.cairo | 8 ++------ packages/ec_groups/src/bn.cairo | 1 - 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/bn_ate_loop/src/ate_loop.cairo b/packages/bn_ate_loop/src/ate_loop.cairo index 52eb01f..ba535db 100644 --- a/packages/bn_ate_loop/src/ate_loop.cairo +++ b/packages/bn_ate_loop/src/ate_loop.cairo @@ -1,7 +1,4 @@ pub trait MillerRunner { - // Returns accumulator - fn accumulator(self: @TRunner, ref curve: TCurve) -> TAccumulator; - // first and second step, O and N fn bit_1st_2nd(self: @TRunner, ref curve: TCurve, i1: u32, i2: u32, ref acc: TAccumulator); @@ -26,17 +23,13 @@ pub fn ate_miller_loop< +Drop, +Drop >( - ref curve: TCurve, runner: TRunner + ref curve: TCurve, runner: TRunner, ref q_acc: TAccumulator ) -> TAccumulator { core::gas::withdraw_gas().unwrap(); core::internal::revoke_ap_tracking(); - // Get accumulator from runner - let mut q_acc: TAccumulator = runner.accumulator(ref curve); - _loop_inner_1_of_2(@runner, ref curve, ref q_acc); _loop_inner_2_of_2(@runner, ref curve, ref q_acc); - q_acc } pub fn _loop_inner_1_of_2< diff --git a/packages/bn_ate_loop/src/groth16.cairo b/packages/bn_ate_loop/src/groth16.cairo index 258b922..75f8857 100644 --- a/packages/bn_ate_loop/src/groth16.cairo +++ b/packages/bn_ate_loop/src/groth16.cairo @@ -33,13 +33,21 @@ pub struct Groth16MillerG2 { // Points in G2 } #[derive(Copy, Drop, Serde)] -pub struct Groth16PreCompute { +pub struct Groth16PreCompute { pub p: TG1Pts, pub q: TG2Pts, - pub ppc: TG1Pts, + pub ppc: TG1Precomputes, pub neg_q: TG2Pts, pub lines: TLines, pub residue_witness: TFq12, pub residue_witness_inv: TFq12, pub field_nz: NonZero, } + + +#[derive(Drop)] +pub enum CubicScale { + Zero, + One, + Two, +} diff --git a/packages/bn_ate_loop/src/lib.cairo b/packages/bn_ate_loop/src/lib.cairo index 231dd39..280ca1a 100644 --- a/packages/bn_ate_loop/src/lib.cairo +++ b/packages/bn_ate_loop/src/lib.cairo @@ -2,7 +2,9 @@ pub mod ate_loop; pub mod groth16; pub use ate_loop::{MillerRunner, ate_miller_loop, _loop_inner_1_of_2, _loop_inner_2_of_2}; -pub use groth16::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; +pub use groth16::{ + PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, CubicScale +}; #[cfg(test)] mod test; diff --git a/packages/bn_ate_loop/src/test.cairo b/packages/bn_ate_loop/src/test.cairo index 1cf9559..0654291 100644 --- a/packages/bn_ate_loop/src/test.cairo +++ b/packages/bn_ate_loop/src/test.cairo @@ -8,11 +8,6 @@ struct MockMillerRunner {} type MockAccumulator = felt252; impl Miller_u256 of MillerRunner<(), MockMillerRunner, MockAccumulator> { - // Returns accumulator - fn accumulator(self: @MockMillerRunner, ref curve: ()) -> MockAccumulator { - 1 - } - // first and second step, O and N fn bit_1st_2nd( self: @MockMillerRunner, ref curve: (), i1: u32, i2: u32, ref acc: MockAccumulator @@ -47,6 +42,7 @@ impl Miller_u256 of MillerRunner<(), MockMillerRunner, MockAccumulator> { #[test] fn test_ate_miller_loop() { let mut curve = (); - let res: MockAccumulator = ate_miller_loop(ref curve, MockMillerRunner {}); + let mut acc = 1; + let res: MockAccumulator = ate_miller_loop(ref curve, MockMillerRunner {}, ref acc); assert(res == 0x19d797039be763ba8, 'wrong value for 6u + 2'); } diff --git a/packages/ec_groups/src/bn.cairo b/packages/ec_groups/src/bn.cairo index bfb502e..4704b17 100644 --- a/packages/ec_groups/src/bn.cairo +++ b/packages/ec_groups/src/bn.cairo @@ -44,7 +44,6 @@ pub impl AffineOpsBn< self.pt_on_slope(pt, self.chord(pt, rhs), rhs.x) } - fn pt_dbl(ref self: TCurve, pt: Affine) -> Affine { self.pt_on_slope(pt, self.tangent(pt), pt.x) } From 4aff51ed98624ee06fa26d9b3803ca7c3749b37b Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 19:04:48 +0530 Subject: [PATCH 29/97] bn254 u256 pairing utils --- packages/bn254_u256/src/lib.cairo | 8 +++- packages/bn254_u256/src/pairing/utils.cairo | 50 ++++++++++++++++----- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index ca23512..a63c5af 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -10,6 +10,10 @@ pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3Gen>; pub type Fq12 = Fq2Gen; -mod pairing { - mod utils; +pub mod pairing { + pub mod utils; } + +pub use pairing::utils::{ICProcess, ICArrayInput, CubicScale}; +pub use pairing::utils::{SchzipCommitment, SchzipPreCompute, SchZipAccumulator}; +pub use pairing::utils::{p_precompute}; diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 7e8c2cc..8d14018 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -1,29 +1,59 @@ use ec_groups::ECOperations; -use bn_ate_loop::{PPrecompute}; -use bn254_u256::{Fq, Fq2, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; -use bn254_u256::Bn254U256Curve; +use bn_ate_loop::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; +use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; +use bn254_u256::{Bn254U256Curve}; + +pub use bn_ate_loop::CubicScale; + +#[derive(Drop)] +pub struct SchzipCommitment { + pub remainders: Array, + pub q_rlc_sum: Array, +} + +#[derive(Drop)] +pub struct SchzipPreCompute { + pub g16_precompute: Groth16PreCompute< + Groth16MillerG1, Groth16MillerG1>, Groth16MillerG2, TLines, Fq12 + >, + pub schzip: SchzipCommitment, +} + +#[derive(Drop)] +pub struct SchZipAccumulator { + pub g2: Groth16MillerG2, + pub schzip_i: u256, + pub lhs_rhs: Fq, +} + +// Precomputes p for the pairing function +pub fn p_precompute(ref self: Bn254U256Curve, p: PtG1) -> PPrecompute { + let y_inv = self.inv(p.y); + let negx = self.neg(p.x); + PPrecompute { neg_x_over_y: self.mul(negx, y_inv), y_inv } +} // Generic Input constraints processing -trait ICProcess { - fn process_inputs_and_ic(ref self: TIC, inputs: TInputs, ref curve: TCurve) -> TG1; +pub trait ICProcess { + fn process_inputs_and_ic(ref self: TCurve, points: TIC, inputs: TInputs) -> TG1; } // Input constraints processing for array of IC paramters -impl ICArrayInput of ICProcess, Array, PtG1> { +pub impl ICArrayInput of ICProcess, Array, PtG1> { fn process_inputs_and_ic( - ref self: Array, mut inputs: Array, ref curve: Bn254U256Curve + ref self: Bn254U256Curve, mut points: Array, mut inputs: Array ) -> PtG1 { // First element is the initial point - let mut ic_point = self.pop_front().unwrap(); + let mut ic_point = points.pop_front().unwrap(); - assert(inputs.len() == self.len(), 'incorrect input length'); + assert(inputs.len() == points.len(), 'incorrect input length'); if inputs.len() == 0 { return ic_point; } loop { - match self.pop_front() { + match points.pop_front() { Option::Some(point) => { // match inputs.pop_front() { Option::Some(in) => { From 0c3805dbfcdb6a32cc9f8cf929e02bc4d3bf0dc7 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 19:06:08 +0530 Subject: [PATCH 30/97] bn254 u256 package --- Scarb.lock | 22 +++++++++++++++++++--- packages/bn254_u256/Scarb.toml | 11 +++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 packages/bn254_u256/Scarb.toml diff --git a/Scarb.lock b/Scarb.lock index 774c989..d2204df 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -5,9 +5,22 @@ version = 1 name = "bn" version = "0.1.0" +[[package]] +name = "bn254_u256" +version = "0.1.0" +dependencies = [ + "bn_ate_loop", + "ec_groups", + "fq_types", +] + [[package]] name = "bn_ate_loop" version = "0.1.0" +dependencies = [ + "ec_groups", + "fq_types", +] [[package]] name = "bn_contracts" @@ -17,13 +30,16 @@ dependencies = [ ] [[package]] -name = "fast_mod" +name = "ec_groups" version = "0.1.0" +dependencies = [ + "fq_types", +] [[package]] -name = "fq_types" +name = "fast_mod" version = "0.1.0" [[package]] -name = "pairing" +name = "fq_types" version = "0.1.0" diff --git a/packages/bn254_u256/Scarb.toml b/packages/bn254_u256/Scarb.toml new file mode 100644 index 0000000..85f81ad --- /dev/null +++ b/packages/bn254_u256/Scarb.toml @@ -0,0 +1,11 @@ +[package] +name = "bn254_u256" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +bn_ate_loop = { path = "../bn_ate_loop" } +ec_groups = { path = "../ec_groups" } +fq_types = { path = "../fq_types" } \ No newline at end of file From 0c86cdce747f3edc793d3658ac4c79f8ff07320f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 19:29:10 +0530 Subject: [PATCH 31/97] bn254 u256 miller impl --- packages/bn254_u256/src/lib.cairo | 3 +- .../src/pairing/schzip_miller_runner.cairo | 34 +++++++++++++++++++ packages/bn254_u256/src/pairing/utils.cairo | 15 +++++--- 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 packages/bn254_u256/src/pairing/schzip_miller_runner.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index a63c5af..3efd061 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -12,8 +12,9 @@ pub type Fq12 = Fq2Gen; pub mod pairing { pub mod utils; + pub mod schzip_miller_runner; } pub use pairing::utils::{ICProcess, ICArrayInput, CubicScale}; -pub use pairing::utils::{SchzipCommitment, SchzipPreCompute, SchZipAccumulator}; +pub use pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator}; pub use pairing::utils::{p_precompute}; diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo new file mode 100644 index 0000000..af26320 --- /dev/null +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -0,0 +1,34 @@ +use ec_groups::{LineFn, LinesArray, LinesArrayGet}; +use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve}; +use bn254_u256::pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator, LnFn, SZPreComLines}; +use bn_ate_loop::MillerRunner; + +pub impl Miller_Bn254_U256 of MillerRunner { + // first and second step, O and N + fn bit_1st_2nd( + self: @SZPreComLines, ref curve: Bn254U256Curve, i1: u32, i2: u32, ref acc: SZAccumulator + ) { // + self.bit_o(ref curve, i1, ref acc); + self.bit_n(ref curve, i2, ref acc); + } + + // 0 bit + fn bit_o(self: @SZPreComLines, ref curve: Bn254U256Curve, i: u32, ref acc: SZAccumulator) { // + // @TODO + } + + // 1 bit + fn bit_p(self: @SZPreComLines, ref curve: Bn254U256Curve, i: u32, ref acc: SZAccumulator) { // + // @TODO + } + + // -1 bit + fn bit_n(self: @SZPreComLines, ref curve: Bn254U256Curve, i: u32, ref acc: SZAccumulator) { // + // @TODO + } + + // last step + fn last(self: @SZPreComLines, ref curve: Bn254U256Curve, ref acc: SZAccumulator) { // + // @TODO + } +} diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 8d14018..d4559af 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -1,4 +1,4 @@ -use ec_groups::ECOperations; +use ec_groups::{LineFn, LinesArray, LinesArrayGet, ECOperations}; use bn_ate_loop::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; use bn254_u256::{Bn254U256Curve}; @@ -6,26 +6,31 @@ use bn254_u256::{Bn254U256Curve}; pub use bn_ate_loop::CubicScale; #[derive(Drop)] -pub struct SchzipCommitment { +pub struct SZCommitment { pub remainders: Array, pub q_rlc_sum: Array, } #[derive(Drop)] -pub struct SchzipPreCompute { +pub struct SZPreCompute { pub g16_precompute: Groth16PreCompute< Groth16MillerG1, Groth16MillerG1>, Groth16MillerG2, TLines, Fq12 >, - pub schzip: SchzipCommitment, + pub schzip: SZCommitment, } #[derive(Drop)] -pub struct SchZipAccumulator { +pub struct SZAccumulator { pub g2: Groth16MillerG2, pub schzip_i: u256, pub lhs_rhs: Fq, } +pub type LnFn = LineFn; +pub type LnArray = LinesArray; + +pub type SZPreComLines = SZPreCompute; + // Precomputes p for the pairing function pub fn p_precompute(ref self: Bn254U256Curve, p: PtG1) -> PPrecompute { let y_inv = self.inv(p.y); From 67c2a36a73acb36a4ec48f269c72539794b71771 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 11 Jul 2024 19:29:42 +0530 Subject: [PATCH 32/97] bn254 u256 miller functions --- packages/bn254_u256/src/lib.cairo | 1 + .../src/pairing/schzip_miller.cairo | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 packages/bn254_u256/src/pairing/schzip_miller.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 3efd061..3d69df8 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -13,6 +13,7 @@ pub type Fq12 = Fq2Gen; pub mod pairing { pub mod utils; pub mod schzip_miller_runner; + pub mod schzip_miller; } pub use pairing::utils::{ICProcess, ICArrayInput, CubicScale}; diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo new file mode 100644 index 0000000..9edadc2 --- /dev/null +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -0,0 +1,90 @@ +use ec_groups::ECOperations; +use bn_ate_loop::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; +use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing}; +use bn254_u256::pairing::schzip_miller_runner::Miller_Bn254_U256; +use bn254_u256::pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArray}; +use bn254_u256::pairing::utils::{ICArrayInput, p_precompute}; +use bn_ate_loop::{MillerRunner, ate_miller_loop, CubicScale}; +use ec_groups::{LineFn, StepLinesGet, LinesArrayGet}; + + +pub type InputConstraintPoints = Array; + +type SchzipAccumulator = felt252; +type LnFn = LineFn; + +// Does the verification +fn schzip_miller( + ref curve: Bn254U256Curve, + pi_a: PtG1, + pi_b: PtG2, + pi_c: PtG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + setup: Groth16Circuit, + schzip_remainders: Array, + schzip_qrlc: Array, + field_nz: NonZero, +) -> (Fq12, Fq12, SZPreCompute, SZAccumulator) { // + // Compute k from ic and public_inputs + let Groth16Circuit { alpha_beta, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; + + let k: PtG1 = curve.process_inputs_and_ic(ic, inputs); + + let pi_a = curve.pt_neg(pi_a); + + // build precompute + let p = Groth16MillerG1 { pi_a, pi_c, k, }; + let q = Groth16MillerG2 { pi_b, gamma, delta }; + let neg_q = Groth16MillerG2 { pi_b: curve.pt_neg(pi_b), gamma: gamma_neg, delta: delta_neg }; + let ppc = Groth16MillerG1 { + pi_a: p_precompute(ref curve, pi_a), + pi_c: p_precompute(ref curve, pi_c), + k: p_precompute(ref curve, k), + }; + let g16_precompute = Groth16PreCompute { + p, q, ppc, neg_q, lines, residue_witness, residue_witness_inv, field_nz, + }; + + let precomp = SZPreCompute { + g16_precompute, + schzip: SZCommitment { remainders: schzip_remainders, q_rlc_sum: schzip_qrlc }, + }; + + // miller accumulator + let mut q_acc = SZAccumulator { g2: q, schzip_i: 0, lhs_rhs: 0_u256.into() }; + + ate_miller_loop(ref curve, precomp, ref q_acc); +} + +// Does the verification +pub fn schzip_base_verify>, +Drop>( + ref curve: TCurve, + pi_a: PtG1, + pi_b: PtG2, + pi_c: PtG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: CubicScale, + setup: Groth16Circuit, + schzip: Array, + field_nz: NonZero, +) { + // residue_witness_inv as starter to incorporate 6 * x + 2 in the miller loop + + // miller loop result + let (f, alpha_beta, precomp, mut acc) = schzip_miller( + ref curve, + pi_a, + pi_b, + pi_c, + inputs, + residue_witness, + residue_witness_inv, + setup, + schzip, + field_nz + ); +} From ac7fe91132bd67a07bab9105cce2eae5eb39bb76 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Fri, 12 Jul 2024 12:45:15 +0530 Subject: [PATCH 33/97] schzip miller loop cleanup --- .../src/pairing/schzip_miller.cairo | 19 +++++++++---------- packages/bn_ate_loop/src/groth16.cairo | 1 - 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 9edadc2..16d689e 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -14,7 +14,7 @@ type SchzipAccumulator = felt252; type LnFn = LineFn; // Does the verification -fn schzip_miller( +fn schzip_miller( ref curve: Bn254U256Curve, pi_a: PtG1, pi_b: PtG2, @@ -25,7 +25,6 @@ fn schzip_miller( setup: Groth16Circuit, schzip_remainders: Array, schzip_qrlc: Array, - field_nz: NonZero, ) -> (Fq12, Fq12, SZPreCompute, SZAccumulator) { // // Compute k from ic and public_inputs let Groth16Circuit { alpha_beta, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; @@ -44,7 +43,7 @@ fn schzip_miller( k: p_precompute(ref curve, k), }; let g16_precompute = Groth16PreCompute { - p, q, ppc, neg_q, lines, residue_witness, residue_witness_inv, field_nz, + p, q, ppc, neg_q, lines, residue_witness, residue_witness_inv, }; let precomp = SZPreCompute { @@ -59,8 +58,8 @@ fn schzip_miller( } // Does the verification -pub fn schzip_base_verify>, +Drop>( - ref curve: TCurve, +pub fn schzip_base_verify( + ref curve: Bn254U256Curve, pi_a: PtG1, pi_b: PtG2, pi_c: PtG1, @@ -69,13 +68,13 @@ pub fn schzip_base_verify>, + residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - schzip: Array, - field_nz: NonZero, + schzip_remainders: Array, + schzip_qrlc: Array, ) { // residue_witness_inv as starter to incorporate 6 * x + 2 in the miller loop // miller loop result - let (f, alpha_beta, precomp, mut acc) = schzip_miller( + schzip_miller( ref curve, pi_a, pi_b, @@ -84,7 +83,7 @@ pub fn schzip_base_verify>, + residue_witness, residue_witness_inv, setup, - schzip, - field_nz + schzip_remainders, + schzip_qrlc ); } diff --git a/packages/bn_ate_loop/src/groth16.cairo b/packages/bn_ate_loop/src/groth16.cairo index 75f8857..f1eaafd 100644 --- a/packages/bn_ate_loop/src/groth16.cairo +++ b/packages/bn_ate_loop/src/groth16.cairo @@ -41,7 +41,6 @@ pub struct Groth16PreCompute { pub lines: TLines, pub residue_witness: TFq12, pub residue_witness_inv: TFq12, - pub field_nz: NonZero, } From 5794cef49b5fd1d88f5d29100d339fa01e622765 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 13 Jul 2024 17:28:57 +0530 Subject: [PATCH 34/97] bn ate loop on curve --- packages/bn_ate_loop/src/ate_loop.cairo | 144 ++++++++++++------------ packages/bn_ate_loop/src/groth16.cairo | 8 -- packages/bn_ate_loop/src/lib.cairo | 4 +- packages/bn_ate_loop/src/test.cairo | 28 +++-- 4 files changed, 86 insertions(+), 98 deletions(-) diff --git a/packages/bn_ate_loop/src/ate_loop.cairo b/packages/bn_ate_loop/src/ate_loop.cairo index ba535db..52ec19e 100644 --- a/packages/bn_ate_loop/src/ate_loop.cairo +++ b/packages/bn_ate_loop/src/ate_loop.cairo @@ -1,18 +1,18 @@ pub trait MillerRunner { // first and second step, O and N - fn bit_1st_2nd(self: @TRunner, ref curve: TCurve, i1: u32, i2: u32, ref acc: TAccumulator); + fn miller_bit_1_2(ref self: TCurve, runner: @TRunner, i1: u32, i2: u32, ref acc: TAccumulator); // 0 bit - fn bit_o(self: @TRunner, ref curve: TCurve, i: u32, ref acc: TAccumulator); + fn miller_bit_o(ref self: TCurve, runner: @TRunner, i: u32, ref acc: TAccumulator); // 1 bit - fn bit_p(self: @TRunner, ref curve: TCurve, i: u32, ref acc: TAccumulator); + fn miller_bit_p(ref self: TCurve, runner: @TRunner, i: u32, ref acc: TAccumulator); // -1 bit - fn bit_n(self: @TRunner, ref curve: TCurve, i: u32, ref acc: TAccumulator); + fn miller_bit_n(ref self: TCurve, runner: @TRunner, i: u32, ref acc: TAccumulator); // last step - fn last(self: @TRunner, ref curve: TCurve, ref acc: TAccumulator); + fn miller_last(ref self: TCurve, runner: @TRunner, ref acc: TAccumulator); } pub fn ate_miller_loop< @@ -23,13 +23,13 @@ pub fn ate_miller_loop< +Drop, +Drop >( - ref curve: TCurve, runner: TRunner, ref q_acc: TAccumulator + ref curve: TCurve, runner: TRunner, mut q_acc: TAccumulator ) -> TAccumulator { - core::gas::withdraw_gas().unwrap(); core::internal::revoke_ap_tracking(); _loop_inner_1_of_2(@runner, ref curve, ref q_acc); _loop_inner_2_of_2(@runner, ref curve, ref q_acc); + q_acc } pub fn _loop_inner_1_of_2< @@ -38,39 +38,39 @@ pub fn _loop_inner_1_of_2< runner: @TRunner, ref curve: TCurve, ref q_acc: TAccumulator ) { // ate_loop[64] = O and ate_loop[63] = N - runner.bit_1st_2nd(ref curve, 64, 63, ref q_acc); - runner.bit_o(ref curve, 62, ref q_acc); // ate_loop[62] = O - runner.bit_p(ref curve, 61, ref q_acc); // ate_loop[61] = P - runner.bit_o(ref curve, 60, ref q_acc); // ate_loop[60] = O - runner.bit_o(ref curve, 59, ref q_acc); // ate_loop[59] = O - runner.bit_o(ref curve, 58, ref q_acc); // ate_loop[58] = O - runner.bit_n(ref curve, 57, ref q_acc); // ate_loop[57] = N - runner.bit_o(ref curve, 56, ref q_acc); // ate_loop[56] = O - runner.bit_n(ref curve, 55, ref q_acc); // ate_loop[55] = N - runner.bit_o(ref curve, 54, ref q_acc); // ate_loop[54] = O - runner.bit_o(ref curve, 53, ref q_acc); // ate_loop[53] = O - runner.bit_o(ref curve, 52, ref q_acc); // ate_loop[52] = O - runner.bit_n(ref curve, 51, ref q_acc); // ate_loop[51] = N - runner.bit_o(ref curve, 50, ref q_acc); // ate_loop[50] = O - runner.bit_p(ref curve, 49, ref q_acc); // ate_loop[49] = P - runner.bit_o(ref curve, 48, ref q_acc); // ate_loop[48] = O - runner.bit_n(ref curve, 47, ref q_acc); // ate_loop[47] = N - runner.bit_o(ref curve, 46, ref q_acc); // ate_loop[46] = O - runner.bit_o(ref curve, 45, ref q_acc); // ate_loop[45] = O - runner.bit_n(ref curve, 44, ref q_acc); // ate_loop[44] = N - runner.bit_o(ref curve, 43, ref q_acc); // ate_loop[43] = O - runner.bit_o(ref curve, 42, ref q_acc); // ate_loop[42] = O - runner.bit_o(ref curve, 41, ref q_acc); // ate_loop[41] = O - runner.bit_o(ref curve, 40, ref q_acc); // ate_loop[40] = O - runner.bit_o(ref curve, 39, ref q_acc); // ate_loop[39] = O - runner.bit_p(ref curve, 38, ref q_acc); // ate_loop[38] = P - runner.bit_o(ref curve, 37, ref q_acc); // ate_loop[37] = O - runner.bit_o(ref curve, 36, ref q_acc); // ate_loop[36] = O - runner.bit_n(ref curve, 35, ref q_acc); // ate_loop[35] = N - runner.bit_o(ref curve, 34, ref q_acc); // ate_loop[34] = O - runner.bit_p(ref curve, 33, ref q_acc); // ate_loop[33] = P - runner.bit_o(ref curve, 32, ref q_acc); // ate_loop[32] = O - runner.bit_o(ref curve, 31, ref q_acc); // ate_loop[31] = O + curve.miller_bit_1_2(runner, 64, 63, ref q_acc); + curve.miller_bit_o(runner, 62, ref q_acc); // ate_loop[62] = O + curve.miller_bit_p(runner, 61, ref q_acc); // ate_loop[61] = P + curve.miller_bit_o(runner, 60, ref q_acc); // ate_loop[60] = O + curve.miller_bit_o(runner, 59, ref q_acc); // ate_loop[59] = O + curve.miller_bit_o(runner, 58, ref q_acc); // ate_loop[58] = O + curve.miller_bit_n(runner, 57, ref q_acc); // ate_loop[57] = N + curve.miller_bit_o(runner, 56, ref q_acc); // ate_loop[56] = O + curve.miller_bit_n(runner, 55, ref q_acc); // ate_loop[55] = N + curve.miller_bit_o(runner, 54, ref q_acc); // ate_loop[54] = O + curve.miller_bit_o(runner, 53, ref q_acc); // ate_loop[53] = O + curve.miller_bit_o(runner, 52, ref q_acc); // ate_loop[52] = O + curve.miller_bit_n(runner, 51, ref q_acc); // ate_loop[51] = N + curve.miller_bit_o(runner, 50, ref q_acc); // ate_loop[50] = O + curve.miller_bit_p(runner, 49, ref q_acc); // ate_loop[49] = P + curve.miller_bit_o(runner, 48, ref q_acc); // ate_loop[48] = O + curve.miller_bit_n(runner, 47, ref q_acc); // ate_loop[47] = N + curve.miller_bit_o(runner, 46, ref q_acc); // ate_loop[46] = O + curve.miller_bit_o(runner, 45, ref q_acc); // ate_loop[45] = O + curve.miller_bit_n(runner, 44, ref q_acc); // ate_loop[44] = N + curve.miller_bit_o(runner, 43, ref q_acc); // ate_loop[43] = O + curve.miller_bit_o(runner, 42, ref q_acc); // ate_loop[42] = O + curve.miller_bit_o(runner, 41, ref q_acc); // ate_loop[41] = O + curve.miller_bit_o(runner, 40, ref q_acc); // ate_loop[40] = O + curve.miller_bit_o(runner, 39, ref q_acc); // ate_loop[39] = O + curve.miller_bit_p(runner, 38, ref q_acc); // ate_loop[38] = P + curve.miller_bit_o(runner, 37, ref q_acc); // ate_loop[37] = O + curve.miller_bit_o(runner, 36, ref q_acc); // ate_loop[36] = O + curve.miller_bit_n(runner, 35, ref q_acc); // ate_loop[35] = N + curve.miller_bit_o(runner, 34, ref q_acc); // ate_loop[34] = O + curve.miller_bit_p(runner, 33, ref q_acc); // ate_loop[33] = P + curve.miller_bit_o(runner, 32, ref q_acc); // ate_loop[32] = O + curve.miller_bit_o(runner, 31, ref q_acc); // ate_loop[31] = O } pub fn _loop_inner_2_of_2< @@ -78,36 +78,36 @@ pub fn _loop_inner_2_of_2< >( runner: @TRunner, ref curve: TCurve, ref q_acc: TAccumulator ) { - runner.bit_n(ref curve, 30, ref q_acc); // ate_loop[30] = N - runner.bit_o(ref curve, 29, ref q_acc); // ate_loop[29] = O - runner.bit_o(ref curve, 28, ref q_acc); // ate_loop[28] = O - runner.bit_o(ref curve, 27, ref q_acc); // ate_loop[27] = O - runner.bit_o(ref curve, 26, ref q_acc); // ate_loop[26] = O - runner.bit_n(ref curve, 25, ref q_acc); // ate_loop[25] = N - runner.bit_o(ref curve, 24, ref q_acc); // ate_loop[24] = O - runner.bit_p(ref curve, 23, ref q_acc); // ate_loop[23] = P - runner.bit_o(ref curve, 22, ref q_acc); // ate_loop[22] = O - runner.bit_o(ref curve, 21, ref q_acc); // ate_loop[21] = O - runner.bit_o(ref curve, 20, ref q_acc); // ate_loop[20] = O - runner.bit_n(ref curve, 19, ref q_acc); // ate_loop[19] = N - runner.bit_o(ref curve, 18, ref q_acc); // ate_loop[18] = O - runner.bit_n(ref curve, 17, ref q_acc); // ate_loop[17] = N - runner.bit_o(ref curve, 16, ref q_acc); // ate_loop[16] = O - runner.bit_o(ref curve, 15, ref q_acc); // ate_loop[15] = O - runner.bit_p(ref curve, 14, ref q_acc); // ate_loop[14] = P - runner.bit_o(ref curve, 13, ref q_acc); // ate_loop[13] = O - runner.bit_o(ref curve, 12, ref q_acc); // ate_loop[12] = O - runner.bit_o(ref curve, 11, ref q_acc); // ate_loop[11] = O - runner.bit_n(ref curve, 10, ref q_acc); // ate_loop[10] = N - runner.bit_o(ref curve, 9, ref q_acc); // ate_loop[ 9] = O - runner.bit_o(ref curve, 8, ref q_acc); // ate_loop[ 8] = O - runner.bit_n(ref curve, 7, ref q_acc); // ate_loop[ 7] = N - runner.bit_o(ref curve, 6, ref q_acc); // ate_loop[ 6] = O - runner.bit_p(ref curve, 5, ref q_acc); // ate_loop[ 5] = P - runner.bit_o(ref curve, 4, ref q_acc); // ate_loop[ 4] = O - runner.bit_p(ref curve, 3, ref q_acc); // ate_loop[ 3] = P - runner.bit_o(ref curve, 2, ref q_acc); // ate_loop[ 2] = O - runner.bit_o(ref curve, 1, ref q_acc); // ate_loop[ 1] = O - runner.bit_o(ref curve, 0, ref q_acc); // ate_loop[ 0] = O - runner.last(ref curve, ref q_acc); + curve.miller_bit_n(runner, 30, ref q_acc); // ate_loop[30] = N + curve.miller_bit_o(runner, 29, ref q_acc); // ate_loop[29] = O + curve.miller_bit_o(runner, 28, ref q_acc); // ate_loop[28] = O + curve.miller_bit_o(runner, 27, ref q_acc); // ate_loop[27] = O + curve.miller_bit_o(runner, 26, ref q_acc); // ate_loop[26] = O + curve.miller_bit_n(runner, 25, ref q_acc); // ate_loop[25] = N + curve.miller_bit_o(runner, 24, ref q_acc); // ate_loop[24] = O + curve.miller_bit_p(runner, 23, ref q_acc); // ate_loop[23] = P + curve.miller_bit_o(runner, 22, ref q_acc); // ate_loop[22] = O + curve.miller_bit_o(runner, 21, ref q_acc); // ate_loop[21] = O + curve.miller_bit_o(runner, 20, ref q_acc); // ate_loop[20] = O + curve.miller_bit_n(runner, 19, ref q_acc); // ate_loop[19] = N + curve.miller_bit_o(runner, 18, ref q_acc); // ate_loop[18] = O + curve.miller_bit_n(runner, 17, ref q_acc); // ate_loop[17] = N + curve.miller_bit_o(runner, 16, ref q_acc); // ate_loop[16] = O + curve.miller_bit_o(runner, 15, ref q_acc); // ate_loop[15] = O + curve.miller_bit_p(runner, 14, ref q_acc); // ate_loop[14] = P + curve.miller_bit_o(runner, 13, ref q_acc); // ate_loop[13] = O + curve.miller_bit_o(runner, 12, ref q_acc); // ate_loop[12] = O + curve.miller_bit_o(runner, 11, ref q_acc); // ate_loop[11] = O + curve.miller_bit_n(runner, 10, ref q_acc); // ate_loop[10] = N + curve.miller_bit_o(runner, 9, ref q_acc); // ate_loop[ 9] = O + curve.miller_bit_o(runner, 8, ref q_acc); // ate_loop[ 8] = O + curve.miller_bit_n(runner, 7, ref q_acc); // ate_loop[ 7] = N + curve.miller_bit_o(runner, 6, ref q_acc); // ate_loop[ 6] = O + curve.miller_bit_p(runner, 5, ref q_acc); // ate_loop[ 5] = P + curve.miller_bit_o(runner, 4, ref q_acc); // ate_loop[ 4] = O + curve.miller_bit_p(runner, 3, ref q_acc); // ate_loop[ 3] = P + curve.miller_bit_o(runner, 2, ref q_acc); // ate_loop[ 2] = O + curve.miller_bit_o(runner, 1, ref q_acc); // ate_loop[ 1] = O + curve.miller_bit_o(runner, 0, ref q_acc); // ate_loop[ 0] = O + curve.miller_last(runner, ref q_acc); } diff --git a/packages/bn_ate_loop/src/groth16.cairo b/packages/bn_ate_loop/src/groth16.cairo index f1eaafd..94fb323 100644 --- a/packages/bn_ate_loop/src/groth16.cairo +++ b/packages/bn_ate_loop/src/groth16.cairo @@ -42,11 +42,3 @@ pub struct Groth16PreCompute { pub residue_witness: TFq12, pub residue_witness_inv: TFq12, } - - -#[derive(Drop)] -pub enum CubicScale { - Zero, - One, - Two, -} diff --git a/packages/bn_ate_loop/src/lib.cairo b/packages/bn_ate_loop/src/lib.cairo index 280ca1a..231dd39 100644 --- a/packages/bn_ate_loop/src/lib.cairo +++ b/packages/bn_ate_loop/src/lib.cairo @@ -2,9 +2,7 @@ pub mod ate_loop; pub mod groth16; pub use ate_loop::{MillerRunner, ate_miller_loop, _loop_inner_1_of_2, _loop_inner_2_of_2}; -pub use groth16::{ - PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, CubicScale -}; +pub use groth16::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; #[cfg(test)] mod test; diff --git a/packages/bn_ate_loop/src/test.cairo b/packages/bn_ate_loop/src/test.cairo index 0654291..36c1a38 100644 --- a/packages/bn_ate_loop/src/test.cairo +++ b/packages/bn_ate_loop/src/test.cairo @@ -3,38 +3,36 @@ use super::{MillerRunner, ate_miller_loop}; #[derive(Drop)] -struct MockMillerRunner {} +struct MockRunner {} type MockAccumulator = felt252; -impl Miller_u256 of MillerRunner<(), MockMillerRunner, MockAccumulator> { +impl Miller_u256 of MillerRunner<(), MockRunner, MockAccumulator> { // first and second step, O and N - fn bit_1st_2nd( - self: @MockMillerRunner, ref curve: (), i1: u32, i2: u32, ref acc: MockAccumulator + fn miller_bit_1_2( + ref self: (), runner: @MockRunner, i1: u32, i2: u32, ref acc: MockAccumulator ) { // - self.bit_o(ref curve, i1, ref acc); - self.bit_n(ref curve, i2, ref acc); + self.miller_bit_o(runner, i1, ref acc); + self.miller_bit_n(runner, i2, ref acc); } // 0 bit - fn bit_o(self: @MockMillerRunner, ref curve: (), i: u32, ref acc: MockAccumulator) { // + fn miller_bit_o(ref self: (), runner: @MockRunner, i: u32, ref acc: MockAccumulator) { // acc = acc + acc; } // 1 bit - fn bit_p(self: @MockMillerRunner, ref curve: (), i: u32, ref acc: MockAccumulator) { // - acc = acc + acc; - acc = acc + 1; + fn miller_bit_p(ref self: (), runner: @MockRunner, i: u32, ref acc: MockAccumulator) { // + acc = acc + acc + 1; } // -1 bit - fn bit_n(self: @MockMillerRunner, ref curve: (), i: u32, ref acc: MockAccumulator) { // - acc = acc + acc; - acc = acc - 1; + fn miller_bit_n(ref self: (), runner: @MockRunner, i: u32, ref acc: MockAccumulator) { // + acc = acc + acc - 1; } // last step - fn last(self: @MockMillerRunner, ref curve: (), ref acc: MockAccumulator) { // + fn miller_last(ref self: (), runner: @MockRunner, ref acc: MockAccumulator) { // // do nothing } } @@ -43,6 +41,6 @@ impl Miller_u256 of MillerRunner<(), MockMillerRunner, MockAccumulator> { fn test_ate_miller_loop() { let mut curve = (); let mut acc = 1; - let res: MockAccumulator = ate_miller_loop(ref curve, MockMillerRunner {}, ref acc); + let res: MockAccumulator = ate_miller_loop(ref curve, MockRunner {}, acc); assert(res == 0x19d797039be763ba8, 'wrong value for 6u + 2'); } From d2fe7ba98cb39da52a63c0357d1c21aee3297c5f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 13 Jul 2024 17:31:36 +0530 Subject: [PATCH 35/97] cubic scale in fq type --- packages/bn254_u256/src/lib.cairo | 4 ++-- packages/bn254_u256/src/pairing/schzip_miller.cairo | 4 ++-- packages/bn254_u256/src/pairing/utils.cairo | 2 -- packages/fq_types/src/lib.cairo | 7 +++++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 3d69df8..dff4654 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -1,4 +1,4 @@ -use fq_types::{Fq2 as Fq2Gen, fq2, Fq3 as Fq3Gen, fq3,}; +use fq_types::{Fq2 as Fq2Gen, fq2, Fq3 as Fq3Gen, fq3, CubicScale}; pub mod curve; pub mod fq_1; @@ -16,6 +16,6 @@ pub mod pairing { pub mod schzip_miller; } -pub use pairing::utils::{ICProcess, ICArrayInput, CubicScale}; +pub use pairing::utils::{ICProcess, ICArrayInput}; pub use pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator}; pub use pairing::utils::{p_precompute}; diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 16d689e..258880c 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,10 +1,10 @@ use ec_groups::ECOperations; use bn_ate_loop::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; -use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing}; +use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing, CubicScale}; use bn254_u256::pairing::schzip_miller_runner::Miller_Bn254_U256; use bn254_u256::pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArray}; use bn254_u256::pairing::utils::{ICArrayInput, p_precompute}; -use bn_ate_loop::{MillerRunner, ate_miller_loop, CubicScale}; +use bn_ate_loop::{MillerRunner, ate_miller_loop}; use ec_groups::{LineFn, StepLinesGet, LinesArrayGet}; diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index d4559af..613f940 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -3,8 +3,6 @@ use bn_ate_loop::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16Miller use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; use bn254_u256::{Bn254U256Curve}; -pub use bn_ate_loop::CubicScale; - #[derive(Drop)] pub struct SZCommitment { pub remainders: Array, diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index 3d1ae0f..a867f71 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -13,6 +13,13 @@ pub struct Fq3 { pub c2: T, } +#[derive(Copy, Drop)] +pub enum CubicScale { + Zero, + One, + Two, +} + pub fn fq2(c0: T, c1: T) -> Fq2 { Fq2 { c0, c1 } } From 22fb2eb904d574bbd2e82554760a8cb737399756 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 13 Jul 2024 17:32:25 +0530 Subject: [PATCH 36/97] schwartz zippel: init and steps trait --- packages/schwartz_zippel/Scarb.toml | 9 +++++++++ packages/schwartz_zippel/src/lib.cairo | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 packages/schwartz_zippel/Scarb.toml create mode 100644 packages/schwartz_zippel/src/lib.cairo diff --git a/packages/schwartz_zippel/Scarb.toml b/packages/schwartz_zippel/Scarb.toml new file mode 100644 index 0000000..e01a942 --- /dev/null +++ b/packages/schwartz_zippel/Scarb.toml @@ -0,0 +1,9 @@ +[package] +name = "schwartz_zippel" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +fq_types = { path = "../fq_types" } \ No newline at end of file diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo new file mode 100644 index 0000000..29fb54a --- /dev/null +++ b/packages/schwartz_zippel/src/lib.cairo @@ -0,0 +1,23 @@ +use fq_types::{Fq2, Fq3, F12S034 as FS034, CubicScale}; + +pub type Lines = (FS034, FS034, FS034); +pub type F034X2 = (FS034, FS034); +pub type LinesDbl = (F034X2, F034X2, F034X2); + +type Fq6 = Fq3>; +type Fq12 = Fq2>; +type Residue = (CubicScale, Fq12, Fq12); + +pub trait SchZipSteps { + fn sz_init(ref self: TCurve, sz: @T, ref f: Fq12); + fn sz_sqr(ref self: TCurve, sz: @T, ref f: Fq12); + fn sz_zero_bit(ref self: TCurve, sz: @T, ref f: Fq12, lines: Lines>); + fn sz_nz_bit( + ref self: TCurve, sz: @T, ref f: Fq12, lines: LinesDbl>, witness: Fq12 + ); + fn sz_last_step(ref self: TCurve, sz: @T, ref f: Fq12, lines: LinesDbl>); + + fn sz_post_miller( + ref self: TCurve, sz: @T, f: Fq12, alpha_beta: Fq12, residue: Residue + ) -> bool; +} From b4c9cd513c41e66d6dca46651dd46926bf72a767 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 13 Jul 2024 18:20:12 +0530 Subject: [PATCH 37/97] bn 254 u256 type errors --- packages/bn254_u256/Scarb.toml | 2 + .../src/pairing/schzip_miller.cairo | 47 +++++++------------ .../src/pairing/schzip_miller_runner.cairo | 33 ++++++++----- packages/bn254_u256/src/pairing/utils.cairo | 12 ++--- packages/bn_ate_loop/src/ate_loop.cairo | 4 +- packages/bn_ate_loop/src/test.cairo | 3 +- 6 files changed, 50 insertions(+), 51 deletions(-) diff --git a/packages/bn254_u256/Scarb.toml b/packages/bn254_u256/Scarb.toml index 85f81ad..7417f5d 100644 --- a/packages/bn254_u256/Scarb.toml +++ b/packages/bn254_u256/Scarb.toml @@ -6,6 +6,8 @@ edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] +schwartz_zippel = { path = "../schwartz_zippel" } +fast_mod = { path = "../fast_mod" } bn_ate_loop = { path = "../bn_ate_loop" } ec_groups = { path = "../ec_groups" } fq_types = { path = "../fq_types" } \ No newline at end of file diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 258880c..451c582 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,16 +1,18 @@ use ec_groups::ECOperations; use bn_ate_loop::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; -use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing, CubicScale}; -use bn254_u256::pairing::schzip_miller_runner::Miller_Bn254_U256; -use bn254_u256::pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArray}; -use bn254_u256::pairing::utils::{ICArrayInput, p_precompute}; -use bn_ate_loop::{MillerRunner, ate_miller_loop}; +use bn254_u256::{ + Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing, CubicScale, + pairing::{ + schzip_miller_runner::Miller_Bn254_U256, + utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArray}, + utils::{ICArrayInput, p_precompute}, + } +}; +use bn_ate_loop::{ate_miller_loop}; use ec_groups::{LineFn, StepLinesGet, LinesArrayGet}; pub type InputConstraintPoints = Array; - -type SchzipAccumulator = felt252; type LnFn = LineFn; // Does the verification @@ -23,11 +25,10 @@ fn schzip_miller( residue_witness: Fq12, residue_witness_inv: Fq12, setup: Groth16Circuit, - schzip_remainders: Array, - schzip_qrlc: Array, -) -> (Fq12, Fq12, SZPreCompute, SZAccumulator) { // + schzip: SZCommitment, +) -> SZAccumulator { // // Compute k from ic and public_inputs - let Groth16Circuit { alpha_beta, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; + let Groth16Circuit { alpha_beta: _, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; let k: PtG1 = curve.process_inputs_and_ic(ic, inputs); @@ -46,19 +47,16 @@ fn schzip_miller( p, q, ppc, neg_q, lines, residue_witness, residue_witness_inv, }; - let precomp = SZPreCompute { - g16_precompute, - schzip: SZCommitment { remainders: schzip_remainders, q_rlc_sum: schzip_qrlc }, - }; + let precomp = SZPreCompute { g16_precompute, schzip, }; // miller accumulator - let mut q_acc = SZAccumulator { g2: q, schzip_i: 0, lhs_rhs: 0_u256.into() }; + let mut q_acc = SZAccumulator { g2: q, schzip: (0, 0_u256.into()) }; - ate_miller_loop(ref curve, precomp, ref q_acc); + ate_miller_loop(ref curve, precomp, q_acc) } // Does the verification -pub fn schzip_base_verify( +pub fn schzip_verify( ref curve: Bn254U256Curve, pi_a: PtG1, pi_b: PtG2, @@ -71,19 +69,10 @@ pub fn schzip_base_verify( schzip_remainders: Array, schzip_qrlc: Array, ) { - // residue_witness_inv as starter to incorporate 6 * x + 2 in the miller loop + let schzip = SZCommitment { remainders: schzip_remainders, q_rlc_sum: schzip_qrlc }; // miller loop result schzip_miller( - ref curve, - pi_a, - pi_b, - pi_c, - inputs, - residue_witness, - residue_witness_inv, - setup, - schzip_remainders, - schzip_qrlc + ref curve, pi_a, pi_b, pi_c, inputs, residue_witness, residue_witness_inv, setup, schzip ); } diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index af26320..0aaa3c4 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,34 +1,45 @@ use ec_groups::{LineFn, LinesArray, LinesArrayGet}; -use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve}; -use bn254_u256::pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator, LnFn, SZPreComLines}; +use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; +use bn254_u256::pairing::utils::{ + LnArray, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn +}; use bn_ate_loop::MillerRunner; +use schwartz_zippel::SchZipSteps; -pub impl Miller_Bn254_U256 of MillerRunner { +type PreCompute = SZPreCompute; + +// TODO: +SchZipSteps + +pub impl Miller_Bn254_U256 of MillerRunner { // first and second step, O and N - fn bit_1st_2nd( - self: @SZPreComLines, ref curve: Bn254U256Curve, i1: u32, i2: u32, ref acc: SZAccumulator + fn miller_bit_1_2( + ref self: Curve, runner: @PreCompute, i: (u32, u32), ref acc: Accumulator ) { // - self.bit_o(ref curve, i1, ref acc); - self.bit_n(ref curve, i2, ref acc); + let (i1, i2) = i; + self.miller_bit_o(runner, i1, ref acc); + self.miller_bit_n(runner, i2, ref acc); } // 0 bit - fn bit_o(self: @SZPreComLines, ref curve: Bn254U256Curve, i: u32, ref acc: SZAccumulator) { // + fn miller_bit_o(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { // // @TODO } // 1 bit - fn bit_p(self: @SZPreComLines, ref curve: Bn254U256Curve, i: u32, ref acc: SZAccumulator) { // + fn miller_bit_p(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { // // @TODO } // -1 bit - fn bit_n(self: @SZPreComLines, ref curve: Bn254U256Curve, i: u32, ref acc: SZAccumulator) { // + fn miller_bit_n(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { // // @TODO } // last step - fn last(self: @SZPreComLines, ref curve: Bn254U256Curve, ref acc: SZAccumulator) { // + fn miller_last(ref self: Curve, runner: @PreCompute, ref acc: Accumulator) { // // @TODO } } +// Trait has no implementation in context: MillerRunner>, SZCommitment>, SZAccumulator> + + diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 613f940..1358275 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -10,25 +10,22 @@ pub struct SZCommitment { } #[derive(Drop)] -pub struct SZPreCompute { +pub struct SZPreCompute { pub g16_precompute: Groth16PreCompute< Groth16MillerG1, Groth16MillerG1>, Groth16MillerG2, TLines, Fq12 >, - pub schzip: SZCommitment, + pub schzip: TCommitment, } #[derive(Drop)] pub struct SZAccumulator { pub g2: Groth16MillerG2, - pub schzip_i: u256, - pub lhs_rhs: Fq, + pub schzip: (u32, Fq), } pub type LnFn = LineFn; pub type LnArray = LinesArray; -pub type SZPreComLines = SZPreCompute; - // Precomputes p for the pairing function pub fn p_precompute(ref self: Bn254U256Curve, p: PtG1) -> PPrecompute { let y_inv = self.inv(p.y); @@ -54,13 +51,12 @@ pub impl ICArrayInput of ICProcess, Array, PtG if inputs.len() == 0 { return ic_point; } - loop { match points.pop_front() { Option::Some(point) => { // match inputs.pop_front() { Option::Some(in) => { - ic_point = curve.pt_add(ic_point, curve.pt_mul(point, in)); + ic_point = self.pt_add(ic_point, self.pt_mul(point, in)); }, Option::None => {} // This wouldn't happen } diff --git a/packages/bn_ate_loop/src/ate_loop.cairo b/packages/bn_ate_loop/src/ate_loop.cairo index 52ec19e..ac33bfd 100644 --- a/packages/bn_ate_loop/src/ate_loop.cairo +++ b/packages/bn_ate_loop/src/ate_loop.cairo @@ -1,6 +1,6 @@ pub trait MillerRunner { // first and second step, O and N - fn miller_bit_1_2(ref self: TCurve, runner: @TRunner, i1: u32, i2: u32, ref acc: TAccumulator); + fn miller_bit_1_2(ref self: TCurve, runner: @TRunner, i: (u32, u32), ref acc: TAccumulator); // 0 bit fn miller_bit_o(ref self: TCurve, runner: @TRunner, i: u32, ref acc: TAccumulator); @@ -38,7 +38,7 @@ pub fn _loop_inner_1_of_2< runner: @TRunner, ref curve: TCurve, ref q_acc: TAccumulator ) { // ate_loop[64] = O and ate_loop[63] = N - curve.miller_bit_1_2(runner, 64, 63, ref q_acc); + curve.miller_bit_1_2(runner, (64, 63), ref q_acc); curve.miller_bit_o(runner, 62, ref q_acc); // ate_loop[62] = O curve.miller_bit_p(runner, 61, ref q_acc); // ate_loop[61] = P curve.miller_bit_o(runner, 60, ref q_acc); // ate_loop[60] = O diff --git a/packages/bn_ate_loop/src/test.cairo b/packages/bn_ate_loop/src/test.cairo index 36c1a38..0ce1b1c 100644 --- a/packages/bn_ate_loop/src/test.cairo +++ b/packages/bn_ate_loop/src/test.cairo @@ -10,8 +10,9 @@ type MockAccumulator = felt252; impl Miller_u256 of MillerRunner<(), MockRunner, MockAccumulator> { // first and second step, O and N fn miller_bit_1_2( - ref self: (), runner: @MockRunner, i1: u32, i2: u32, ref acc: MockAccumulator + ref self: (), runner: @MockRunner, i: (u32, u32), ref acc: MockAccumulator ) { // + let (i1, i2) = i; self.miller_bit_o(runner, i1, ref acc); self.miller_bit_n(runner, i2, ref acc); } From 73384a6f6f30eb3381c275cd2a504d192dd24baf Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 13 Jul 2024 20:02:24 +0530 Subject: [PATCH 38/97] type updates for contract --- packages/bn254_u256/src/lib.cairo | 28 +++++++++++++++---- .../src/pairing/schzip_miller.cairo | 10 ++++--- .../src/pairing/schzip_miller_runner.cairo | 9 ++---- packages/bn254_u256/src/pairing/utils.cairo | 4 +-- packages/bn_ate_loop/src/test.cairo | 2 +- packages/ec_groups/src/lib.cairo | 2 +- packages/ec_groups/src/lines.cairo | 22 +++++++++------ packages/fq_types/src/lib.cairo | 2 +- 8 files changed, 49 insertions(+), 30 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index dff4654..684b9d3 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -1,10 +1,12 @@ -use fq_types::{Fq2 as Fq2Gen, fq2, Fq3 as Fq3Gen, fq3, CubicScale}; +use fq_types::{Fq2 as Fq2Gen, fq2, Fq3 as Fq3Gen, fq3,}; pub mod curve; pub mod fq_1; pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn}; -pub use fq_1::{scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}; -pub use fq_1::{U256IntoFq, Bn254FqOps, Bn254FqUtils}; +pub use fq_1::{ + {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, {U256IntoFq, Bn254FqOps, Bn254FqUtils} +}; +pub use fq_types::CubicScale; pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3Gen>; @@ -16,6 +18,20 @@ pub mod pairing { pub mod schzip_miller; } -pub use pairing::utils::{ICProcess, ICArrayInput}; -pub use pairing::utils::{SZCommitment, SZPreCompute, SZAccumulator}; -pub use pairing::utils::{p_precompute}; +pub use pairing::{ + utils::{ + p_precompute, ICProcess, ICArrayInput, LnArrays, // + {SZCommitment, SZPreCompute, SZAccumulator} + }, + schzip_miller::{ + schzip_verify, InputConstraintPoints, PPrecompute, + {Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit} + }, +}; + +pub fn bn254_curve() -> Bn254U256Curve { + Bn254U256Curve { + q: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, + qnz: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, + } +} diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 451c582..a3e6f0a 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,10 +1,12 @@ use ec_groups::ECOperations; -use bn_ate_loop::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; +pub use bn_ate_loop::{ + PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit +}; use bn254_u256::{ Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing, CubicScale, pairing::{ schzip_miller_runner::Miller_Bn254_U256, - utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArray}, + utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArrays}, utils::{ICArrayInput, p_precompute}, } }; @@ -24,7 +26,7 @@ fn schzip_miller( inputs: Array, residue_witness: Fq12, residue_witness_inv: Fq12, - setup: Groth16Circuit, + setup: Groth16Circuit, schzip: SZCommitment, ) -> SZAccumulator { // // Compute k from ic and public_inputs @@ -65,7 +67,7 @@ pub fn schzip_verify( residue_witness: Fq12, residue_witness_inv: Fq12, cubic_scale: CubicScale, - setup: Groth16Circuit, + setup: Groth16Circuit, schzip_remainders: Array, schzip_qrlc: Array, ) { diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index 0aaa3c4..794d190 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,12 +1,12 @@ -use ec_groups::{LineFn, LinesArray, LinesArrayGet}; +use ec_groups::{LineFn, LinesArrayGet}; use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; use bn254_u256::pairing::utils::{ - LnArray, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn + LnArrays, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn }; use bn_ate_loop::MillerRunner; use schwartz_zippel::SchZipSteps; -type PreCompute = SZPreCompute; +type PreCompute = SZPreCompute; // TODO: +SchZipSteps @@ -40,6 +40,3 @@ pub impl Miller_Bn254_U256 of MillerRunner { // @TODO } } -// Trait has no implementation in context: MillerRunner>, SZCommitment>, SZAccumulator> - - diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 1358275..7745c9c 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -1,4 +1,4 @@ -use ec_groups::{LineFn, LinesArray, LinesArrayGet, ECOperations}; +use ec_groups::{LineFn, LinesArrays, LinesArrayGet, ECOperations}; use bn_ate_loop::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; use bn254_u256::{Bn254U256Curve}; @@ -24,7 +24,7 @@ pub struct SZAccumulator { } pub type LnFn = LineFn; -pub type LnArray = LinesArray; +pub type LnArrays = LinesArrays>; // Precomputes p for the pairing function pub fn p_precompute(ref self: Bn254U256Curve, p: PtG1) -> PPrecompute { diff --git a/packages/bn_ate_loop/src/test.cairo b/packages/bn_ate_loop/src/test.cairo index 0ce1b1c..0591251 100644 --- a/packages/bn_ate_loop/src/test.cairo +++ b/packages/bn_ate_loop/src/test.cairo @@ -7,7 +7,7 @@ struct MockRunner {} type MockAccumulator = felt252; -impl Miller_u256 of MillerRunner<(), MockRunner, MockAccumulator> { +impl Miller_u of MillerRunner<(), MockRunner, MockAccumulator> { // first and second step, O and N fn miller_bit_1_2( ref self: (), runner: @MockRunner, i: (u32, u32), ref acc: MockAccumulator diff --git a/packages/ec_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo index 804041f..01d2384 100644 --- a/packages/ec_groups/src/lib.cairo +++ b/packages/ec_groups/src/lib.cairo @@ -3,7 +3,7 @@ pub mod lines; use fq_types::{FieldOps}; use core::num::traits::One; pub use bn::AffineOpsBn; -pub use lines::{LineFn, StepLinesGet, LinesArray, LinesArrayGet}; +pub use lines::{LineFn, StepLinesGet, LinesArrays, LinesArrayGet}; #[derive(Copy, Drop, Serde)] pub struct Affine { diff --git a/packages/ec_groups/src/lines.cairo b/packages/ec_groups/src/lines.cairo index dc36392..70f86fd 100644 --- a/packages/ec_groups/src/lines.cairo +++ b/packages/ec_groups/src/lines.cairo @@ -11,27 +11,31 @@ pub trait StepLinesGet { fn get_delta_lines(self: @T, step: u32, line_index: u32) -> (TLnFn, TLnFn); } -#[derive(Drop)] -pub struct LinesArray { - gamma: Array, - delta: Array, +#[derive(Drop, Serde)] +pub struct LinesArrays { + gamma: TLinesArray, + delta: TLinesArray, } pub impl LinesArrayGet< TLnFn, +Copy, +Drop -> of StepLinesGet, TLnFn> { - fn get_gamma_line(self: @LinesArray, step: u32, line_index: u32) -> TLnFn { +> of StepLinesGet>, TLnFn> { + fn get_gamma_line(self: @LinesArrays>, step: u32, line_index: u32) -> TLnFn { // let l1: LineFn = *self.gamma[line_index]; // println!("Get {}.{} {}", step, line_index, l1.slope.c0.c0.low); *self.gamma[line_index] } - fn get_delta_line(self: @LinesArray, step: u32, line_index: u32) -> TLnFn { + fn get_delta_line(self: @LinesArrays>, step: u32, line_index: u32) -> TLnFn { *self.delta[line_index] } - fn get_gamma_lines(self: @LinesArray, step: u32, line_index: u32) -> (TLnFn, TLnFn) { + fn get_gamma_lines( + self: @LinesArrays>, step: u32, line_index: u32 + ) -> (TLnFn, TLnFn) { (*self.gamma[line_index], *self.gamma[line_index + 1]) } - fn get_delta_lines(self: @LinesArray, step: u32, line_index: u32) -> (TLnFn, TLnFn) { + fn get_delta_lines( + self: @LinesArrays>, step: u32, line_index: u32 + ) -> (TLnFn, TLnFn) { (*self.delta[line_index], *self.delta[line_index + 1]) } } diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index a867f71..d38dd6a 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -13,7 +13,7 @@ pub struct Fq3 { pub c2: T, } -#[derive(Copy, Drop)] +#[derive(Copy, Drop, Serde)] pub enum CubicScale { Zero, One, From 30d7854da0eae1f7c88cae96b3042012529313cf Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 13 Jul 2024 20:02:39 +0530 Subject: [PATCH 39/97] bn254 u256 contract init --- packages/bn254_u256_contract/Scarb.toml | 12 ++++ packages/bn254_u256_contract/src/lib.cairo | 74 ++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 packages/bn254_u256_contract/Scarb.toml create mode 100644 packages/bn254_u256_contract/src/lib.cairo diff --git a/packages/bn254_u256_contract/Scarb.toml b/packages/bn254_u256_contract/Scarb.toml new file mode 100644 index 0000000..f3b45f2 --- /dev/null +++ b/packages/bn254_u256_contract/Scarb.toml @@ -0,0 +1,12 @@ +[package] +name = "bn254_u256_contract" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[[target.starknet-contract]] + +[dependencies] +starknet = "2.6.2" +bn254_u256 = { path = "../bn254_u256" } \ No newline at end of file diff --git a/packages/bn254_u256_contract/src/lib.cairo b/packages/bn254_u256_contract/src/lib.cairo new file mode 100644 index 0000000..a2906d3 --- /dev/null +++ b/packages/bn254_u256_contract/src/lib.cairo @@ -0,0 +1,74 @@ +pub use bn254_u256::{ + schzip_verify, PtG1, PtG2, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, bn254_curve, + LnArrays, InputConstraintPoints +}; + +#[starknet::interface] +trait IBN_Pairing { + // fn final_exponentiation(self: @T, a: Fq12) -> Fq12; + // fn final_exponentiation_bench(self: @T) -> Fq12; + // fn pairing_bench(self: @T) -> Fq12; + // fn miller_bench(self: @T) -> Fq12; + fn verify( + ref self: T, + pi_a: PtG1, + pi_b: PtG2, + pi_c: PtG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: CubicScale, + setup: Groth16Circuit, + schzip_remainders: Array, + schzip_qrlc: Array, + ); +} + +#[starknet::contract] +mod BN_Pairing { + use super::{ + schzip_verify, bn254_curve, + { + PtG1, PtG2, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, LnArrays, + InputConstraintPoints + } + }; + + #[storage] + struct Storage {} + + #[constructor] + fn constructor(ref self: ContractState) {} + + #[abi(embed_v0)] + impl BN_Pairing of super::IBN_Pairing { + fn verify( + ref self: ContractState, + pi_a: PtG1, + pi_b: PtG2, + pi_c: PtG1, + inputs: Array, + residue_witness: Fq12, + residue_witness_inv: Fq12, + cubic_scale: CubicScale, + setup: Groth16Circuit, + schzip_remainders: Array, + schzip_qrlc: Array, + ) { + let mut curve = bn254_curve(); + schzip_verify( + ref curve, + pi_a, + pi_b, + pi_c, + inputs, + residue_witness, + residue_witness_inv, + cubic_scale, + setup, + schzip_remainders, + schzip_qrlc, + ) + } + } +} From ec0aa05d00e04dc89780410b679c8d2c5905aca3 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 14 Jul 2024 16:21:57 +0530 Subject: [PATCH 40/97] pairing package --- packages/bn254_u256/Scarb.toml | 3 ++- packages/bn254_u256/src/pairing/schzip_miller.cairo | 6 ++---- packages/bn254_u256/src/pairing/utils.cairo | 2 +- packages/bn_ate_loop/src/lib.cairo | 2 -- packages/pairing/Scarb.toml | 10 ++++++++++ packages/pairing/src/lib.cairo | 3 +++ .../src/groth16.cairo => pairing/src/types.cairo} | 0 7 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 packages/pairing/Scarb.toml create mode 100644 packages/pairing/src/lib.cairo rename packages/{bn_ate_loop/src/groth16.cairo => pairing/src/types.cairo} (100%) diff --git a/packages/bn254_u256/Scarb.toml b/packages/bn254_u256/Scarb.toml index 7417f5d..419489c 100644 --- a/packages/bn254_u256/Scarb.toml +++ b/packages/bn254_u256/Scarb.toml @@ -10,4 +10,5 @@ schwartz_zippel = { path = "../schwartz_zippel" } fast_mod = { path = "../fast_mod" } bn_ate_loop = { path = "../bn_ate_loop" } ec_groups = { path = "../ec_groups" } -fq_types = { path = "../fq_types" } \ No newline at end of file +fq_types = { path = "../fq_types" } +pairing = { path = "../pairing" } \ No newline at end of file diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index a3e6f0a..91f9ad7 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,9 +1,7 @@ use ec_groups::ECOperations; -pub use bn_ate_loop::{ - PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit -}; +pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; use bn254_u256::{ - Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing, CubicScale, + Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, CubicScale, pairing::{ schzip_miller_runner::Miller_Bn254_U256, utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArrays}, diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 7745c9c..a17db11 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -1,5 +1,5 @@ use ec_groups::{LineFn, LinesArrays, LinesArrayGet, ECOperations}; -use bn_ate_loop::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; +use pairing::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; use bn254_u256::{Bn254U256Curve}; diff --git a/packages/bn_ate_loop/src/lib.cairo b/packages/bn_ate_loop/src/lib.cairo index 231dd39..c7b118b 100644 --- a/packages/bn_ate_loop/src/lib.cairo +++ b/packages/bn_ate_loop/src/lib.cairo @@ -1,8 +1,6 @@ pub mod ate_loop; -pub mod groth16; pub use ate_loop::{MillerRunner, ate_miller_loop, _loop_inner_1_of_2, _loop_inner_2_of_2}; -pub use groth16::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; #[cfg(test)] mod test; diff --git a/packages/pairing/Scarb.toml b/packages/pairing/Scarb.toml new file mode 100644 index 0000000..51ec602 --- /dev/null +++ b/packages/pairing/Scarb.toml @@ -0,0 +1,10 @@ +[package] +name = "pairing" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +ec_groups = { path = "../ec_groups" } +fq_types = { path = "../fq_types" } \ No newline at end of file diff --git a/packages/pairing/src/lib.cairo b/packages/pairing/src/lib.cairo new file mode 100644 index 0000000..be20e80 --- /dev/null +++ b/packages/pairing/src/lib.cairo @@ -0,0 +1,3 @@ +pub mod types; + +pub use types::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; diff --git a/packages/bn_ate_loop/src/groth16.cairo b/packages/pairing/src/types.cairo similarity index 100% rename from packages/bn_ate_loop/src/groth16.cairo rename to packages/pairing/src/types.cairo From 3b9706937181bb5e28f07f5575a49b5674bfdfee Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 14 Jul 2024 16:23:49 +0530 Subject: [PATCH 41/97] pairing utils --- packages/bn254_u256/src/lib.cairo | 6 ++---- .../src/pairing/schzip_miller.cairo | 14 +++++--------- packages/bn254_u256/src/pairing/utils.cairo | 9 +-------- packages/pairing/src/lib.cairo | 2 ++ packages/pairing/src/utils.cairo | 19 +++++++++++++++++++ 5 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 packages/pairing/src/utils.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 684b9d3..980cdd2 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -19,10 +19,8 @@ pub mod pairing { } pub use pairing::{ - utils::{ - p_precompute, ICProcess, ICArrayInput, LnArrays, // - {SZCommitment, SZPreCompute, SZAccumulator} - }, + utils::{ICProcess, ICArrayInput, LnArrays, // + {SZCommitment, SZPreCompute, SZAccumulator}}, schzip_miller::{ schzip_verify, InputConstraintPoints, PPrecompute, {Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit} diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 91f9ad7..6338a66 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -4,12 +4,12 @@ use bn254_u256::{ Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, CubicScale, pairing::{ schzip_miller_runner::Miller_Bn254_U256, - utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArrays}, - utils::{ICArrayInput, p_precompute}, + utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArrays, ICArrayInput}, } }; use bn_ate_loop::{ate_miller_loop}; use ec_groups::{LineFn, StepLinesGet, LinesArrayGet}; +use pairing::PairingUtils; pub type InputConstraintPoints = Array; @@ -39,15 +39,11 @@ fn schzip_miller( let q = Groth16MillerG2 { pi_b, gamma, delta }; let neg_q = Groth16MillerG2 { pi_b: curve.pt_neg(pi_b), gamma: gamma_neg, delta: delta_neg }; let ppc = Groth16MillerG1 { - pi_a: p_precompute(ref curve, pi_a), - pi_c: p_precompute(ref curve, pi_c), - k: p_precompute(ref curve, k), - }; - let g16_precompute = Groth16PreCompute { - p, q, ppc, neg_q, lines, residue_witness, residue_witness_inv, + pi_a: curve.p_precompute(pi_a), pi_c: curve.p_precompute(pi_c), k: curve.p_precompute(k), }; + let g16 = Groth16PreCompute { p, q, ppc, neg_q, lines, residue_witness, residue_witness_inv, }; - let precomp = SZPreCompute { g16_precompute, schzip, }; + let precomp = SZPreCompute { g16, schzip, }; // miller accumulator let mut q_acc = SZAccumulator { g2: q, schzip: (0, 0_u256.into()) }; diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index a17db11..dfdab27 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -11,7 +11,7 @@ pub struct SZCommitment { #[derive(Drop)] pub struct SZPreCompute { - pub g16_precompute: Groth16PreCompute< + pub g16: Groth16PreCompute< Groth16MillerG1, Groth16MillerG1>, Groth16MillerG2, TLines, Fq12 >, pub schzip: TCommitment, @@ -26,13 +26,6 @@ pub struct SZAccumulator { pub type LnFn = LineFn; pub type LnArrays = LinesArrays>; -// Precomputes p for the pairing function -pub fn p_precompute(ref self: Bn254U256Curve, p: PtG1) -> PPrecompute { - let y_inv = self.inv(p.y); - let negx = self.neg(p.x); - PPrecompute { neg_x_over_y: self.mul(negx, y_inv), y_inv } -} - // Generic Input constraints processing pub trait ICProcess { fn process_inputs_and_ic(ref self: TCurve, points: TIC, inputs: TInputs) -> TG1; diff --git a/packages/pairing/src/lib.cairo b/packages/pairing/src/lib.cairo index be20e80..60086e9 100644 --- a/packages/pairing/src/lib.cairo +++ b/packages/pairing/src/lib.cairo @@ -1,3 +1,5 @@ pub mod types; +pub mod utils; pub use types::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; +pub use utils::PairingUtils; diff --git a/packages/pairing/src/utils.cairo b/packages/pairing/src/utils.cairo new file mode 100644 index 0000000..8b3049f --- /dev/null +++ b/packages/pairing/src/utils.cairo @@ -0,0 +1,19 @@ +use fq_types::{FieldOps}; +use ec_groups::{Affine, ECOperations}; +use pairing::PPrecompute; + +pub trait PairingUtilsTrait { + fn p_precompute(ref self: TCurve, p: Affine) -> PPrecompute; +} + + +pub impl PairingUtils< + TCurve, TFq, +FieldOps, +ECOperations, +Drop, +Copy +> of PairingUtilsTrait { + // Precomputes p for the pairing function + fn p_precompute(ref self: TCurve, p: Affine) -> PPrecompute { + let y_inv = self.inv(p.y); + let negx = self.neg(p.x); + PPrecompute { neg_x_over_y: self.mul(negx, y_inv), y_inv } + } +} From 9f8bf4422ad1e36ea1180b08bcb5ef17c425a2ab Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 00:52:39 +0530 Subject: [PATCH 42/97] pairing utils --- Scarb.lock | 29 +++++ Scarb.toml | 9 +- packages/pairing/src/lib.cairo | 2 +- packages/pairing/src/utils.cairo | 195 ++++++++++++++++++++++++++++++- 4 files changed, 228 insertions(+), 7 deletions(-) diff --git a/Scarb.lock b/Scarb.lock index d2204df..e369e65 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -11,7 +11,17 @@ version = "0.1.0" dependencies = [ "bn_ate_loop", "ec_groups", + "fast_mod", "fq_types", + "pairing", + "schwartz_zippel", +] + +[[package]] +name = "bn254_u256_contract" +version = "0.1.0" +dependencies = [ + "bn254_u256", ] [[package]] @@ -29,6 +39,10 @@ dependencies = [ "bn", ] +[[package]] +name = "cairo_pairing" +version = "0.1.0" + [[package]] name = "ec_groups" version = "0.1.0" @@ -43,3 +57,18 @@ version = "0.1.0" [[package]] name = "fq_types" version = "0.1.0" + +[[package]] +name = "pairing" +version = "0.1.0" +dependencies = [ + "ec_groups", + "fq_types", +] + +[[package]] +name = "schwartz_zippel" +version = "0.1.0" +dependencies = [ + "fq_types", +] diff --git a/Scarb.toml b/Scarb.toml index 2228b66..2afb13d 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -8,9 +8,12 @@ members = [ version = "0.1.0" cairo-version = "2.6.2" +[workspace.dependencies] +# cairo_test = "2.7.0-rc.0" + [package] -name = "pairing" -version.workspace = true +name = "cairo_pairing" # the name of the package +version = "0.1.0" # the current version, obeying semver # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html @@ -19,7 +22,7 @@ new = "scarb new --no-vcs" addchain_gen_t = "addchain gen -tmpl addchain/tpl addchain/t" contracts = "scarb build -p bn_contracts" # Declares class for the contract -ktn_declare = "starkli declare target/dev/bn_contracts_BN_Pairing.contract_class.json --account katana --rpc=http://localhost:5050" +ktn_declare = "starkli declare target/dev/bn254_u256_contract_BN_Pairing.contract_class.json" # Deploys the contract for input classhash ktn_deploy = "starkli deploy --account katana --rpc=http://localhost:5050" # Invokes final_exponentiation_bench on input contract address diff --git a/packages/pairing/src/lib.cairo b/packages/pairing/src/lib.cairo index 60086e9..729d1c2 100644 --- a/packages/pairing/src/lib.cairo +++ b/packages/pairing/src/lib.cairo @@ -2,4 +2,4 @@ pub mod types; pub mod utils; pub use types::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; -pub use utils::PairingUtils; +pub use utils::{PairingUtils, PairingUtilsTrait, PiMapping}; diff --git a/packages/pairing/src/utils.cairo b/packages/pairing/src/utils.cairo index 8b3049f..3df1fec 100644 --- a/packages/pairing/src/utils.cairo +++ b/packages/pairing/src/utils.cairo @@ -1,14 +1,59 @@ -use fq_types::{FieldOps}; -use ec_groups::{Affine, ECOperations}; +use fq_types::{FieldOps, FieldUtils, Fq2, F12S034}; +use ec_groups::{Affine, ECOperations, LineFn}; use pairing::PPrecompute; +type F034 = F12S034>; + pub trait PairingUtilsTrait { + // region Utils fn p_precompute(ref self: TCurve, p: Affine) -> PPrecompute; + fn line_fn(ref self: TCurve, slope: Fq2, s: Affine>) -> LineFn>; + fn line_fn_at_p(ref self: TCurve, line: LineFn>, ppc: @PPrecompute) -> F034; + fn point_and_slope_at_p( + ref self: TCurve, slope: Fq2, s: Affine>, ppc: @PPrecompute + ) -> F034; + fn scale_fq2(ref self: TCurve, a: Fq2, x: TFq) -> Fq2; + fn conjugate_fq2(ref self: TCurve, a: Fq2) -> Fq2; + + // region point operations + fn step_dbl_add( + ref self: TCurve, ref acc: Affine>, q: Affine>, ppc: @PPrecompute + ) -> (F034, F034); + fn step_double( + ref self: TCurve, ref acc: Affine>, ppc: @PPrecompute + ) -> F034; + fn step_add( + ref self: TCurve, ref acc: Affine>, q: Affine>, ppc: @PPrecompute + ) -> F034; + fn correction_step( + ref self: TCurve, + ref acc: Affine>, + q: Affine>, + pi_map: PiMapping, + ppc: @PPrecompute + ) -> (F034, F034); } +#[derive(Copy, Drop)] +pub struct PiMapping { + // for πₚ mapping + PiQ1X2: Fq2, + PiQ1X3: Fq2, + // for π² mapping, only Fq2.c0, c1 is 0 + PiQ2X2: TFq, + PiQ2X3: TFq, +} +// #[generate_trait] pub impl PairingUtils< - TCurve, TFq, +FieldOps, +ECOperations, +Drop, +Copy + TCurve, + TFq, + +FieldOps, + +FieldOps>, + +ECOperations, + +ECOperations>, + +Drop, + +Copy > of PairingUtilsTrait { // Precomputes p for the pairing function fn p_precompute(ref self: TCurve, p: Affine) -> PPrecompute { @@ -16,4 +61,148 @@ pub impl PairingUtils< let negx = self.neg(p.x); PPrecompute { neg_x_over_y: self.mul(negx, y_inv), y_inv } } + + #[inline(always)] + fn line_fn(ref self: TCurve, slope: Fq2, s: Affine>) -> LineFn> { + let mx = self.mul(slope, s.x); + LineFn { slope, c: self.sub(mx, s.y), } + } + + #[inline(always)] + fn line_fn_at_p(ref self: TCurve, line: LineFn>, ppc: @PPrecompute) -> F034 { + F034 { + c3: self.scale_fq2(line.slope, *ppc.neg_x_over_y), + c4: self.scale_fq2(line.c, *ppc.y_inv), + } + } + + #[inline(always)] + fn point_and_slope_at_p( + ref self: TCurve, slope: Fq2, s: Affine>, ppc: @PPrecompute + ) -> F034 { + // 𝝺x - y + let c = self.sub(self.mul(slope, s.x), s.y); + F034 { + c3: self.scale_fq2(slope, *ppc.neg_x_over_y), // 𝝺x/y + c4: self.scale_fq2(c, *ppc.y_inv), // c/y + } + } + fn scale_fq2(ref self: TCurve, a: Fq2, x: TFq) -> Fq2 { + let Fq2 { c0, c1 } = a; + Fq2 { c0: self.mul(x, c0), c1: self.mul(x, c1) } + } + fn conjugate_fq2(ref self: TCurve, a: Fq2) -> Fq2 { + let Fq2 { c0, c1 } = a; + Fq2 { c0, c1: self.neg(c1) } + } + + // https://eprint.iacr.org/2022/1162 (Section 6.1) + // computes acc = acc + q + acc and line evals for p + // returns product of line evaluations to multiply with f + // #[inline(always)] + fn step_dbl_add( + ref self: TCurve, ref acc: Affine>, q: Affine>, ppc: @PPrecompute + ) -> (F034, F034) { + let s = acc; + let Affine { x: x1, y: y1 } = s; + // s + q + let slope1 = self.chord(s, q); + let x2 = self.x_on_slope(s, slope1, q.x); + let line1 = self.point_and_slope_at_p(slope1, s, ppc); + + // we skip y1 calculation and sub slope1 directly in second slope calculation + + // (s + q) + s + // λ2 = (y2-y1)/(x2-x1), subbing y2 = λ(x2-x1)+y1 + // λ2 = -λ1-2y1/(x2-x1) + let neg_slope1 = self.neg(slope1); // neg_slope1 = -λ1 + let y_2x = self.add(y1, y1); // y_2x = 2y1 + + // x2 - s.x + let x_diff = self.sub(x2, s.x); // x_diff = x2 - s.x + + // (y1 + y1) / (x2 - s.x) + let slope_fraction = self.div(y_2x, x_diff); // slope_fraction = y_2x / x_diff + + // -λ1 - (y1 + y1) / (x1 - s.x) + let slope2 = self.sub(neg_slope1, slope_fraction); // slope2 = neg_slope1 - slope_fraction + acc = self.pt_on_slope(s, slope2, x1); + let line2 = self.point_and_slope_at_p(slope2, s, ppc); + + // line functions + (line1, line2) + } + + // https://eprint.iacr.org/2022/1162 (Section 6.1) + // computes acc = 2 * acc and line eval for p + // returns line evaluation to multiply with f + // #[inline(always)] + fn step_double( + ref self: TCurve, ref acc: Affine>, ppc: @PPrecompute + ) -> F034 { + let s = acc; + // λ = 3x²/2y + let slope = self.tangent(s); + // p = (λ²-2x, λ(x-xr)-y) + acc = self.pt_on_slope(s, slope, acc.x); + self.point_and_slope_at_p(slope, s, ppc) + } + // https://eprint.iacr.org/2022/1162 (Section 6.1) + // computes acc = acc + q and line eval for p + // returns line evaluation to multiply with f + // #[inline(always)] + fn step_add( + ref self: TCurve, ref acc: Affine>, q: Affine>, ppc: @PPrecompute + ) -> F034 { + let s = acc; + // λ = (yS−yQ)/(xS−xQ) + let slope = self.chord(s, q); + // p = (λ²-2x, λ(x-xr)-y) + acc = self.pt_on_slope(s, slope, q.x); + self.point_and_slope_at_p(slope, s, ppc) + } + + // Realm of pairings, Algorithm 1, lines 8, 9, 10 + // https://eprint.iacr.org/2013/722.pdf + // Code inspired by gnark + // https://github.com/Consensys/gnark/blob/v0.9.1/std/algebra/emulated/sw_bn254/pairing.go#L529 + // #[inline(always)] + fn correction_step( + ref self: TCurve, + ref acc: Affine>, + q: Affine>, + pi_map: PiMapping, + ppc: @PPrecompute, + ) -> (F034, F034) { + // Line 9: Q1 ← πₚ(Q),Q2 ← πₚ²(Q) + // πₚ(x,y) = (xp,yp) + // Q1 = π(Q) + let q1 = Affine { + x: self.mul(self.conjugate_fq2(q.x), pi_map.PiQ1X2), + y: self.mul(self.conjugate_fq2(q.y), pi_map.PiQ1X3), + }; + + // Q2 = -π²(Q) + let q2 = Affine { + x: self.scale_fq2(q.x, pi_map.PiQ2X2), y: self.neg(self.scale_fq2(q.y, pi_map.PiQ2X3)), + }; + + // Line 10: if u < 0 then T ← −T, f ← fp6 + // skip line 10, ∵ x > 0 + + // Line 11: d ← (gT,Q1)(P), T ← T + Q1, e ← (gT,−Q2)(P), T ← T − Q2 + + // d ← (gT,Q1)(P), T ← T + Q1 + let d = self.step_add(ref acc, q1, ppc); + + // e ← (gT,−Q2)(P), T ← T − Q2 + // we can skip the T ← T − Q2 step coz we don't need the final point, just the line function + let slope = self.chord(acc, q2); + let e = self.point_and_slope_at_p(slope, acc, ppc); + + // f ← f·(d·e) is left for the caller + + // return line functions + (d, e) + } } From 0cb59e080450689dbe030c6bd8b2b143c246eaad Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 02:39:55 +0530 Subject: [PATCH 43/97] lines in pairing package --- .../src/pairing/schzip_miller.cairo | 2 +- .../src/pairing/schzip_miller_runner.cairo | 2 +- packages/bn254_u256/src/pairing/utils.cairo | 5 +- packages/ec_groups/src/lib.cairo | 3 +- packages/ec_groups/src/lines.cairo | 41 --------------- packages/pairing/src/lib.cairo | 5 ++ packages/pairing/src/lines.cairo | 51 +++++++++++++++++++ packages/pairing/src/utils.cairo | 7 ++- 8 files changed, 67 insertions(+), 49 deletions(-) delete mode 100644 packages/ec_groups/src/lines.cairo create mode 100644 packages/pairing/src/lines.cairo diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 6338a66..6e73c41 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -8,7 +8,7 @@ use bn254_u256::{ } }; use bn_ate_loop::{ate_miller_loop}; -use ec_groups::{LineFn, StepLinesGet, LinesArrayGet}; +use pairing::{LineFn, StepLinesGet, LinesArrayGet}; use pairing::PairingUtils; diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index 794d190..fcbda4a 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,4 +1,4 @@ -use ec_groups::{LineFn, LinesArrayGet}; +use pairing::{LineFn, LinesArrayGet}; use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; use bn254_u256::pairing::utils::{ LnArrays, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index dfdab27..e07cd5c 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -1,4 +1,5 @@ -use ec_groups::{LineFn, LinesArrays, LinesArrayGet, ECOperations}; +use ec_groups::ECOperations; +use pairing::{LineFn, LinesArrays, LinesArrayGet}; use pairing::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; use bn254_u256::{Bn254U256Curve}; @@ -23,7 +24,7 @@ pub struct SZAccumulator { pub schzip: (u32, Fq), } -pub type LnFn = LineFn; +pub type LnFn = LineFn; pub type LnArrays = LinesArrays>; // Generic Input constraints processing diff --git a/packages/ec_groups/src/lib.cairo b/packages/ec_groups/src/lib.cairo index 01d2384..4464e69 100644 --- a/packages/ec_groups/src/lib.cairo +++ b/packages/ec_groups/src/lib.cairo @@ -1,9 +1,8 @@ pub mod bn; -pub mod lines; use fq_types::{FieldOps}; use core::num::traits::One; pub use bn::AffineOpsBn; -pub use lines::{LineFn, StepLinesGet, LinesArrays, LinesArrayGet}; +pub use pairing::{LineFn, StepLinesGet, LinesArrays, LinesArrayGet}; #[derive(Copy, Drop, Serde)] pub struct Affine { diff --git a/packages/ec_groups/src/lines.cairo b/packages/ec_groups/src/lines.cairo deleted file mode 100644 index 70f86fd..0000000 --- a/packages/ec_groups/src/lines.cairo +++ /dev/null @@ -1,41 +0,0 @@ -#[derive(Copy, Drop, Serde)] -pub struct LineFn { - pub slope: TFq, - pub c: TFq, -} - -pub trait StepLinesGet { - fn get_gamma_line(self: @T, step: u32, line_index: u32) -> TLnFn; - fn get_delta_line(self: @T, step: u32, line_index: u32) -> TLnFn; - fn get_gamma_lines(self: @T, step: u32, line_index: u32) -> (TLnFn, TLnFn); - fn get_delta_lines(self: @T, step: u32, line_index: u32) -> (TLnFn, TLnFn); -} - -#[derive(Drop, Serde)] -pub struct LinesArrays { - gamma: TLinesArray, - delta: TLinesArray, -} - -pub impl LinesArrayGet< - TLnFn, +Copy, +Drop -> of StepLinesGet>, TLnFn> { - fn get_gamma_line(self: @LinesArrays>, step: u32, line_index: u32) -> TLnFn { - // let l1: LineFn = *self.gamma[line_index]; - // println!("Get {}.{} {}", step, line_index, l1.slope.c0.c0.low); - *self.gamma[line_index] - } - fn get_delta_line(self: @LinesArrays>, step: u32, line_index: u32) -> TLnFn { - *self.delta[line_index] - } - fn get_gamma_lines( - self: @LinesArrays>, step: u32, line_index: u32 - ) -> (TLnFn, TLnFn) { - (*self.gamma[line_index], *self.gamma[line_index + 1]) - } - fn get_delta_lines( - self: @LinesArrays>, step: u32, line_index: u32 - ) -> (TLnFn, TLnFn) { - (*self.delta[line_index], *self.delta[line_index + 1]) - } -} diff --git a/packages/pairing/src/lib.cairo b/packages/pairing/src/lib.cairo index 729d1c2..b903e74 100644 --- a/packages/pairing/src/lib.cairo +++ b/packages/pairing/src/lib.cairo @@ -1,5 +1,10 @@ pub mod types; +pub mod lines; pub mod utils; pub use types::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; pub use utils::{PairingUtils, PairingUtilsTrait, PiMapping}; +pub use lines::{ + // Line function stuff + {LineFn, StepLinesGet, LinesArrays, LinesArrayGet}, // +}; diff --git a/packages/pairing/src/lines.cairo b/packages/pairing/src/lines.cairo new file mode 100644 index 0000000..ed009d1 --- /dev/null +++ b/packages/pairing/src/lines.cairo @@ -0,0 +1,51 @@ +use pairing::{Groth16MillerG1, Groth16MillerG2, PPrecompute, PairingUtilsTrait}; +use fq_types::{Fq2, F12S034}; + +#[derive(Copy, Drop, Serde)] +pub struct LineFn { + pub slope: TFq, + pub c: TFq, +} + +type LineResult = (F12S034>, F12S034>); +type LnFn = LineFn>; + +pub trait StepLinesGet { + fn get_gamma_line(self: @T, line_index: u32) -> LineFn>; + fn get_delta_line(self: @T, line_index: u32) -> LineFn>; + fn get_gamma_lines(self: @T, line_index: u32) -> (LineFn>, LineFn>); + fn get_delta_lines(self: @T, line_index: u32) -> (LineFn>, LineFn>); +} + +#[derive(Drop, Serde)] +pub struct LinesArrays { + gamma: TLinesArray, + delta: TLinesArray, +} + +pub impl LinesArrayGet< + TFq, +Copy, +Drop +> of StepLinesGet>>>, TFq> { + fn get_gamma_line( + self: @LinesArrays>>>, line_index: u32 + ) -> LineFn> { + // let l1: LineFn = *self.gamma[line_index]; + // println!("Get {}.{} {}", step, line_index, l1.slope.c0.c0.low); + *self.gamma[line_index] + } + fn get_delta_line( + self: @LinesArrays>>>, line_index: u32 + ) -> LineFn> { + *self.delta[line_index] + } + fn get_gamma_lines( + self: @LinesArrays>>>, line_index: u32 + ) -> (LineFn>, LineFn>) { + (*self.gamma[line_index], *self.gamma[line_index + 1]) + } + fn get_delta_lines( + self: @LinesArrays>>>, line_index: u32 + ) -> (LineFn>, LineFn>) { + (*self.delta[line_index], *self.delta[line_index + 1]) + } +} diff --git a/packages/pairing/src/utils.cairo b/packages/pairing/src/utils.cairo index 3df1fec..d5cfa86 100644 --- a/packages/pairing/src/utils.cairo +++ b/packages/pairing/src/utils.cairo @@ -1,6 +1,6 @@ use fq_types::{FieldOps, FieldUtils, Fq2, F12S034}; -use ec_groups::{Affine, ECOperations, LineFn}; -use pairing::PPrecompute; +use ec_groups::{Affine, ECOperations}; +use pairing::{PPrecompute, LineFn}; type F034 = F12S034>; @@ -87,6 +87,8 @@ pub impl PairingUtils< c4: self.scale_fq2(c, *ppc.y_inv), // c/y } } + + // Maybe there's a better place for these functions, here for now fn scale_fq2(ref self: TCurve, a: Fq2, x: TFq) -> Fq2 { let Fq2 { c0, c1 } = a; Fq2 { c0: self.mul(x, c0), c1: self.mul(x, c1) } @@ -206,3 +208,4 @@ pub impl PairingUtils< (d, e) } } + From 038856e99f634f18dda83774aa76ca7c358b743f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 02:42:20 +0530 Subject: [PATCH 44/97] fixed point line step functions --- packages/pairing/src/lib.cairo | 2 + packages/pairing/src/lines.cairo | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/packages/pairing/src/lib.cairo b/packages/pairing/src/lib.cairo index b903e74..932b95d 100644 --- a/packages/pairing/src/lib.cairo +++ b/packages/pairing/src/lib.cairo @@ -7,4 +7,6 @@ pub use utils::{PairingUtils, PairingUtilsTrait, PiMapping}; pub use lines::{ // Line function stuff {LineFn, StepLinesGet, LinesArrays, LinesArrayGet}, // + // Precomputed line function steps + {FixedPointLinesTrait, FixedPointLines} }; diff --git a/packages/pairing/src/lines.cairo b/packages/pairing/src/lines.cairo index ed009d1..4310606 100644 --- a/packages/pairing/src/lines.cairo +++ b/packages/pairing/src/lines.cairo @@ -49,3 +49,67 @@ pub impl LinesArrayGet< (*self.delta[line_index], *self.delta[line_index + 1]) } } + +pub trait FixedPointLinesTrait { + fn with_fxd_pt_line( + self: @T, ref curve: TCurve, ppc: @Groth16MillerG1>, ref line_count: u32 + ) -> LineResult; + fn with_fxd_pt_lines( + self: @T, ref curve: TCurve, ppc: @Groth16MillerG1>, ref line_count: u32 + ) -> (LineResult, LineResult); + fn lines_helper( + self: @T, + ref curve: TCurve, + lines: (LineFn>, LineFn>), + p_prec: @PPrecompute + ) -> LineResult; +} + +pub impl FixedPointLines< + T, + TCurve, + TFq, + +StepLinesGet, + +PairingUtilsTrait, + +Copy, + +Drop, + +Drop +> of FixedPointLinesTrait { + // reimplementation of step_double for both gamma and delta at once + // but instead of G2 point doublings, uses precomputed slope and const + fn with_fxd_pt_line( + self: @T, ref curve: TCurve, ppc: @Groth16MillerG1>, ref line_count: u32 + ) -> LineResult { + let line_index = line_count; + line_count = line_count + 1; + let a = curve.line_fn_at_p(self.get_gamma_line(line_index), ppc.k); + // get line functions and multiply with p_precomputes + (a, curve.line_fn_at_p(self.get_delta_line(line_index), ppc.pi_c)) + } + + // reimplementation of step_dbl_add for both gamma and delta at once + // but instead of G2 point doublings, uses precomputed slope and const + fn with_fxd_pt_lines( + self: @T, ref curve: TCurve, ppc: @Groth16MillerG1>, ref line_count: u32 + ) -> (LineResult, LineResult) { // + let line_index = line_count; + line_count = line_count + 2; + ( + // get line functions and multiply with p_precomputes + self.lines_helper(ref curve, self.get_gamma_lines(line_index), ppc.k), + self.lines_helper(ref curve, self.get_delta_lines(line_index), ppc.pi_c) + ) + } + + #[inline(always)] + fn lines_helper( + self: @T, + ref curve: TCurve, + lines: (LineFn>, LineFn>), + p_prec: @PPrecompute + ) -> LineResult { + let (lf1, lf2) = lines; + (curve.line_fn_at_p(lf1, p_prec), curve.line_fn_at_p(lf2, p_prec)) + } +} + From 69b2132531482194e607b3e3ec24eeaa49c197e6 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 02:43:29 +0530 Subject: [PATCH 45/97] schzip miller runner --- .../src/pairing/schzip_miller.cairo | 13 +++++--- .../src/pairing/schzip_miller_runner.cairo | 30 ++++++++++++++----- packages/bn254_u256/src/pairing/utils.cairo | 2 ++ packages/schwartz_zippel/src/lib.cairo | 30 ++++++++++++++----- 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 6e73c41..dde2909 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -5,18 +5,20 @@ use bn254_u256::{ pairing::{ schzip_miller_runner::Miller_Bn254_U256, utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArrays, ICArrayInput}, - } + }, + Bn254SchwartzZippelSteps, }; use bn_ate_loop::{ate_miller_loop}; use pairing::{LineFn, StepLinesGet, LinesArrayGet}; use pairing::PairingUtils; +use schwartz_zippel::SchZipSteps; pub type InputConstraintPoints = Array; type LnFn = LineFn; // Does the verification -fn schzip_miller( +fn schzip_miller, +Drop>( ref curve: Bn254U256Curve, pi_a: PtG1, pi_b: PtG2, @@ -25,7 +27,7 @@ fn schzip_miller( residue_witness: Fq12, residue_witness_inv: Fq12, setup: Groth16Circuit, - schzip: SZCommitment, + schzip: TSchZip, ) -> SZAccumulator { // // Compute k from ic and public_inputs let Groth16Circuit { alpha_beta: _, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; @@ -46,7 +48,9 @@ fn schzip_miller( let precomp = SZPreCompute { g16, schzip, }; // miller accumulator - let mut q_acc = SZAccumulator { g2: q, schzip: (0, 0_u256.into()) }; + let mut q_acc = SZAccumulator { + f: residue_witness_inv, g2: q, line_index: 0, schzip: (0, 0_u256.into()) + }; ate_miller_loop(ref curve, precomp, q_acc) } @@ -62,6 +66,7 @@ pub fn schzip_verify( residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, + // schzip: TSchZip, schzip_remainders: Array, schzip_qrlc: Array, ) { diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index fcbda4a..ad3196e 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,4 +1,5 @@ use pairing::{LineFn, LinesArrayGet}; +use pairing::{PairingUtils}; use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; use bn254_u256::pairing::utils::{ LnArrays, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn @@ -6,37 +7,50 @@ use bn254_u256::pairing::utils::{ use bn_ate_loop::MillerRunner; use schwartz_zippel::SchZipSteps; -type PreCompute = SZPreCompute; +type PreCompute = SZPreCompute; // TODO: +SchZipSteps -pub impl Miller_Bn254_U256 of MillerRunner { +pub impl Miller_Bn254_U256< + TSchZip, +SchZipSteps +> of MillerRunner, Accumulator> { // first and second step, O and N fn miller_bit_1_2( - ref self: Curve, runner: @PreCompute, i: (u32, u32), ref acc: Accumulator + ref self: Curve, runner: @PreCompute, i: (u32, u32), ref acc: Accumulator ) { // let (i1, i2) = i; + // runner.schzip self.miller_bit_o(runner, i1, ref acc); self.miller_bit_n(runner, i2, ref acc); } // 0 bit - fn miller_bit_o(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { // - // @TODO + fn miller_bit_o( + ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator + ) { // + let g16 = runner.g16; + let ppc = g16.ppc; + let l1 = self.step_double(ref acc.g2.pi_b, ppc.pi_a); + let (l2, l3) = g16.lines.with_fxd_pt_line(ref self, g16.ppc, ref acc.line_index); + self.sz_zero_bit(runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3)); } // 1 bit - fn miller_bit_p(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { // + fn miller_bit_p( + ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator + ) { // // @TODO } // -1 bit - fn miller_bit_n(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { // + fn miller_bit_n( + ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator + ) { // // @TODO } // last step - fn miller_last(ref self: Curve, runner: @PreCompute, ref acc: Accumulator) { // + fn miller_last(ref self: Curve, runner: @PreCompute, ref acc: Accumulator) { // // @TODO } } diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index e07cd5c..8eb3cda 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -20,7 +20,9 @@ pub struct SZPreCompute { #[derive(Drop)] pub struct SZAccumulator { + pub f: Fq12, pub g2: Groth16MillerG2, + pub line_index: u32, pub schzip: (u32, Fq), } diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index 29fb54a..2aa4e67 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -3,21 +3,35 @@ use fq_types::{Fq2, Fq3, F12S034 as FS034, CubicScale}; pub type Lines = (FS034, FS034, FS034); pub type F034X2 = (FS034, FS034); pub type LinesDbl = (F034X2, F034X2, F034X2); +pub type Residue = (CubicScale, Fq12, Fq12); type Fq6 = Fq3>; type Fq12 = Fq2>; -type Residue = (CubicScale, Fq12, Fq12); -pub trait SchZipSteps { - fn sz_init(ref self: TCurve, sz: @T, ref f: Fq12); - fn sz_sqr(ref self: TCurve, sz: @T, ref f: Fq12); - fn sz_zero_bit(ref self: TCurve, sz: @T, ref f: Fq12, lines: Lines>); +pub trait SchZipSteps { + fn sz_init(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12); + fn sz_sqr(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12); + fn sz_zero_bit( + ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12, lines: Lines> + ); fn sz_nz_bit( - ref self: TCurve, sz: @T, ref f: Fq12, lines: LinesDbl>, witness: Fq12 + ref self: TCurve, + sz: @T, + ref sz_acc: TAcc, + ref f: Fq12, + lines: LinesDbl>, + witness: Fq12 + ); + fn sz_last_step( + ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12, lines: LinesDbl> ); - fn sz_last_step(ref self: TCurve, sz: @T, ref f: Fq12, lines: LinesDbl>); fn sz_post_miller( - ref self: TCurve, sz: @T, f: Fq12, alpha_beta: Fq12, residue: Residue + ref self: TCurve, + sz: @T, + ref sz_acc: TAcc, + f: Fq12, + alpha_beta: Fq12, + residue: Residue ) -> bool; } From d04748d027746081a9d7ad5010274345e43a54ff Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 02:43:38 +0530 Subject: [PATCH 46/97] schwartz zippel steps --- packages/bn254_u256/src/lib.cairo | 2 ++ .../src/pairing/schzip_miller_runner.cairo | 2 +- .../bn254_u256/src/pairing/schzip_steps.cairo | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 packages/bn254_u256/src/pairing/schzip_steps.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 980cdd2..880f767 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -16,6 +16,7 @@ pub mod pairing { pub mod utils; pub mod schzip_miller_runner; pub mod schzip_miller; + pub mod schzip_steps; } pub use pairing::{ @@ -25,6 +26,7 @@ pub use pairing::{ schzip_verify, InputConstraintPoints, PPrecompute, {Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit} }, + schzip_steps::Bn254SchwartzZippelSteps, }; pub fn bn254_curve() -> Bn254U256Curve { diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index ad3196e..f09bd71 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,4 +1,4 @@ -use pairing::{LineFn, LinesArrayGet}; +use pairing::{LineFn, LinesArrayGet, FixedPointLines}; use pairing::{PairingUtils}; use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; use bn254_u256::pairing::utils::{ diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo new file mode 100644 index 0000000..0e20a73 --- /dev/null +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -0,0 +1,35 @@ +use bn254_u256::{Fq, Fq2, Fq12, Bn254U256Curve, SZCommitment}; +use schwartz_zippel::{SchZipSteps, Lines, F034X2, LinesDbl, Residue}; + +type Curve = Bn254U256Curve; +type SZAcc = (u32, Fq); + +pub impl Bn254SchwartzZippelSteps of SchZipSteps { + fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12) {} + fn sz_sqr(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12) {} + fn sz_zero_bit( + ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12, lines: Lines + ) {} + fn sz_nz_bit( + ref self: Curve, + sz: @SZCommitment, + ref sz_acc: SZAcc, + ref f: Fq12, + lines: LinesDbl, + witness: Fq12 + ) {} + fn sz_last_step( + ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12, lines: LinesDbl + ) {} + + fn sz_post_miller( + ref self: Curve, + sz: @SZCommitment, + ref sz_acc: SZAcc, + f: Fq12, + alpha_beta: Fq12, + residue: Residue + ) -> bool { + false + } +} From de5c30247c4a9aedfb38d24e678f572b67169680 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 03:11:42 +0530 Subject: [PATCH 47/97] miller steps and pi maps --- .../src/pairing/schzip_miller_runner.cairo | 82 +++++++++++++++++-- packages/pairing/src/utils.cairo | 8 +- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index f09bd71..2df3f2d 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,6 +1,6 @@ -use pairing::{LineFn, LinesArrayGet, FixedPointLines}; +use pairing::{LineFn, LinesArrayGet, FixedPointLines, PiMapping}; use pairing::{PairingUtils}; -use bn254_u256::{Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; +use bn254_u256::{Fq, Fq2, fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; use bn254_u256::pairing::utils::{ LnArrays, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn }; @@ -36,21 +36,87 @@ pub impl Miller_Bn254_U256< } // 1 bit - fn miller_bit_p( - ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator - ) { // - // @TODO + fn miller_bit_p(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { + let g16 = runner.g16; + let ppc = g16.ppc; + let pi_b = runner.g16.q.pi_b; + + let l1 = self.step_dbl_add(ref acc.g2.pi_b, *pi_b, ppc.pi_a); + let (l2, l3) = g16.lines.with_fxd_pt_lines(ref self, g16.ppc, ref acc.line_index); + self + .sz_nz_bit( + runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3), *g16.residue_witness_inv + ); } // -1 bit fn miller_bit_n( ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator ) { // - // @TODO + let g16 = runner.g16; + let ppc = g16.ppc; + // use neg q + let pi_b = runner.g16.neg_q.pi_b; + + let l1 = self.step_dbl_add(ref acc.g2.pi_b, *pi_b, ppc.pi_a); + let (l2, l3) = g16.lines.with_fxd_pt_lines(ref self, g16.ppc, ref acc.line_index); + self + .sz_nz_bit( + runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3), *g16.residue_witness + ); + // println!("n_bit {i}: {}", f); + } // last step fn miller_last(ref self: Curve, runner: @PreCompute, ref acc: Accumulator) { // - // @TODO + let g16 = runner.g16; + let ppc = g16.ppc; + // use neg q + let pi_b = runner.g16.neg_q.pi_b; + + let l1 = self.correction_step(ref acc.g2.pi_b, *pi_b, pi_mapping(), ppc.pi_a); + let (l2, l3) = g16.lines.with_fxd_pt_lines(ref self, g16.ppc, ref acc.line_index); + self.sz_last_step(runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3)); + } +} + +fn pi_mapping() -> PiMapping { + // π (Pi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves + // ----------------------------------------------------------------- + // BN254_Snarks is a D-Twist: pi1_coef1 = ξ^((p-1)/6) + // https://github.com/mratsim/constantine/blob/976c8bb215a3f0b21ce3d05f894eb506072a6285/constantine/math/constants/bn254_snarks_frobenius.nim#L131 + // In the link above this is referred to as ψ (Psi) + + // pi2_coef3 is always -1 (mod p^m) with m = embdeg/twdeg + // Recap, with ξ (xi) the sextic non-residue for D-Twist or 1/SNR for M-Twist + // pi_2 ≡ ξ^((p-1)/6)^2 ≡ ξ^(2(p-1)/6) ≡ ξ^((p-1)/3) + // pi_3 ≡ pi_2 * ξ^((p-1)/6) ≡ ξ^((p-1)/3) * ξ^((p-1)/6) ≡ ξ^((p-1)/2) + + // ----------------------------------------------------------------- + // for πₚ mapping + + // Fp2::NONRESIDUE^(2((q^1) - 1) / 6) + let Q1X2_0: Fq = 0x2fb347984f7911f74c0bec3cf559b143b78cc310c2c3330c99e39557176f553d_u256.into(); + let Q1X2_1: Fq = 0x16c9e55061ebae204ba4cc8bd75a079432ae2a1d0b7c9dce1665d51c640fcba2_u256.into(); + + // Fp2::NONRESIDUE^(3((q^1) - 1) / 6) + let Q1X3_0: Fq = 0x63cf305489af5dcdc5ec698b6e2f9b9dbaae0eda9c95998dc54014671a0135a_u256.into(); + let Q1X3_1: Fq = 0x7c03cbcac41049a0704b5a7ec796f2b21807dc98fa25bd282d37f632623b0e3_u256.into(); + + // ----------------------------------------------------------------- + // for π² mapping + + // Fp2::NONRESIDUE^(2(p^2-1)/6) + let PiQ2X2: Fq = 0x30644e72e131a0295e6dd9e7e0acccb0c28f069fbb966e3de4bd44e5607cfd48_u256.into(); + // Fp2::NONRESIDUE^(3(p^2-1)/6) + let PiQ2X3: Fq = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46_u256.into(); + + PiMapping { + PiQ1X2: fq2(Q1X2_0, Q1X2_1,), // Fp2::NONRESIDUE^(2((q^1) - 1) / 6) + PiQ1X3: fq2(Q1X3_0, Q1X3_1,), // Fp2::NONRESIDUE^(3((q^1) - 1) / 6) + // for π² mapping + PiQ2X2, // Fp2::NONRESIDUE^(2(p^2-1)/6) + PiQ2X3, // Fp2::NONRESIDUE^(3(p^2-1)/6) } } diff --git a/packages/pairing/src/utils.cairo b/packages/pairing/src/utils.cairo index d5cfa86..2f6b39a 100644 --- a/packages/pairing/src/utils.cairo +++ b/packages/pairing/src/utils.cairo @@ -37,11 +37,11 @@ pub trait PairingUtilsTrait { #[derive(Copy, Drop)] pub struct PiMapping { // for πₚ mapping - PiQ1X2: Fq2, - PiQ1X3: Fq2, + pub PiQ1X2: Fq2, + pub PiQ1X3: Fq2, // for π² mapping, only Fq2.c0, c1 is 0 - PiQ2X2: TFq, - PiQ2X3: TFq, + pub PiQ2X2: TFq, + pub PiQ2X3: TFq, } // #[generate_trait] From 30a29560de0dabb82e43d4639287d3d02c650b44 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 12:25:29 +0530 Subject: [PATCH 48/97] fix offset overflow error --- packages/bn_ate_loop/src/ate_loop.cairo | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/bn_ate_loop/src/ate_loop.cairo b/packages/bn_ate_loop/src/ate_loop.cairo index ac33bfd..bd02ae1 100644 --- a/packages/bn_ate_loop/src/ate_loop.cairo +++ b/packages/bn_ate_loop/src/ate_loop.cairo @@ -37,6 +37,7 @@ pub fn _loop_inner_1_of_2< >( runner: @TRunner, ref curve: TCurve, ref q_acc: TAccumulator ) { + core::internal::revoke_ap_tracking(); // ate_loop[64] = O and ate_loop[63] = N curve.miller_bit_1_2(runner, (64, 63), ref q_acc); curve.miller_bit_o(runner, 62, ref q_acc); // ate_loop[62] = O @@ -51,6 +52,7 @@ pub fn _loop_inner_1_of_2< curve.miller_bit_o(runner, 53, ref q_acc); // ate_loop[53] = O curve.miller_bit_o(runner, 52, ref q_acc); // ate_loop[52] = O curve.miller_bit_n(runner, 51, ref q_acc); // ate_loop[51] = N + core::internal::revoke_ap_tracking(); curve.miller_bit_o(runner, 50, ref q_acc); // ate_loop[50] = O curve.miller_bit_p(runner, 49, ref q_acc); // ate_loop[49] = P curve.miller_bit_o(runner, 48, ref q_acc); // ate_loop[48] = O @@ -78,6 +80,7 @@ pub fn _loop_inner_2_of_2< >( runner: @TRunner, ref curve: TCurve, ref q_acc: TAccumulator ) { + core::internal::revoke_ap_tracking(); curve.miller_bit_n(runner, 30, ref q_acc); // ate_loop[30] = N curve.miller_bit_o(runner, 29, ref q_acc); // ate_loop[29] = O curve.miller_bit_o(runner, 28, ref q_acc); // ate_loop[28] = O @@ -95,6 +98,7 @@ pub fn _loop_inner_2_of_2< curve.miller_bit_o(runner, 16, ref q_acc); // ate_loop[16] = O curve.miller_bit_o(runner, 15, ref q_acc); // ate_loop[15] = O curve.miller_bit_p(runner, 14, ref q_acc); // ate_loop[14] = P + core::internal::revoke_ap_tracking(); curve.miller_bit_o(runner, 13, ref q_acc); // ate_loop[13] = O curve.miller_bit_o(runner, 12, ref q_acc); // ate_loop[12] = O curve.miller_bit_o(runner, 11, ref q_acc); // ate_loop[11] = O From 9e04f82154170682c3ba90c841925a76d4d16932 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 13:20:29 +0530 Subject: [PATCH 49/97] simpler bn254 fq2 fn --- packages/bn254_u256/src/curve.cairo | 20 ++++++------------- packages/bn254_u256/src/lib.cairo | 19 ++++++++++-------- .../src/pairing/schzip_miller_runner.cairo | 8 ++++---- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/packages/bn254_u256/src/curve.cairo b/packages/bn254_u256/src/curve.cairo index c0b4e4e..e81bcd3 100644 --- a/packages/bn254_u256/src/curve.cairo +++ b/packages/bn254_u256/src/curve.cairo @@ -20,21 +20,13 @@ impl PtG1One of ECGroupUtils { impl PtG2One of ECGroupUtils { fn pt_one(ref self: Bn254U256Curve) -> PtG2 { Affine { - x: fq2::< - Fq - >( - 10857046999023057135944570762232829481370756359578518086990519993285655852781_u256 - .into(), - 11559732032986387107991004021392285783925812861821192530917403151452391805634_u256 - .into(), + x: fq2( + 10857046999023057135944570762232829481370756359578518086990519993285655852781, + 11559732032986387107991004021392285783925812861821192530917403151452391805634, ), - y: fq2::< - Fq - >( - 8495653923123431417604973247489272438418190587263600148770280649306958101930_u256 - .into(), - 4082367875863433681332203403145435568316851327593401208105741076214120093531_u256 - .into(), + y: fq2( + 8495653923123431417604973247489272438418190587263600148770280649306958101930, + 4082367875863433681332203403145435568316851327593401208105741076214120093531, ) } } diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 880f767..7ff5511 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -1,7 +1,13 @@ -use fq_types::{Fq2 as Fq2Gen, fq2, Fq3 as Fq3Gen, fq3,}; pub mod curve; pub mod fq_1; +pub mod pairing { + pub mod utils; + pub mod schzip_miller_runner; + pub mod schzip_miller; + pub mod schzip_steps; +} +use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, fq3,}; pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn}; pub use fq_1::{ {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, {U256IntoFq, Bn254FqOps, Bn254FqUtils} @@ -12,13 +18,6 @@ pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3Gen>; pub type Fq12 = Fq2Gen; -pub mod pairing { - pub mod utils; - pub mod schzip_miller_runner; - pub mod schzip_miller; - pub mod schzip_steps; -} - pub use pairing::{ utils::{ICProcess, ICArrayInput, LnArrays, // {SZCommitment, SZPreCompute, SZAccumulator}}, @@ -35,3 +34,7 @@ pub fn bn254_curve() -> Bn254U256Curve { qnz: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, } } + +pub fn fq2(c0: u256, c1: u256) -> Fq2 { + Fq2 { c0: c0.into(), c1: c1.into() } +} diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index 2df3f2d..34a1425 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -97,12 +97,12 @@ fn pi_mapping() -> PiMapping { // for πₚ mapping // Fp2::NONRESIDUE^(2((q^1) - 1) / 6) - let Q1X2_0: Fq = 0x2fb347984f7911f74c0bec3cf559b143b78cc310c2c3330c99e39557176f553d_u256.into(); - let Q1X2_1: Fq = 0x16c9e55061ebae204ba4cc8bd75a079432ae2a1d0b7c9dce1665d51c640fcba2_u256.into(); + let Q1X2_0 = 0x2fb347984f7911f74c0bec3cf559b143b78cc310c2c3330c99e39557176f553d; + let Q1X2_1 = 0x16c9e55061ebae204ba4cc8bd75a079432ae2a1d0b7c9dce1665d51c640fcba2; // Fp2::NONRESIDUE^(3((q^1) - 1) / 6) - let Q1X3_0: Fq = 0x63cf305489af5dcdc5ec698b6e2f9b9dbaae0eda9c95998dc54014671a0135a_u256.into(); - let Q1X3_1: Fq = 0x7c03cbcac41049a0704b5a7ec796f2b21807dc98fa25bd282d37f632623b0e3_u256.into(); + let Q1X3_0 = 0x63cf305489af5dcdc5ec698b6e2f9b9dbaae0eda9c95998dc54014671a0135a; + let Q1X3_1 = 0x7c03cbcac41049a0704b5a7ec796f2b21807dc98fa25bd282d37f632623b0e3; // ----------------------------------------------------------------- // for π² mapping From 6f6d157e3c2a49985a0c3ffadc927606241e1103 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 13:54:49 +0530 Subject: [PATCH 50/97] cubic scale type in pairing package --- packages/bn254_u256/src/curve.cairo | 1 + packages/bn254_u256/src/lib.cairo | 3 +-- packages/bn254_u256/src/pairing/schzip_miller.cairo | 4 ++-- packages/fq_types/src/lib.cairo | 7 ------- packages/pairing/src/lib.cairo | 4 +++- packages/pairing/src/types.cairo | 7 +++++++ packages/schwartz_zippel/src/lib.cairo | 3 ++- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/bn254_u256/src/curve.cairo b/packages/bn254_u256/src/curve.cairo index e81bcd3..5ffb62d 100644 --- a/packages/bn254_u256/src/curve.cairo +++ b/packages/bn254_u256/src/curve.cairo @@ -1,6 +1,7 @@ use bn254_u256::{Fq, U256IntoFq, Fq2, fq2, fq3, Bn254FqOps, Bn254FqUtils}; use ec_groups::{Affine, ECGroupUtils}; pub use ec_groups::AffineOpsBn; +pub use pairing::CubicScale; #[derive(Drop, Serde)] pub struct Bn254U256Curve { diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 7ff5511..c21ba29 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -8,11 +8,10 @@ pub mod pairing { } use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, fq3,}; -pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn}; +pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale}; pub use fq_1::{ {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, {U256IntoFq, Bn254FqOps, Bn254FqUtils} }; -pub use fq_types::CubicScale; pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3Gen>; diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index dde2909..4faca10 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,7 +1,7 @@ use ec_groups::ECOperations; pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; use bn254_u256::{ - Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, CubicScale, + Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ schzip_miller_runner::Miller_Bn254_U256, utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArrays, ICArrayInput}, @@ -10,7 +10,7 @@ use bn254_u256::{ }; use bn_ate_loop::{ate_miller_loop}; use pairing::{LineFn, StepLinesGet, LinesArrayGet}; -use pairing::PairingUtils; +use pairing::{PairingUtils, CubicScale}; use schwartz_zippel::SchZipSteps; diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index d38dd6a..3d1ae0f 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -13,13 +13,6 @@ pub struct Fq3 { pub c2: T, } -#[derive(Copy, Drop, Serde)] -pub enum CubicScale { - Zero, - One, - Two, -} - pub fn fq2(c0: T, c1: T) -> Fq2 { Fq2 { c0, c1 } } diff --git a/packages/pairing/src/lib.cairo b/packages/pairing/src/lib.cairo index 932b95d..e39a3fc 100644 --- a/packages/pairing/src/lib.cairo +++ b/packages/pairing/src/lib.cairo @@ -2,7 +2,9 @@ pub mod types; pub mod lines; pub mod utils; -pub use types::{PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute}; +pub use types::{ + PPrecompute, Groth16Circuit, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, CubicScale +}; pub use utils::{PairingUtils, PairingUtilsTrait, PiMapping}; pub use lines::{ // Line function stuff diff --git a/packages/pairing/src/types.cairo b/packages/pairing/src/types.cairo index 94fb323..0377e62 100644 --- a/packages/pairing/src/types.cairo +++ b/packages/pairing/src/types.cairo @@ -42,3 +42,10 @@ pub struct Groth16PreCompute { pub residue_witness: TFq12, pub residue_witness_inv: TFq12, } + +#[derive(Copy, Drop, Serde)] +pub enum CubicScale { + Zero, + One, + Two, +} diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index 2aa4e67..5d68f12 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -1,4 +1,5 @@ -use fq_types::{Fq2, Fq3, F12S034 as FS034, CubicScale}; +use fq_types::{Fq2, Fq3, F12S034 as FS034}; +use pairing::CubicScale; pub type Lines = (FS034, FS034, FS034); pub type F034X2 = (FS034, FS034); From a968925475ef416df01926afb661bdf91525a854 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 17:10:32 +0530 Subject: [PATCH 51/97] legacy maintenance --- legacy/bn_contracts/src/lib.cairo | 3 ++- .../src/curve/pairing/optimal_ate_utils.cairo | 12 ++++-------- legacy/bn_legacy/src/fields/print.cairo | 15 ++++++++++++++- legacy/bn_legacy/src/groth16/schzip.cairo | 2 +- legacy/bn_legacy/src/groth16/schzip/base.cairo | 4 +++- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/legacy/bn_contracts/src/lib.cairo b/legacy/bn_contracts/src/lib.cairo index f528fbb..13ac5a5 100644 --- a/legacy/bn_contracts/src/lib.cairo +++ b/legacy/bn_contracts/src/lib.cairo @@ -1 +1,2 @@ -mod bench_contract; +// mod bench_contract; + diff --git a/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo b/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo index 2c87448..81711b2 100644 --- a/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo +++ b/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo @@ -6,7 +6,7 @@ use bn::curve::groups::{g1, g2, ECGroup}; use bn::curve::groups::{Affine, AffineG1 as PtG1, AffineG2 as PtG2, AffineOps}; use bn::fields::fq_generics::{TFqAdd, TFqSub, TFqMul, TFqDiv, TFqNeg, TFqPartialEq,}; use bn::fields::{ - Fq, fq, Fq2, fq2, Fq6, Fq12, Fq12Utils, Fq12Ops, FqOps, Fq2Utils, Fq2Ops, Fq12Exponentiation, + Fq, fq, Fq2, fq2, Fq12, Fq12Utils, Fq12Ops, FqOps, Fq2Utils, Fq2Ops, Fq12Exponentiation, }; use bn::fields::{Fq12Sparse034, Fq12Sparse01234, FqSparse}; use bn::fields::print::{Fq2Display, Fq12Display, FqDisplay}; @@ -58,17 +58,14 @@ struct LineFn { } mod line_fn { - use bn::fields::fq_2::Fq2FrobeniusTrait; - use bn::fields::fq_sparse::FqSparseTrait; + // use bn::fields::fq_2::Fq2FrobeniusTrait; + // use bn::fields::fq_sparse::FqSparseTrait; use bn::traits::{FieldShortcuts, FieldUtils}; use bn::curve::groups::ECOperations; use bn::curve::groups::{g1, g2, ECGroup}; use bn::curve::groups::{Affine, AffineG1 as PtG1, AffineG2 as PtG2, AffineOps}; use bn::fields::fq_generics::{TFqAdd, TFqSub, TFqMul, TFqDiv, TFqNeg, TFqPartialEq,}; - use bn::fields::{ - Fq, fq, Fq2, fq2, Fq6, Fq12, Fq12Utils, Fq12Ops, FqOps, Fq2Utils, Fq2Ops, - Fq12Exponentiation, - }; + use bn::fields::{Fq, fq, Fq2, fq2, FqOps, Fq2Utils, Fq2Ops}; use bn::fields::{Fq12Sparse034, Fq12Sparse01234, FqSparse}; use bn::fields::print::{Fq2Display, Fq12Display, FqDisplay}; use bn::fields::frobenius::pi; @@ -119,7 +116,6 @@ mod line_fn { let line1 = line_fn(slope1, s); // we skip y1 calculation and sub slope1 directly in second slope calculation - // s + (s + q) // λ2 = (y2-y1)/(x2-x1), subbing y2 = λ(x2-x1)+y1 // λ2 = -λ1-2y1/(x3-x1) diff --git a/legacy/bn_legacy/src/fields/print.cairo b/legacy/bn_legacy/src/fields/print.cairo index ff58dfb..672a581 100644 --- a/legacy/bn_legacy/src/fields/print.cairo +++ b/legacy/bn_legacy/src/fields/print.cairo @@ -1,5 +1,6 @@ use core::to_byte_array::AppendFormattedToByteArray; use core::traits::TryInto; +use bn::curve::groups::Affine; use bn::fields::{Fq, Fq2, Fq6, Fq12, fq12, FS034, FS01234}; use integer::u512; use debug::PrintTrait; @@ -10,7 +11,7 @@ use bn::fast_mod::u512Display; impl FqDisplay of Display { fn fmt(self: @Fq, ref f: Formatter) -> Result<(), Error> { let base = 16_u256; - write!(f, "\n0x").unwrap(); + write!(f, "\n 0x").unwrap(); self.c0.append_formatted_to_byte_array(ref f.buffer, base.try_into().unwrap()); Result::Ok(()) } @@ -28,6 +29,18 @@ impl F034Display of Display { } } +impl G1Display of Display> { + fn fmt(self: @Affine, ref f: Formatter) -> Result<(), Error> { + write!(f, "g2({},{}\n),", self.x, self.y) + } +} + +impl G2Display of Display> { + fn fmt(self: @Affine, ref f: Formatter) -> Result<(), Error> { + write!(f, "g2({},{},{},{}\n),", self.x.c0, self.x.c1, self.y.c0, self.y.c1,) + } +} + impl F01234Display of Display { fn fmt(self: @FS01234, ref f: Formatter) -> Result<(), Error> { let FS01234 { c0, c1, } = *self; diff --git a/legacy/bn_legacy/src/groth16/schzip.cairo b/legacy/bn_legacy/src/groth16/schzip.cairo index 023fd66..f6b1fd7 100644 --- a/legacy/bn_legacy/src/groth16/schzip.cairo +++ b/legacy/bn_legacy/src/groth16/schzip.cairo @@ -10,4 +10,4 @@ use utils::{F034X2, Lines, LinesDbl, SchZipAccumulator, SchzipPreCompute, SchZip use utils::{fq12_at_coeffs_index, powers_51}; use eval::SchZipEval; use base::{schzip_base_verify, SchZipMock}; -use v1::{schzip_verify_with_commitments}; +use v1::schzip_verify_with_commitments; diff --git a/legacy/bn_legacy/src/groth16/schzip/base.cairo b/legacy/bn_legacy/src/groth16/schzip/base.cairo index a5d4e01..3c5c117 100644 --- a/legacy/bn_legacy/src/groth16/schzip/base.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/base.cairo @@ -8,7 +8,9 @@ use bn::fields::{fq_12::Fq12FrobeniusTrait, fq_12_direct}; use bn::fields::{Fq, Fq2, Fq6, Fq12, fq12, FS034, FS01234, FS01,}; use bn::fields::{FqSparseTrait, Fq12Utils, Fq12Exponentiation, Fq12Sparse034, Fq12Sparse01234}; use bn::fields::fq_12_exponentiation::PairingExponentiationTrait; -use bn::fields::print::{FqDisplay, Fq12Display, Fq6Display, F034Display, F01234Display}; +use bn::fields::print::{ + FqDisplay, Fq2Display, Fq12Display, Fq6Display, F034Display, F01234Display, G2Display, G1Display +}; // Field direct use fq_12_direct::{FS034Direct, Fq12DirectIntoFq12, Fq12IntoFq12Direct, Fq12Direct}; From a523deb1c0a2808a98698bbefe7862561c726757 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 17:11:03 +0530 Subject: [PATCH 52/97] print impls --- packages/bn254_u256/src/lib.cairo | 1 + packages/bn254_u256/src/print.cairo | 57 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 packages/bn254_u256/src/print.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index c21ba29..7eb5c02 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -1,5 +1,6 @@ pub mod curve; pub mod fq_1; +pub mod print; pub mod pairing { pub mod utils; pub mod schzip_miller_runner; diff --git a/packages/bn254_u256/src/print.cairo b/packages/bn254_u256/src/print.cairo new file mode 100644 index 0000000..37d8320 --- /dev/null +++ b/packages/bn254_u256/src/print.cairo @@ -0,0 +1,57 @@ +use bn254_u256::{Fq, Fq2, Fq12, F034, PtG1, PtG2}; + +use core::to_byte_array::AppendFormattedToByteArray; +use core::fmt::{Display, Formatter, Error}; +pub impl F034Display of core::fmt::Display { + fn fmt(self: @F034, ref f: Formatter) -> Result<(), Error> { + write!(f, "f034({},{},{},{}\n),", *self.c3.c0, *self.c3.c1, *self.c4.c0, *self.c4.c1) + } +} + +pub impl Fq12Display of core::fmt::Display { + fn fmt(self: @Fq12, ref f: Formatter) -> Result<(), Error> { + write!( + f, + "fq12({},{},{},{},{},{},{},{},{},{},{},{}\n),", + *self.c0.c0.c0, + *self.c0.c0.c1, + *self.c0.c1.c0, + *self.c0.c1.c1, + *self.c0.c2.c0, + *self.c0.c2.c1, + *self.c1.c0.c0, + *self.c1.c0.c1, + *self.c1.c1.c0, + *self.c1.c1.c1, + *self.c1.c2.c0, + *self.c1.c2.c1, + ) + } +} + +pub impl FqDisplay of core::fmt::Display { + fn fmt(self: @Fq, ref f: Formatter) -> Result<(), Error> { + let base = 16_u256; + write!(f, "\n 0x").unwrap(); + self.c0.append_formatted_to_byte_array(ref f.buffer, base.try_into().unwrap()); + Result::Ok(()) + } +} + +pub impl Fq2Display of Display { + fn fmt(self: @Fq2, ref f: Formatter) -> Result<(), Error> { + write!(f, "fq2({},{}\n),", *self.c0, *self.c1) + } +} + +pub impl G1Display of Display { + fn fmt(self: @PtG1, ref f: Formatter) -> Result<(), Error> { + write!(f, "g2({},{}\n),", self.x, self.y) + } +} + +pub impl G2Display of Display { + fn fmt(self: @PtG2, ref f: Formatter) -> Result<(), Error> { + write!(f, "g2({},{},{},{}\n),", self.x.c0, self.x.c1, self.y.c0, self.y.c1,) + } +} From 95f3266d2938bbd752ea949268b0b1ef59a3c303 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 17:11:57 +0530 Subject: [PATCH 53/97] bn254 utils --- packages/bn254_u256/src/lib.cairo | 11 +++++----- packages/bn254_u256/src/utils.cairo | 34 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 packages/bn254_u256/src/utils.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 7eb5c02..89710be 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -1,5 +1,6 @@ pub mod curve; pub mod fq_1; +pub mod utils; pub mod print; pub mod pairing { pub mod utils; @@ -8,15 +9,17 @@ pub mod pairing { pub mod schzip_steps; } -use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, fq3,}; +use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, F12S034, fq3,}; pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale}; pub use fq_1::{ {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, {U256IntoFq, Bn254FqOps, Bn254FqUtils} }; +pub use utils::{g1, g2, fq12, fq2}; pub type Fq2 = Fq2Gen; -pub type Fq6 = Fq3Gen>; +pub type Fq6 = Fq3Gen; pub type Fq12 = Fq2Gen; +pub type F034 = F12S034; pub use pairing::{ utils::{ICProcess, ICArrayInput, LnArrays, // @@ -34,7 +37,3 @@ pub fn bn254_curve() -> Bn254U256Curve { qnz: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, } } - -pub fn fq2(c0: u256, c1: u256) -> Fq2 { - Fq2 { c0: c0.into(), c1: c1.into() } -} diff --git a/packages/bn254_u256/src/utils.cairo b/packages/bn254_u256/src/utils.cairo new file mode 100644 index 0000000..71a09d9 --- /dev/null +++ b/packages/bn254_u256/src/utils.cairo @@ -0,0 +1,34 @@ +use core::traits::Into; +use bn254_u256::{Fq, Fq2, Fq6, Fq12, U256IntoFq, PtG1, PtG2}; + +pub fn g1(x: u256, y: u256) -> PtG1 { + let x = x.into(); + let y = y.into(); + PtG1 { x, y } +} +pub fn g2(x0: u256, x1: u256, y0: u256, y1: u256) -> PtG2 { + PtG2 { x: fq2(x0, x1), y: fq2(y0, y1) } +} +pub fn fq12( + c0: u256, + c1: u256, + c2: u256, + c3: u256, + c4: u256, + c5: u256, + c6: u256, + c7: u256, + c8: u256, + c9: u256, + c10: u256, + c11: u256, +) -> Fq12 { + Fq12 { + c0: Fq6 { c0: fq2(c0, c1), c1: fq2(c2, c3), c2: fq2(c4, c5) }, + c1: Fq6 { c0: fq2(c6, c7), c1: fq2(c8, c9), c2: fq2(c10, c11) }, + } +} + +pub fn fq2(c0: u256, c1: u256) -> Fq2 { + Fq2 { c0: c0.into(), c1: c1.into() } +} From e33abb5e96a7b25db73d3123347669a0813fb3c2 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 17:12:51 +0530 Subject: [PATCH 54/97] bn254 minor tweaks --- packages/bn254_u256/src/fq_1.cairo | 2 +- packages/bn254_u256/src/pairing/schzip_miller.cairo | 1 - packages/bn254_u256/src/pairing/schzip_miller_runner.cairo | 1 + packages/bn254_u256/src/pairing/schzip_steps.cairo | 6 ++++-- packages/pairing/src/lines.cairo | 4 ++-- packages/schwartz_zippel/src/lib.cairo | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/bn254_u256/src/fq_1.cairo b/packages/bn254_u256/src/fq_1.cairo index 7505f32..864de65 100644 --- a/packages/bn254_u256/src/fq_1.cairo +++ b/packages/bn254_u256/src/fq_1.cairo @@ -4,7 +4,7 @@ pub use bn254_u256::Bn254U256Curve; #[derive(Copy, Drop, Serde, Debug)] pub struct Fq { - c0: u256, + pub c0: u256, } pub impl U256IntoFq of Into { diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 4faca10..3799a0d 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -66,7 +66,6 @@ pub fn schzip_verify( residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - // schzip: TSchZip, schzip_remainders: Array, schzip_qrlc: Array, ) { diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index 34a1425..2aeb455 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,6 +1,7 @@ use pairing::{LineFn, LinesArrayGet, FixedPointLines, PiMapping}; use pairing::{PairingUtils}; use bn254_u256::{Fq, Fq2, fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; +use bn254_u256::print::{FqDisplay, Fq12Display, G2Display}; use bn254_u256::pairing::utils::{ LnArrays, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn }; diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index 0e20a73..b8d995e 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -1,5 +1,5 @@ use bn254_u256::{Fq, Fq2, Fq12, Bn254U256Curve, SZCommitment}; -use schwartz_zippel::{SchZipSteps, Lines, F034X2, LinesDbl, Residue}; +use schwartz_zippel::{SchZipSteps, Lines, FS034, F034X2, LinesDbl, Residue}; type Curve = Bn254U256Curve; type SZAcc = (u32, Fq); @@ -9,7 +9,9 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps fn sz_sqr(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12) {} fn sz_zero_bit( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12, lines: Lines - ) {} + ) { + let (_l1, _l2, _l3) = lines; + } fn sz_nz_bit( ref self: Curve, sz: @SZCommitment, diff --git a/packages/pairing/src/lines.cairo b/packages/pairing/src/lines.cairo index 4310606..79a731e 100644 --- a/packages/pairing/src/lines.cairo +++ b/packages/pairing/src/lines.cairo @@ -19,8 +19,8 @@ pub trait StepLinesGet { #[derive(Drop, Serde)] pub struct LinesArrays { - gamma: TLinesArray, - delta: TLinesArray, + pub gamma: TLinesArray, + pub delta: TLinesArray, } pub impl LinesArrayGet< diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index 5d68f12..8f717a0 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -1,4 +1,4 @@ -use fq_types::{Fq2, Fq3, F12S034 as FS034}; +pub use fq_types::{Fq2, Fq3, F12S034 as FS034}; use pairing::CubicScale; pub type Lines = (FS034, FS034, FS034); From 0da429650c9d2c82f6634ef0d96941cd0e431ae8 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 16 Jul 2024 17:14:20 +0530 Subject: [PATCH 55/97] bn254 tests and fixtures wip --- packages/bn254_u256/src/lib.cairo | 6 + packages/bn254_u256/src/tests/fixtures.cairo | 3 + .../src/tests/fixtures/lines_fix.cairo | 1073 +++++++++++++++++ .../src/tests/fixtures/proof_fix.cairo | 212 ++++ packages/bn254_u256/src/tests/tests.cairo | 27 + 5 files changed, 1321 insertions(+) create mode 100644 packages/bn254_u256/src/tests/fixtures.cairo create mode 100644 packages/bn254_u256/src/tests/fixtures/lines_fix.cairo create mode 100644 packages/bn254_u256/src/tests/fixtures/proof_fix.cairo create mode 100644 packages/bn254_u256/src/tests/tests.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 89710be..a5d39a2 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -9,6 +9,12 @@ pub mod pairing { pub mod schzip_steps; } +#[cfg(test)] +mod tests { + pub mod tests; + pub mod fixtures; +} + use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, F12S034, fq3,}; pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale}; pub use fq_1::{ diff --git a/packages/bn254_u256/src/tests/fixtures.cairo b/packages/bn254_u256/src/tests/fixtures.cairo new file mode 100644 index 0000000..e89b3db --- /dev/null +++ b/packages/bn254_u256/src/tests/fixtures.cairo @@ -0,0 +1,3 @@ +pub mod lines_fix; +pub mod proof_fix; +pub use proof_fix::{circuit_setup, residue_witness, proof}; diff --git a/packages/bn254_u256/src/tests/fixtures/lines_fix.cairo b/packages/bn254_u256/src/tests/fixtures/lines_fix.cairo new file mode 100644 index 0000000..2d2f438 --- /dev/null +++ b/packages/bn254_u256/src/tests/fixtures/lines_fix.cairo @@ -0,0 +1,1073 @@ +use bn254_u256::{Fq2, fq2}; +use pairing::{LineFn as LineFnGeneric}; +type LineFn = LineFnGeneric; +#[inline(always)] +fn line_fn_from_u256(slope_c0: u256, slope_c1: u256, c_c0: u256, c_c1: u256) -> LineFn { + LineFn { slope: fq2(slope_c0, slope_c1), c: fq2(c_c0, c_c1), } +} + +pub fn gamma_lines() -> Array { + array![ + line_fn_from_u256( + 0xce69bdf84ed6d6d204fe74db6b371d37e4615ab1b3d578c32d1af5736582972, + 0x1e23d69196b41dbf47d406f500e66ea29c8764b3fd262357407c3d96bb3ba710, + 0x2cad36e65bbb6f4f41d975b678200fce07c48a5e1ec8ee6f65402483ad127f3a, + 0x54c8bc1b50aa258d4fe3a18872139b0287570c3cfa9b8144c3ea2ab524386f5 + ), + line_fn_from_u256( + 0x237db2935c4432bc98005e68cacde68a193b54e64d347301094edcbfa224d3d5, + 0x124077e14a7d826a707c3ec1809ae9bafafa05dd6b4ba735fba44e801d415637, + 0x3b7178c857630da7676d0000961488f8fbce03349a8dc1dd6e067932b6a7e0d, + 0x2b17c2b12c26fdd0e3520b9dfa601ead6f0bf9cd98c81278efe1e96b86397652 + ), + line_fn_from_u256( + 0x2a0dd3f377bee86df8af1493203288c14f2e45f5b283a7d2e9789f0a85418bd4, + 0x27ca8354ad922aa6f422d09ed311ff1858d237c9992f9b668fa9e7c6a2dd7ba9, + 0x1f4279a8c504f4f387a0d0750b107a29b7d80bb6c9494b44f94a033f28a32fe0, + 0x28255bfe26b88c84293b4ef2de9e8e864c4cee92ec2574cacb0f994d3654056f + ), + line_fn_from_u256( + 0x1234f85fbc425be21a706f9958e5f2b3e35c261a6c4e24186b96a246f981df8f, + 0x2fcf4f59596004c6eb77f32d49eb2eef4a62976071f75fef0a29f4bbb676ba5d, + 0x3678848c935b15e518d6de5b00ab4a1438de3a93265a03271c6f2a9b3b0e400, + 0x1d73ac7a11db5fc209b5495eed3a0fa561b590823a9557549e46e2339714249e + ), + line_fn_from_u256( + 0x15b641064299177ca11814969284e168319e1c06cbdb8e4161421f33041c4cd0, + 0x46d5f98b3a5be977f09c53b7a2a6fe73107dbb65f4aa50b3e2881127be0be3d, + 0x24f4c6aef1273059e048d611f1ed67c01658c7e929dc542b88c6f6c1a8c88769, + 0x190536b710848e1067034108e8e5c676ffd710829959f3c01b1f5c0491d40ae3 + ), + line_fn_from_u256( + 0x174dc1209fccabc5e390a081696248d73dd106addf2609007513ea7e5a416da8, + 0x534c43aa39d5089188b5a40b5d1309c5face74fe362e1bc526b009466e28eb5, + 0x2d1c7506fb49a5f7e06fad7ec8deb4a60901856c142001f5f1aff79315cc7d8a, + 0x11e03f84b9d48fc64dee9658d14b9419aa71e91ee6329eeac7e1a9c1f3bb7329 + ), + line_fn_from_u256( + 0x2059fa5c7e77d2ad20e8633b7ed87e265667430a4f9b9a33adc7d0b9d77a4a39, + 0x28da2376ea0e8841e3b3774bc430a2e8a4653d1f6825235bfe2daaadf09712d7, + 0x87ce08da73093489ac933e35fdfc49f644dae28fad892023206244023ef7567, + 0x2901a083df0a5821f28134db6a760872e821db75f13dae985ac02d7ea8d7f28a + ), + line_fn_from_u256( + 0x25af34756438b82fc30d0e30bffa8b4c96d5ff10c73a10fb81904367ee82f180, + 0x2e2694f8e8e983cab6d0caf4782e3139a5573645d7ee9b4768e6ffb62e628865, + 0x1e35d5988c27b24e882042a95b4038d974252f9bf636bc6979a001b9b9d64c2a, + 0x2ac1b254b9d034f4c261d7bc45ae3132687779c977003e6f1a76cfd8105a0a2e + ), + line_fn_from_u256( + 0x1838369b4d45f8dcaaf5e56345b089e52d91ae7bac52ec4533ac8f2b5143ac29, + 0x1354ed1c38975de540fa1387dda550cb0dac4b63e4b291b423a9de8d3f2b9185, + 0xac0f5dc6704f80bf8bc1d4a5d29c373882b3b5efdb7655e22a4a31d417544bb, + 0x2fe0633a013d0a1ae568b3c10a52842292157eefa848fe8df36077e2efcac7df + ), + line_fn_from_u256( + 0x1d523e5da70f885364dd99cb8c19137eb17408f8a5cf13056339732ebf0c21c7, + 0x20433aa92a32eff3c0f3a3bff235ca729c642f48f82fb10d0ae2826e3797551a, + 0x1438d78ea783d75d11da43f9de9bc329ff4e5177221d096fc862e3ce649e61c1, + 0x1278b4f94558e9ef16d62d300c297eeddfbe7247cc1e260075b46cc9743bf755 + ), + line_fn_from_u256( + 0x25fbed7d17c8a87bd61572b7594dbf4a624db771a551a3c7d8df629737fc843b, + 0x23f10de776cd38a8bca7c70e212c6482400cca023f0afb679e5a795033a467ca, + 0x18458d883acb91e43a546e26e11c4efd4b747e0405fefc33c5479d5ccf8691ff, + 0x1f1c7188a78d256c109a63d4731c81b3edb2dc301fc292cb99ec56c0dc8459f0 + ), + line_fn_from_u256( + 0x2b6eda24b76fb4f90135ff8cdd17ed363d8888f3283e056ecdd9f3fe86602a99, + 0x1899dfce5bda496e34f103457a8cb1a4ffba9b6dc37d4ed0db5585ccfbdb35d5, + 0x13f1f62946c5e16aaf94f0bb764acf92cefb5b80e8ed80577431de21c6967ef0, + 0x36f87c4c5dbc7abe9e076c01a144ab0c3eb8e77579f60cbc480f5826a2b7b01 + ), + line_fn_from_u256( + 0x1b64711d78d622a728035578e450a65ef9ba571cbcfd23d258b5746505b0ecc6, + 0xf7502d2ab2bd262f826821ff70ba24b674527f940f2590c84515817f9aba50b, + 0xb9a3c568ac2e7d2aedcd2b46dab8150591e93b592ca28112074e89dbdcb73f0, + 0xda761c6b55bbb0ea9f7fa4b5c670635d0751908c9259ca3378d96ce29ff5eb4 + ), + line_fn_from_u256( + 0x25f7392b502c30e347095429abef843a1037d3aa346547f5ecae6a7198ba099b, + 0x150cd696c87f168e302db4eb2dc9c2acafb8a888f7e87be6fa97fb419d1e1c1d, + 0x5cd0517de029ae70680c359009fbe97cdb9d4dbced0e564669e8bac761af691, + 0xb6429c69c6e41e9fd4644932afa36221c0f99aba0a26f47deb1506f9a9111a2 + ), + line_fn_from_u256( + 0x55be8e443d5fa5e0348cf53b0b2bae83c9026259b7988bde003932238349f1f, + 0x2ff20a1caca8e57758568a390d30fd585529e7f7fb8ba9089aca065c1b050ac8, + 0x8a1c914805e3e6ca5dcad76680c285ce9f85d5d7bfa4a4468dbdfa5b11f672a, + 0xc7c5f48b0a35657f005d5e26560e2bda08253f75df7ca1b59f5992330e2ea6d + ), + line_fn_from_u256( + 0x74b649254bb5401a56e0f7ecb3fad4f3c4f3fb8f76cc840f90658ae9adff1aa, + 0x5f97cd0e98151330b54fc184b5ec68ce72dae9b423981136a2b4a9893621288, + 0x27982ece4cbf361d5db80b4b86e4a02c9d2603aaae2415777dafc892d06d334e, + 0x44c14c302cbe52ec9184f4b7bf60bc679e4d3e10ea81af9a2338bd453919c42 + ), + line_fn_from_u256( + 0xdd60383235a6749c0c2edc5f7c15a6d1b19fede61b2b6eac1113d60730240fc, + 0x6a524cf10bfb3ddbe1091673700f442fbcdae88193026823733f5d0befaccf4, + 0x2e9772f9ca18cee53ea3b2c56da32f387aaa2ff8e4ef8cbf3d1dce4e37965344, + 0x893b910091beb83a95c9eb64d37e406cfb168ebc7fd1cb36bb9b07cae1cb691 + ), + line_fn_from_u256( + 0x1496f20487b42ccba04ed69fffff05278a54dfb1e0cd7d58ff592b11692dce99, + 0x195113107fb23c829ae2aeb47627892f4c48ac420f34564878a9954045f3973c, + 0x1177d4b9060a542022934b370575e7d24a0def94dfa700f4d26558b80f27c2d7, + 0x5243191f0d2b96e31c1ffea6d995ac062a05257840c254e9c40062b7fd63ed2 + ), + line_fn_from_u256( + 0x28a7a65ca2ad7441bef2b2833cec147f1ebacc1be47d3ad2765ed2d251ba2d10, + 0x6bec470982420d6b5458c9ded8464bff9b24f08085c4f5d453bb4def5a23adc, + 0x2d5a9dfd5e00261693a9618a692184f2dc1aa5d716622dd7bc1a2047ab948a6c, + 0x1c5f063c4781fe20a8851f3faad72f9365fc50bf0e25689d91e3827085b5d8d6 + ), + line_fn_from_u256( + 0x156687599d240f38bee69bfd1fdeccd6692abfcea891efa4db1ea9793494938f, + 0x2016c26ff5b23f60f8acbe0fecbb1690a89d26567a2e00f7d3b1785c2ecc8ae1, + 0x1c3e9d124fa63014e5086b80526958e2e990172db2cb48a88c74d9d4d90254c, + 0x9a3b3e4180167f358a56a7ffd04b84d5fed7046f9f7645cc860a38cad7acad8 + ), + line_fn_from_u256( + 0x3c5527e6780608538e4b844a06203d24a2eab602614bd19a476a9a0dc4f48ae, + 0x28f3418e225dcf23a7bd7a8e6397f70b451ae9e46d224a59888f49027b1fa5eb, + 0xfb1679a312b90d4c29815c29cea9ca490410fbda2991f50753b08370fe6e70b, + 0x264f356a8fdea1f1ce8071e70f6eff09a910d7fb235863b36a60533b2ed17261 + ), + line_fn_from_u256( + 0x60e5d585d1ec3072522d5d26bf076edc83a41b2bb9dd153556bad96c2a7f2fd, + 0x135f614f3d7dbe6b7dde31aefb47af3f6d7c6329e8fb88075a561830893e2e6e, + 0x1b5e3871d3c1fcba38ad0262452b09bf1407244cfe85468b42312247129df38c, + 0x1b9c6933672f0233e2c1eadc049dce8ca51398ff70f5e0107552879f2a3c0ef + ), + line_fn_from_u256( + 0x10ebba94e16374fffee9b95f9ab6c4fd44e7676ee52c5015e98b66a2ad351016, + 0x27f7f4667be45dbe34b91209e24854d7b80609e00435b16f0341d1baf73af164, + 0x2337ba8f4f1d43d284b492818b075cb97c2f7c9338bfc06103c02e3f51dc21f8, + 0x26893fa62e5681b639306df869eaba330c27d3be259ceb9ca59b892dd067c020 + ), + line_fn_from_u256( + 0x1708c536fd78b531e07184496f17bbd59a4b7bbd95b7b32bcc3119c64a62a8de, + 0x2d2287dd024e42189a00c53309a9e525bef171afa85b5778c77166c1523a75e, + 0x23c7f99715257261537e04ea344beb57ee64502631fd0884eaf2208bf8831e72, + 0x2973d5159ddc479af838a99d9ec8ed6dcec6a2a88c38b3aeea525f3c2d2fdc22 + ), + line_fn_from_u256( + 0xc5963c4d9ada42f9945b51e54baca0fbaa92c3a296c3d00d822fbb99bda6205, + 0x24f135b47e8d2979f62fb7489900eb6905c3f5bd5991dc0b6412e905da8c2c6f, + 0x1335321a292d6d47951dbbb61e6eb13ae97816062c08a9c499dc3750a3897449, + 0x10e321f4be3e6663ead90a2e92372e9c2ffca4e2b1484a35eca604a1519ec2e4 + ), + line_fn_from_u256( + 0x758737f279112661bd6e2caf5c29f02fad99b406985e163fa2730a836ac678c, + 0x44b932705030ac20679a79ecccb6c67487418b00004d07b724bd2e06333a7ae, + 0xa5bd2c1e049a08a37649eb77f08da1fae1cc5c066fdb0dc4580401a3fa5e820, + 0x2c59dc52037e0c4845d987dc538a83436e63b02850acdc4a782a79529e7406be + ), + line_fn_from_u256( + 0x9d95c905b75462a5335194af558383d16070751e5645311231c86a536a5cd77, + 0x1dc253f4a5fb0de764404c4ad35f8ad1fc9c27057a8a3ee304043048d0fdb90a, + 0x22be3ec7b36bf9f080f096b5906ce206dfc06331eef5c484567b563e650fb182, + 0x1c3d1f900ed27f725c8aed258279f035f6e2e64d0764a484df24a03ba7aeb5d9 + ), + line_fn_from_u256( + 0x2ebac378f05d105621573f48a2adb484fe7f0f9c91eb9c72ef7cd95be184249d, + 0x1d97b695ee090974720cabd0a17ddd47ff1ab84b410689107601e9bd1768cbf9, + 0x1f943ade068b815983c808cc67c2be148ced9b6578ff660deff3831ad4f0b9d0, + 0x2181a66524118d862708c525f2b2f37633b4ca2e893d78534f3cdf6c75eb6704 + ), + line_fn_from_u256( + 0x25179a093e54ab37eb3e00d8eba4285d382e4b104b1798986b967d575a75df47, + 0x109327d0273e23c2b5bd9aade8262f22d7b5c945ec1891df8ce7d8c1cf4f1b56, + 0x182425e04f6e45b740fb6d6312917e3d71e0f750f9d495623978c09fb8b0c94e, + 0x20c14d5068b0f7e7c05941f2c52b58d39586d72b801284392468cea14c288219 + ), + line_fn_from_u256( + 0x2f53ab5e410f2d7845018b905fefcddb8c9d240cc46c494353f1e70375c56163, + 0x16ba267f96816aa477b421470b555736f5cdb2d985bd91294cd036379c586734, + 0x1aed29b4b7273b0a4cad231cd12226acfddd7b8450d71d2dda1ef824b079dfe5, + 0x17c9832d6f5c99979225f43211377ea8beb2c7f9c536a1b3971d8b321cb36c10 + ), + line_fn_from_u256( + 0xc50ffb9cc2150e68e63027141e757d0060a7a8d3eb4870b8dd58faf59997e71, + 0x16b7ec843d2769ad0d1487d089c5a37e2d160e77e7184b0a80b8a30c9a0a3f75, + 0x285b9964d26641dbc34f558dda46a0a5bc8065ed856751590c6d728086ce1a4d, + 0x1ca0a22e5885cef0c172c4ef66ca6fc9a4b221b6127f4908e85d6e82b4382371 + ), + line_fn_from_u256( + 0x29c0cc1bf29aaf160cd0c7e966be2cd6ffecf8c1972b8823803591c2692761b8, + 0x1545ee1f9627356f8345461a9a87f332c33fc6e3772479f4edba925a969daec9, + 0x54bb85ad08b70a1e8c71fd64255a29bdd7807b3c9d97a0f95543b71697ac4fe, + 0x1c6f64d777029dcb4903d9a283f0636fd45ef1222e2568d4044c34d8994f5aae + ), + line_fn_from_u256( + 0x1180e991be100fdfa989ca56b797171357615731886070142a15a384314dbf7c, + 0x1b1bd6c00fa116946050652161fb1a8cd5be8116c124c126cc8c6254e678e06e, + 0x18431c50ee9e252dd1a35ba22c1db8126f5f997167a5e4a8694dc2f9fb3030a7, + 0x1de8f6eabaf70dab9e14f5254fed0525d42adac16a511ae64542a0ea21145799 + ), + line_fn_from_u256( + 0x6435a1c85b1a7a3bc5ee39034e109788b10aca880ab71de6e753e63103d8420, + 0x8e0eaffd0a87a551d826d23bcf54f7f930ed3d522c0079c9afe28b4e4567987, + 0x214360c6582c61b6eca8f6ec0a78ed6b51b00a22a78737f888daa5424f5686a0, + 0xe9fa5adbc7fb1ac7e34096081e43772d6776fde1bdf27fe14a6e6ef31f269bb + ), + line_fn_from_u256( + 0x703e7850008109d5c23495abcb43d14a311295cc1f1a8b7a85c29d0295aa7a9, + 0x162c43c078a099456a1a6827f220cfa28357cb036a59ed25d634f080b29192c3, + 0xc278da41bf5289e16f260c74cde5848d1de80e2e5b6fb59bf7ff3c2f93a40ee, + 0xa7ffc6c2ff25c65833cfa917bb5a2b8ce625fcc9d47ae9bade4e2e23d727155 + ), + line_fn_from_u256( + 0xc26a096993bca6740e9333dd54d66dfa0cf8f08d9da1a853c4702fb079586f7, + 0xeb9b5e44c2449e9c0ff00ab7eb81bdfb8d811590311e5c4803a9e102ddcf7fc, + 0x231d8b9d27d34af733af429f1ac973f7a1c57684b3568f21b69dadd82828682f, + 0x250dc322f90080968ec81315c53a6c700b82090117baecb496319c10622ae429 + ), + line_fn_from_u256( + 0x1b8acae46418876dc13612b6684009edb89a13908abceef360b86ee0e162e7ab, + 0x28ad74f1bb94f45018870628ddf28c344050310f48353ee0ca8b71b7ac17c637, + 0x2171a8afd24199d717d4fab422c2ebc788a36e3ac1484db1e03fbfd103f05698, + 0x16ee28cd883e73f377d2e0939f878a31cb895bb6b0816e1663bfa304ad461070 + ), + line_fn_from_u256( + 0x2c90e0619f25bfd5dbf6752ebb5984da629bb127b7817c935d574414f3f28d50, + 0x640f9c0590a9982b8cba5eac599985113d6180ea062c38d3a767690bfdefb32, + 0x2437193ef44a47aff1ed16bc09cdee13822f9a8e1fa259c52d17d54efc044f95, + 0x15e24858aded9beddd81936ba3dbb813d8aed04104899eead6094aaccd061f9d + ), + line_fn_from_u256( + 0x2f1c5ace8696577deed18f6b4bc6e001b8e5919d71ecbbe2cce58012bb53589, + 0x7e0465f35a7801db9640c66c2482d4bd115bc6a634085cd581d7cd7391dff9f, + 0x1fa2ad292abc847b5cf0b8196a67ba48fae37b2289ae196d7ff7d910fee38e80, + 0x27a92c994b231cadba78d8af9d1276b453c8f20402133bd5544d1573ff5b34be + ), + line_fn_from_u256( + 0x14e26dacb00e379e44b9157c4ceac86c1b7a82902e0a080324ce8b30a6d2acdd, + 0x18c49b1deb28c628cc38103db865c7a66928e2da33e0fab84ba9c5f4fdb85c1b, + 0x27958928b81241d1bbdbc39b1af422ecccaddb05d54f0cab37d2adbece044314, + 0x289a83d73621a3aa2ad4e09bb01965b95a073d86a5f03f22a6ef9d9103ca4efe + ), + line_fn_from_u256( + 0x15579c902baa8dc5d749191c6a8f5570a401ae5cc2fb89fdb91faddc61681699, + 0x2cf58215232b025f63919e9d2a3ee95d7278737c4748e85bf58bd5b3b00eda29, + 0x28fe26d488ac0d6a005b598abf108a2d43f180d950aa4db4ac8333a64304ac79, + 0x29145d3e461939617798d37edee4aabb43c043cb4d051cae23425ce5de17fc25 + ), + line_fn_from_u256( + 0xbbd38cd07a990f12c14bced487edfd659acba49326ea41f36ca802a2d460258, + 0x18b10442023975734289a223d636f5de335e66af7e7c34dc2a50bc09baaa74b6, + 0x19f59419b27fa3b1a183c6764ecd6471c8b3d113816aebfe067408a471dd3474, + 0x818b53fa7fcc0bb56571ad5280bdc1920972be609c459c3967a5c90cbfe15e + ), + line_fn_from_u256( + 0x22aa9c6c52ec91191cbc0b0544d41342aa6661ef614f76b402bd5c8aaf81a5e4, + 0x154878971322f6c32e48b3e1af93f7a52931827de781a4b07f3d5cb28e82862e, + 0x2bffa3e8e8ce84ef68341beecad29c137c3d2a11bdff276f54487668670b9773, + 0x12c160dad27460ffdafddb6574b909488abc9536fce4b70f1d7c4f422686e696 + ), + line_fn_from_u256( + 0x2e48aefac027ba824e184803c8e819707ec66c02e1f4fbb49c10070d7f88dd52, + 0xcf5ddef544391540b9a22e7eed974c9bba05eeff56a830fd71a73306a997038, + 0x7175d5d3efcf6406253d3d39043cbac6bac4c1cb30d2784912aae75e3cdee3a, + 0x1e005a1793f9093a8b11bffbc723b8efbfb7df5ab5b6a355ccacae11ffdc754 + ), + line_fn_from_u256( + 0x119bb68b40f056ead6a7abdc5fbf7d624f24fa128996cb5b3664f6dbac43f1bd, + 0x646570bfb4df5faf1fd9b968c4d76b2c02e478b73458e5c6ed35a14253c7367, + 0xeb8fe90d39a11b25b6d4c901ad28f3332717bafedab34b95a831264a3a24e0a, + 0xcda946d734c359c5194252b306c548c6f820bb2c2273953127edd41f80376e3 + ), + line_fn_from_u256( + 0x4df9bc930416151851e02024445d86c0a74a41f8fe6b3a6b61feae86c5d9d41, + 0x1fbcf0267353ebe7e087b102833005c6dc7c1d61748f150f617409ea8adc63b6, + 0x256bc45cd6c66a55965b58e54145a0d66db980f5f4ab6ad18bb610f5201750f1, + 0x23b7eac83cfb6e3a3d95e498dd8777e8f1690a5ba8badac309bf9407e7d9477 + ), + line_fn_from_u256( + 0x1a5934840fdf790d8d669f2ae415c16a04a29d2588e675daf8100c0df083c9f7, + 0x8fe333291489ec777c2f3ce9cd36a84a2881d8aa6e740f86c655d88e43618fe, + 0x1870543f6dc9c24da37ad2b48b81288a6e8e944454e117e989a1481f2c097a1b, + 0x2a57fb6b39fbf019eed66ec2fb8673a7b3090fc1eea7118de02d94b41345cdc7 + ), + line_fn_from_u256( + 0x2059a63628ee6aeab97d5b6ef2e7364d6ef0f0af30044f697543c08f750ce47e, + 0x18ebbcf067da10d9903f3f4583641f985784a39a45d56e64dd1bef1214a0a060, + 0x25d877fbd5c44580ca50f052bdbd708ababd67a47ec49e11b208ea2575fd0caa, + 0x1fbe3fc7004562b133e1d1e562543f5f19634fef01ac08de4ec487cfcd2e730a + ), + line_fn_from_u256( + 0x19780bbd16496e28e781765a2200c5f11f842220dfa7b16fb6626caab82aa558, + 0x31ca9f538face826200d9cad57bb3699c6e16e55325100af619395d8f66e4da, + 0x1612b518975c91032486de12f198e9561dc2292db4d57d2beb632762712dba8d, + 0x2469b29aebd6c77da653aba435f4e3a9c22b5bec7cf5ebc8843d875b2837f73f + ), + line_fn_from_u256( + 0x1e0812b4f625cd4ee60ca9bed1757a98c7d14f8538957340b6518009f29c82f6, + 0x37e6b907dbf46e86ef4444439f0d3284e8b85b2cb0b8378813b4f670d1e07ea, + 0x1b4d71523dea855f459dc6edc558566c26112f1d06aabd53d97c3048d8ec5d3, + 0x2a5f8ded032df077e7509ebfba0ec80a7b691660448c7143f33e6e64d25f32b5 + ), + line_fn_from_u256( + 0x28d6722d6d35803c8cca34f234599aa12bdebfcb79af395f2629ce733b2efce9, + 0x3c4500563b309f858670ea67819829143321fa02068307f9b01e9f8f867daaa, + 0x185fcccd620ea326b5a297eb045fbcac3f72fbf4c164a57aa53171335b918044, + 0xa46195c1de8f2172df7fc9e6bb9f2fb04d9ed67bb7d5cd3d9105439453e461d + ), + line_fn_from_u256( + 0x1f802bf10ae8986f3e2b66768dba46c33dacd7793c77979c9b844de9dced930f, + 0xe4a6352d2a401d852d9b7426e4b5ed825df7e39a2fb312d552a0d4d0abdf3b, + 0x2e0f7c1f172b0d9a7d7b455665c5e9dec651571a05c8caf83f041086a2cdb901, + 0x7c3f06283cc7171387cd17337efcafad35445c46f80521063395b4dd3c8c4da + ), + line_fn_from_u256( + 0xdd8401c5212e669b1e63ea5fd05f253c8a71950f97eac879ec0637eddee7c9f, + 0x1cb5e0bdbbe3b00f4d0140c90fcbcaadc7161815ed2a18dc085f629b92af25ac, + 0xa4377cd04abe6d47f88dea837eb3f3c866037a9a79ac0445016c909591f6d, + 0x28cfdad039ee1cd5fb765ef375936a4c2c7d2d043b483245f90c144e3f26ee78 + ), + line_fn_from_u256( + 0x6c4f6e5d1fc4b4311818b53924e09edae6e68bc02baaaa6a638bf42241c2279, + 0x29bc54937219443197bb43a94a4743860109d2e6b8f9acbd0b7e172eeb8c2da3, + 0x297aa17ec0d57206d6bda416b358fc4ad10a6a07d9dfe7b195a3790ccd55af54, + 0xa700e869f5eede4b1f99dd395b9d607c25d3de7ab9c08868626c499720b7388 + ), + line_fn_from_u256( + 0x73679c87dc32900abd153562e21a101fa4361f21a1ae419ff526b3d12cb8fb1, + 0x2f57a1c6cdbd8e3e7be98855ec7127c9119f44c9f9f3ba5488e998b1beb30298, + 0x1e06a7b577e8446ffe0860329f0c4d1a9e44d4601e333ef71495cb83da2dc232, + 0x1173881a183279cf48de1f6abf5582cd71dc602b9f773e1f08af1b7781c281e + ), + line_fn_from_u256( + 0x16b47175144ea41ca652e9409f1760ba87dd55423853c20773d364db6b4acc23, + 0xb06c3a8b03cbf32e4191025ec397dea13f8f5952b5e78eda8db65585720c497, + 0x14c38138414acb6e7ef8a2e5fcf503a48fe1a97cd7ccc4d5ccfae8dd6a5012ce, + 0x1279385c73e98e9e1f1629051a978451abd667dea3f8999194a6452b26a1cc9e + ), + line_fn_from_u256( + 0xa7fd54af803af45ef45b93c867cfc092e90293fb7160fa0eb214243ca3305fd, + 0x2e4f007e20e1e32cdfde08e53601e990b68169f107b6183664c7e1b4c01afeb, + 0xfba3cff44e6047544c589a0fd38c25dc30e350a3e42735223864f8ea659e9b3, + 0x1f3d602fc4df728950ea9acfb5f7fe3990da8d1317086bc7272e8cca0a4d9776 + ), + line_fn_from_u256( + 0x2d4008a677bf268d1c8777672b3f28542679f9a8d65cce5b322f3a8bd27fdb81, + 0x20e9cd258a0ac5dee9f5d19be939b718c7d1ddfad4828a6e6e839133742fda61, + 0x1ca3ce987fc6cb565b27fe836681c4e3055005e96df65b3b52f2865a4d3e13b, + 0x264d009e34a2ba016aa059063545a6216032660b2ad9f3a447d0194a39f71935 + ), + line_fn_from_u256( + 0x67ce5239a4dfdb732b54b1a0b186afc44a89eedcf9919c88e516459ed4ca11b, + 0x1d99d69ee5a2b1c5e84d6c7ba9ed7708e79bb5f64adac24805caf7e65cd387f1, + 0x2541a116b970144fc04e797c12ad04a7d90e32ac94895924c686588b7ac1a10, + 0xb043d1a485a69ff526a76bc3ecefddeaeef0aeaed955dd4beb54916ca589691 + ), + line_fn_from_u256( + 0x10532e033b2bb556bb44f4e2d8fa5d69626b2450399662905b852eaca478083, + 0xd0b7528c94575e566843dee925876a4be4cae5e8c3e01b2dfc92d276ef55c66, + 0x159363c7d180e27e7441112833056b3de59622de72184631b984d07374dab3cc, + 0x2b3eb6499aedfb7fa52d2bd76e236a7fa1c6bc2a4f2d0f243a7edca82ecd564b + ), + line_fn_from_u256( + 0xe819f089e2009c3f56fc2a65c8adb3c96435eb3f17435c7552f0c7064612569, + 0x28644760132e0d36dae84d34c34ea7bffd14f3f0bb48bbe2035a40094d6975ac, + 0xdb632cc13acc807b4bf02a18c95015e359ea7f29567839881f29dda5daef310, + 0x1ff7bed8b95d85da24173048980c84622a1590230ae940144540bd7863380c05 + ), + line_fn_from_u256( + 0x23da8ba2397ed80ae5766f0981a9d5cd30b520c2d5b12c45a6001096b714c92c, + 0x17af81ac9650f7d2519cfeace61d21e44a9107a6208e08bdcf451cd7da0570c8, + 0x14a418fc00e60b5a18494480b75392ebe4f32df4eb1a372cd1acd9a2cc0bb4fd, + 0x2c36c3e6aa470863a2c1168bb545355cdbe1d86c4cc96f63b4c2288ac78b90ae + ), + line_fn_from_u256( + 0x2bd603b1e0b09b9c64d549aa7482c86635bf1c88d4311d79fb9d72480d75f4cc, + 0x264704574b35c2aab18adc624f1a00e2c1e5c95c4f21262387dcb5badd7f0f8, + 0x14f31515fb637f7ad70e764e74d601155b7e85c9a3149bdb518b59a0f0fc16ec, + 0x83b5c5d8cc1361b68c313eef38d7c78ec0f4b9e8377156b4aff61f9a86c9769 + ), + line_fn_from_u256( + 0x29e09ca4e15b955c20a432030511989660dd963adb82079a8cf65b9420ec84f9, + 0x2e5da216038d7cb29f7cb26a694880a0af663ba5c60b2274b193f8d9087ed045, + 0x68dca455e98d0ab4292c41d3e43f7e662401ba8d83ea43af8a11dff5ab94abb, + 0xd7c62956e6aa887fbde0c07e46d05381749ab95ba83d61fad7f72e3fd7ce466 + ), + line_fn_from_u256( + 0x20209760e8c5ecea64f8b96fd0269d23bd4bc52333e3b557be8df2315679cc11, + 0x1e4620ee839a7994414f1b6ac90c453af37b6843c8cf99e7126939fee82b6ecb, + 0x46f52c38560cf4a4871e3be0a85e1fc77c8fe771270d7b81cfeb2372c471237, + 0x65537323e9db939048b4cf30a7d558b5218462c913f2081dabee116fd93aa23 + ), + line_fn_from_u256( + 0x795cc16a26f851a21441908b14712fe88e7552be8edae92175f36b7f0a7407, + 0x15724757f9c04e65c9f39187f6558ec3b46e8a5f2cba1ab97b78f0ac15b83ce4, + 0x23c5ba32e554a25e9824fabc9c6278957ced2ca44b82ae7fb2c9b44825cb9a60, + 0x1bf18e49d37c5fe76268223f4fed48568de673d886e6af58c29581fe02cfb96a + ), + line_fn_from_u256( + 0x214cd2fb310046bc80f5cb790b283f7f7301286e5d2551295b4eb00eaa9c8ae9, + 0xa3bcd2c7b276715492cf898b9901f1241fbe280e0ca10c74b1b8b66246f8329, + 0x1962a3b6bc270362b1f854b8a76da664a9501e6ec2413e036d624bd25dbdb2ad, + 0x1baf7035ba743947fa5683f52735835af6676ef8cab80b272e590f58b0f455f2 + ), + line_fn_from_u256( + 0x29144cf60028f43632a18d309d6f1bb4c45e3ab214ad2e2a718a8b98c439aab2, + 0x4e036cbb58ac6e97e71c1f74a7585a38612e68bae05d6aadee98a93f3faeb0e, + 0x2da087fc860c000c61b8deff82b6f719f1a38bf3bf4ed587eb4d42923d68cccc, + 0x147057da0326d1c8fd9bb28a96c81a7efc25e035085bc9715fe53bb174cc0c30 + ), + line_fn_from_u256( + 0x118e401882ba14e7564e753240cec9b724c77ffdae816a8f98326b873f6d099f, + 0x23510bb5dff171003fc74b2b5930b79841d3b34dd9ed61d4049b3f7ad824d011, + 0x1f6609eb38bffc10841e2071942768411423980572ad0422a4d3462a6331c4d4, + 0x1d6b2665f90d190532bd5710ed947416aecea2557a7d1b5f445f4eb398766631 + ), + line_fn_from_u256( + 0x10d12fe49dedf001261c630d24421c1da48984d881f257c667c170669479e9a8, + 0x13ccf493e8881180deb4df7e92e4e5488c312bed478276fcc12974130a40577d, + 0x1805c17c2d4d0b42d8ae3da33ed9afc891522c40c7ce1840ab96b9f2564d4ff4, + 0x29e5cecefe2e414aa3bd0398e119b42f18445b01e11f2969a76def0b30e318d1 + ), + line_fn_from_u256( + 0x1aa4c3c9f415b032d185d21137f30b904bcadac9fb1091c3e7bba62f63ce81a7, + 0x26fae34bba8f737d1b26e90b4bc5e8044018538bc9a053328d1b81123e6900b, + 0x64bd7f7a0537f6bd5141add1f058d1294f54738eb7da1fc5e1d36171634f001, + 0x51286410df152cb0fc0576057c8413ba4b48d99eefe4d42b425d6b5e4a4eb81 + ), + line_fn_from_u256( + 0x2831206a2e464e3c77ee824b78ab9b898ed01b77d05ed478df28a2ccde5c7e27, + 0x5973e1fe421b082013099f8b9f64735265437ec5e274fa445c4ea9613593214, + 0x1cb53a3058cc46e5158df39c13a865569f13fcd9f9cc70ff1a016657b08d372f, + 0xb9364065a4d13ccc04b1f21b08384698c27fe707e2b2e4203197570576cfdea + ), + line_fn_from_u256( + 0x26c80957657a7951c3113b4c60df66e55c72c7c13a380c2bee904066ee24547a, + 0x26bd3ca5330703d00ccdfbc39cb76cb6705ef0a3f8575e87192e3de5870a60a, + 0x129241b613460704fe9314c59844fcc9ea4e2ee56d01a8051fb61c3726ef189d, + 0x21b589017bb6318c27a4bd72ec30bcc3713cf7bd5198eaadc31620356e6ea78d + ), + line_fn_from_u256( + 0x2ad444ad1192f9c6565784fa0220aaf981ab867799f8ce28364588aac78235d6, + 0xc6ace849343f7e286d55035249b985dd1daadf9b4bdd3f53febb5cb38294433, + 0xef09af90beaa4e268a8f12b07b38808b57e01f47317e9f0448065a22c4d5705, + 0x274c88322c783daae05ccba6795e1ce8d2f81b3bf2e1df31ea55bf173adc05b8 + ), + line_fn_from_u256( + 0x29a5b46507ae5f83f9afa81234532162c71bf0ef61d3c7fa7b512ae95ad106f, + 0x1c433c8c39f471a6e14747cd0f404f0563b31088bf2e0c099523fbd5955c880c, + 0x15c6ea0197ad73d6b1b84a2250c7ab588a93fdc2a0d33d38d6342cee605ecca5, + 0x1be8f967e5e614a4f9d760126aa7f201b13963b2ccc68123e9caf8b48015d77a + ), + line_fn_from_u256( + 0x13aa8efc408ac4bc256679971ff4e4a52153656dd8f19362deefcafe72468b42, + 0x243fa5e8b9565d2527ee90891a4192164a243bcb3f3515228ccac772bf9e840e, + 0x2b6c78c812d5036dd4646ce9f56e69e1234898096d88616fd7671c934b67f3a1, + 0x16825f2842c5dd61e02dd08c8b3ea89d9bde59ee69d6100c0c6d31d48dbced05 + ), + line_fn_from_u256( + 0x86f50436454be20ba540c955fa08cb8bcfa53e632461b91acc8d930363308b8, + 0x9e20218e575a76319cc4a473b10f440ad557754ac002130d3a38ff1567db39c, + 0x27726610b8d257db2b42208845bf722da09e06ab82953cc3b1b1b23a1d354e74, + 0x14373a4260fe55bb0c257dea535abcdc404ff479b96163973aa783a0cbc22ab3 + ), + line_fn_from_u256( + 0xf765326a27e70d7077919a5b106cb1d202cb4c18117b5632d73735485fa3674, + 0x131c6f4607605a68bf8efebc20466eeaa529d318ca2cf15d67ba6ab317dec91d, + 0x22c49dc88c57f9d36a51b6e9b8e5ef107116fc9ec267a0e91d05c9ca8efc505f, + 0x19f0fdcd8f9dfc07b91977ba2f9d8befc9ae4c39e5f3448915dbd3107af2959a + ), + line_fn_from_u256( + 0x18ab5d81a42189be0afe799a518490c033fd2a05ffcca3b351bf73357f99e094, + 0x1f63cf46a33ffd8b1d26a42ea08abd1bdb69dab4ed91899416f35cfbe028eb54, + 0xc09fe2cfac26846b3850e7b0a6c7e59c9c699d292f05026915a81ac8411e58, + 0xb8d9042a40b396e918bf5ca23c9769a886cca7ac277e8c70ae098f2fdb76515 + ), + line_fn_from_u256( + 0x1e4cd3ce251500e339fa57e60537ea76a5e0c999f011901f31e93b080616d687, + 0xe360102ba300ba962c6ff353b74aa1b8e9ce94b3339ba3fdafcc05ddefb8dcd, + 0x132702d05d634a6b43e94bead0bdb9145a2ba5b68b99d8b36e5ff08ce35eae1f, + 0x2886c3aba521cf7118a71fbcd9583010b1a1e0bc3c3d65df27967bbf6c2073e5 + ), + line_fn_from_u256( + 0xbc57607e5b1e3aaf770f9a14887cb94fb1a7b12757b3511113109e85c136cb4, + 0x142050ec99c7fd7fbc25ca9f178f77d9c1b59e0d062603785d74eba713946a68, + 0x83a0901f39cdb9e218fba92a1e71230f0279ae1d4b077e7e830410c3e3f4337, + 0xa80ef6b234d8cb6ea1c0687589c67a077581c659ad1377a9e75ed0191b164fa + ), + line_fn_from_u256( + 0x8c2fe2799316543181a00de27ba4be1b380d6c8537ecf0916b38aeea21d4e47, + 0x7b4be349766aba47b8685c8a725ae79cfac8f99e68fff5ee73364fff3fe403b, + 0x22ea21f18ddec9470ce316c76191f1e7cd7d03f3df7c93c0095545ad5e5361ea, + 0x16fc78a64c45f518ffa1e4be3bed5faba2ccbbf4a19620b4c32db68cc1c2ef0c + ), + line_fn_from_u256( + 0x2d16988cf5101f59df065736e2f8e3f40c785ac73d06d61646ffd7575838e78b, + 0xe1c66e17fe968c5f56a0e5b06fd97bd8321e14f2a6b27684be7df8c1b81d470, + 0x2fc95dc9bc835c6f08cc51ad2c1325b311d2d7d1f7ea56b48de6788554fa01aa, + 0xbed6635e2a3f5cd62ad97bb5ae768ffb1294f6fc173dd6c0c2ad9485f07a250 + ), + line_fn_from_u256( + 0x104d49466efb90e6cdbe52a4a70e25df68ad630c4c2a70d0445a841898f95ffa, + 0x18cef9d4307828a5bbbffe2e27ea96bf12a995a72fa24049d3601b7d58635d84, + 0x239d5d6c3534acb21a711e6a56e1ce735bbc9421b1624bbd7d5fa1227037147b, + 0x104f8810a211eacb5bedaae405cb3a1570c6577d7172b8bf130829df91f0d6af + ), + line_fn_from_u256( + 0x9a58fbbecc5719cd94b3edbad8d87c4d647070aa229c53ef0bf575adb14b4c8, + 0x1f3c75c1623edfc5881142d69b67e3328179d573cb64ef6492de879f6c0e91a1, + 0x10d55e3e5e149ef7b60cf0807f393ac20eb7587f85252974b092d7326f3293db, + 0x2c5e7e0243209425e1bf9032d49f0cbd63a446b084cbeadbc3c9fb3bffe22c3b + ), + line_fn_from_u256( + 0x14b2d427197b5c3c5762ea1a6103d92b9c1f35e5f5a59d9e149abdc6e3934598, + 0x4ca140f253cf090176d06dac6d779cefb610a37d44cdf77871dbe2f46008817, + 0x274db3ec80605cc12d7384d20f945a0b282a8e582639b8c1d899a6100955b30b, + 0x2acf77cafa7e5576ebbc31aef713b1c4f9d2feff725b0229b3144f88a56a8416 + ), + line_fn_from_u256( + 0x3f186433881bce446d0baa5ad17b66f69ef78ff759bb0dec41bf01dc460c778, + 0x450954848cc8b9746ffdba98cd39f787bc9b337afdea96b009de93a5f40fbc2, + 0x16bb15a1f9a76a9603fb6f2ffbd5ecf4209a4bcc1f29db60b2f91c9edeaaf405, + 0x28fad6cfdfd3dec50e49ce1d5f7cd90a98d50daaa9e98bdc22bff0ce3c7b3442 + ), + line_fn_from_u256( + 0xd7a5f3383e67d9214d4bbdde00912daa6bc496b24c86034bc1b87dc91d21e1b, + 0x211acad86bc52df8cd335f0a0bee496bcfe662abdc025d08c7511dbc80367316, + 0x1b90fe2784a45d9a8c33bc9dd301303b8ecab853e5b983f995c9c32e16839a4a, + 0x1ad1e9af7069003d4b1fb4eb91927c9a6148a31707827b4a174b2a7b77d941c3 + ), + ] +} + +pub fn delta_lines() -> Array { + array![ + line_fn_from_u256( + 0x2fdabad1256f90e9ef80508d117bc0ab728c7910bd7f0eb9f1e931282f6df16c, + 0x11042a7f3b24652129c8834d81a09f749515a935cb6ead8d8172aa24dc6053ee, + 0x1cdd347b021affa40c7797b12a3919a1256ef84d4f6a65643445140b1f8a49e6, + 0xb201fc4350d5d3632ed5542856407700cc551fd087e0948af68e114d5d7e889 + ), + line_fn_from_u256( + 0x8993a1bbc20f3fc8cff529700597b224f4f180aaf2bbd34a375aeea90f0bdb, + 0x1f6023f3a60d3b088e87c268ffe0b8e9026bc15b9d031cffbaade1f1fc1ca959, + 0x138719f7df16a085abd8ae0557483ebc721272441907652907db780bb8f2b361, + 0x25442eaeac2442f38562f073fc1d50ed8abc18945ff3c1448cb7ab0202a514be + ), + line_fn_from_u256( + 0x2d720e8e9b0644e435ed7d3883440c92693d6247cc507fe4d09161f74e0bb2c2, + 0x2b1baddbcbf3638fc097ae76d46c27ebe0603a492efb74dafe3b922ad7cf52e2, + 0x20bafc4c80882e096d8c8bef4840a8a595dc9d76a2c00842fbf52760c82ca237, + 0x2cae87e8cf8f589a7be249871630e36b4c29c8668616c21e1522675277138683 + ), + line_fn_from_u256( + 0x2dcb2d7bec5de5f3bc5c18aa7672f3b6c887079c3e8088c015c104139b908d49, + 0x199c4241d6b6487dc8f15b7b299c28f52f012ca14d6d0a62b5ad4889db5c94b3, + 0x245e7eae771493bcca8b88fdef963ab4f49b87e03e3205e1f55b145905ca9cc3, + 0x19508ac7d56c95e2126d5894cb975303860f4fa8cfa047d9deb6385125b02be0 + ), + line_fn_from_u256( + 0x9b2e572df202924457b828337e91d2f746aecf7b4b57a9cbf71554ad0ea13c1, + 0x9050bb2c953c506a5a0e4ea2f876859fa71b5bcbb82a29f6ab5f642d3447b8e, + 0x20b304fdc594722410b55bc6266f78c0e18c51433bdda0d58f53162f432dbd11, + 0x1367d211b31a0949c99d744b599d17c176a7ab9e17bd8041209763a587d2a613 + ), + line_fn_from_u256( + 0x21cb15fcf25eff54ae58c29a831f08080621913c868e6fb19853fa3eb5ad768d, + 0x1a3fb15f03bfb074556d370c79429114479336488b5a96cf142eafb4d0792d85, + 0x1a9dbd6313c4d944cc8e9a1645a60754f2846356e721707049f7764239f5f7f4, + 0x2a7be1ac2741e294e27a96881dd644e5037d21b2b45743fc5b61afc192adfc3b + ), + line_fn_from_u256( + 0x2b160150afdf67bbf0e889a4e5f76359df9e33c8db532196e1f8ffdb08864633, + 0x278cfba759f2d6abcb2bfa922869943195b1917a4db6af53c6043ee5d034a8f0, + 0x20bea5cdb1c9c65911e8a6035e9e96b4f2b9efda00524662f040b9e23949d484, + 0x1b7e612780b108ed889b8fccbe830bb9230a64854c8b95d0b01c995a06d97a3b + ), + line_fn_from_u256( + 0x232b42a4d831499986fb6c14f23876f1e8b906cc2993ec4e72b9341537880db0, + 0x1cf9078300b3179b9d7b9525d68214a917951f32b0a6f9d662790675a7bb5b03, + 0x145ad18b427285dee644e84b8aeffd03bd9a7a4f72b5a51b26e287f6863c2394, + 0xa4764ddb29b9183d07f278df9aebf87bc11469f40ecd2a648a68260fa9f1a66 + ), + line_fn_from_u256( + 0x10af9f0eaaf5a458b83b476f0927aeeb66c50bd1e9c11041f1b772100fed1fe0, + 0x2aedc397d5a6936ef6081bd1f8ecb9ce787168ad4e4145c75a3691c388850f7c, + 0xb834d431ff295c3b1ae5f65452f1da4f146a6d8a9d1fa4d2f4aec55842bff92, + 0x160057bc5d5a209bc21bb9af3fd1ba5b27d97736bc4bdc0ae59f5698e6f271f7 + ), + line_fn_from_u256( + 0x274a3e8b38572a34875e9eb4145d5187c7d55b079c6395f5609d05c0d0a3577e, + 0x3c8dcf91e69ea61995e16c04c5a2193b5c79e8e27f640585615475eb41c45c3, + 0x2282a5f5cc5c55e6688532761629f856ebf2d8992aa657b67e2529e07cfe0b83, + 0x14fdfc684f10f315e6650ed1faa78f559b81772699327aed413feac2f97249fb + ), + line_fn_from_u256( + 0x4b7c89609e6a873bc5fa8392d5ce81cde0e629324422b60a3e3cac2df50e170, + 0x24e94ab04dea70668edf0802b206fc43007e46af99c5482d29bfbe6d7dd70b14, + 0x27402d871a854e72dee9eeb67aaec5de73c77d2130d9bdd6d161a58e30c96a05, + 0x4b9a57054c57c32e4e2cac8b7257771b5e5aeafb6f1b32d4d69d0e0f7d0db44 + ), + line_fn_from_u256( + 0x20711846506035486796f8c2611ae2df9755399cc4599f84832408e7f0963aeb, + 0x1ff0bde7a987445a9c48e018e7a9e96b9c9e25a73e24fab4dafb82e6f108be7, + 0x24c3ec9e0af950f377448b6ff6332b6159223cb0cb973be9378b6136c8c0f57d, + 0x235053a4f4bcb6ae772932d23e6a03f5ebe7418517e16433d64d4d67c6816e67 + ), + line_fn_from_u256( + 0x1f91263cbec3472d2a21481a3d3fcaa6e77a02cb94cbd577b249cc33233f212e, + 0x2caa111dac10fd2fb1472d261b4d89523938380cc48791a9e599f10f4212402b, + 0x123414cb35c4954fbd6f8eae42a7479af2e3ac0475ba0e23968874b4fe3e0d58, + 0x1229c5490203c44805768f8e25774cb108d0075c66dfcd27ff1457f17dd733c3 + ), + line_fn_from_u256( + 0x16c10f3d7a950f83bc5bd3b72a31878bdacdc16fbdd382de6716f239ee89f6d5, + 0x2a13e56a257d1455a8c481135db2f1b4fbad9d8d007d8bc145b120443c7d6fcb, + 0xe84fcaf4f337256c31ad5193aeabe80d48bd9819db9cdddd07930789b9f93c0, + 0x27d919bc9734a293ef146abfd7e43d7a543ab4fbfe65d525429ced7f8c7548b7 + ), + line_fn_from_u256( + 0x18f418614ee4154688d2ea0c372727dc01859b5a61f6c3588de34bd1a9a5d725, + 0x124cf78b550dfc1345507287aee8aafdf8f8efc5a8c649f7647c40be15a3513d, + 0x184f713604a8ffa399891862ce71be6e22532e25819034f3cfc19e06e5173d2b, + 0x1a6d2742d9bd945288692af03248455f1cd399b28d55a8600ad221d1b489994d + ), + line_fn_from_u256( + 0x15e7c4da43d549d8c3604afbfe82e9859182a71ac3d1a953aadcee28ddcc4441, + 0x2c921c9cd12f7cb2cd8967cf169d71acd7d5ce257370f158cee83f625e24f849, + 0x13a92b478419903d5b57f637186ee5ad497e869be80e50184543913d30397f3a, + 0xf8cc1cef3968ef3656138eb60f91fa1fd8f506a802d0f8b97277bda4a5ed44 + ), + line_fn_from_u256( + 0x2b3384434041685428c8ea6d4c11b33a9e83046fafde063f17edb2f78000f06c, + 0x1e99bf7c724101d42f96e8559c9880caaf514b9932fdef908a04d41214115a8e, + 0x6229e45f72bb3f3187c4c36d3eea036ab9f521e03f214289e4823472901c2b7, + 0xadec309f2466faabc2c8499b57585ca0f462840e8c9e37a8fb6a292143d09b6 + ), + line_fn_from_u256( + 0x24b9a8531497fed694bc29e87df6f9b525b7238051e58905d6f4cede7f8ddc0c, + 0x11c56774186dc8a23a9a35a72317a254e41d0306c8c7468bbdc34b40388d8d1a, + 0x2a8cc10094813210a022e20074d00196506ea777ffc1e25f85f424e8ab9d6529, + 0x1798c0462d349e391cb6274612ad932b9f9b0edcafac358b3ef8f6cf98282ae5 + ), + line_fn_from_u256( + 0x1aa04f71f00aa01f691319b34829607c387fcbaa91459a44af08207486d46950, + 0x169e4fd0433c270c0c96208f148460a41affc843782f4ec0e69bf0dc3f14b59a, + 0x14260231363742729cc8d97bb95a68f2d18e2bf09048c6918e2966baddd32c0c, + 0x96ab8a26e2079028b28fc8e6dc147be6755cfd78677d81ae43f01ea3c6f4917 + ), + line_fn_from_u256( + 0xd89324f46c65d12649cb3b2abf202c66fc9af293ddeeafaac8b2c90f4acf5a4, + 0x26307183d5112a453aa7b230bda53d7f041352a14c191b48d02aa3e9815b7035, + 0x114fc57244a5a7ba1ff5166ec3d3c3f01f1a494eb6a87669fc60d30ea054682a, + 0x2c1d18272880226e44ff5593b136e791ad737152f4f3bb3594aa8f785944b14b + ), + line_fn_from_u256( + 0x2a585c5de066b966d5e988ae33a73fbc0f6fe351aeec43e8c2b78b84cd803274, + 0x161f65c0ecd6c47871390192f68c276716d9d9ca533800f6184854f6e6b5dd1d, + 0x556f354235c8598847e0ae125a016a18bcf3d7860ea833d1a50b501b64f4208, + 0xcb4e88aff0d08bce636350b781c86bf9b3d2dd53318b79e9ff5e7d8d407e5fc + ), + line_fn_from_u256( + 0x2bef9f154148e4417e2b71a3971adff7cb54bdf4e5c3e9c8fb20e38ea8ae9f8e, + 0x71bef8498d885815d9c16ae6ee0a5ad051306ccf36fb6214ca70b8dd68b5fe6, + 0x1e390d6a5ba5faf1c4307cddc6e1355a710f7be8c84fa00bb68728a861baf12b, + 0x20e0794d0ea20210025d6eb2098165f7a14d6ca86566ce632ec85f6f110a4afe + ), + line_fn_from_u256( + 0x13e1d7d545981975a871533d7c31d996a07e38904fb251f0ed7f4c1f15eaaaad, + 0x2dea57c19b72b5f4f179e1ff60bf94698d5447f2adf263729deb71a34f1bb07, + 0x277fd63e7bb52f775c80e5c5495b71556077eb4768aa00d52070a480ceafd14, + 0x179b585282c30df456d655baea02f9e63673c37e69162ecc41ed0ba402ad5d56 + ), + line_fn_from_u256( + 0x266ecfc0992af01eafb93b8bac6bcf3a3a0e543add46cf319bd112cd12614803, + 0x16022ad4df0b2ce88f7afd090f24748c060e2171bb22507a33639b332a850c0a, + 0x20804576420862b70594b87eaa5990a5dffff09886f0389addde609a711daa82, + 0x10740ac3cb457b1d829f1a1dd4c842b2604869f8a096e136dbe6e702676c648c + ), + line_fn_from_u256( + 0x1b1fb460b83718374e770b729355356badeefc30ab8856a0654df0188a9ca50e, + 0x2b320cf98cf9d0fcdaca85cf10856f48bc13945616c9ff6578723602f047eefe, + 0x28eeec73908d37f46d964ce79feb9e9cdd697b76c1d3a850949b0ca6096fb62c, + 0x1159050fe7f1df9dd74e7987da981705df176b60168e0a291bbe95396704821b + ), + line_fn_from_u256( + 0x1769bc3a1614a547f1257ba2970a44c717ec9e6a1278b5ba6870972b303ca076, + 0x10882ee55f25bc59ee411a4802ee1649c20872c6e1d5dee428ab886890fdcd37, + 0xe61c09d2eeedfbb80cbc7cc234240aa76f6de63c1252aed782d0b175b22e4fc, + 0x203f16bf76afd1249552338c683fb4c4c2a89a625724d1bf20790047a66df2fa + ), + line_fn_from_u256( + 0x2cdbcb0609d09f3e061c4b0a179616c86de1b219db6291b3a1aedf03bc89c870, + 0x2a36270f90dd1475ab3912365cd55872efa1523170ed782b6bc0a4863078fd50, + 0xc99ae925ac414035e4c72662218f1dcf07449c1bbb4420147290411099df03f, + 0xb2ba0a2a48a5668daf2b93ac5b675d437e257be63c9850b2063c93ee0338795 + ), + line_fn_from_u256( + 0x4586d09d5a69ba63149cbe1d9c7d9f8cdd257d27de171e52f248344dc1304d2, + 0x1c19294e84271fbf67b00899e72280ba58cae6b8556881c92da5c88eba1c4dc4, + 0xbb4114eef5b1fdec7e4d75d0aaeb01b988baf03b316567b0b14cc64176ef36e, + 0x28ede8be76a366ee5cc947ae0ea41597e26e8d97d797f4f82dfa5e1050cf74bf + ), + line_fn_from_u256( + 0x1cc87dfc856efa16e6e79e5e2915488d6b61e6504a986eecf470ab7875a3cd11, + 0xe48e7cce3cf5fab172a50ad753bc367f356d55f9f2f3dab2985c280242ec99c, + 0x50dcff53c4630026bf28585f37bb409b12cd1c910b9e4b4572049535bd3ed6a, + 0x24c1a05b6fed19b7e22fc60976d6d3202882010944f4e9f711a37c91cc857fd + ), + line_fn_from_u256( + 0x131b33ee52f3104903c8ffc51349ab0d5f2fdd58e0306b48ddc0e841b435b8ad, + 0x10b77e123dada6b41a5e8d54bd8434f7a039eb607b73a7027d951628fd38c43b, + 0x12e550d2b2de3e0865ffd36a344a404cd56a83d946dd41fe2b17f53f3266225, + 0x17afbc991ac366d82df72ca19365c2e68076a29b6854a915ba78aee7c56ce1b1 + ), + line_fn_from_u256( + 0x2b8ec6bd0d531d306f3c06c16b41c30b237475295a675ec2d55c4e577fc54f88, + 0xb014e1c51d34f7700d245635cc6fd0bfd1e6aa9003cc1f82ba5e415416fd983, + 0xb4a84a99f4e1b60b23d2a65c151ca042b14ec4ae3a1843652adf6c9b4f36702, + 0xb5965dbf3946fbb3e8a6456a8fdd1ce49ef7f6293028ea4cc4646e39a48df70 + ), + line_fn_from_u256( + 0xc90f6dbc47bf5e9dcf07699b7921daf7935ac88d22007b423e395406d4e3e75, + 0x15a8fb913687ef4c249e52aabd7f77a8f333dd28aed5dc8b4a2dc143423c1f6b, + 0x11da5f26d16bec8868ae57c835f09de32307eb47bb4a7555fdf2edbf1a2651d9, + 0x203ef360a5ab56ff5c9903456d6b1a2919457ed831fd3d480774f7a27b4a3bc9 + ), + line_fn_from_u256( + 0x2697981c7f99a76c8431b25e9c105c62829c38a688900b13a440f06e8ae15ade, + 0x2aa8766edab0329c144f45102f33482aa159c1872d5706f3e82a5fb876ee1a50, + 0x2822469685ce15739bad4064469bb2484ad228db0d7977db1451384a850be557, + 0xc4e00338e8b10adf42d861ca1f14463b04f1a2324e1d72a1dd4989d812a9409 + ), + line_fn_from_u256( + 0xc1025fac56f2ca61c980e5c0b83d8660ae5d390e4a5ddee8ae433a6cd4987ca, + 0x29617bcfa335048f0cbe3ae0fe1ade658239cd523a430814f680bb2a867cbf99, + 0x2ce83d6ed486715781f2ea6f3d2835d7925517bbde24a21812601430cd295196, + 0x2c5c4a69cb68a803c49f9eb32d566bf85952970eecf21096ca64e721d7a1b43f + ), + line_fn_from_u256( + 0x1bd5850f7029ad6b370c00e5c59db5cc5ea464185ba03fdef766d5c461fbb75d, + 0x19f97053ad37fbc1177c36b0979775a957dad66d411d4d0a673af78fc757fff2, + 0xff399f2b6b02d01d7bff3a10a75300ecd342f62f182fe64a741f897128cdcf3, + 0x2e7e1492bcbd2c0303526dc440c754eba82525ba7e6ce4bf0b892a77a8935aea + ), + line_fn_from_u256( + 0x3449bcb7d00300bd3cb6ea46704c0837b6ce3d56be26cca0104b583dc0a1dd2, + 0xd3c2c7a9d0c0e9cd910366738312770c75f546cf6b383016265e3508f0b98a6, + 0xf53f60068a70fdf07f04649ac307e4c17591ae8bf78155b54f898d4bd5cccbb, + 0x8c03e474458826a62f9197116300cc9e6a2251f931141e00cf28bd602d6263a + ), + line_fn_from_u256( + 0x15030decf151af1edef10f24de3f1b9c4b26ce7cc885ade3a9efb2d1d64a214f, + 0x11ea4828a4f7ef1953c8f28cc5265749216c3286410932cb71d37d1f0079a4c2, + 0xa7f2692aa30eaf765be0a5c558497f2ea5c3c33331d4632c2b82a3be3810171, + 0xb4912457c57cd820cd0374073044b9aff8ba3bd4d569599d9bc2c3270a62703 + ), + line_fn_from_u256( + 0x24e430e7348d8d9f681a1a95e910e54f6a4a3920b8bf75ca3e431d3c0ed5cfbd, + 0xe531a0cced9ea4d21476b6820e0970facd196a09832655ab9552614b27dc5ab, + 0x14d0e1cf727051270517b0a77393cd1a7cb36192848dea9f8fa825ad91ad3ec4, + 0x2bf61ba6ab33b0c3e50ac9fd8b22b2d92035b937badb306c1cc45290a68a1d11 + ), + line_fn_from_u256( + 0x11df59726b043aec513df5d83177eb4147bd906e11186d70c226d8569b03867, + 0x1cba05736cdb324bfd114277b41bdf95480839b9feb4b0fc4283bd25a5b85355, + 0xa6ccdc982724fd187fcc50c1be8f071f348d85dba52303725df77c883199894, + 0x266d459f68741430ae28e0f085942a4b51634f8bd8b5bdfbde678a2970a815b9 + ), + line_fn_from_u256( + 0x24d227efbc2c10e2b8d93be29e0c99e8efac86cecac761d0f95a18a70443c631, + 0x2da9441eb302a5ba3edb227b6a8619bd89eb19a09ab6dc693c4e67c9723f8a69, + 0x16b6c902418dea04bb1da162d600c054b9a7b77af47184f7dc1ff3dbfeaf8be4, + 0x1335a3476e89930366f918746dd706a09186937e73fc32c39741da9fb918e8c2 + ), + line_fn_from_u256( + 0x5494eb0916139460dfbe3f70008fbdc8479950e26530b69cb7c021b15c398c7, + 0x1b5ed2ef8f5d9d4c3b02edfe02571fadf76e3961539f246eac112437001da0e8, + 0x1451bb463d512be27e54cb6a04d7433667305861555d721ad642cc775cbc32c3, + 0x16046a5b09ea7e82f1673ece4615095146922884df632f276b22a272fc40d2a2 + ), + line_fn_from_u256( + 0x2fc684f8433ccac8958bf25b5df25e14a6d77eb22f06050b64e017f35147765, + 0xa4e0f712f695419af2a21282355dca0f9987c252c70470c36b89e0e5460dad, + 0x1c510c7bcd373ac244fc110a8e14764b0fc2b8be0f0212d9bb62b8354dde76b3, + 0x1c3b6de16cf13f3b986fa039045e920ecaed0c7c053f3e0d34f4c4097db5ca20 + ), + line_fn_from_u256( + 0x12740f7e27555dc25297c66fb23ba9742faa145ce514f8802d5960e840ab4bf8, + 0x1b922c09c6453f49d6adc75387d566fbae6c7ab6243826389eb0e95fc45f9e55, + 0x8a21a7c10e37cc0b88e122003a4c8e011518e3d008f156fbc5d231dbd32f8d1, + 0x110d0dbd62107e3529d9404a574447a9b36575a43a9157158c10ab7a50e9c84d + ), + line_fn_from_u256( + 0x13db441b005605aa79d6c762e210615b5b431295960bc287a30547678b3ff960, + 0xf7048767ce6a220e58bda6c130f915da8f788cc637506d5ebd352832864d0df, + 0x1e527ad59c2c8c9464fa2ddb6186b418cfa4d1df6bc4434671c61373ad240099, + 0x1e74389daa3a6fbe38cbdb5ad9bf72fd725f1e20bc7b28cff4580b74c802307a + ), + line_fn_from_u256( + 0x292a1bfdd96b013de55a79eb043a6758d998975d6f96a661af507452f99d9b63, + 0x16e9808632ed33edf46b339903f069d6a1737384eb802bf8cb2d2422d63c359a, + 0x1c273bef35523133199155862c980a5845d3a6cf53e0382bcfb79a75ff5dc3a1, + 0x94084a0c89f4405460cb54015446353647c643051fc340e374e6083d061a0a9 + ), + line_fn_from_u256( + 0x24cf495f0f56b278fc2523b85b30cdd5369c73302172176f97b0fcb2e916cd9a, + 0xd39b5db69a3da7abbd52078a55067dc6155123a21b11e619885061638b3dde0, + 0x56890634ebc625c9fbf5dc05629a5fd7d7b8e6733368c3db0d9230016819621, + 0x2c4f6fa293c565169f24dff8de7f4f7a1a83d8a5c6b7decdc79972c2b9553d2d + ), + line_fn_from_u256( + 0x1d4dfbe62109acb073dc6fa60566099efdca92767b35c171c8a6a9f4ee12be0, + 0x1f0aed1ea5dcbba14f0ee27c22cfe88a558fff9fddf51f9b9b4412ce1bb0cd03, + 0x2fe9ac6a7c8f2e971d0ce931ea938a8993ce10f3e89a90701c4501aa21c576ea, + 0x19b214898405e49b795eaec3d284d0b917734f28893a9952889c34b183738353 + ), + line_fn_from_u256( + 0x2deac60432bcb17f32ce1c35eb55eee72b025f6678e715233e251383b202e8a5, + 0x14d28cc0fe56d59d04e4c6a483f17f260ebf99f25c29c1fa9b3d8d5d458f9d92, + 0x9b266dc4e801f47d545bb34ec2fab397c42cee3d99efabd9ef99bff0a6bc450, + 0x2164566b910483dd94b6214707e1a4680e66030419ce782a64159bb7fcd1a97d + ), + line_fn_from_u256( + 0x23c04c43b9a420967c1f7e55fe66212bc1f162f96bd716afab0ff6bb1cf88767, + 0xf53235dc5f4c072a4384d0231f0cfce167ce1f86451f3a9db4a9a26a0d71454, + 0x15edb8132be58f7ac7510bc402d604940001982d421409ab255228115736fb7f, + 0x2925dc04132d5e361cb5a912cf5532505a9a0af092029dfaae7f694ca1af291e + ), + line_fn_from_u256( + 0x142429b292fcee082872c88dc88a624af79e9f0a65b56a2c38aac130cc687c91, + 0x1252d471bed9bf47421efec55a104b55888af34e0692c18df2e843b35243da11, + 0x23333b06092247c15e2b17ec9428c4857b9778fdf08b382c725acd606ec7d5d3, + 0x13d52e0d7581c379f05cc28d5bdcc048c8083dd4ef2923c8d27c8ba67f1285b9 + ), + line_fn_from_u256( + 0xb2f53155751174f71926c9e843a20e208d23071e19abd6e6ec386dc11fe816a, + 0x18eea752d7f957d25491aae04e659e101c1e1800b0ed33648f1de2b4ee6bac70, + 0x2313d49aa08b41a71064cdc3d89f9da600457224aa5ec7e9d2ee24a32a41798c, + 0xbdc71449498f894b8ca5c5b80078946aaee0b1a797adf9e25f4863a286fd932 + ), + line_fn_from_u256( + 0x22ce4c87a12cdfde0d3efb158d625fde567d67706653707c272e3825ea4a89, + 0x2511f9709a1469dd248e129dcc4dd8849fab8c1a329b96694f94a5dda1d7aa76, + 0x92be181f71c6f0a66707f46352c06fd1957dfbe8be8a9222562601d571a750e, + 0x34eb4b57fd5a17bb21b7ef74a6d47e3313f60968c1f15d786c628d1f7267120 + ), + line_fn_from_u256( + 0x25bd33cb96e002a63bb7b432087f333fd127181164fba1b646aa422168297a5f, + 0x1c60f7bf5b4e86e7161bba8f4cb3e6d8e4ad9b59518e427ced3e7cc324eeca6d, + 0x10b5c6536f9cee9c767eff17ebb12363ae7618a8950cdc42a5a007eb511fdce9, + 0x293a026087852522d22ac87672851aa47db846342dddde4273843a62ee56dc70 + ), + line_fn_from_u256( + 0x1352e6b28eda78caf995705c9fda7f78da8a6e5a0fd4e8a63fcc68373f23d4c0, + 0x6ef3ebf0dc777a73d6dd93efa92c2ee0b9752a094b54995332a980c5bb7913a, + 0x2798c288f8ca08c141f4205aea9cb6259e09702331ccf99eb66d618abc28ed98, + 0x2a5ee3055bd03cf775a4ee61da2797d47b01a779a09cadf10b6f4d1df4d6bf7e + ), + line_fn_from_u256( + 0x2f380621a58bd9e81a4771f2a07906250c665a3e4f5279cd29a0e4f8d5f88d29, + 0x1f8e2f982f098350cea0d2e822d61618db4319a615521864d5f4a011dda19a0c, + 0x2f97ae7a8516c4b79b0b14c6a1184ca2d5107db26713c87a400b39eacaf8f4ec, + 0x8d132a7c2554b2fa3072e1df6c97ec9074c319d72aadb4dc35f6986f6b3545c + ), + line_fn_from_u256( + 0x8f2a054eb3ec03e49d81221ae0e221216328e551e815ffe58e2b28590b29ff5, + 0x32d96e9db0d6be06951c328965fd8184715573ea27cb560e9c9efc87d7017a0, + 0x14c2becf6f559bc62f54bdf35abc79700f11703cfd2ab4c79e12fcbdc47591f4, + 0xef73ab583b40f689376709b14b4a226de65495657740e71564b48b6e89f8146 + ), + line_fn_from_u256( + 0x126ceecb0d509abacc7062d05e305aa277f5b1944e9bc42c5850920db0f302ef, + 0x95aca621c1ce4b5bcb46fef97a60dd6dbc40960fbca9cc104f5e5bed06ad7d5, + 0x1bbb609be1cb202015b837c3f90c3e29a05d4600f6c427417aeeb5ab64dde35f, + 0xfb3779e4a945d16d5cb97fc98bbf69c2dada6c70add23ff870643b8ac9892b8 + ), + line_fn_from_u256( + 0x2cc4b3afde19e4e5a1b37caa18b15121914d3af4bae13f14ccd6acd0df31f94d, + 0xa555efcfdacb863e263b215304d143211e5c15b89ed4cbc7ace3abdbe200119, + 0x1eb75bc34588966738d4a317381a540364b60b709804338f1e9e05b10541d596, + 0x972dc5f62a36a73e3e5bcd12a616acaafc86fce7f9cb3e92874cef7e1acf38e + ), + line_fn_from_u256( + 0x289843fd54be2e56795eee8bfd7466a0cca2222d70176d873e059508ebdfc144, + 0x1265a7d4fcff644eedcbc76a723ad7c63baa65767efe52ec99b4f46d6b94a071, + 0x64cdc94cbcef5dbedb970b5107c0863e41d235173541029c7ba712086ba1af3, + 0x12922af0838b2a1185775ffca4e3cd6849dfedec077b5bb3bd40c622130f83b4 + ), + line_fn_from_u256( + 0x228fc068f58dbca46db1b2ecb2e51c1661b5b93f7d6dbf48118177e3fafc0216, + 0x271165c0cd3f335bf46e1f80533716036318ced1373288e955f2f4830e1510af, + 0x9b7d7aae6e8d129152ddf18a6a724c0dfeb92bc9fd91a32411aca099a4eae83, + 0x84314f5d065277ce0ddbf5797fa9fa7690a68d97586f73fee62c60c843259a9 + ), + line_fn_from_u256( + 0x1f48e5cb355f14c146a6c05b4c79b95735fc5de30a2e9a5eede7e093a8f07c2b, + 0x2c4b058e601277d432a4f8b6c183ccef16ebdb76805d3b8e9fd46ef92f060f3, + 0x20d8429768eb37891b86621aceb9d324575a7f83f0a54371fb1cde8af3623d87, + 0x1a16f81a4eee2f3eb349bd78e313ec818718a03f22cb53787b3bcf94871252df + ), + line_fn_from_u256( + 0x2f50000fcd45d94db85ebe81b596bbcd823728b1e0963de87decb015b73b3c6c, + 0x1e8b8627bb1c5233cee91c234265f62c7fb6463d7712bfcddc2379e256fbab41, + 0x27942046cf1fc2d7c5969df1a08d80c2612b370ba6111a207b04dc26a56d5930, + 0x2f19f4f81ce14734ff3f573e90e5e24be2abba106825e6755d68fa4403d3441f + ), + line_fn_from_u256( + 0x2ac7bbe4b4d42a0cc5a08b19df1e32fa4bf81c5996f24d32b21569462781f4d2, + 0x1f30cb991919b4bc7c0e7c02c1e5cdaf8de38028b15cd5a18f044a70aa7aa4e0, + 0x1cd42c2d4a827f5a809f72f80d21e3413620e4e6f09d7962d176ecf91b721b7d, + 0x20f031c32478ab847295f57c051de9d75fa7888dbb02fee72504bc73c9836e0d + ), + line_fn_from_u256( + 0x1cae0c309d5726e4d49de2fe0d8d6f5222202ee58bd5e1fe42cc04162ceeaaad, + 0x9e407f6d690eb79bbf77ba46d9fb588c23588749e5d60af7eb8811c2bab0e8, + 0x12cd75a84153d64e3d05405d4244411b5b6053e7542d0f3c87de91bb0df0a68f, + 0x19492eab9d3069b575e6676ba13783e1d83f7ef3ecf3a272cb4773deace4dd1f + ), + line_fn_from_u256( + 0x63df3526fd94660608a76c0a5501f07800da53d2f954bfe94511644b6937e4a, + 0x5b3caeacf2ced8d58f6fd2a73b31f5732f615e6beaec4424594bf287ceda161, + 0x108f6c9a6b11729d944ebf61d2875d0663ceb0265a236c76834ff4e316287295, + 0x1d6ef756cf79701824fdeb109ba6f1b69f20859d35884fdebb5f41f22a2c36c1 + ), + line_fn_from_u256( + 0x2f831a8cb11faec5bbd459ca8a7966f631b8c79e7d688186052a9b2a0cb1cc59, + 0x1b689982048ab244b10e5508568b41c58dd072b352ceebff64c3f3280af3ea6f, + 0xa97b986fa8f64815896129e95c4d5d44c4f15c48a61360031f508c15add9cf3, + 0x26a1018621324bb3faa22e0aa2a65ca7058f0c3b68109d24a1f8bfda76c5f67b + ), + line_fn_from_u256( + 0x160dde21dbb5acbf8e86c01feb912100c991767000c2c5e4ab316b0d5921027d, + 0xecb2503feb199f3257be61f788cf2488b00ef6d411e9111e435682c2c7b153b, + 0x169f3ec6d8aa2c99d694ae8fbfd801ec61e4956a5243d012fca42d58f2147729, + 0xf790aff921865b7c9dbed5dc40bd7b0c7ea740edccd2d0e9b39bd109f56e3db + ), + line_fn_from_u256( + 0x2d111191f831e2584af374011b9b3069c90a92411240fa783fbc4316e46e6563, + 0x2f70ca984f3a1d8786d202263e2e9b1b502b1f7f33e8667f9bace3b51bae9a07, + 0x2c000df8ae8bc77bacca0f992795033cefe08d88158e951eb7fc8156d715ac2, + 0x22dc07acf83c443227a3b2fe8129988fb26e2266832edd1bcc6d295e70b12a16 + ), + line_fn_from_u256( + 0x2be6c54a3aca53b95f89bb61bb93ee71eeaccbfbf6511d4f49a9fea592da27b7, + 0x254a6eed29384a5a984278aef6cfdc48ad8a4b4e1127fd5795f12421520a0bac, + 0x1ca6b2d585d3c508844a2f7d24ec647a74bc367df6eba344fc65f401c2f0dfcc, + 0x70f79b94941a9e5552bda2b1f1ce8c87822980645c65d58aaf03f803a25d55c + ), + line_fn_from_u256( + 0x1f41e7d6b435a5d3453153ae3a70a64a64999e0b6e5a4005b66c066183fc6807, + 0x1cf5c3c52d5caa538e4ef3791ab9e6c5a46638251088c60ed9192129769bf85f, + 0xee2136362693dad669c76fb9dd211e4161bb8be830ca39f991369ba879b2aa2, + 0x169a9f98b4915218959297e7835c953b30eabc9566837ac29b92a069d1f13598 + ), + line_fn_from_u256( + 0x2ff64620d6d4b0e48f4656a1f4b31dc00bf1f37d0070309a4934d6ed9b33f0b0, + 0x233bcf9bd44ecc5ecb3863f7096bcb4e4baf2b1f12374e47237f5c77b94c42d0, + 0x1fabe9b214fd503af962ab1cc1b973c53e57b59868949e675381ad36e67fd209, + 0x6730eee288e5f03a35f95f0481483eefe40a635a3ead5ac2b34571879ef0311 + ), + line_fn_from_u256( + 0x1670a12446b68764cbf216773bc9c7b390d04e9bb48e17869133184825f3178a, + 0x1fb4045266b6146a7f5ee2a7957459c2cad7392a4d5089380b2bbb855604168d, + 0x26fecd4849b30f2294bb31e67f99a1049a0af39990c705940ba8dc18c289fb29, + 0x1eba8ab976f2268f79127fbc64bd636237be0df81923e0945d5e1d63cab633bc + ), + line_fn_from_u256( + 0x11e0936d1938a7ab9739f41241833d61f8c1cdeab7171b6071aac03eae8d5663, + 0x279bd36a425b1eccfa54bed2525c7e919732b5bb7f7f9885348924cb32081d18, + 0x1c0df502f251ff2cb52a9f5ed65d9d9a16ef7818863691735aab7dc4940bdb53, + 0x21a55c132c893a8371303ba45c36dfc2398077f6d0b93d7cc1e8e4b9e213a0f5 + ), + line_fn_from_u256( + 0x2d9619066fdc7286cafc1a0674bfa7f29d0df1c01f0600f7cfb8a8a8b1994bb6, + 0x24413483fdd89db80c2897b792fc8b2bcb83b9d63f612366ea6a71913030140e, + 0x12ae159bd5945bfc0b49bbed14ef6262e82f260554d346d7221010e81a72c0fd, + 0x300a8ff0e12500cc88d99268ef4fbe79d748c81249b7ee8ec23b2d14fecf83b3 + ), + line_fn_from_u256( + 0xeee4503a6488ec0000530687efbd8b23b2b0146a602806a2090f68f7376374f, + 0x9d9c0b9464e2fe1aba008237f6ea0321f3110de83d28ab21bf96a39b4f18e13, + 0x2c24a32ad9ace2b3b37daa5db24520043d44844b7de09a7a3f617fffe6acbeb7, + 0x117814eba0ad7a565bfad052f3e88948f1ea639ac303fbd440db53a626eaf673 + ), + line_fn_from_u256( + 0xe264bdd6b983b57919bf4e0a18f77241c87b0df13cdbcfd481fad56ac812508, + 0x239e35df6fec7ad92fe5d0e43b7af8cbd3e7a26ff4ba133a39a2382527dd4ab9, + 0x145737cffd1d4d6d73aa49d216cdbd6a66207ba9da13e852081f79e5dc69e756, + 0xc810a220da9929013580fdd85308728f82768f70c0dbfd873fd6e9c8dc00c0f + ), + line_fn_from_u256( + 0x26c0c160bb1555e6601d253877806c709a5eb8e025cb4c397c29b47ab6747e74, + 0x16e1f4a0bc339441296d6b799c67393dd36e0aa465e4684befb98e3ccfa65d09, + 0x2e55f06a2c4bbdb5bcd95eb84e103bc033106e446ae8d1d433fed7e1b00fb186, + 0x110b6bf7aa4504e2074022b43798abb38bf91128d3794ac6f17fc27d52cb5cee + ), + line_fn_from_u256( + 0x1c419aa8711d1cb7d99f84b7e060878ab95a167078a199208f3b41269dd33c0d, + 0x62e69133bbbbb8184b5f07123810ad71b7450a7acaa5d1200ba6ff68d8b00ff, + 0x6deae6a1cd4b591a44fc130a5157fa857f2d3d7f351d6665fa3e06d1f69273b, + 0x2b2ceb0180b352259730fe0aa86f1b4c011c0de543063099502fdc53507d1c65 + ), + line_fn_from_u256( + 0x2256ae0b565783e3ab7db1558b5b4b8209d590e9a92ccff1b3b0b178f379bf78, + 0x11eb3d2fe46c7a044e943434e35db8bb839777d0220f48e9e6c061d7a681f0c6, + 0x116dfe7a9908288f97c2ec5062554bd4d06d55234cd98b7e94d324ef000aac90, + 0xcaca4f32705b46572d58a6b0a89e36b122ac0d5e02ab65e87beb0a4d7266e8d + ), + line_fn_from_u256( + 0x23fb087072caccebd6a2956c5579e525cde63a01ec900b2c1cc43d629542dc2a, + 0x1b2782d0db0fc4fb031cc81ccacf0a368070358262c6694898955ea21bdd3251, + 0x4be4f20eec5e85102507d1d5cff72ca6b8add52615305b9e0f4ec27fe62245c, + 0x21c8fb29b262a0c4a1b2a6230c7d1a2841a9c01caa9298f0637a542859584afe + ), + line_fn_from_u256( + 0x2bd57fac8dbf72e2f8c05b098d0dd4abbfa3088bc03bf105dffe2c9abd31b397, + 0x26c49dd7fb2012b0a58f6f24f6aaa19c522d5deb9b5ed8ead8c9bfff7ec7133d, + 0x25d2833eff89b609db9fcae0560a2167ed1dd0e3d575507f2c663ea0994c1344, + 0x290f67e7f95b1d325782cac844fdc2dfd6859692566b43ecfdc927497cabd5cf + ), + line_fn_from_u256( + 0xe1c1f9fbae157d9f585b116eec368728284f0319fcbec540957a616da2cdf52, + 0x12d7b3a59f40c36a81a8d014fc888e3d51727090b9b62d212b3feb196c5aa366, + 0x1ef2731936e5ff492cb4412653bd67b2838d556a5dc41925329f42f09c28e1db, + 0x2a3c08fd3a527218408f8998a19df8de4fee00d3c855e0af355d8c23089cfac8 + ), + line_fn_from_u256( + 0x109c36d195cddf609884bbd2afcd1a5bfa125dbb7c5b77e8540e02a354fc7690, + 0xec64849b7cf17616115a08a0291909d58cd752dbb4d517aca4d8835349d98ab, + 0xc1eba49ce4a00e8ba655703630486efa602359a72ebf29ea5fc1d51ecb43800, + 0x3fa906df251eee2a18a633d6e5714810f5fac53ab9e8ac2aedc61858ef01346 + ), + line_fn_from_u256( + 0x28df92a107e08d0140fa05e64f0de78abfc1410ecdbcd905ca8c428503f0ca2e, + 0x16169a7e5714d3f8739f2fdb157c1bfc58098a947451eee154dca4eef2581599, + 0xd324e46a8af58939227a7d78df1a531b49627fbb9647ea715594faa6d2f9e04, + 0xe12b7ed2ad6e5b6a09ca228f15af6c1b22ca69fa1b2af3b8362febb66041101 + ), + line_fn_from_u256( + 0x3d737fdf2648537e0c9c3bbad97a59aeb955fcaa490cc99b350ccea848f79d5, + 0x2e357f1afd5603c08606e3fb00279b240cefb466c19e4b4abf997a63659a904c, + 0x9dcaeda77448a6d8050db07fea9905c549e2b16cf9f2edb77bdcc316dd510fb, + 0x197c0ceb01342a608dc0eb548deae4fecde86f24be97d812980145737267539f + ), + line_fn_from_u256( + 0x22de9f81522e72d34ff54093b4062fa54fc76150097b65e26a25308b29028bbe, + 0x2451bc1124b8b6b80e3d890005fadf817f35a727276b17630c3af600aec1c7ae, + 0x1ac9c92a310afe9d235ba1706ea9bb5e32776055baec7887ffc22c9a792a4ed1, + 0xb6fef3ebc42e3d4ca4248c45205b73cfedf57f5e990d88ae1af1e8a6efdcb64 + ), + line_fn_from_u256( + 0xbe07459780f6a75f8afd124d26f63d3e514a02963c8324eb0ad6b096d22ae51, + 0x1b49bfa5f2b8060569ccfe40a501bc5afbfcd2abae95246d7b8dd8c5668176e2, + 0x1331c2d38c032da3a9fa3659100c5c3e31a599a7809fde679dfc2a5e75a36545, + 0x124c0502033c3162c8bd88ec5111681834f5f21cc1668c3b9630879d8554283b + ), + line_fn_from_u256( + 0xd6fbc7dfbbca1db00dd8704fc3e517862fddeb55f22011d081c8f6f290e54c, + 0x20656b2a9cc50290f76e52a5a8029f24ace3b0b1238677e0742fc367f6ff2eed, + 0x135c0cd040f32ceb48e06a05f2ff10b130c73ad9d2d35dc26d4a9431aa54ff88, + 0x15ad031688735dbf1f513d8987000c008c399c96011e8aaa097b62e3e789ee35 + ), + ] +} diff --git a/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo b/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo new file mode 100644 index 0000000..13ebe12 --- /dev/null +++ b/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo @@ -0,0 +1,212 @@ +use super::lines_fix::{gamma_lines, delta_lines}; +use bn254_u256::{CubicScale, PtG1, PtG2, Fq2, Fq12, fq2, fq12, g1, g2}; +use bn254_u256::{Groth16Circuit, LnArrays, InputConstraintPoints}; + +pub fn vk() -> (PtG1, PtG2, PtG2, PtG2, Fq12, Array) { + let mut alpha = g1( + 20491192805390485299153009773594534940189261866228447918068658471970481763042, + 9383485363053290200918347156157836566562967994039712273449902621266178545958 + ); + let beta = g2( + 6375614351688725206403948262868962793625744043794305715222011528459656738731, + 4252822878758300859123897981450591353533073413197771768651442665752259397132, + 10505242626370262277552901082094356697409835680220590971873171140371331206856, + 21847035105528745403288232691147584728191162732299865338377159692350059136679 + ); + let gamma = g2( + 10857046999023057135944570762232829481370756359578518086990519993285655852781, + 11559732032986387107991004021392285783925812861821192530917403151452391805634, + 8495653923123431417604973247489272438418190587263600148770280649306958101930, + 4082367875863433681332203403145435568316851327593401208105741076214120093531 + ); + let delta = g2( + 18843522656454103229460441939617973919282852773928454389351548381771109175804, + 20939788735433971235553050176856161353732417040828392785429509147312127378598, + 20154620275540267962893477662314018482859018034691595131178696575286779357689, + 4547106032091524596969837323375385497187441697194445474662172759730343393129 + ); + let ic = array![ + g1( + 1655549413518972190198478012616802994254462093161203201613599472264958303841, + 21742734017792296281216385119397138748114275727065024271646515586404591497876 + ), + g1( + 16497930821522159474595176304955625435616718625609462506360632944366974274906, + 10404924572941018678793755094259635830045501866471999610240845041996101882275 + ) + ]; + let _neg_albe_miller = fq12( + 0x27c20318505e03cea84a04223b8679a6c84c1e55e83957a21e8986c1b8140510, + 0x104bb1b78f934618c94ba0290a964c58f1400e450e9e19680c39a8aca6fa15f4, + 0x2e56f81476f8d79f0caef927ac110b77cec88490d0860c746d82583440bb8919, + 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, + 0x19bdc2cd81965796abc4dd1ac13a5941ce94ead67c26445a67ca63f07def54fa, + 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, + 0x159ad96d8a0f81d1e048379cb2dee2671581cb84e58de9cbf2d4ea8d11a5a262, + 0xf63ca25374f5b91be7d57a067f1e5ec7a906be473fb01f091d1793fd999b926, + 0x231b22b4c91411c1aeb9724839622abf9d9297cad863a0312452df9f56e9872a, + 0x2cc3c64540e5e5af46b3c583a7314a94fedb672da5da977c6ac70927247c73bb, + 0xbd670107051399799978f2a70d7a08ed0bb130d1fa74638dce3d81536701c96, + 0x221446e74ef53a921abb7b8a0fa2afee56481780d136bc649916f1beeb52aaa + ); + let _alphabeta_miller = fq12( + 0x27c20318505e03cea84a04223b8679a6c84c1e55e83957a21e8986c1b8140510, + 0x104bb1b78f934618c94ba0290a964c58f1400e450e9e19680c39a8aca6fa15f4, + 0x2e56f81476f8d79f0caef927ac110b77cec88490d0860c746d82583440bb8919, + 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, + 0x19bdc2cd81965796abc4dd1ac13a5941ce94ead67c26445a67ca63f07def54fa, + 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, + 0x1ac9750557221e57d8080e19cea275f681ff9f0c82e3e0c1494ba189c6d75ae5, + 0x2100844da9e24497f9d2ee16198f72711cf0feacf476c89caa4f12d6fee34421, + 0xd492bbe181d8e680996d36e481f2d9df9eed2c6900e2a5c17cdac778193761d, + 0x3a0882da04bba7a719c8032da500dc898a60363c2973310d15982efb400898c, + 0x248dde6270e066921eb8b68c10a9b7cec6c6578448ca84545f3cb401a20ce0b1, + 0x2e430a046c424c8096a48dfde0872d5eb21ce9195b5e5ec6f28f1cfae9c7d29d + ); + (alpha, beta, gamma, delta, _neg_albe_miller, ic) +} + +pub fn circuit_setup() -> Groth16Circuit { + let (_alpha, _beta, gamma, delta, _alphabeta_miller, _ic) = vk(); + Groth16Circuit::< + PtG1, PtG2, LnArrays, InputConstraintPoints, Fq12 + > { + alpha_beta: fq12( + 0x27c20318505e03cea84a04223b8679a6c84c1e55e83957a21e8986c1b8140510, + 0x104bb1b78f934618c94ba0290a964c58f1400e450e9e19680c39a8aca6fa15f4, + 0x2e56f81476f8d79f0caef927ac110b77cec88490d0860c746d82583440bb8919, + 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, + 0x19bdc2cd81965796abc4dd1ac13a5941ce94ead67c26445a67ca63f07def54fa, + 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, + 0x159ad96d8a0f81d1e048379cb2dee2671581cb84e58de9cbf2d4ea8d11a5a262, + 0xf63ca25374f5b91be7d57a067f1e5ec7a906be473fb01f091d1793fd999b926, + 0x231b22b4c91411c1aeb9724839622abf9d9297cad863a0312452df9f56e9872a, + 0x2cc3c64540e5e5af46b3c583a7314a94fedb672da5da977c6ac70927247c73bb, + 0xbd670107051399799978f2a70d7a08ed0bb130d1fa74638dce3d81536701c96, + 0x221446e74ef53a921abb7b8a0fa2afee56481780d136bc649916f1beeb52aaa + ), + gamma: g2( + 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed, + 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, + 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d, + 0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec + ), + gamma_neg: gamma, + delta: g2( + 0x29a90e4d611e9d08120c9dc6d165625795d3f80ea2b9831b8e16693e4d7f11fc, + 0x2e4b801bb7360ff6d90a87d882ac82b4de3914e3aa2068ee755a669878e684a6, + 0x3d53213f8bcba0e4267b8fe667b9ba9fcf7365d12b83cf9717e8b2f3e48534e, + 0x2656bc524250d4ea3a0ae2858e13402ba1b1754e60617286821c31aba408c5de + ), + delta_neg: delta, + lines: LnArrays { gamma: gamma_lines(), delta: delta_lines(), }, + ic: array![ + // Starter point + g1( + 1655549413518972190198478012616802994254462093161203201613599472264958303841, + 21742734017792296281216385119397138748114275727065024271646515586404591497876 + ), + // Remaining input constraints + g1( + 16497930821522159474595176304955625435616718625609462506360632944366974274906, + 10404924572941018678793755094259635830045501866471999610240845041996101882275 + ) + ], + } +} + +pub fn proof() -> (PtG1, PtG2, PtG1, u256, Fq12) { + let pi_a = g1( + 21869318927288279352976009554602485400194222893443965440964860860113038611333, + 18311135712289946861315992474690361768373551919702286485795766144098633284656, + ); + let pi_b = g2( + 10022883437199133497429724894217743345007175536382603527810937928471784278544, + 17847188618426698749899308504244999133998140738319907268599259829537979435105, + 7206719342459067270750328127893044383768922785737900891173474267747233610797, + 10190861912483383555079439540237798028694495449372197543107740729805978332256, + ); + let pi_c = g1( + 9705330802798333149196349399272648034569447771243096213977283095662805051802, + 5611531129077709352565605843416215629032027923761887684873913606256162034924, + ); + let pub_input = 16941831391195391826097405368824996545623792600381113317588874714920518273658; + let miller_result = fq12( + 0x1bf4e21820e6cc2b2dbc9453733a8d7c48f05e73f90ecc8bdd80505d2d3b1715, + 0x264f54f6b719920c4ac00aafb3df29cc8a9ddc25e264bdee1ade5e36077d58d7, + 0xdb269e3cd7ed27d825bcbaaefb01023cf9b17beed6092f7b96eab87b571f3fe, + 0x25ce534442ee86a32c46b56d2bf289a0be5f8703fb05c260b2cb820f2b253cf, + 0x33fc62c521f4ffdcb362b12220db6c57f487906c0daf4dc9ba736f882a420e1, + 0xe8b074995703e92a7b9568c90ae160e4d5b81affe628dc1d790241de43d00d0, + 0x84e35bd0eea3430b350041d235bb394e338e3a9ed2f0a9a1ba7fe786d391de1, + 0x244d38253da236f714cb763abf68f7829ee631b4cc5ede89b382e518d676d992, + 0x1ee0a098b62c76a9ebdf4d76c8dfc1586e3fcb6a01712cbda8d10d07b32c5af4, + 0xd23aeb23acacf931f02eca9eceee31ee9607ec003ff934694119a9c6cffc4bd, + 0x16558217bb9b1bcda995b123619808719cb8a282a190630e6d06d7d03e6333ca, + 0x14354c051802f8704939c9948ef91d89db28fe9513ad7bbf58a4639af347ea86 + ); + (pi_a, pi_b, pi_c, pub_input, miller_result) +} + +pub fn residue_witness() -> (Fq12, Fq12, Fq12, (Fq2, Fq2, Fq2), CubicScale) { + let f = fq12( + 0x1bf4e21820e6cc2b2dbc9453733a8d7c48f05e73f90ecc8bdd80505d2d3b1715, + 0x264f54f6b719920c4ac00aafb3df29cc8a9ddc25e264bdee1ade5e36077d58d7, + 0xdb269e3cd7ed27d825bcbaaefb01023cf9b17beed6092f7b96eab87b571f3fe, + 0x25ce534442ee86a32c46b56d2bf289a0be5f8703fb05c260b2cb820f2b253cf, + 0x33fc62c521f4ffdcb362b12220db6c57f487906c0daf4dc9ba736f882a420e1, + 0xe8b074995703e92a7b9568c90ae160e4d5b81affe628dc1d790241de43d00d0, + 0x84e35bd0eea3430b350041d235bb394e338e3a9ed2f0a9a1ba7fe786d391de1, + 0x244d38253da236f714cb763abf68f7829ee631b4cc5ede89b382e518d676d992, + 0x1ee0a098b62c76a9ebdf4d76c8dfc1586e3fcb6a01712cbda8d10d07b32c5af4, + 0xd23aeb23acacf931f02eca9eceee31ee9607ec003ff934694119a9c6cffc4bd, + 0x16558217bb9b1bcda995b123619808719cb8a282a190630e6d06d7d03e6333ca, + 0x14354c051802f8704939c9948ef91d89db28fe9513ad7bbf58a4639af347ea86 + ); + + // residue witness c, + + let c = fq12( + 0x1baf2a84eb47ce42094fd98972bc4bb0f2936ef400aea71eaff2c663e3a0fc4d, + 0x1386ba1f43d9bfa49764547c97cce737f86a88b32d9129370bdd1c3aaceae690, + 0x19ca8adfe0165968c479453ceac5d78d54beec199fd30af10476e46a7da56127, + 0x8c68ad81fefa3678a4c488228f6ec2e68fab44f5fc386a71edf490d13165baf, + 0xaa529ad6ed3d0a32aa2abd113ef97605f58eea5ace47a9a946899faefcb3895, + 0x1eeed7320d8c8646893377a138b1a265f171e37e7f73a58c52d4ec94e6bc0529, + 0x1e46a4ab1efe63cc304f321e79b74b5e52728df2fc3f3043dcdfcf9f816c568c, + 0x2c12b2472cffc96ef1cd313aeae8462296f4ad7b8e6b06073c97b7f0ebf0ad31, + 0x5303c5eded61bd49638d9b64b23971f19c50bc4651ec93df1ee04c676cf5b77, + 0x130ba50aed6232a4885ad91ee99e4a7b2c0d65e4f2ced84de31f0449ad05ca0a, + 0xa5aec882ca48f7ed31209c6ea95b0cd055cbd8c184715ce59c40ccf95c566cd, + 0x40837988d67f97256bb7e5e121802b523f460b3713e079588a5ff10659cfe2d + ); + + let c_inverse = fq12( + 0x5b9a079bc26832a0f6c91a8c3d52f0696e128c4dc02c2e7eccd6750879db37f, + 0x2e555f161b4d72f939ffdc89ec00f1933d46dbba698eb47dd16427d357fc293d, + 0x1b137f9bf629c0dbcdd8087034e1f3557ce533998e4e2566b9961515fe3e8874, + 0x9d878a403981d9dc63f4987d88df92f797412464f26753411b8e7500d316487, + 0x14e05eb80b6f7e23ecfa04a410cfa1cf8036f3161c7d586802b485fba82fa9e9, + 0x35039dc8c011db7eb2c0e91709001ba13c91c6b2a06f5ed32005c4990ed64cb, + 0xb67955a9eed460c7fe5f21790cb806e1a6faa832e5ed9751f4c769b94f233d4, + 0x1a87d2b49b7fe718a8aaed495061c6c7ab0f83010aa102badce3b5f057717586, + 0x1426dbe6a25c91a8d3ac59a34c4ea7d7e0075ef206a5dd08a33d1998b58651c1, + 0x27acb2e47242c471014d129c1a37d0fb662480c13480796cdc381735384a6c5a, + 0x7459382fd7b5f159e32ae6eb1f5a1ac9adde6e0e347011855cc9f8b5bc89021, + 0x2884f79cd78dbef6b64fd2a8af7abbb9cb36d280c0c63074e74f0287d3b2eb2d + ); + + // witness scaling wi, + + let wi = ( + fq2(0, 0), + fq2( + 0x25ba8e0531275a44594c4f53b44497bd8d7341fd41e5faf337fa74dbbff9fe1, + 0x10bd041a04b5422922463bd8b6519b59af036109a228aa43fdb7f215226ece12, + ), + fq2(0, 0), + ); + + let w_pow = CubicScale::Two; + (f, c, c_inverse, wi, w_pow) +} diff --git a/packages/bn254_u256/src/tests/tests.cairo b/packages/bn254_u256/src/tests/tests.cairo new file mode 100644 index 0000000..aef1377 --- /dev/null +++ b/packages/bn254_u256/src/tests/tests.cairo @@ -0,0 +1,27 @@ +use super::fixtures::{circuit_setup, residue_witness, proof}; +use bn254_u256::{schzip_verify, bn254_curve, Bn254SchwartzZippelSteps,}; + +#[test] +fn verify() { + let mut curve = bn254_curve(); + let (pi_a, pi_b, pi_c, input, _) = proof(); + let circuit = circuit_setup(); + let (_f, residue_witness, residue_witness_inv, _, cubic_scale) = residue_witness(); + let remainders = array![]; + let q_rlc_sum = array![]; + let verify = schzip_verify( + ref curve, + pi_a, + pi_b, + pi_c, + array![input], + residue_witness, + residue_witness_inv, + cubic_scale, + circuit, + remainders, + q_rlc_sum + ); + println!("verify: {:?}", verify); + assert(true, ''); +} From dd81b0537e91f429e0ec9986923f7ee349aec9d3 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 17 Jul 2024 04:41:44 +0530 Subject: [PATCH 56/97] partial equal impls --- packages/bn254_u256/src/fq_1.cairo | 12 ++++++++++++ packages/bn254_u256/src/lib.cairo | 6 ++++-- packages/fq_types/src/common.cairo | 24 ++++++++++++++++++++++++ packages/fq_types/src/lib.cairo | 2 +- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/bn254_u256/src/fq_1.cairo b/packages/bn254_u256/src/fq_1.cairo index 864de65..cbbd516 100644 --- a/packages/bn254_u256/src/fq_1.cairo +++ b/packages/bn254_u256/src/fq_1.cairo @@ -7,6 +7,18 @@ pub struct Fq { pub c0: u256, } +pub impl FqPartialEq of PartialEq { + #[inline(always)] + fn eq(lhs: @Fq, rhs: @Fq) -> bool { + lhs.c0 == rhs.c0 + } + + #[inline(always)] + fn ne(lhs: @Fq, rhs: @Fq) -> bool { + lhs.c0 != rhs.c0 + } +} + pub impl U256IntoFq of Into { #[inline(always)] fn into(self: u256) -> Fq { diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index a5d39a2..d7ccff7 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -12,13 +12,15 @@ pub mod pairing { #[cfg(test)] mod tests { pub mod tests; + pub mod test_pairing_utils; pub mod fixtures; } -use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, F12S034, fq3,}; +use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, F12S034, fq3, Fq2PartialEq, Fq3PartialEq,}; pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale}; pub use fq_1::{ - {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, {U256IntoFq, Bn254FqOps, Bn254FqUtils} + {U256IntoFq, FqPartialEq, Bn254FqOps, Bn254FqUtils}, + {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, }; pub use utils::{g1, g2, fq12, fq2}; diff --git a/packages/fq_types/src/common.cairo b/packages/fq_types/src/common.cairo index 93c8ce7..f8b977b 100644 --- a/packages/fq_types/src/common.cairo +++ b/packages/fq_types/src/common.cairo @@ -1,5 +1,29 @@ use super::{Fq2, Fq3, FieldOps, FieldUtils}; +pub impl Fq2PartialEq> of PartialEq> { + #[inline(always)] + fn eq(lhs: @Fq2, rhs: @Fq2) -> bool { + lhs.c0 == rhs.c0 && lhs.c1 == rhs.c1 + } + + #[inline(always)] + fn ne(lhs: @Fq2, rhs: @Fq2) -> bool { + lhs.c0 != rhs.c0 && lhs.c1 != rhs.c1 + } +} + +pub impl Fq3PartialEq> of PartialEq> { + #[inline(always)] + fn eq(lhs: @Fq3, rhs: @Fq3) -> bool { + lhs.c0 == rhs.c0 && lhs.c1 == rhs.c1 && lhs.c2 == rhs.c2 + } + + #[inline(always)] + fn ne(lhs: @Fq3, rhs: @Fq3) -> bool { + lhs.c0 != rhs.c0 && lhs.c1 != rhs.c1 && lhs.c2 != rhs.c2 + } +} + pub impl Fq2Ops< TCurve, TFq, diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index 3d1ae0f..2ad5ba1 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -74,4 +74,4 @@ pub trait FieldOpsExtended { pub type Fq12Direct = (T, T, T, T, T, T, T, T, T, T, T, T); pub type F12S01234Direct = ((T, T, T, T, T), (T, T, T, T, T)); -pub use common::{Fq2Ops, Fq3Ops}; +pub use common::{Fq2Ops, Fq2PartialEq, Fq3Ops, Fq3PartialEq}; From 3cb832c9e7af5ef0451fb99b1a55d7a9225a2b1a Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 17 Jul 2024 04:43:07 +0530 Subject: [PATCH 57/97] fq1 tests --- packages/bn254_u256/src/tests/fq1_tests.cairo | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 packages/bn254_u256/src/tests/fq1_tests.cairo diff --git a/packages/bn254_u256/src/tests/fq1_tests.cairo b/packages/bn254_u256/src/tests/fq1_tests.cairo new file mode 100644 index 0000000..ba2877a --- /dev/null +++ b/packages/bn254_u256/src/tests/fq1_tests.cairo @@ -0,0 +1,59 @@ +// This is not included in the package + +pub use bn254_u256::{Bn254U256Curve, bn254_curve, Fq, Bn254FqOps}; +const A: u256 = 25; +const B: u256 = 34; +fn fq(c0: u256) -> Fq { + Fq { c0 } +} + +#[test] +fn test_add() { + let mut curve = bn254_curve(); + let result = curve.add(fq(A), fq(B)); + assert_eq!(result, fq(A + B)); +} + +#[test] +fn test_sub() { + let mut curve = bn254_curve(); + let result = curve.sub(fq(A), fq(B)); + assert_eq!(result, fq(A + curve.q - B)); +} + +#[test] +fn test_neg() { + let mut curve = bn254_curve(); + let result = curve.neg(fq(A)); + assert_eq!(result, fq(curve.q - A)); +} + +#[test] +fn test_mul() { + let mut curve = bn254_curve(); + let result = curve.mul(fq(A), fq(B)); + assert_eq!(result, fq(A * B)); +} + +#[test] +fn test_div() { + let mut curve = bn254_curve(); + let ab = fq(A * B); // ensure the dividend is exactly divisible by the divisor + let result = curve.div(ab, fq(B)); + assert_eq!(result, fq(A)); +} + +#[test] +fn test_sqr() { + let mut curve = bn254_curve(); + let result = curve.sqr(fq(A)); + assert_eq!(result, fq(A * A)); +} + +#[test] +fn test_inv() { + let mut curve = bn254_curve(); + let inv_a = curve.inv(fq(A)); + let one = fq(1); + assert_eq!(curve.mul(fq(A), inv_a), one); +} From 485a9fa2f2ac8b80efcbda04b73b5744b299bf94 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 17 Jul 2024 04:43:32 +0530 Subject: [PATCH 58/97] pairing util tests wip --- .../src/tests/test_pairing_utils.cairo | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 packages/bn254_u256/src/tests/test_pairing_utils.cairo diff --git a/packages/bn254_u256/src/tests/test_pairing_utils.cairo b/packages/bn254_u256/src/tests/test_pairing_utils.cairo new file mode 100644 index 0000000..cabc70e --- /dev/null +++ b/packages/bn254_u256/src/tests/test_pairing_utils.cairo @@ -0,0 +1,157 @@ +use ec_groups::ECOperations; +use bn254_u256::{Bn254FqOps, Bn254U256Curve, PtG1, PtG2, Fq2PartialEq}; +use bn254_u256::{bn254_curve, fq2, g1, g2, AffineOpsBn}; +use bn254_u256::print::{Fq2Display, FqDisplay, G2Display}; +use pairing::{PPrecompute, LineFn}; +use pairing::{PairingUtils, CubicScale}; + +fn points() -> (PtG1, PtG2) { + ( + // g1 * 3 + g1( + 0x769bf9ac56bea3ff40232bcb1b6bd159315d84715b8e679f2d355961915abf0, + 0x2ab799bee0489429554fdb7c8d086475319e63b40b9c5b57cdf1ff3dd9fe2261, + ), + // g2 * 5 + g2( + 0x2e539c423b302d13f4e5773c603948eaf5db5df8ae8a9a9113708390a06410d8, + 0xa09ccf561b55fd99d1c1208dee1162457b57ac5af3759d50671e510e428b2a1, + 0x2f8d9f9ab83727c77a2fec063cb7b6e5eb23044ccf535ad49d46d394fb6f6bf6, + 0x19b763513924a736e4eebd0d78c91c1bc1d657fee4214057d21414011cfcc763, + ) + ) +} + +#[test] +#[available_gas(25000000)] +fn test_step_double() { + let mut curve = bn254_curve(); + let (p, mut acc) = points(); + let pc = curve.p_precompute(p); + + let lines = curve.step_double(ref acc, @pc); + // let lines = step_double(ref acc, @pc.ppc, p, pc.field_nz); + + let expected = g2( + 0x20101834550a7d15aa7a685d3f0095b689822cb568dfc9690e0cc58e9826d8fb, + 0x566eed2b6bb584ca75fbe0ca9ffc98eb586c25812617df7e01a2b6d8270f0bf, + 0x19ea09d089c848b2dee00082395883e0b405de1da65d4b4aeebd50c84e47349d, + 0xa66c012d8ebf11c9a9fc4ccfeeab0ace62b1c1fa744f6c6173f1994e9241db7, + ); + + let expected_c3 = fq2( + 0x1c43298c88df08230fee9d84ac09ee48d34a29e278e8d58cb18769030ec4438, + 0x1c5954ca0cd04a09cd9b039b450f0241731c800e47aaa858c7e7142df032479c, + ); + + let expected_c4 = fq2( + 0x2269a2f98ab148f9c027b04961479c312d53748fc7eeba24a6a08850431486e7, + 0x200812b02c8345ebc2ac8cfd83b0ab717735e789edc6fbed6427646339d76800, + ); + + assert(acc == expected, 'wrong dbl point'); + assert(lines.c3 == expected_c3, 'wrong dbl c3'); + assert(lines.c4 == expected_c4, 'wrong dbl c4'); +} +#[test] +#[available_gas(25000000)] +fn test_step_dbl_add() { + let mut self = bn254_curve(); + let (p, mut q) = points(); + let pc = self.p_precompute(p); + + let mut acc = g2( + 0x20101834550a7d15aa7a685d3f0095b689822cb568dfc9690e0cc58e9826d8fb, + 0x566eed2b6bb584ca75fbe0ca9ffc98eb586c25812617df7e01a2b6d8270f0bf, + 0x19ea09d089c848b2dee00082395883e0b405de1da65d4b4aeebd50c84e47349d, + 0xa66c012d8ebf11c9a9fc4ccfeeab0ace62b1c1fa744f6c6173f1994e9241db7, + ); + + let q = self.pt_neg(q); + + let (l1, l2) = self.step_dbl_add(ref acc, q, @pc); + + let expected = g2( + 0x13f6762080e4a32b0d11bf75b55989e08b3be57060b4bd2148e9be49fc1ca587, + 0x1ace10298838161fdd3a6bb5dd157a808c19d4dac316bb5c001f68ee586f30b, + 0x51d866c133978bdaf7b2ea418164cc0c60477b9364bf9acae265a87e861daf, + 0xbc83eb241f95b562bfabecd0c21f1b335bdfb10d49ade6efa26ccef5dd4b570, + ); + + let expected_l1c3 = fq2( + 0x2ea01bda18a3afa787515bde36c0b9790a4cc7f340e33d3471081586a790b90f, + 0x140af9a8d461561feab5421b3c72561c2464ea8320c72234743977e8e84ab5ab, + ); + + let expected_l1c4 = fq2( + 0xdfaab795680572ff828956d2039bc2c6a2df601a0831068958003c695687660, + 0x105c3bc2b4ae5a3df5a3b8b8fdd0acec204b83077aaace9fd7f927b39ea59547, + ); + + let expected_l2c3 = fq2( + 0x25891a7b883843168b2ed6ed8b42d4fdada5df85402f00d884d7937fae24e496, + 0x1dfb565c82eac32c96880b9b1da38241175076b36ae8abbb8379ebec2f907b81, + ); + + let expected_l2c4 = fq2( + 0x2558f709e26d6843da2ffd7122906325c7fd61e6efd90886e94177d2520a6a50, + 0x2a0a12744f9deeb8e3aa6a42ee95f27d9939cdd9e62904e1f65cb72b98e9dfd8, + ); + + assert(acc == expected, 'wrong dbl_add point'); + assert(l1.c3 == expected_l1c3, 'wrong dbl_add l1c3'); + assert(l1.c4 == expected_l1c4, 'wrong dbl_add l1c4'); + assert(l2.c3 == expected_l2c3, 'wrong dbl_add l2c3'); + assert(l2.c4 == expected_l2c4, 'wrong dbl_add l2c4'); +} +// #[test] +// #[available_gas(250000000)] +// fn test_step_correction() { +// let mut curve = bn254_curve(); +// let (p, q) = points(); +// let (pc, _): (PreCompute, AffineG2) = (p, q).precompute(get_field_nz()); +// let mut acc = g2( +// 0x235817357e89826e377fd16a7f1a2ff53e0df7e86895b1958bd95fb6560fa941, +// 0x22108c7158743b9927b624e1a61a4aa7ba9b2f717799e4e0c5424e8343de2884, +// 0x934368739662af976071d3e9152e3172a82cd6012bf0d605f67e735e3b3cdfe, +// 0x15484f6b2822b319e27f88795c1512a5bf6b1837e4749dffb7086239979f4d21, +// ); +// let (l1, l2) = correction_step(ref acc, @pc.ppc, p, pc.q); + +// // We skip final point operation to save costs +// // let expected = g2( +// // 0x242898b9a67f64300e584ef995ba56d75a6a66b236ee16145e9b1308dc24e3ce, +// // 0x290d75d7b30b60ea7a2809bb7fd095e5c4131719ff499b33ddc8c67d95a743c7, +// // 0x275fc70fde9a73de316c4ba654097840197be9141f31d3567188a8de06525572, +// // 0x1c79853dd0050acf0f1de573eed5b81d5e287994df2452eb560c6262746e07fc, +// // ); + +// let expected_l1c3 = fq2( +// 0xd238aea84f1c5f3cc252629ef407db0ad7b441dd6616b994e374fb8c0413383, +// 0x304554bb4d99a4cebabe260f60ef18d59e887078e74321d4fdba79a9eeab1ddb, +// ); + +// let expected_l1c4 = fq2( +// 0x907fba323881daa70e1c572f69e77964e70ba22fb812dd9abcf304140574def, +// 0x404c3e3275e836536af9a08a8dff1fe867efac4a34ca9a42e10706f4d811b8d, +// ); + +// let expected_l2c3 = fq2( +// 0xd06e75cebbc8df7fd2ee7b4afe5a42586c26a96c3fc205128dfd9184f131d92, +// 0x1a80e9ca6ed93b661603d4f1acc3c982065301e91154bf63203e815a11befb0f, +// ); + +// let expected_l2c4 = fq2( +// 0x1fe98cea2f6991fdf8d51c06b75b57ee944309336cb488c4c85e2966afaf5dba, +// 0x16d794265926a808f8ce74b6d4b31606c9b429603f4f522be6e2cb3fcb069dcd, +// ); + +// assert(l1.c3 == expected_l1c3, 'wrong correction l1c3'); +// assert(l1.c4 == expected_l1c4, 'wrong correction l1c4'); +// assert(l2.c3 == expected_l2c3, 'wrong correction l2c3'); +// assert(l2.c4 == expected_l2c4, 'wrong correction l2c4'); +// // We skip final point operation to save costs +// // assert(q == expected, 'wrong correction point'); +// } + + From ba136ff74fc6e36ab59c96ace40741b0764db55e Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 17 Jul 2024 04:43:48 +0530 Subject: [PATCH 59/97] pairing util fixes --- packages/fq_types/src/common.cairo | 3 ++- packages/pairing/src/lines.cairo | 2 -- packages/pairing/src/utils.cairo | 17 +++++++---------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/fq_types/src/common.cairo b/packages/fq_types/src/common.cairo index f8b977b..da1a9db 100644 --- a/packages/fq_types/src/common.cairo +++ b/packages/fq_types/src/common.cairo @@ -85,8 +85,9 @@ pub impl Fq2Ops< let a1_nr = self.mul_by_nonresidue(a1); // βa1 let t1 = FqOps::add(ref self, a0, a1_nr); // a0 + βa1 let t2 = FqOps::mul(ref self, t0, t1); // (a0 + a1) * (a0 + βa1) + let t3 = FqOps::sub(ref self, t2, v); // (a0 + a1) * (a0 + βa1) - v - βv let v_nr = self.mul_by_nonresidue(v); // βv - let c0 = FqOps::sub(ref self, t2, v_nr); // (a0 + a1) * (a0 + βa1) - v - βv + let c0 = FqOps::sub(ref self, t3, v_nr); // (a0 + a1) * (a0 + βa1) - v - βv // c1 = v + v; let c1 = FqOps::add(ref self, v, v); // 2v Fq2 { c0, c1 } diff --git a/packages/pairing/src/lines.cairo b/packages/pairing/src/lines.cairo index 79a731e..8c5dc3c 100644 --- a/packages/pairing/src/lines.cairo +++ b/packages/pairing/src/lines.cairo @@ -29,8 +29,6 @@ pub impl LinesArrayGet< fn get_gamma_line( self: @LinesArrays>>>, line_index: u32 ) -> LineFn> { - // let l1: LineFn = *self.gamma[line_index]; - // println!("Get {}.{} {}", step, line_index, l1.slope.c0.c0.low); *self.gamma[line_index] } fn get_delta_line( diff --git a/packages/pairing/src/utils.cairo b/packages/pairing/src/utils.cairo index 2f6b39a..24a1aba 100644 --- a/packages/pairing/src/utils.cairo +++ b/packages/pairing/src/utils.cairo @@ -101,15 +101,13 @@ pub impl PairingUtils< // https://eprint.iacr.org/2022/1162 (Section 6.1) // computes acc = acc + q + acc and line evals for p // returns product of line evaluations to multiply with f - // #[inline(always)] fn step_dbl_add( ref self: TCurve, ref acc: Affine>, q: Affine>, ppc: @PPrecompute ) -> (F034, F034) { let s = acc; - let Affine { x: x1, y: y1 } = s; // s + q let slope1 = self.chord(s, q); - let x2 = self.x_on_slope(s, slope1, q.x); + let x1 = self.x_on_slope(s, slope1, q.x); let line1 = self.point_and_slope_at_p(slope1, s, ppc); // we skip y1 calculation and sub slope1 directly in second slope calculation @@ -117,17 +115,15 @@ pub impl PairingUtils< // (s + q) + s // λ2 = (y2-y1)/(x2-x1), subbing y2 = λ(x2-x1)+y1 // λ2 = -λ1-2y1/(x2-x1) - let neg_slope1 = self.neg(slope1); // neg_slope1 = -λ1 - let y_2x = self.add(y1, y1); // y_2x = 2y1 + let neg_slope1 = self.neg(slope1); // -λ1 + let y_2x = self.add(s.y, s.y); // 2s.y - // x2 - s.x - let x_diff = self.sub(x2, s.x); // x_diff = x2 - s.x + let x_diff = self.sub(x1, s.x); // x2 - s.x - // (y1 + y1) / (x2 - s.x) - let slope_fraction = self.div(y_2x, x_diff); // slope_fraction = y_2x / x_diff + let slope_fraction = self.div(y_2x, x_diff); // y_2x / x_diff // -λ1 - (y1 + y1) / (x1 - s.x) - let slope2 = self.sub(neg_slope1, slope_fraction); // slope2 = neg_slope1 - slope_fraction + let slope2 = self.sub(neg_slope1, slope_fraction); // -λ1 - slope_fraction acc = self.pt_on_slope(s, slope2, x1); let line2 = self.point_and_slope_at_p(slope2, s, ppc); @@ -145,6 +141,7 @@ pub impl PairingUtils< let s = acc; // λ = 3x²/2y let slope = self.tangent(s); + // p = (λ²-2x, λ(x-xr)-y) acc = self.pt_on_slope(s, slope, acc.x); self.point_and_slope_at_p(slope, s, ppc) From 37653b36308413fb76d8a64345a7e0c6da31e1e9 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 18 Jul 2024 04:33:41 +0530 Subject: [PATCH 60/97] correction step tests --- packages/bn254_u256/src/lib.cairo | 4 +- .../src/tests/test_pairing_utils.cairo | 108 +++++++++--------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index d7ccff7..f318d2a 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -30,13 +30,13 @@ pub type Fq12 = Fq2Gen; pub type F034 = F12S034; pub use pairing::{ - utils::{ICProcess, ICArrayInput, LnArrays, // - {SZCommitment, SZPreCompute, SZAccumulator}}, + utils::{ICProcess, ICArrayInput, LnArrays, SZCommitment, SZPreCompute, SZAccumulator}, schzip_miller::{ schzip_verify, InputConstraintPoints, PPrecompute, {Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit} }, schzip_steps::Bn254SchwartzZippelSteps, + schzip_miller_runner::{Miller_Bn254_U256, PiMapping, pi_mapping}, }; pub fn bn254_curve() -> Bn254U256Curve { diff --git a/packages/bn254_u256/src/tests/test_pairing_utils.cairo b/packages/bn254_u256/src/tests/test_pairing_utils.cairo index cabc70e..cdad4f1 100644 --- a/packages/bn254_u256/src/tests/test_pairing_utils.cairo +++ b/packages/bn254_u256/src/tests/test_pairing_utils.cairo @@ -1,6 +1,6 @@ -use ec_groups::ECOperations; -use bn254_u256::{Bn254FqOps, Bn254U256Curve, PtG1, PtG2, Fq2PartialEq}; -use bn254_u256::{bn254_curve, fq2, g1, g2, AffineOpsBn}; +use ec_groups::{ECOperations, Affine}; +use bn254_u256::{Bn254FqOps, Bn254U256Curve, PtG1, PtG2, AffineOpsBn, Fq2PartialEq}; +use bn254_u256::{bn254_curve, fq2, g1, g2, pi_mapping}; use bn254_u256::print::{Fq2Display, FqDisplay, G2Display}; use pairing::{PPrecompute, LineFn}; use pairing::{PairingUtils, CubicScale}; @@ -53,6 +53,7 @@ fn test_step_double() { assert(lines.c3 == expected_c3, 'wrong dbl c3'); assert(lines.c4 == expected_c4, 'wrong dbl c4'); } + #[test] #[available_gas(25000000)] fn test_step_dbl_add() { @@ -104,54 +105,57 @@ fn test_step_dbl_add() { assert(l2.c3 == expected_l2c3, 'wrong dbl_add l2c3'); assert(l2.c4 == expected_l2c4, 'wrong dbl_add l2c4'); } -// #[test] -// #[available_gas(250000000)] -// fn test_step_correction() { -// let mut curve = bn254_curve(); -// let (p, q) = points(); -// let (pc, _): (PreCompute, AffineG2) = (p, q).precompute(get_field_nz()); -// let mut acc = g2( -// 0x235817357e89826e377fd16a7f1a2ff53e0df7e86895b1958bd95fb6560fa941, -// 0x22108c7158743b9927b624e1a61a4aa7ba9b2f717799e4e0c5424e8343de2884, -// 0x934368739662af976071d3e9152e3172a82cd6012bf0d605f67e735e3b3cdfe, -// 0x15484f6b2822b319e27f88795c1512a5bf6b1837e4749dffb7086239979f4d21, -// ); -// let (l1, l2) = correction_step(ref acc, @pc.ppc, p, pc.q); - -// // We skip final point operation to save costs -// // let expected = g2( -// // 0x242898b9a67f64300e584ef995ba56d75a6a66b236ee16145e9b1308dc24e3ce, -// // 0x290d75d7b30b60ea7a2809bb7fd095e5c4131719ff499b33ddc8c67d95a743c7, -// // 0x275fc70fde9a73de316c4ba654097840197be9141f31d3567188a8de06525572, -// // 0x1c79853dd0050acf0f1de573eed5b81d5e287994df2452eb560c6262746e07fc, -// // ); - -// let expected_l1c3 = fq2( -// 0xd238aea84f1c5f3cc252629ef407db0ad7b441dd6616b994e374fb8c0413383, -// 0x304554bb4d99a4cebabe260f60ef18d59e887078e74321d4fdba79a9eeab1ddb, -// ); - -// let expected_l1c4 = fq2( -// 0x907fba323881daa70e1c572f69e77964e70ba22fb812dd9abcf304140574def, -// 0x404c3e3275e836536af9a08a8dff1fe867efac4a34ca9a42e10706f4d811b8d, -// ); - -// let expected_l2c3 = fq2( -// 0xd06e75cebbc8df7fd2ee7b4afe5a42586c26a96c3fc205128dfd9184f131d92, -// 0x1a80e9ca6ed93b661603d4f1acc3c982065301e91154bf63203e815a11befb0f, -// ); - -// let expected_l2c4 = fq2( -// 0x1fe98cea2f6991fdf8d51c06b75b57ee944309336cb488c4c85e2966afaf5dba, -// 0x16d794265926a808f8ce74b6d4b31606c9b429603f4f522be6e2cb3fcb069dcd, -// ); - -// assert(l1.c3 == expected_l1c3, 'wrong correction l1c3'); -// assert(l1.c4 == expected_l1c4, 'wrong correction l1c4'); -// assert(l2.c3 == expected_l2c3, 'wrong correction l2c3'); -// assert(l2.c4 == expected_l2c4, 'wrong correction l2c4'); -// // We skip final point operation to save costs -// // assert(q == expected, 'wrong correction point'); -// } +#[test] +#[available_gas(250000000)] +fn test_step_correction() { + let mut self = bn254_curve(); + let (p, mut q) = points(); + let pc = self.p_precompute(p); + let mut acc = g2( + 0x235817357e89826e377fd16a7f1a2ff53e0df7e86895b1958bd95fb6560fa941, + 0x22108c7158743b9927b624e1a61a4aa7ba9b2f717799e4e0c5424e8343de2884, + 0x934368739662af976071d3e9152e3172a82cd6012bf0d605f67e735e3b3cdfe, + 0x15484f6b2822b319e27f88795c1512a5bf6b1837e4749dffb7086239979f4d21, + ); + + let pi_map = pi_mapping(); + + let (l1, l2) = self.correction_step(ref acc, q, pi_map, @pc); + + // We skip final point operation to save costs + // let expected = g2( + // 0x242898b9a67f64300e584ef995ba56d75a6a66b236ee16145e9b1308dc24e3ce, + // 0x290d75d7b30b60ea7a2809bb7fd095e5c4131719ff499b33ddc8c67d95a743c7, + // 0x275fc70fde9a73de316c4ba654097840197be9141f31d3567188a8de06525572, + // 0x1c79853dd0050acf0f1de573eed5b81d5e287994df2452eb560c6262746e07fc, + // ); + + let expected_l1c3 = fq2( + 0xd238aea84f1c5f3cc252629ef407db0ad7b441dd6616b994e374fb8c0413383, + 0x304554bb4d99a4cebabe260f60ef18d59e887078e74321d4fdba79a9eeab1ddb, + ); + + let expected_l1c4 = fq2( + 0x907fba323881daa70e1c572f69e77964e70ba22fb812dd9abcf304140574def, + 0x404c3e3275e836536af9a08a8dff1fe867efac4a34ca9a42e10706f4d811b8d, + ); + + let expected_l2c3 = fq2( + 0xd06e75cebbc8df7fd2ee7b4afe5a42586c26a96c3fc205128dfd9184f131d92, + 0x1a80e9ca6ed93b661603d4f1acc3c982065301e91154bf63203e815a11befb0f, + ); + + let expected_l2c4 = fq2( + 0x1fe98cea2f6991fdf8d51c06b75b57ee944309336cb488c4c85e2966afaf5dba, + 0x16d794265926a808f8ce74b6d4b31606c9b429603f4f522be6e2cb3fcb069dcd, + ); + + assert(l1.c3 == expected_l1c3, 'wrong correction l1c3'); + assert(l1.c4 == expected_l1c4, 'wrong correction l1c4'); + assert(l2.c3 == expected_l2c3, 'wrong correction l2c3'); + assert(l2.c4 == expected_l2c4, 'wrong correction l2c4'); +// We skip final point operation to save costs +// assert(q == expected, 'wrong correction point'); +} From fb29246dbf9f3c2c93e2f3d9a8b406689c8a6f1c Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 18 Jul 2024 04:35:33 +0530 Subject: [PATCH 61/97] fix miller last correction step --- .../src/pairing/schzip_miller_runner.cairo | 13 ++++++------- packages/bn254_u256/src/pairing/schzip_steps.cairo | 2 ++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index 2aeb455..bf468cf 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,10 +1,11 @@ -use pairing::{LineFn, LinesArrayGet, FixedPointLines, PiMapping}; +use pairing::{LineFn, LinesArrayGet, FixedPointLines}; use pairing::{PairingUtils}; use bn254_u256::{Fq, Fq2, fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; use bn254_u256::print::{FqDisplay, Fq12Display, G2Display}; use bn254_u256::pairing::utils::{ LnArrays, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn }; +pub use pairing::PiMapping; use bn_ate_loop::MillerRunner; use schwartz_zippel::SchZipSteps; @@ -20,7 +21,6 @@ pub impl Miller_Bn254_U256< ref self: Curve, runner: @PreCompute, i: (u32, u32), ref acc: Accumulator ) { // let (i1, i2) = i; - // runner.schzip self.miller_bit_o(runner, i1, ref acc); self.miller_bit_n(runner, i2, ref acc); } @@ -31,6 +31,7 @@ pub impl Miller_Bn254_U256< ) { // let g16 = runner.g16; let ppc = g16.ppc; + let l1 = self.step_double(ref acc.g2.pi_b, ppc.pi_a); let (l2, l3) = g16.lines.with_fxd_pt_line(ref self, g16.ppc, ref acc.line_index); self.sz_zero_bit(runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3)); @@ -65,24 +66,22 @@ pub impl Miller_Bn254_U256< .sz_nz_bit( runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3), *g16.residue_witness ); - // println!("n_bit {i}: {}", f); - } // last step fn miller_last(ref self: Curve, runner: @PreCompute, ref acc: Accumulator) { // let g16 = runner.g16; let ppc = g16.ppc; - // use neg q - let pi_b = runner.g16.neg_q.pi_b; + let pi_b = runner.g16.q.pi_b; let l1 = self.correction_step(ref acc.g2.pi_b, *pi_b, pi_mapping(), ppc.pi_a); + let (l2, l3) = g16.lines.with_fxd_pt_lines(ref self, g16.ppc, ref acc.line_index); self.sz_last_step(runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3)); } } -fn pi_mapping() -> PiMapping { +pub fn pi_mapping() -> PiMapping { // π (Pi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves // ----------------------------------------------------------------- // BN254_Snarks is a D-Twist: pi1_coef1 = ξ^((p-1)/6) diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index b8d995e..be51dd8 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -12,6 +12,7 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps ) { let (_l1, _l2, _l3) = lines; } + fn sz_nz_bit( ref self: Curve, sz: @SZCommitment, @@ -20,6 +21,7 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps lines: LinesDbl, witness: Fq12 ) {} + fn sz_last_step( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12, lines: LinesDbl ) {} From dbd56278469c755e3c3377471f654b309a0c7f71 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 18 Jul 2024 06:01:03 +0530 Subject: [PATCH 62/97] sz commitment and sz accumulator types --- packages/bn254_u256/src/lib.cairo | 5 ++++- .../bn254_u256/src/pairing/schzip_miller.cairo | 6 +++++- .../src/pairing/schzip_miller_runner.cairo | 5 +++-- .../bn254_u256/src/pairing/schzip_steps.cairo | 18 +++++++++--------- packages/bn254_u256/src/pairing/utils.cairo | 11 ++++++++--- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index f318d2a..71ea1af 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -30,7 +30,10 @@ pub type Fq12 = Fq2Gen; pub type F034 = F12S034; pub use pairing::{ - utils::{ICProcess, ICArrayInput, LnArrays, SZCommitment, SZPreCompute, SZAccumulator}, + utils::{ + {ICProcess, ICArrayInput, LnArrays}, + {SZCommitment, SZPreCompute, SZAccumulator, SZCommitmentAccumulator} + }, schzip_miller::{ schzip_verify, InputConstraintPoints, PPrecompute, {Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit} diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 3799a0d..4e1b14f 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,10 +1,14 @@ +use fq_types::FieldOps; use ec_groups::ECOperations; pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; use bn254_u256::{ Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ schzip_miller_runner::Miller_Bn254_U256, - utils::{SZCommitment, SZPreCompute, SZAccumulator, LnArrays, ICArrayInput}, + utils::{ + SZCommitment, SZPreCompute, SZCommitmentAccumulator, SZAccumulator, LnArrays, + ICArrayInput + }, }, Bn254SchwartzZippelSteps, }; diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index bf468cf..acf46c7 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -3,7 +3,8 @@ use pairing::{PairingUtils}; use bn254_u256::{Fq, Fq2, fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; use bn254_u256::print::{FqDisplay, Fq12Display, G2Display}; use bn254_u256::pairing::utils::{ - LnArrays, SZCommitment, SZPreCompute, SZAccumulator as Accumulator, LnFn + LnArrays, SZCommitment, SZCommitmentAccumulator, SZPreCompute, SZAccumulator as Accumulator, + LnFn }; pub use pairing::PiMapping; use bn_ate_loop::MillerRunner; @@ -14,7 +15,7 @@ type PreCompute = SZPreCompute; // TODO: +SchZipSteps pub impl Miller_Bn254_U256< - TSchZip, +SchZipSteps + TSchZip, +SchZipSteps > of MillerRunner, Accumulator> { // first and second step, O and N fn miller_bit_1_2( diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index be51dd8..cb6e70c 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -1,14 +1,14 @@ -use bn254_u256::{Fq, Fq2, Fq12, Bn254U256Curve, SZCommitment}; +use bn254_u256::{Fq, Fq2, Fq12, Bn254U256Curve, SZCommitment, SZCommitmentAccumulator}; use schwartz_zippel::{SchZipSteps, Lines, FS034, F034X2, LinesDbl, Residue}; type Curve = Bn254U256Curve; -type SZAcc = (u32, Fq); +type SZCAcc = SZCommitmentAccumulator; -pub impl Bn254SchwartzZippelSteps of SchZipSteps { - fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12) {} - fn sz_sqr(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12) {} +pub impl Bn254SchwartzZippelSteps of SchZipSteps { + fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12) {} + fn sz_sqr(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12) {} fn sz_zero_bit( - ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12, lines: Lines + ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12, lines: Lines ) { let (_l1, _l2, _l3) = lines; } @@ -16,20 +16,20 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps fn sz_nz_bit( ref self: Curve, sz: @SZCommitment, - ref sz_acc: SZAcc, + ref sz_acc: SZCAcc, ref f: Fq12, lines: LinesDbl, witness: Fq12 ) {} fn sz_last_step( - ref self: Curve, sz: @SZCommitment, ref sz_acc: SZAcc, ref f: Fq12, lines: LinesDbl + ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12, lines: LinesDbl ) {} fn sz_post_miller( ref self: Curve, sz: @SZCommitment, - ref sz_acc: SZAcc, + ref sz_acc: SZCAcc, f: Fq12, alpha_beta: Fq12, residue: Residue diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 8eb3cda..9d025ec 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -6,8 +6,11 @@ use bn254_u256::{Bn254U256Curve}; #[derive(Drop)] pub struct SZCommitment { - pub remainders: Array, - pub q_rlc_sum: Array, + pub remainders: Array, + pub qrlc: Array, + pub rem_fiat_shamir_powers: Array, + pub fiat_shamir_powers: Array, + pub p12_x: Fq, } #[derive(Drop)] @@ -18,12 +21,14 @@ pub struct SZPreCompute { pub schzip: TCommitment, } +pub type SZCommitmentAccumulator = (u32, Fq); + #[derive(Drop)] pub struct SZAccumulator { pub f: Fq12, pub g2: Groth16MillerG2, pub line_index: u32, - pub schzip: (u32, Fq), + pub schzip: SZCommitmentAccumulator, } pub type LnFn = LineFn; From acaac3f0e8a7c89b64109b9ee680e46b13076682 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 18 Jul 2024 06:01:28 +0530 Subject: [PATCH 63/97] sz commitment proof init --- .../src/pairing/schzip_miller.cairo | 73 ++++++++++++++++++- packages/bn254_u256_contract/src/lib.cairo | 12 +-- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 4e1b14f..57fb4d6 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -15,6 +15,7 @@ use bn254_u256::{ use bn_ate_loop::{ate_miller_loop}; use pairing::{LineFn, StepLinesGet, LinesArrayGet}; use pairing::{PairingUtils, CubicScale}; +use core::hash::HashStateTrait; use schwartz_zippel::SchZipSteps; @@ -22,7 +23,9 @@ pub type InputConstraintPoints = Array; type LnFn = LineFn; // Does the verification -fn schzip_miller, +Drop>( +fn schzip_miller< + TSchZip, +SchZipSteps, +Drop +>( ref curve: Bn254U256Curve, pi_a: PtG1, pi_b: PtG2, @@ -59,6 +62,68 @@ fn schzip_miller, ate_miller_loop(ref curve, precomp, q_acc) } +// Prepares SZ commitment +// ---------------------- +// Remainders Fiat Shamir is used for RLC (Random Linear Combination). +// The commitment for Schwartz Zippel lemma includes all remainders and an RLC of all quotients (QRLC). +// The verifier accumulates all the remainders and RHS from miller loop with same RLC as the QRLC. +// Quotient terms are accumulated in QRLC for all individual equations, and cannot change the terms +// of remainders in the final clubbed equation. +// The terms of remainders are between x^0 to x^11, and QRLC terms are all x^12 and up. +// This is because the terms in the QRLC are all multiplied by a polynomial of degree 12, x^12 + 18x^6 + 82 +// So Any changes in the remainders will change the RLC and equation will not be satisfiable with any QRLC. +// Fiat Shamir for the final Schwartz Zippel includes all remainders and QRLC for soundness. +pub fn prepare_sz_commitment( + ref curve: Bn254U256Curve, remainders: Array, qrlc: Array, +) -> SZCommitment { + let mut rem_coeff_i = 0; + let mut hasher = core::poseidon::PoseidonImpl::new(); + let rem_coeffs_count = remainders.len(); + let rem_snap = @remainders; + while rem_coeff_i != rem_coeffs_count { + let c = *(rem_snap[rem_coeff_i]); + hasher = hasher.update(c.c0.low.into()); + hasher = hasher.update(c.c0.high.into()); + rem_coeff_i += 1; + }; + let remainders_fiat_shamir: u256 = hasher.finalize().into(); + + let mut qrlc_coeff_i = 0; + let qrlc_count = qrlc.len(); + let qrlc_snap = @qrlc; + // continue with the rest of the coefficients from quotient RLC + while qrlc_coeff_i != qrlc_count { + let c = *(qrlc_snap[qrlc_coeff_i]); + hasher = hasher.update(c.c0.low.into()); + hasher = hasher.update(c.c0.high.into()); + qrlc_coeff_i += 1; + }; + let fiat_shamir: u256 = hasher.finalize().into(); + + // @TODO + let p12_x = 1_u256.into(); + + SZCommitment { + remainders, + fiat_shamir_powers: fs_pow(ref curve, fiat_shamir, 40), + rem_fiat_shamir_powers: fs_pow(ref curve, remainders_fiat_shamir, 68), + p12_x, + qrlc + } +} + +pub fn fs_pow(ref curve: Bn254U256Curve, x: u256, powers: u32) -> Array { + let x_fq: Fq = x.into(); + let mut arr: Array = array![x_fq]; + let mut i = 0; + let powers = powers / 2 + 1; + while i != powers { + let even_power = curve.sqr(*arr[i]); + arr.append(even_power); // even i * 2 power + arr.append(curve.mul(even_power, x_fq)); // odd i * 2 + 1 power + }; + arr +} // Does the verification pub fn schzip_verify( ref curve: Bn254U256Curve, @@ -70,10 +135,10 @@ pub fn schzip_verify( residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - schzip_remainders: Array, - schzip_qrlc: Array, + schzip_remainders: Array, + schzip_qrlc: Array, ) { - let schzip = SZCommitment { remainders: schzip_remainders, q_rlc_sum: schzip_qrlc }; + let schzip = prepare_sz_commitment(ref curve, schzip_remainders, schzip_qrlc); // miller loop result schzip_miller( diff --git a/packages/bn254_u256_contract/src/lib.cairo b/packages/bn254_u256_contract/src/lib.cairo index a2906d3..f9f9046 100644 --- a/packages/bn254_u256_contract/src/lib.cairo +++ b/packages/bn254_u256_contract/src/lib.cairo @@ -1,5 +1,5 @@ pub use bn254_u256::{ - schzip_verify, PtG1, PtG2, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, bn254_curve, + schzip_verify, PtG1, PtG2, Fq, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, bn254_curve, LnArrays, InputConstraintPoints }; @@ -19,8 +19,8 @@ trait IBN_Pairing { residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - schzip_remainders: Array, - schzip_qrlc: Array, + schzip_remainders: Array, + schzip_qrlc: Array, ); } @@ -29,7 +29,7 @@ mod BN_Pairing { use super::{ schzip_verify, bn254_curve, { - PtG1, PtG2, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, LnArrays, + PtG1, PtG2, Fq, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, LnArrays, InputConstraintPoints } }; @@ -52,8 +52,8 @@ mod BN_Pairing { residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - schzip_remainders: Array, - schzip_qrlc: Array, + schzip_remainders: Array, + schzip_qrlc: Array, ) { let mut curve = bn254_curve(); schzip_verify( From b989c17b176c25cc42e1ce9c2174dada05c80b89 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 18 Jul 2024 14:11:30 +0530 Subject: [PATCH 64/97] use fq12 array for remainders --- .../src/pairing/schzip_miller.cairo | 25 ++++++++++++++----- packages/bn254_u256/src/pairing/utils.cairo | 4 +-- packages/bn254_u256_contract/src/lib.cairo | 4 +-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 57fb4d6..00c3ddd 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -16,6 +16,7 @@ use bn_ate_loop::{ate_miller_loop}; use pairing::{LineFn, StepLinesGet, LinesArrayGet}; use pairing::{PairingUtils, CubicScale}; use core::hash::HashStateTrait; +use core::poseidon::{PoseidonImpl, HashState}; use schwartz_zippel::SchZipSteps; @@ -62,6 +63,13 @@ fn schzip_miller< ate_miller_loop(ref curve, precomp, q_acc) } +fn hasher_fq2(ref hasher: HashState, a: Fq2) { + hasher = hasher.update(a.c0.c0.low.into()); + hasher = hasher.update(a.c0.c0.high.into()); + hasher = hasher.update(a.c1.c0.low.into()); + hasher = hasher.update(a.c1.c0.high.into()); +} + // Prepares SZ commitment // ---------------------- // Remainders Fiat Shamir is used for RLC (Random Linear Combination). @@ -74,16 +82,21 @@ fn schzip_miller< // So Any changes in the remainders will change the RLC and equation will not be satisfiable with any QRLC. // Fiat Shamir for the final Schwartz Zippel includes all remainders and QRLC for soundness. pub fn prepare_sz_commitment( - ref curve: Bn254U256Curve, remainders: Array, qrlc: Array, + ref curve: Bn254U256Curve, remainders: Array, qrlc: Array, ) -> SZCommitment { let mut rem_coeff_i = 0; - let mut hasher = core::poseidon::PoseidonImpl::new(); + let mut hasher = PoseidonImpl::new(); let rem_coeffs_count = remainders.len(); let rem_snap = @remainders; while rem_coeff_i != rem_coeffs_count { - let c = *(rem_snap[rem_coeff_i]); - hasher = hasher.update(c.c0.low.into()); - hasher = hasher.update(c.c0.high.into()); + let Fq12 { c0, c1 } = *(rem_snap[rem_coeff_i]); + + hasher_fq2(ref hasher, c0.c0); + hasher_fq2(ref hasher, c0.c1); + hasher_fq2(ref hasher, c0.c2); + hasher_fq2(ref hasher, c1.c0); + hasher_fq2(ref hasher, c1.c1); + hasher_fq2(ref hasher, c1.c2); rem_coeff_i += 1; }; let remainders_fiat_shamir: u256 = hasher.finalize().into(); @@ -135,7 +148,7 @@ pub fn schzip_verify( residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - schzip_remainders: Array, + schzip_remainders: Array, schzip_qrlc: Array, ) { let schzip = prepare_sz_commitment(ref curve, schzip_remainders, schzip_qrlc); diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 9d025ec..07552d8 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -4,9 +4,9 @@ use pairing::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; use bn254_u256::{Bn254U256Curve}; -#[derive(Drop)] +#[derive(Drop, Serde)] pub struct SZCommitment { - pub remainders: Array, + pub remainders: Array, pub qrlc: Array, pub rem_fiat_shamir_powers: Array, pub fiat_shamir_powers: Array, diff --git a/packages/bn254_u256_contract/src/lib.cairo b/packages/bn254_u256_contract/src/lib.cairo index f9f9046..bf73a62 100644 --- a/packages/bn254_u256_contract/src/lib.cairo +++ b/packages/bn254_u256_contract/src/lib.cairo @@ -19,7 +19,7 @@ trait IBN_Pairing { residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - schzip_remainders: Array, + schzip_remainders: Array, schzip_qrlc: Array, ); } @@ -52,7 +52,7 @@ mod BN_Pairing { residue_witness_inv: Fq12, cubic_scale: CubicScale, setup: Groth16Circuit, - schzip_remainders: Array, + schzip_remainders: Array, schzip_qrlc: Array, ) { let mut curve = bn254_curve(); From c66fae6eeb8be4f175cc8e1c459a371ac24b6bd1 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Fri, 19 Jul 2024 00:39:48 +0530 Subject: [PATCH 65/97] sz accumulator, p12 and minor utils --- packages/bn254_u256/src/lib.cairo | 2 +- .../src/pairing/schzip_miller.cairo | 59 +++++++++++-------- packages/bn254_u256/src/pairing/utils.cairo | 10 +++- packages/bn254_u256/src/utils.cairo | 4 ++ 4 files changed, 49 insertions(+), 26 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 71ea1af..1f4a60e 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -22,7 +22,7 @@ pub use fq_1::{ {U256IntoFq, FqPartialEq, Bn254FqOps, Bn254FqUtils}, {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, }; -pub use utils::{g1, g2, fq12, fq2}; +pub use utils::{g1, g2, fq12, fq2, fq}; pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3Gen; diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 00c3ddd..9f74783 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,8 +1,9 @@ use fq_types::FieldOps; use ec_groups::ECOperations; pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; +use bn254_u256::print::{FqDisplay}; use bn254_u256::{ - Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, + fq, Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ schzip_miller_runner::Miller_Bn254_U256, utils::{ @@ -36,6 +37,7 @@ fn schzip_miller< residue_witness_inv: Fq12, setup: Groth16Circuit, schzip: TSchZip, + schzip_acc: SZCommitmentAccumulator, ) -> SZAccumulator { // // Compute k from ic and public_inputs let Groth16Circuit { alpha_beta: _, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; @@ -57,7 +59,7 @@ fn schzip_miller< // miller accumulator let mut q_acc = SZAccumulator { - f: residue_witness_inv, g2: q, line_index: 0, schzip: (0, 0_u256.into()) + f: residue_witness_inv, g2: q, line_index: 0, schzip: schzip_acc }; ate_miller_loop(ref curve, precomp, q_acc) @@ -83,7 +85,7 @@ fn hasher_fq2(ref hasher: HashState, a: Fq2) { // Fiat Shamir for the final Schwartz Zippel includes all remainders and QRLC for soundness. pub fn prepare_sz_commitment( ref curve: Bn254U256Curve, remainders: Array, qrlc: Array, -) -> SZCommitment { +) -> (SZCommitment, SZCommitmentAccumulator) { let mut rem_coeff_i = 0; let mut hasher = PoseidonImpl::new(); let rem_coeffs_count = remainders.len(); @@ -99,7 +101,9 @@ pub fn prepare_sz_commitment( hasher_fq2(ref hasher, c1.c2); rem_coeff_i += 1; }; - let remainders_fiat_shamir: u256 = hasher.finalize().into(); + let remainders_fiat_shamir_felt = hasher.finalize(); + let remainders_fiat_shamir: u256 = remainders_fiat_shamir_felt.into(); + let mut qrlc_coeff_i = 0; let qrlc_count = qrlc.len(); @@ -112,28 +116,34 @@ pub fn prepare_sz_commitment( qrlc_coeff_i += 1; }; let fiat_shamir: u256 = hasher.finalize().into(); - - // @TODO - let p12_x = 1_u256.into(); - - SZCommitment { - remainders, - fiat_shamir_powers: fs_pow(ref curve, fiat_shamir, 40), - rem_fiat_shamir_powers: fs_pow(ref curve, remainders_fiat_shamir, 68), - p12_x, - qrlc - } + let fiat_shamir_powers = fs_pow(ref curve, fq(fiat_shamir), 40); + + // x^12 - 18x^6 + 82 + let _18x6 = curve.mul(fq(18), *fiat_shamir_powers[6]); // 18x^6 + let _x12_18x6 = curve.sub(*fiat_shamir_powers[12], _18x6); // x^12 - 18x^6 + let p12_x = curve.add(_x12_18x6, fq(82)); + + ( + SZCommitment { + remainders, + fiat_shamir_powers, + rem_fiat_shamir_powers: fs_pow(ref curve, fq(remainders_fiat_shamir), 68), + p12_x, + qrlc + }, + SZCommitmentAccumulator { index: 0, rhs_lhs: 0_u256.into(), rem_cache: 0_u256.into() } + ) } -pub fn fs_pow(ref curve: Bn254U256Curve, x: u256, powers: u32) -> Array { - let x_fq: Fq = x.into(); - let mut arr: Array = array![x_fq]; - let mut i = 0; - let powers = powers / 2 + 1; +pub fn fs_pow(ref curve: Bn254U256Curve, x: Fq, powers: u32) -> Array { + let mut arr: Array = array![0_u256.into(), x]; + let mut i = 1; + let powers = powers / 2; while i != powers { let even_power = curve.sqr(*arr[i]); arr.append(even_power); // even i * 2 power - arr.append(curve.mul(even_power, x_fq)); // odd i * 2 + 1 power + arr.append(curve.mul(even_power, x)); // odd i * 2 + 1 power + i += 1; }; arr } @@ -150,11 +160,12 @@ pub fn schzip_verify( setup: Groth16Circuit, schzip_remainders: Array, schzip_qrlc: Array, -) { - let schzip = prepare_sz_commitment(ref curve, schzip_remainders, schzip_qrlc); +) { // let p = fs_pow(ref curve, fq(2), 6); + // println!("{} {} {} {} {} {}", p[0], p[1], p[2], p[3], p[4], p[5]); + let (sz, sz_acc) = prepare_sz_commitment(ref curve, schzip_remainders, schzip_qrlc); // miller loop result schzip_miller( - ref curve, pi_a, pi_b, pi_c, inputs, residue_witness, residue_witness_inv, setup, schzip + ref curve, pi_a, pi_b, pi_c, inputs, residue_witness, residue_witness_inv, setup, sz, sz_acc ); } diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 07552d8..d271bc3 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -21,7 +21,15 @@ pub struct SZPreCompute { pub schzip: TCommitment, } -pub type SZCommitmentAccumulator = (u32, Fq); +#[derive(Drop, Serde)] +pub struct SZCommitmentAccumulator { + // index of equation (remainder) being processed, used for rlc + pub index: u32, + // accumulation of rhs and lhs to compare against qrlc + pub rhs_lhs: Fq, + // remainder cache for next equation + pub rem_cache: Fq, +} #[derive(Drop)] pub struct SZAccumulator { diff --git a/packages/bn254_u256/src/utils.cairo b/packages/bn254_u256/src/utils.cairo index 71a09d9..7975f11 100644 --- a/packages/bn254_u256/src/utils.cairo +++ b/packages/bn254_u256/src/utils.cairo @@ -29,6 +29,10 @@ pub fn fq12( } } +pub fn fq(c0: u256) -> Fq { + c0.into() +} + pub fn fq2(c0: u256, c1: u256) -> Fq2 { Fq2 { c0: c0.into(), c1: c1.into() } } From 6371b7e833de5cb94ee52dda9981352f7baaa5de Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 20 Jul 2024 17:51:11 +0530 Subject: [PATCH 66/97] allow fq12 direct in traits/impls --- packages/bn254_u256/src/lib.cairo | 8 +- .../src/pairing/schzip_miller.cairo | 7 +- .../src/pairing/schzip_miller_runner.cairo | 2 +- .../bn254_u256/src/pairing/schzip_steps.cairo | 74 +++++++++++++++---- packages/fq_types/src/lib.cairo | 6 +- packages/schwartz_zippel/src/lib.cairo | 23 +++--- 6 files changed, 87 insertions(+), 33 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 1f4a60e..456613f 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -16,7 +16,9 @@ mod tests { pub mod fixtures; } -use fq_types::{Fq2 as Fq2Gen, Fq3 as Fq3Gen, F12S034, fq3, Fq2PartialEq, Fq3PartialEq,}; +use fq_types::{ + Fq2 as Fq2Gen, Fq3, F12S034, Fq12Direct, Fq4Direct, fq3, Fq2PartialEq, Fq3PartialEq, +}; pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale}; pub use fq_1::{ {U256IntoFq, FqPartialEq, Bn254FqOps, Bn254FqUtils}, @@ -25,8 +27,10 @@ pub use fq_1::{ pub use utils::{g1, g2, fq12, fq2, fq}; pub type Fq2 = Fq2Gen; -pub type Fq6 = Fq3Gen; +pub type Fq6 = Fq3; pub type Fq12 = Fq2Gen; +pub type FqD12 = Fq12Direct; +pub type FqD4 = Fq4Direct; pub type F034 = F12S034; pub use pairing::{ diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 9f74783..6ab7ab3 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -3,7 +3,7 @@ use ec_groups::ECOperations; pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; use bn254_u256::print::{FqDisplay}; use bn254_u256::{ - fq, Fq, Fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, + fq, Fq, Fq2, Fq12, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ schzip_miller_runner::Miller_Bn254_U256, utils::{ @@ -26,7 +26,9 @@ type LnFn = LineFn; // Does the verification fn schzip_miller< - TSchZip, +SchZipSteps, +Drop + TSchZip, + +SchZipSteps, + +Drop >( ref curve: Bn254U256Curve, pi_a: PtG1, @@ -104,7 +106,6 @@ pub fn prepare_sz_commitment( let remainders_fiat_shamir_felt = hasher.finalize(); let remainders_fiat_shamir: u256 = remainders_fiat_shamir_felt.into(); - let mut qrlc_coeff_i = 0; let qrlc_count = qrlc.len(); let qrlc_snap = @qrlc; diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index acf46c7..f056de7 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -15,7 +15,7 @@ type PreCompute = SZPreCompute; // TODO: +SchZipSteps pub impl Miller_Bn254_U256< - TSchZip, +SchZipSteps + TSchZip, +SchZipSteps > of MillerRunner, Accumulator> { // first and second step, O and N fn miller_bit_1_2( diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index cb6e70c..d424389 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -1,39 +1,87 @@ -use bn254_u256::{Fq, Fq2, Fq12, Bn254U256Curve, SZCommitment, SZCommitmentAccumulator}; -use schwartz_zippel::{SchZipSteps, Lines, FS034, F034X2, LinesDbl, Residue}; +use bn254_u256::{ + Fq, Fq2, Fq3, Fq12, FqD12, FqD4, scale_9, Bn254U256Curve, Bn254FqOps, SZCommitment, + SZCommitmentAccumulator +}; +use schwartz_zippel::{SchZipSteps, SchZipEval, Lines, FS034, F034X2, LinesDbl, Residue}; type Curve = Bn254U256Curve; type SZCAcc = SZCommitmentAccumulator; -pub impl Bn254SchwartzZippelSteps of SchZipSteps { - fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12) {} - fn sz_sqr(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12) {} +pub impl Bn254SchwartzZippelSteps of SchZipSteps { + fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) {} + fn sz_sqr(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) {} fn sz_zero_bit( - ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12, lines: Lines + ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12, lines: Lines ) { let (_l1, _l2, _l3) = lines; + let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); } fn sz_nz_bit( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, - ref f: Fq12, + ref f: FqD12, lines: LinesDbl, - witness: Fq12 - ) {} + witness: FqD12 + ) { + let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); + let _wit_eval: Fq = self.eval_fq12(witness, sz.fiat_shamir_powers); + } fn sz_last_step( - ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: Fq12, lines: LinesDbl - ) {} + ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12, lines: LinesDbl + ) { + let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); + } fn sz_post_miller( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, - f: Fq12, - alpha_beta: Fq12, + f: FqD12, + alpha_beta: FqD12, residue: Residue ) -> bool { + let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); + let _albe_eval: Fq = self.eval_fq12(alpha_beta, sz.fiat_shamir_powers); false } } + +fn direct_fq12(ref curve: Curve, a: Fq12) -> FqD12 { + let Fq12 { // + c0: Fq3 { // + c0: Fq2 { c0: a0, c1: a1 }, // + c1: Fq2 { c0: a2, c1: a3 }, // + c2: Fq2 { c0: a4, c1: a5 } // + }, // + c1: Fq3 { // + c0: Fq2 { c0: a6, c1: a7 }, // + c1: Fq2 { c0: a8, c1: a9 }, // + c2: Fq2 { c0: a10, c1: a11 } // + } // + } = + a; + ( + ( + curve.sub(a0, scale_9(ref curve, a1)), + curve.sub(a6, scale_9(ref curve, a7)), + curve.sub(a2, scale_9(ref curve, a3)), + curve.sub(a8, scale_9(ref curve, a9)), + ), + (curve.sub(a4, scale_9(ref curve, a5)), curve.sub(a10, scale_9(ref curve, a11)), a1, a7,), + (a3, a9, a5, a11,) + ) +} + +fn direct_f034(ref curve: Curve, a: FS034) -> FqD4 { + let FS034:: { c3: Fq2 { c0: a6, c1: a7 }, c4: Fq2 { c0: a8, c1: a9 } } = a; + + ( + curve.sub(a6, scale_9(ref curve, a7)), // c1 + curve.sub(a8, scale_9(ref curve, a9)), // c3 + a7, // c7 + a9, // c9 + ) +} diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index 2ad5ba1..d8e850d 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -13,6 +13,9 @@ pub struct Fq3 { pub c2: T, } +pub type Fq6 = Fq3>; +pub type Fq12 = Fq2>; + pub fn fq2(c0: T, c1: T) -> Fq2 { Fq2 { c0, c1 } } @@ -71,7 +74,8 @@ pub trait FieldOpsExtended { fn to_fq(ref self: TCurve, lhs: TFqU512) -> TFq; } -pub type Fq12Direct = (T, T, T, T, T, T, T, T, T, T, T, T); +pub type Fq4Direct = (T, T, T, T); +pub type Fq12Direct = (Fq4Direct, Fq4Direct, Fq4Direct); pub type F12S01234Direct = ((T, T, T, T, T), (T, T, T, T, T)); pub use common::{Fq2Ops, Fq2PartialEq, Fq3Ops, Fq3PartialEq}; diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index 8f717a0..25fd225 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -1,4 +1,4 @@ -pub use fq_types::{Fq2, Fq3, F12S034 as FS034}; +pub use fq_types::{Fq2, Fq3, F12S034 as FS034, Fq12}; use pairing::CubicScale; pub type Lines = (FS034, FS034, FS034); @@ -6,33 +6,30 @@ pub type F034X2 = (FS034, FS034); pub type LinesDbl = (F034X2, F034X2, F034X2); pub type Residue = (CubicScale, Fq12, Fq12); -type Fq6 = Fq3>; -type Fq12 = Fq2>; - -pub trait SchZipSteps { - fn sz_init(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12); - fn sz_sqr(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12); +pub trait SchZipSteps { + fn sz_init(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12); + fn sz_sqr(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12); fn sz_zero_bit( - ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12, lines: Lines> + ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12, lines: Lines> ); fn sz_nz_bit( ref self: TCurve, sz: @T, ref sz_acc: TAcc, - ref f: Fq12, + ref f: TFq12, lines: LinesDbl>, - witness: Fq12 + witness: TFq12 ); fn sz_last_step( - ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: Fq12, lines: LinesDbl> + ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12, lines: LinesDbl> ); fn sz_post_miller( ref self: TCurve, sz: @T, ref sz_acc: TAcc, - f: Fq12, - alpha_beta: Fq12, + f: TFq12, + alpha_beta: TFq12, residue: Residue ) -> bool; } From fe96890a90eb89bdaa7384606fcc3e1cb56354fb Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sat, 20 Jul 2024 17:51:22 +0530 Subject: [PATCH 67/97] schwartz zippel eval --- packages/schwartz_zippel/src/eval.cairo | 90 +++++++++++++++++++++++++ packages/schwartz_zippel/src/lib.cairo | 2 + 2 files changed, 92 insertions(+) create mode 100644 packages/schwartz_zippel/src/eval.cairo diff --git a/packages/schwartz_zippel/src/eval.cairo b/packages/schwartz_zippel/src/eval.cairo new file mode 100644 index 0000000..9c86ed2 --- /dev/null +++ b/packages/schwartz_zippel/src/eval.cairo @@ -0,0 +1,90 @@ +pub use schwartz_zippel::{Fq12Direct, Fq4Direct}; +use fq_types::{FieldOps, FieldUtils}; + +pub trait SchZipEvalTrait { + fn eval_fq12(ref self: TCurve, a: Fq12Direct, fiat_shamir: @Array) -> TFq; + fn eval_f1379(ref self: TCurve, a: Fq4Direct, fiat_shamir: @Array) -> TFq; + fn eval_poly(ref self: TCurve, a: Array, fiat_shamir: @Array) -> TFq; +} +pub impl SchZipEval< + TCurve, + TFq, + +FieldOps, + +FieldUtils, + +Copy, + +Drop, + +Drop +> of SchZipEvalTrait { + fn eval_fq12(ref self: TCurve, a: Fq12Direct, fiat_shamir: @Array) -> TFq { + let ((a0, a1, a2, a3), (a4, a5, a6, a7), (a8, a9, a10, a11)) = a; + + // First term doesn't require multiplication + let mut acc = a0; + + // terms 1 to 11 + let term_1 = self.mul((*fiat_shamir[1]), a1); + let term_2 = self.mul((*fiat_shamir[2]), a2); + let term_3 = self.mul((*fiat_shamir[3]), a3); + let term_4 = self.mul((*fiat_shamir[4]), a4); + let term_5 = self.mul((*fiat_shamir[5]), a5); + let term_6 = self.mul((*fiat_shamir[6]), a6); + let term_7 = self.mul((*fiat_shamir[7]), a7); + let term_8 = self.mul((*fiat_shamir[8]), a8); + let term_9 = self.mul((*fiat_shamir[9]), a9); + let term_10 = self.mul((*fiat_shamir[10]), a10); + let term_11 = self.mul((*fiat_shamir[11]), a11); + + // accumulate terms 1 to 11 + acc = self.add(acc, term_1); + acc = self.add(acc, term_2); + acc = self.add(acc, term_3); + acc = self.add(acc, term_4); + acc = self.add(acc, term_5); + acc = self.add(acc, term_6); + acc = self.add(acc, term_7); + acc = self.add(acc, term_8); + acc = self.add(acc, term_9); + acc = self.add(acc, term_10); + acc = self.add(acc, term_11); + acc + } + + fn eval_f1379(ref self: TCurve, a: Fq4Direct, fiat_shamir: @Array) -> TFq { + let (a1, a3, a7, a9) = a; + + // First term is one, no multiplication required + let mut acc = self.one(); + + // terms 1, 3, 7 and 9 + let term_1 = self.mul((*fiat_shamir[1]), a1); + let term_3 = self.mul((*fiat_shamir[3]), a3); + let term_7 = self.mul((*fiat_shamir[7]), a7); + let term_9 = self.mul((*fiat_shamir[9]), a9); + + // accumulate terms 1, 3, 7 and 9 + acc = self.add(acc, term_1); + acc = self.add(acc, term_3); + acc = self.add(acc, term_7); + acc = self.add(acc, term_9); + + acc + } + + fn eval_poly(ref self: TCurve, a: Array, fiat_shamir: @Array) -> TFq { + let len = a.len(); + + if len == 0 { + return self.zero(); + } + + let mut i = 1; + let mut acc = *a[0]; + + while i != len { + let term = self.mul((*fiat_shamir[i]), *a[i]); + acc = self.add(acc, term); + i += 1; + }; + acc + } +} diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index 25fd225..f35941b 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -1,3 +1,5 @@ +pub mod eval; +pub use eval::{SchZipEvalTrait, SchZipEval}; pub use fq_types::{Fq2, Fq3, F12S034 as FS034, Fq12}; use pairing::CubicScale; From e2a6da37cd233f20a740ca0da65e6903fa209c98 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 21 Jul 2024 04:25:21 +0530 Subject: [PATCH 68/97] hashes in accumulator --- .gitignore | 1 + legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo | 5 +++-- legacy/bn_legacy/src/groth16/schzip/base.cairo | 4 ++-- legacy/bn_legacy/src/groth16/schzip/tests.cairo | 4 ++-- legacy/bn_legacy/src/groth16/schzip/utils.cairo | 2 ++ legacy/bn_legacy/src/groth16/schzip/v1.cairo | 4 +++- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index c4ec583..642b103 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ src/fields/fq_6_torus.cairo profile.pb.gz /bn_contracts scripts/__pycache__ +miller_steps.py diff --git a/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo b/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo index 81711b2..a100d35 100644 --- a/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo +++ b/legacy/bn_legacy/src/curve/pairing/optimal_ate_utils.cairo @@ -9,7 +9,7 @@ use bn::fields::{ Fq, fq, Fq2, fq2, Fq12, Fq12Utils, Fq12Ops, FqOps, Fq2Utils, Fq2Ops, Fq12Exponentiation, }; use bn::fields::{Fq12Sparse034, Fq12Sparse01234, FqSparse}; -use bn::fields::print::{Fq2Display, Fq12Display, FqDisplay}; +use bn::fields::print::{G2Display, G1Display, Fq2Display, Fq12Display, FqDisplay}; use bn::fields::frobenius::pi; // This implementation follows the paper at https://eprint.iacr.org/2022/1162 @@ -67,7 +67,8 @@ mod line_fn { use bn::fields::fq_generics::{TFqAdd, TFqSub, TFqMul, TFqDiv, TFqNeg, TFqPartialEq,}; use bn::fields::{Fq, fq, Fq2, fq2, FqOps, Fq2Utils, Fq2Ops}; use bn::fields::{Fq12Sparse034, Fq12Sparse01234, FqSparse}; - use bn::fields::print::{Fq2Display, Fq12Display, FqDisplay}; + use bn::fields::print::{G2Display, G1Display, Fq2Display, Fq12Display, FqDisplay}; + use bn::fields::frobenius::pi; use super::{LineFn, PPre, NZNum, F034}; diff --git a/legacy/bn_legacy/src/groth16/schzip/base.cairo b/legacy/bn_legacy/src/groth16/schzip/base.cairo index 3c5c117..cc40924 100644 --- a/legacy/bn_legacy/src/groth16/schzip/base.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/base.cairo @@ -33,10 +33,10 @@ use bn::groth16::utils::{ICProcess, G16CircuitSetup, Groth16MillerG1, Groth16Mil use bn::groth16::utils::{StepLinesGet, StepLinesTrait}; use bn::groth16::utils_line::LineResult01234Trait; - #[derive(Drop)] pub struct SchZipMock { print: bool, + f01234: bool, } pub impl SchZipMockSteps of SchZipSteps { @@ -284,7 +284,7 @@ fn schzip_miller< }; // q points accumulator - let mut q_acc = SchZipAccumulator { g2: q, coeff_i: 0 }; + let mut q_acc = SchZipAccumulator { g2: q, coeff_i: 0, rem_hash: PoseidonImpl::new() }; // let miller_loop_result = precomp.miller_first_second(64, 65, ref acc); let (precomp, mut miller_loop_result) = ate_miller_loop_steps_first_half(precomp, ref q_acc); diff --git a/legacy/bn_legacy/src/groth16/schzip/tests.cairo b/legacy/bn_legacy/src/groth16/schzip/tests.cairo index f9262a7..0e5416a 100644 --- a/legacy/bn_legacy/src/groth16/schzip/tests.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/tests.cairo @@ -17,7 +17,7 @@ use core::hash::HashStateTrait; #[test] #[available_gas(20000000000)] -fn verify() { +fn verify_print() { // Verification key parameters // let (_, _, gamma, delta, albe_miller, mut ic) = vk(); let circuit_setup: G16CircuitSetup = fixture::circuit_setup(); @@ -36,7 +36,7 @@ fn verify() { residue_witness_inv, cubic_pow, circuit_setup, - SchZipMock { print: false }, + SchZipMock { print: true, f01234: false }, get_field_nz() ); diff --git a/legacy/bn_legacy/src/groth16/schzip/utils.cairo b/legacy/bn_legacy/src/groth16/schzip/utils.cairo index 7c1ceb1..2590bc0 100644 --- a/legacy/bn_legacy/src/groth16/schzip/utils.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/utils.cairo @@ -2,6 +2,7 @@ use bn::curve::residue_witness::{CubicScale}; use bn::groth16::utils::{ICProcess,}; use bn::groth16::utils::{Groth16MillerG1, Groth16MillerG2, PPrecomputeX3}; +use core::poseidon::{PoseidonImpl, HashState}; // Fields use bn::fields::{fq12, Fq12, FS034}; @@ -123,6 +124,7 @@ pub fn powers_51(x: u256, field_nz: NonZero) -> Array { pub struct SchZipAccumulator { g2: Groth16MillerG2, coeff_i: u32, + rem_hash: HashState, } #[derive(Copy, Drop)] diff --git a/legacy/bn_legacy/src/groth16/schzip/v1.cairo b/legacy/bn_legacy/src/groth16/schzip/v1.cairo index 126951c..e87e9b9 100644 --- a/legacy/bn_legacy/src/groth16/schzip/v1.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/v1.cairo @@ -23,6 +23,7 @@ use bn::curve::{UAddSubTrait, U512BnAdd, U512BnSub, u512, U512Ops}; use bn::g::{AffineG1, AffineG2,}; use bn::traits::{MillerPrecompute, MillerSteps}; use core::hash::HashStateTrait; +use core::poseidon::{PoseidonImpl, HashState}; // Groth16 utils use residue_witness::{ROOT_27TH_DIRECT, ROOT_27TH_SQ_DIRECT, CubicScale}; @@ -317,6 +318,7 @@ pub impl SchZipPolyCommitImpl of SchZipSteps { residue: Fq12, residue_inv: Fq12, cubic_scale: CubicScale, + hasher: HashState, f_nz: NonZero ) -> bool { // Verify residue witness and it's inverse @@ -352,7 +354,7 @@ pub fn schzip_verify_with_commitments, +Drop, ) -> bool { let mut coeff_i = 0; - let mut hasher = core::poseidon::PoseidonImpl::new(); + let mut hasher = PoseidonImpl::new(); let coeffs = @coefficients; let coeffs_count = coeffs.len(); while coeff_i != coeffs_count { From f4c0bb31765a42679fb65247f44afbf8250a4ea5 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 21 Jul 2024 04:25:49 +0530 Subject: [PATCH 69/97] hasher for remainders --- .../bn_legacy/src/groth16/schzip/base.cairo | 92 +++++++++++++++---- .../bn_legacy/src/groth16/schzip/utils.cairo | 1 + 2 files changed, 76 insertions(+), 17 deletions(-) diff --git a/legacy/bn_legacy/src/groth16/schzip/base.cairo b/legacy/bn_legacy/src/groth16/schzip/base.cairo index cc40924..067f2a8 100644 --- a/legacy/bn_legacy/src/groth16/schzip/base.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/base.cairo @@ -11,6 +11,8 @@ use bn::fields::fq_12_exponentiation::PairingExponentiationTrait; use bn::fields::print::{ FqDisplay, Fq2Display, Fq12Display, Fq6Display, F034Display, F01234Display, G2Display, G1Display }; +use core::poseidon::{PoseidonImpl, HashState}; +use core::hash::HashStateTrait; // Field direct use fq_12_direct::{FS034Direct, Fq12DirectIntoFq12, Fq12IntoFq12Direct, Fq12Direct}; @@ -39,12 +41,32 @@ pub struct SchZipMock { f01234: bool, } +fn fq2_hash(a: Fq, b: Fq, ref hasher: HashState) { + hasher = hasher.update(a.c0.low.into()); + hasher = hasher.update(a.c0.high.into()); + hasher = hasher.update(b.c0.low.into()); + hasher = hasher.update(b.c0.high.into()); +} + +fn remainder_hash(remainder: Fq12, ref hasher: HashState) { + let r_tup = tower_to_direct(remainder); + // deconstruct a tuple containing 12 field elements + let (r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11) = r_tup; + fq2_hash(r0, r1, ref hasher); + fq2_hash(r2, r3, ref hasher); + fq2_hash(r4, r5, ref hasher); + fq2_hash(r6, r7, ref hasher); + fq2_hash(r8, r9, ref hasher); + fq2_hash(r10, r11, ref hasher); +} + pub impl SchZipMockSteps of SchZipSteps { #[inline(always)] fn sz_init(self: @SchZipMock, ref f: Fq12, f_nz: NonZero) { if *self.print { + println!("from schzip_runner import fq12, f034, fq6, sz_print, sz_inv_verify",); println!( - "from schzip_runner import fq12, f01234, f034, sz_zero_bit, sz_nz_bit, sz_last_step" + "from schzip_runner import sz_zero_bit, sz_nz_bit, sz_last_step, sz_post_miller" ); } } @@ -58,7 +80,11 @@ pub impl SchZipMockSteps of SchZipSteps { let (l1, l2, l3) = lines; let l1_l2 = l1.mul_034_by_034(l2, f_nz); if *self.print { - println!("sz_zero_bit(\n{}\n{}\n{}\n)", f, l1_l2, l3); + if *self.f01234 { + println!("sz_zero_bit(\n{}\n{}\n{}\n)", f, l1_l2, l3); + } else { + println!("sz_zero_bit(\n{}\n{}\n{}\n{}\n)", f, l1, l2, l3); + } } f = f.sqr(); f = f.mul(l1_l2.mul_01234_034(l3, f_nz)); @@ -74,11 +100,26 @@ pub impl SchZipMockSteps of SchZipSteps { f_nz: NonZero ) { let (l1, l2, l3) = lines; + let ((l10, l11), (l20, l21), (l30, l31)) = lines; let l1 = l1.as_01234(f_nz); let l2 = l2.as_01234(f_nz); let l3 = l3.as_01234(f_nz); if *self.print { - println!("sz_nz_bit(\n{}\n{}\n{}\n{}\n{}\n)", f, l1, l2, l3, witness); + if *self.f01234 { + println!("sz_nz_bit(\n{}\n{}\n{}\n{}\n{}\n)", f, l1, l2, l3, witness); + } else { + println!( + "sz_nz_bit(\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n)", + f, + l10, + l11, + l20, + l21, + l30, + l31, + witness + ); + } } f = f.sqr(); f = f.mul_01234(l1, f_nz); @@ -92,13 +133,21 @@ pub impl SchZipMockSteps of SchZipSteps { self: @SchZipMock, ref f: Fq12, ref i: u32, lines: LinesDbl, f_nz: NonZero ) { let (l1, l2, l3) = lines; + let ((l10, l11), (l20, l21), (l30, l31)) = lines; let l1 = l1.as_01234(f_nz); let l2 = l2.as_01234(f_nz); let l3 = l3.as_01234(f_nz); if *self.print { - println!("sz_last_step(\n{}\n{}\n{}\n{}\n)", f, l1, l2, l3); + if *self.f01234 { + println!("sz_last_step(\n{}\n{}\n{}\n{}\n)", f, l1, l2, l3); + } else { + println!( + "sz_last_step(\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n)", f, l10, l11, l20, l21, l30, l31 + ); + } } + f = f.mul_01234(l1, f_nz); f = f.mul_01234(l2, f_nz); f = f.mul_01234(l3, f_nz); @@ -112,6 +161,7 @@ pub impl SchZipMockSteps of SchZipSteps { residue: Fq12, residue_inv: Fq12, cubic_scale: CubicScale, + mut hasher: HashState, f_nz: NonZero ) -> bool { let one = Fq12Utils::one(); @@ -124,8 +174,15 @@ pub impl SchZipMockSteps of SchZipSteps { CubicScale::Two => (mul_by_root_27th_sq(f, f_nz), ROOT_27TH_SQ), }; + // Finishing up `q - q**2 + q**3` of `6 * x + 2 + q - q**2 + q**3` + // result * residue^q * (1/residue)^(q**2) * residue^q**3 + let result = result + * alpha_beta + * residue_inv.frob1() + * residue.frob2() + * residue_inv.frob3(); + if *self.print { - println!("sz_residue_inv_verify(\n{}\n{}\n)", residue_inv, residue,); println!( "sz_post_miller(\n{}\n{}\n{}\n{}\n{}\n{}\n)", f, @@ -135,16 +192,14 @@ pub impl SchZipMockSteps of SchZipSteps { residue.frob2(), residue_inv.frob3() ); - println!("sz_print_coeffs()"); - } + remainder_hash(result, ref hasher); + println!("sz_inv_verify(\n{}\n{}\n)", residue_inv, residue,); + remainder_hash(FieldUtils::one(), ref hasher); - // Finishing up `q - q**2 + q**3` of `6 * x + 2 + q - q**2 + q**3` - // result * residue^q * (1/residue)^(q**2) * residue^q**3 - let result = result - * alpha_beta - * residue_inv.frob1() - * residue.frob2() - * residue_inv.frob3(); + let remainder_hash = hasher.finalize(); + + println!("sz_finalize({})", remainder_hash); + } // return result == 1 result == one @@ -167,6 +222,7 @@ pub impl Groth16MillerSteps< self: @SchzipPreCompute, i1: u32, i2: u32, ref acc: SchZipAccumulator ) -> Fq12 { // let mut f = *self.residue_witness_inv; + self.schzip.sz_init(ref f, *self.field_nz); self.sqr_target(i1, ref acc, ref f); @@ -178,7 +234,6 @@ pub impl Groth16MillerSteps< // step -1, the next negative one step self.miller_bit_n(i2, ref acc, ref f); - f } @@ -192,8 +247,7 @@ pub impl Groth16MillerSteps< let l1 = step_double(ref acc.g2.pi_b, pi_a_ppc, *self.p.pi_a, f_nz); let (l2, l3) = self.lines.with_fxd_pt_line(self.ppc, ref acc.g2, i, f_nz); self.schzip.sz_zero_bit(ref f, ref acc.coeff_i, (l1, l2, l3), f_nz); - // println!("o_bit {i}: {}", f); - // println!("o_bit direct {i}: {}", tower_to_direct(f)); + remainder_hash(f, ref acc.rem_hash); } // 1 bit @@ -209,6 +263,7 @@ pub impl Groth16MillerSteps< self .schzip .sz_nz_bit(ref f, ref acc.coeff_i, (l1, l2, l3), *self.residue_witness_inv, f_nz); + remainder_hash(f, ref acc.rem_hash); } // -1 bit @@ -223,6 +278,7 @@ pub impl Groth16MillerSteps< let l1 = step_dbl_add(ref acc.g2.pi_b, pi_a_ppc, *self.p.pi_a, *pi_b, f_nz); let (l2, l3) = self.lines.with_fxd_pt_lines(self.ppc, ref acc.g2, i, f_nz); self.schzip.sz_nz_bit(ref f, ref acc.coeff_i, (l1, l2, l3), *self.residue_witness, f_nz); + remainder_hash(f, ref acc.rem_hash); // println!("n_bit {i}: {}", f); // println!("n_bit direct {i}: {}", tower_to_direct(f)); } @@ -237,6 +293,7 @@ pub impl Groth16MillerSteps< let l1 = correction_step(ref acc.g2.pi_b, pi_a_ppc, *self.p.pi_a, *self.q.pi_b, f_nz); let (l2, l3) = self.lines.with_fxd_pt_lines(self.ppc, ref acc.g2, 'last', f_nz); self.schzip.sz_last_step(ref f, ref acc.coeff_i, (l1, l2, l3), f_nz); + remainder_hash(f, ref acc.rem_hash); } } @@ -325,6 +382,7 @@ pub fn schzip_base_verify< residue_witness, residue_witness_inv, cubic_scale, + acc.rem_hash, field_nz ) } diff --git a/legacy/bn_legacy/src/groth16/schzip/utils.cairo b/legacy/bn_legacy/src/groth16/schzip/utils.cairo index 2590bc0..8285e2f 100644 --- a/legacy/bn_legacy/src/groth16/schzip/utils.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/utils.cairo @@ -157,6 +157,7 @@ pub trait SchZipSteps { residue: Fq12, residue_inv: Fq12, cubic_scale: CubicScale, + hasher: HashState, f_nz: NonZero ) -> bool; } From 75215a020c850be76b4e28d3841de7b890d76b6b Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 21 Jul 2024 04:27:27 +0530 Subject: [PATCH 70/97] fqd12: direct fq 12 extension --- packages/bn254_u256/src/lib.cairo | 2 +- packages/bn254_u256/src/pairing/utils.cairo | 12 +++++++---- packages/bn254_u256/src/print.cairo | 24 ++++++++++++++++++++- packages/schwartz_zippel/src/eval.cairo | 2 +- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 456613f..8e7f78a 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -24,7 +24,7 @@ pub use fq_1::{ {U256IntoFq, FqPartialEq, Bn254FqOps, Bn254FqUtils}, {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, }; -pub use utils::{g1, g2, fq12, fq2, fq}; +pub use utils::{g1, g2, fqd12, fq12, fq2, fq}; pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3; diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index d271bc3..8534618 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -1,12 +1,12 @@ use ec_groups::ECOperations; use pairing::{LineFn, LinesArrays, LinesArrayGet}; use pairing::{PPrecompute, Groth16PreCompute, Groth16MillerG1, Groth16MillerG2}; -use bn254_u256::{Fq, Fq2, Fq12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; +use bn254_u256::{Fq, Fq2, Fq12, FqD12, Bn254FqOps, PtG1, PtG2, AffineOpsBn}; use bn254_u256::{Bn254U256Curve}; #[derive(Drop, Serde)] pub struct SZCommitment { - pub remainders: Array, + pub remainders: Array, pub qrlc: Array, pub rem_fiat_shamir_powers: Array, pub fiat_shamir_powers: Array, @@ -16,7 +16,11 @@ pub struct SZCommitment { #[derive(Drop)] pub struct SZPreCompute { pub g16: Groth16PreCompute< - Groth16MillerG1, Groth16MillerG1>, Groth16MillerG2, TLines, Fq12 + Groth16MillerG1, + Groth16MillerG1>, + Groth16MillerG2, + TLines, + FqD12 >, pub schzip: TCommitment, } @@ -33,7 +37,7 @@ pub struct SZCommitmentAccumulator { #[derive(Drop)] pub struct SZAccumulator { - pub f: Fq12, + pub f: FqD12, pub g2: Groth16MillerG2, pub line_index: u32, pub schzip: SZCommitmentAccumulator, diff --git a/packages/bn254_u256/src/print.cairo b/packages/bn254_u256/src/print.cairo index 37d8320..04c7e3d 100644 --- a/packages/bn254_u256/src/print.cairo +++ b/packages/bn254_u256/src/print.cairo @@ -1,4 +1,4 @@ -use bn254_u256::{Fq, Fq2, Fq12, F034, PtG1, PtG2}; +use bn254_u256::{Fq, Fq2, Fq12, FqD12, F034, PtG1, PtG2}; use core::to_byte_array::AppendFormattedToByteArray; use core::fmt::{Display, Formatter, Error}; @@ -29,6 +29,28 @@ pub impl Fq12Display of core::fmt::Display { } } +pub impl FqD12Display of core::fmt::Display { + fn fmt(self: @FqD12, ref f: Formatter) -> Result<(), Error> { + let ((r0, r1, r2, r3), (r4, r5, r6, r7), (r8, r9, r10, r11)) = self; + write!( + f, + "fq12({},{},{},{},{},{},{},{},{},{},{},{}\n),", + *r0, + *r1, + *r2, + *r3, + *r4, + *r5, + *r6, + *r7, + *r8, + *r9, + *r10, + *r11, + ) + } +} + pub impl FqDisplay of core::fmt::Display { fn fmt(self: @Fq, ref f: Formatter) -> Result<(), Error> { let base = 16_u256; diff --git a/packages/schwartz_zippel/src/eval.cairo b/packages/schwartz_zippel/src/eval.cairo index 9c86ed2..f1db322 100644 --- a/packages/schwartz_zippel/src/eval.cairo +++ b/packages/schwartz_zippel/src/eval.cairo @@ -1,4 +1,4 @@ -pub use schwartz_zippel::{Fq12Direct, Fq4Direct}; +pub use fq_types::{Fq12Direct, Fq4Direct}; use fq_types::{FieldOps, FieldUtils}; pub trait SchZipEvalTrait { From 118d40784025bee65b3720b92ed6c7a60925e3d2 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 21 Jul 2024 04:27:54 +0530 Subject: [PATCH 71/97] schzip fixtures --- packages/bn254_u256/src/tests/fixtures.cairo | 2 + .../src/tests/fixtures/schzip_fix.cairo | 1015 +++++++++++++++++ 2 files changed, 1017 insertions(+) create mode 100644 packages/bn254_u256/src/tests/fixtures/schzip_fix.cairo diff --git a/packages/bn254_u256/src/tests/fixtures.cairo b/packages/bn254_u256/src/tests/fixtures.cairo index e89b3db..dccd8b7 100644 --- a/packages/bn254_u256/src/tests/fixtures.cairo +++ b/packages/bn254_u256/src/tests/fixtures.cairo @@ -1,3 +1,5 @@ pub mod lines_fix; pub mod proof_fix; +pub mod schzip_fix; pub use proof_fix::{circuit_setup, residue_witness, proof}; +pub use schzip_fix::{schzip}; diff --git a/packages/bn254_u256/src/tests/fixtures/schzip_fix.cairo b/packages/bn254_u256/src/tests/fixtures/schzip_fix.cairo new file mode 100644 index 0000000..eaac09b --- /dev/null +++ b/packages/bn254_u256/src/tests/fixtures/schzip_fix.cairo @@ -0,0 +1,1015 @@ +use bn254_u256::{Fq, FqD12, fq, fqd12, g1, g2}; + +pub fn schzip() -> (Array, Array) { + // remainders: 68 + // remainders hash: 857849275211174718759342352757723903671239889747597921306912679690827306109 + // quotients: 68 + ( + array![ + fqd12( + 0x18412d9d03395e063a0e55dded4a5bd7033cefbe0edd137c2d3927dfe31eb0f0, + 0x13a290cb5759d074a4b1d2349c8747372aa718324b8faf4cba1f4a6df7edc263, + 0xcfa66eb69b176509f808dc7970428b08f27d9f8bb837bdcc217249700217ab0, + 0x44687a879e5d5a1ac5c5d5515fbcc2db31d412f71a28598f35038017435b700, + 0x5242ad8d4547cf359842d06ec7c90e5b55e84f577e39a3af99978233297782, + 0x136c82f404389fe88a248247bc62645520654e51a49f14633c8299e7f4d59dfb, + 0x1ad3085832f02db30dad3a38cf967c8948fabf90895bf5d0a407d0aa584bd32e, + 0x7a161d713740c29cb8751dfdb0356b683840f804c630e626286c406e7fdcf3d, + 0x566102cdb5869b6f0b0c3342806346613fac9cce8b781a7307cdb9e672f312a, + 0x83a69098de2b18eed6bd8eacbe4643ef5992e7c106e160425be05e9d27c91e5, + 0x11a1a49c01d86eeab6189b48bfbd9d9265e6a00c3c426fbcd88394692cbbb70c, + 0x2281f657560c385b4b012bc66c195b4ee12e7ead34af187701a56a60b1810bde, + ), + fqd12( + 0xf64805337824e3fe26eab89b5ca4529cdc780dfa1a0ec7042aa4144a28b8a2, + 0x210675164a6dae60a813cce9a9db946f14879ad36b1ac8ed12af07f634576152, + 0x24efa636c94a27b310f22d272c8c462c20ad249636ded4e0df9a501500d87e69, + 0x2b22f7843667129e82161786cf31fc5e4019306bfff86b37b40cfc5135cf206a, + 0x19269751183be7eae7f6d0cf6074df1bcb1297990586f2c03a4a1649d07c943d, + 0x29b071182063d8d9c1e33f221480b05b1e054a19d52aba10e8eb8b8920a02cda, + 0xdb072f0bd5b4f19fee9f161789550f5e67742d736c0cd42564cd43c4c0fc072, + 0x24dcef9c675a40f91dc402da0d79bfd2751ab708e86bc0917e30574d827ec80, + 0x11894f9cea1e134afd42cc1b191930fb115e4d43242530e51dbeab2be1713bb8, + 0x2c886edae25d33313b622c97379ffe6e02c707a0aa354d0e92849bf5c043a7cd, + 0x57c2abb0843c42d30ab938b0a9a8f7c60d03f07d70ca255d346aaa566dc4726, + 0x22bd6e03c2f4ee6476ba66c28d2cdbe7c66d404b6c36eaac33c274c0b34ff049, + ), + fqd12( + 0x17e97724a161bb2d24426bdc542fade7404d3e7708b01ff4f8943c45b4794f62, + 0x2631aa8696819436f11edabdf7ac0bf6369984c47ffbb8009bb3e2c48db9136b, + 0x2af77509a6a410c65dd5f7644bf8451997340e0adb0373785b6e32f6c493e7ea, + 0x5dc725b793314c41f18e09500523e67f0af6dd6b91d284fb46b60a0c35d980a, + 0x43ccc8c0f06a529580f4119891e6d5c6f01c3cc6dec72162b308fe84f357873, + 0xfc2a74d2ca57251069e0962294ba767fd1a8cca71ba087f728078922f284f1b, + 0x28386356f2bb4c5986e19190a0b002905bed2ac41cc3a9d9d645ad85539772fd, + 0x118d61510c32d35245246cbf126130f00a55e766f797a6cd7d5ccbc93e8501df, + 0xd7112f3f96f7810ffcc733864d0ebbb7710e8969176b46fca63a2970a7372, + 0x27eabb6f55c1f8308d6b4182c0565b45c695179d8c89dbf62ce027363f0855fe, + 0x1a6341909dead8722cd655f7eae0ceb47032fccdc1712a8ab0604d0adf439f2e, + 0x232cd82ba0f9a834667402e00ffa6b91fe88a5eb48655a83fd3ad1c11434cd8b, + ), + fqd12( + 0x16402a868d0f9eb9aebafac3b97cfec61fdbf80789a24f05753af2ea06bba1ba, + 0x14940c7fb482946aba5460b1fe8d83524f90f71d1bfd3448599b638beda73896, + 0x2101a8831a9f6639f7a7565f4fb3a3acd16db8f06259c47464325db597e79c0a, + 0x25eb879141d2949f94d46c3c4a8101b41fb0fcd97fb1bc76ee93d81d5953bef0, + 0x2e2f6f93ec4e118b4a217f1be439ad9ef70c9e27e1255c6c1081363a94daf5b9, + 0x1adbd4ea182cb2cbcc5c5a66c3cd5fe51a3e4dbb85fe73ae4a28885598493ca4, + 0xc9f88b839c7de546c789553ba9a68491f8efddb6d7a527c4675bba3861fda56, + 0x4b2d644c1b488713cb5e1eeb47beb9fceecdcb81e6d25843c14fa2b5b0cf317, + 0x1c48ae8b00bacb3bea6e05b94c73f19179703870c536346ce9e4c90a2b67e7ce, + 0x28562afbf1ab2ac4dba510047b998c5b6506b8c17aafc70fc673027540212f4c, + 0x2c12e103f4ca37f7bfac70a8460f56598c3999ec484de8c6f6e822476f3ccfc9, + 0x1850b167f0937f142b501528c84bcc44e96910599018029a02af5c3a1c2557e5, + ), + fqd12( + 0x99402343edaf77e95ac08d91b07201ea2cd61ff1953621483797b5c2bbd2b1, + 0x1e5e2741f733f2745fc885d124b1d66d0e4a1df3c24b5bfe5f821f7ca7c21314, + 0x1d1aaac339e2ac8238c19b354623f75402e9c8a05515a58f954030d613e24489, + 0x222ce108aa69c008eaa060587b17539de82c6f1fb42a10ed25c70fa34c193ae9, + 0x2147e8bd29586bcb2500d089dab6b28aa2227efd90a8237b4105cf5ae1ce4a1b, + 0x1b36f4f8751a80c61cd6180ab7a27fb34e9b79dbcb11682d33dca38fb6c0ebe0, + 0x2090b40b8fb7885f278dd753410811e369fcd7b71250bc72505bdc9a1a139514, + 0x1d3f2f995fea435beafe3196374009e3b405d91f095e030838cfe5512715e56c, + 0xefbbe11b7bf5b7e0d75730dd421c9149f3160fd19f7a7864353ad54d9a1125c, + 0x1e6e6194a4b964aa2b4f0dc0e5b64d6af660470d8aca71df067490a1b1eab165, + 0x2d6f09187ab1cbd37431c02afaf9a84a47f78ffa0541ce4165b3992343f56693, + 0x27a99ad2605da5bdff9337ab5c4bcb8256defc5ba2cac57d394f694b97098da0, + ), + fqd12( + 0x657e42f5f5b8b223c7b0f5adf474ffe0d289e1becf960c2431091993e635886, + 0x2bf100dcce0ceaa7edc673816f828da2dd5a7cee75d116108ff594122cde8c03, + 0xaa4d4b483b351b761805cdd0029711a4d6a7bb5263c226ab21c8348d983464, + 0xe2a026ab227a0d09fd367b9ae108f047c4df0e7c6b5662dee435b9482051437, + 0x20fcb9102d6bdac328e93101c7fae56ff9aab7c7fdfcc9b309b8e7e137908c65, + 0xa55b59504cb1288a5a68d56953581c3c92421bfaef3b085ab3e0ba0780b9322, + 0x231efd9c8c610da016795aa966a226230d06208e5a8925d3ef51876084af1234, + 0x208b48cb1e1e7c1148a91ebeed6e546803a2f936f19e4fc3916c921b89bb1d97, + 0x1deb79bdb1ac608ba40a9af9618a6562970a107c3cd6fbcfad1f70bac45a7f9c, + 0x1323833fbe11f78b26bb6241c225e8f777f283fc294715aa8ed6eaa4f5d71442, + 0x1c904803d1b3fe92b5b89d85edba3dc9d409900e65fd558a69b6777f8a3a992e, + 0x2a632c21b06ee37511b98d88758fe1e6abff7083be6feaf89b4c909f918155d6, + ), + fqd12( + 0x1476d039cab2642d13ff28aebb3bd43c4e12cc1a70bbc0e313e91e9baf2afeaf, + 0xfa34b6a75ded40c5bd079ebf31e3c03be20a845ecc8f745bb905d89be4e3a1b, + 0x1cc8a84c41f0c29047834449e7f97b74998637b7dff2cefaf72798dfd519f267, + 0x24a457223c3d8b0bba70b4a707ab2fb66c6dc07eddca73f94014bda45518b095, + 0x1328eaa010c237190c8df96fb68723a151124d56f952c96de8dc0407562b5486, + 0x2215eb9e75267e01cf4c12eb6fae6a6a39baf04a83e1fb4c66eb8a59090dbb2a, + 0x1bb5438040dfd1a108507b2b007be615223649e3ebd31eb411b05a259275d7f3, + 0x79385e8dbdc12322dff8dca7824f759d84e6834d2304f6cf70a6f55db490618, + 0x2ac4bb1c128afa199881b882a7ef2d7cc62c9df527f5a8b48efa215e28dbdef2, + 0x1f6d6758453178ffdc7905a34c26053d8a0f6b5b0d062ac7566608e26e6969fe, + 0x235e95ac724f6b8ea90a1a42144e97b1a0d3e891239eb102b7315afda60a3560, + 0x24bc2efb0cf42b6d417e3f765d18c78edc4f1749c53ac51af5c8da9f88c5e406, + ), + fqd12( + 0xa87414057fce550c7b074c8c6e3994e46f682af942e958f3a2c0fecf30497ce, + 0xa0c488922aacc57a9cffe77e1686622ade6a7b13e1e8ba752b5ca833f892dd, + 0x18ca6ad3e93b1c20ed8a777246d8655aa0dc2f247a98f8e4879f543699aa1888, + 0x27673aff3570be67389f62a314dd8649c8077f4cbac8907c4de6a4cb0ae42454, + 0x1555c68d78cc9ac88e9fe2650322c87c6e589f9134db4f3927bc4b1e643f540f, + 0x5060c35cdfa759dccf18ac748faafb4b38fdb13b70b3f84ac6d29058f75daa0, + 0x94e86a2bf164595e4eb727aded4e37fbc98c4e6cc2a6416c625810e991c4a8, + 0x2aa384e5c560d2fff76a4e8af75d84acd8a324cf48acdb37fd0ea071311035d, + 0x25a4b1822393d09ec2cc7ce11dae1d749dfe32c960798bbb6a19b4e051c5ea36, + 0x275edd20342af5ae780bec2520b71161f225672f615a4920a4c438cf2513a20a, + 0x1741727bcd5964a9d3e9bb4347e983231cb1710eecfe7021fbf4a1e631a35f40, + 0x64dbd7c1f98b2cdf50fd8ec1c1a37496900fbf2ab5c25af5b846a4c4acff219, + ), + fqd12( + 0x1f081f1795e51cb1325792d01321646299db9734b25648a4f896f129378fe860, + 0x2054367c4420fa1f0ff2022eefb537c02aadf84cbfc5d0e78da469b3a341e45e, + 0x1005d508dfdb3284dc2eeb3b2ff4b8b91fc160a04960c5a9c8b71c9b09233cee, + 0x1566de5fec56a2686f262a2bc55b7b6634fec283d5008fb619ac0a6d223c0ebf, + 0xac8226d37f66597e601cc137a8f112e3b8114bee20dd688e4b12eff38e7fc73, + 0x5c08f23f75ee1be3284cff5ab5239a65214072c6d46113f60156e803c1f7124, + 0x17107fca320cd51aaf0c4dd0d70497dc80b330d4c0c8ecb19d0db63f8ad50889, + 0x1bbe1330dd1c1e0bdeb25679df26ce070aa3262e65bd39cbcf9396b6464b4783, + 0x37c47d2594fe6beb2f29657831a05be7fee94e503b3658273d37e84fbdd382f, + 0x1d7bb3affc3c9fa89fac2170111287b9f9e5643088defc502c36852cbc90ec49, + 0x1de2adee8a5a9192ee1ead9abcb02482241ab23af9f19ccb5eef633ef45c219d, + 0x900810ed49a8adc7b5b8d39f3b2f6822634ee8fc65b174e46d6253e74f551e3, + ), + fqd12( + 0xcb9e8a85fa2397c21d6b208c33ac58e4390ef227402da091d2659338c0d3013, + 0x2f430e17589708ae17d80670aaa3e5d557b81ee2de5ea87d486767cf068d6f6e, + 0x18da3d910f2be5be217d02f785fda35601135bde34dd14fa0195942b169abfa3, + 0x2f802538bc86262e6841c7711c4da94b3ff145c36c4afc52f393f2a21049a128, + 0x17d5a9097852571570c339499f515bcceef60600b9011fdbf02810a26d75f61f, + 0xc936a366ecaf8b59228c40f4e042c30a441978a50da74abac1709304ff7b069, + 0x2574f912e3d81523dc18b626074d7017745815457ea9fe8623e82e18283335a4, + 0x36508930b11cf2d392ddcd7aeca75ae0dd9e16db12d7f90acee0a5ae22e30da, + 0xd9212ef700ad1218706e3066b9a6caac75f47adee2f1283664f511e30599ea2, + 0xa5ef425c0c608180c9ca8b84571ab2d50946a64d7dd0d78743fd99979084dce, + 0xb83347ea3e411e026fe2f92c021b99e674cda239177c8de4f8e80e73c834747, + 0x18e1329dbbf7f0ff3f1f8f9f47547eea481990fc1b42cb9b497cd676b73fa5e5, + ), + fqd12( + 0x2433183e1c1f66cce1707df55ca2a71929485e8bba9f6f4f38feba6ceb5fd66e, + 0x25ae6c8a3ea38a592513a0a933fe28176470bd87643cc82c19b8212c5406461e, + 0xbb321462278168bb13b9df5e95cabc7278192d363d92b6680a5277505ccdc27, + 0x4f4a94928ad668a1f31c063868ba1ae6a0e6abbd4cb0426e3904bc015129e0d, + 0x2694944b89ded9becdbbfd575c024dfbc9c9d0f7c44fbde4d75f7ce350bbc4e8, + 0x2fc6e9713c01d6a78bd701b182d59ea256afd6b6bd68122485d802126137ee9a, + 0x19bc64439232f38c3767c5b4009373c1743c7fa0ee0d2680a6c9eafa57f84b50, + 0x243deb38054c3c0fbb3171f702574ee1c8781c2d6866af69de83b14ce95df54e, + 0x84841fc1e7b27066a856c1d4dbb56a9ae8abf946ba2a903be1d079bacc98cf9, + 0x1e265d7110c41b0709d90ea5c10f703f91863b4eb83a346cec182172234d03c5, + 0x2473e90edbb03a209ab1d9fd362a6249e9f2398eae8bdb851686caacfd0584d8, + 0x15dccb4a0ff089fa638c892704715dcc3beb01e01f5be239e0ac108d366fcb1b, + ), + fqd12( + 0x301df92d3253d3f7ed101ec9d85f7f73ceac20f68e382fcbeacbf5ad2f444d43, + 0x267f10a30e23b1c0f2f9a7b936c4748fe548bffbe034b5a9ffa3dfd3ffe1587d, + 0xb4562f93084f0257a9be34948f71fcbeb14a5503b831f2d9f8444740199d706, + 0x1a5cb216a7875567deec3bb82b1ccfe6bd315550e46a480641471767195edbed, + 0x1859fe90e7ec817ce9d0c630df0e84eb892e3acd2ae3c09716545969f1913aa8, + 0x14f3a6fc25f75354f253e00679f813dfd9ec050874d33e51d066240018842fb7, + 0x1bd77f748bb090f5e09bc5b42d325205c3d2973ba0e97f7a2ce151836578392e, + 0x95fa26e7a2d6c0025699e67d9ad62d34abd536e72525aeae088b3b7b9ffe1d, + 0xdf1671f4375297cd02fd35cce762c629c3b548a3ef714ccb32b96e4100a6797, + 0x2f5d4f2d7b0449971e8ad00221dbc115bd9617b7f0c4fa1009fa8f3f460ef821, + 0x20caa6f72280a189a9b0cd48016bdfa7354847407e4b375d4364eb30a9e57adf, + 0x1e6fa3543509bed3bddfb9fca8f548bb62b6c220f3c17d8b602bd8fabdd70e6, + ), + fqd12( + 0x8dde0a117cd15373a9b9d482c40552557fa5345d9f9ecfed70207a4ed21dd2a, + 0x21ecf03006b5fc4440eea655576ff635dbdcf708aac5650ff88e467c4a0090e2, + 0x202e8c244d3d2ca41123397d6463b6e8e73e47bbcfb452085df1d63b5ef0d427, + 0x202609ec763eb40f878a19b876831f0d9997e98d910cdd066ec96065266da3b2, + 0x8b1e0d50ed89ae7b73117d1444bf7f45c03748d198f01d3c6fc845031ff545a, + 0x16913eccc2f8e782b20f896afb4d91d2438677bbbe9d447e668b236dc3134978, + 0x1b5d488b9b836eadd547b6d170c1af441283111824546f76a607d3f8e8686754, + 0x9780fd4c0185f086c007332c11a4b1192f6d7c10d867b46640011c96c0a2da9, + 0x2885fdc94ad95e4e2edf1d2f08dee5f49904afd73cd6973e6573bbecfc0fa872, + 0x168f89e7ec9fb9dd310225eead00564a261ebe042985964696ae988f714fb153, + 0x3046d79d06fb521d1341da866a4292a33d5c11431c4cfcb91e281a0df50b104f, + 0x15ee3f3d6f1e87269bf0adcb052a61881dbd77ac9a6573c21c3a7b9e8a926642, + ), + fqd12( + 0x2e12bd09c5f2fc96ba6ed9a7259d7d7dee77fcb29c5800e5aa346f8fec94c416, + 0x1ac82e5a04d1f21e27e502d02a76f4e85fce0b65e4dabbd776d8959d393a93f5, + 0x17e7e7ed3b8476f9d7a2a9ca8f6aa51e71618fc674b7fd28ed13b2026bf8ea18, + 0x20bd0e2c75f4296c1e52f6d0431b8ba6cf9d2de564e984fee55cb542cddc69b8, + 0x19b105bec0ac4883d5998faab4aec1e6884ddd53bcd3bde9df1abeffa959b709, + 0x11c8f8e170089027f0465c75ad53761974d2f0613bb8f9d8fa102eb34249a77a, + 0x6638dc48404fe7090dc8de2d6d92c2eb0de7e542c0314ededde8e983f578af3, + 0x11b42b132df631a9ecd458e4cc9f534c0fe1d9ee5acc8f5135e89a534fa6e288, + 0xf6e3964c1d28be1eb3cf808fd1f9f81af61eda09b0f5c14d28d097f98a1869f, + 0x29e37ad4d1bcab0cbf16855ecd8c9951b0486971b5bd3973a59b3a8d6ce9c757, + 0x111ddb06851f8b4bd2b2270a1630d060ce0b910321702b5ca5146518749fa02b, + 0x1afe11b42d60ddf50b333a61c5396421a4d3a0383cbd16442e712206a8e3c836, + ), + fqd12( + 0x1dc9b7fea5012fac2014790692bfae855657ffa0db7f09dda5a750cfd8fbf006, + 0x152f037e2ac9976d4f3f542591fd6c473fcdd047f38dead65fb0d66197dfa5e5, + 0x29f4d53de5135217e3fa6bc8979363c6613f13e7e66014b522112d4ddc30e88a, + 0x155493848f0074e04542e907ced75e460abb0b7b0cec12f95f91974d20247017, + 0x2d7950c3b3ad6e6d38dc5446e16b6c886b8c2e03788467865c6bbb53c8f762d6, + 0x112748f68d8f8d90414602b836e736273f15fb6d612be2b4743f36ce3e48affb, + 0x274941b7d8d274e55d8911d9fe41b47ba0db731a12e15982ba226e16546dbb87, + 0x22283002ac28f20a8910b74c953f8926eabd0c470e09a15b3fa8a3ad9bf59b3c, + 0x15814ec5a629fd3b841386763f4c4d7af17932be484c9793211aadc3dc0f4926, + 0x1b4e811c4866354d2c6f9886a2c8d60cbab21862e5a4b539be2f26412d0a8ff3, + 0xffbf6843fd2e9fc2dec539ab2c3abc0d73b36eb0a497ab43f94c94623a6eec0, + 0x1126faaad936a35cc68eeab4f4a6e11031f7ea57aa8c556b82d949c998601340, + ), + fqd12( + 0x15d4e93d57e37775112e8f03037c0412b0f149ad8c722a682457258c70d7f5e4, + 0x2286da0c6c5fa81287ad879dd339c97e1f13cfb537941edd4c38d5b52e08785, + 0x194b194b624bd3965606926a711920e93aeb755e53ac4de3d1615fd49d939811, + 0x1250f690d9c4011ef283ab45dcb4348ec9d841db1237ef6eb10289f73a7694c9, + 0x249728d72aff383749fcfd5be4595b54c9f349f62d7edd8eb2ef175d3618dfd0, + 0x201b03482921dc56f5785cb3e5e4050e8b130376237ec8465e977295f9934499, + 0x1265c9dce5525fe4546c1e0eaa5a0fcaadc74a0310ee0ac4a24ef1bfc9ac026b, + 0x5b6ab11431fb6d5b4c51f59b14532e84e66016154e8787575a61e9d6862c4a4, + 0xca3208a48fb204d55968a4b1b84e1537e8f5a56a09eb7685a6077ce8fddda7a, + 0x2851ca1615471c54a54c2e471dba82ce594568be67bb64fffc456e4048906947, + 0x48e46deadabd3367822d23d9b40937c9c145d91d498bb73b07f3b2d1b00c413, + 0x1cdcbb68b93b5d6841151701e624008e33d7bd064acebc0a4642ea84705be3d4, + ), + fqd12( + 0x27988daf8e12430bf213bd1e60a34768ff0e3b881824522bcf11330dbfade211, + 0x998ae9eb361d0e36f89ac9d887dbc99eb5ce1f3440677e5ca38d4572b179f67, + 0x25e9db32198839fa4d8805c153dbb9bf3533c5c8b3685f0d60f787f1ddb0f1ee, + 0x746caf554e9ce26712e654f7fb16293279adda96e150c40312f08effa5236d8, + 0xebcb47329c06900dea6a2b6fe77b1c943c64b49ca253754e78ac42b78039d53, + 0x14e4dbe5ee8b1af065dd052ac8149347c6181c3b05851c33de05d66c22aa7c49, + 0x1c03681bc08aa0450efaf86f75fbb6c4cf85c07032d30bbade76eb9ff2964bc9, + 0x27d29c61cde0d798551937dd2d52f66695f48269b8ccb5990781da751d99fd50, + 0x2e0bfa3b1efe9a2d7e98938d5aa27d1c674e8d0c23d4d051cb5acd5a245bcf6e, + 0x476751ef7ded3d6ab0f379a28269c7cfb5dfd969f00380e352ab15f68eb23da, + 0x20534cecb11b83c455cae68d05f0a49a08d1519dd8df934b63863e0b728c1c15, + 0x1a89edac1eda942b63fc8726e694e780e0008b64327f24db687e4abb31ba92ed, + ), + fqd12( + 0x840146e531191ccc99e6788774a8fcbd589e8f16e36ccc2fa083cdbb8f360a2, + 0x279e82dc4175471965af923c8ab8f5c84651e50853be2fab2fa2e54d6d1e2086, + 0x96f4cb6be8091a955dd2e0887513113fd2ab635d5ff2ca0c3e1b7caa7b509a8, + 0x274756126f917a9ebcfb87a4c5f58268fa24edd7030760b22657ffef6849028, + 0x765a087bd26e63c91eaff89f2702e503518bcc12e960031578cf6e2aecf820b, + 0x199f8e271f9386c2e356d7b0c84a0d5342ca80c7c0cfa452589d5f82218f624c, + 0xb57187e62ebfff59d767ecfc209a90851f128ef33ba33e414d9c669bd470cc8, + 0x1cded525c6892894a5792153ac7d6e0af913155a027f135d50e20f55f6452ecd, + 0x241086e904a696efaf5318a6afbd4e460b5bcd7556827c1f2e2953c80c4ed939, + 0x2acba2c7e37d0bbd4c5b024aefd11fabe4a4322bd60cf91eb93cefde0d152b09, + 0x2f54a1e60074111a246708bfd4e30499a6fcea118bbb6772139fef84c216b03e, + 0x1e1e7da5054f4226810a8847e6afb20bb05edbecad830646301a4773c40231a2, + ), + fqd12( + 0x1a5048f8cfda38bc456da085e671f7b8a038434f4a93e34186b974bcabdfff67, + 0x1b3d991d3e93c14ea4b02da2b114d97a8b5146c7c35194a05eaefbdad0376afe, + 0x1465e362314aa6c374600671793e6a1f2beda1ff43f8de1a352dfd71093a874e, + 0x54814088246decfdd178e0e2b37f2cb9f3fb9896d4c0150631f6a435329f4b3, + 0x26550c4a250a83fe30a2344543db078e3069676678e5d0f0389fdbef0a730f6f, + 0x88c2381d3676056cc760c9a062d5db18bbada9057eb816826bd3add13e38f9e, + 0x2e9d08037209b399204214df8acb1e6a91df9fb340ccfbf1110dc82f22d3de60, + 0x29e25c1b8c24c1e93ffee60445a446dffde54010e6324477609e5ed9a6630c71, + 0x14ace046f7797f667156de29a825806fd9d01b5621fa847c5b8494a070e427db, + 0x1da94671a1308d4604b45cf2f3ffc09d43974cbf5e24c5993a97a6cbb698f425, + 0x2be08399f50f8d234751ecad90b03fc5d1d2df6de5fe81212014d68b080ac7bc, + 0xb1f33a8ba8448c206f1076c06ef484e771792208d9a71e5b847e7be678e7a92, + ), + fqd12( + 0x2d918f168727b3c4d07ac22e015658268e5dda80323fcbb9e45b3b46145bd18d, + 0x1f4335f0e26c4a7132a1c4801c4a830f662932ab345e6f704db44cb44d4a2728, + 0x148acc2a514c51628ab3868dddeb7b802da4c5c318852ea51d7256f7711770e0, + 0x2f9016969271f139ef1cfb8c9dba741d46fbac43b7b3c0cccd28350ae88c6a23, + 0x21c7291df4b6a32fc2b50a7b22bca6c445a49e798233ae3843937e0b9e1e0e2b, + 0x1b7e2d3352a2a111d20a260e8f8acc13788a708a14b4cd76b9589bdc17a0915e, + 0x2b5c3fea4723ad428d285a6494c6240ff111b8fae03ab4e2f25f551693b27aec, + 0x293005040cd255e49a1ce8e49d2a1abb4e657e4df1b52e0db88e66fe6028b024, + 0x208e2e23ca6749453962d2c83d542afa620fe38d48bcf65fd8b281d3c7cf6012, + 0xd9726068f43680be340bd87739e59d66e35f07198c789b3beaadfecd4602172, + 0xc5e84375fb96d5a120995a554c688d57664aaf0588547fc8f8948598db53bc3, + 0x2aeef3b62e540e4a8a2eba52aaceb4417f47d3653c5c215b9d2839114b35e6f, + ), + fqd12( + 0xbc188162541e3f2f19a39cdf92a92da54ef0732a7c5f69c9d68eccad66e9c15, + 0x88cb7a0d65546907cfda96cc89211822040c7635b86996e51f0a74813196882, + 0x14191b09b1226bf2756649cc6129c25d0dc326e01a59553c02602084a463dcfa, + 0xd5abcbd5865d97dfe18f56ad3be739b9b659acbd98da1a439db86e4d53a68e6, + 0x2b6897606bbdac115f9388f91b8b48c669466ca895f555cfbb5c42c0a1bfbaba, + 0x1aa52fc0afb7f30143b09b99592b6e1c9bc041656f6d80f46a7dd16303f028f0, + 0x1c0950567a65086594054f7bcaf0077d32f159bfffcaa4ad35bc5a842ba514c4, + 0x1be149979c09ca137bd47eacacf82ff1488c1a20c5840abc7ef03fe6bcd10e69, + 0x1dddd6ff744eff40b7e49fc9c79e6ca4d2ed06b0e025247cd9e6d406c084c245, + 0x2234cab1dda4fe93f76c233f7debec89012f2507195a4b0dfe9691cb568ec163, + 0x21385a511e72d2dcb29d48d6b12e95c30588732d57eec111e3be5651caeddc14, + 0x114167b6a864d079d73cf9255206b390d6b417e9a77f0078c08dca198257f629, + ), + fqd12( + 0xdd7add97fb82fbe9b40d9a8d272d916540ec4a182a748dfc72d9afe9b34d256, + 0x1cdf5e650d967f84cfa87b0474d1e85ddc7a2430f50793683089aeac5b664225, + 0x11cafacbcd93e6c2ee3e45c6556697b6a7235eedb8000b758013a701a845aea7, + 0xaca5bce7f90b5faf3093c140175e56d909c7af9905e5c1123a1eb7e0e4a14d0, + 0xf215fe7c1a5693a4ac0c001c76aff7b6b564fab52cd807f49526bb5e4c3241, + 0x149eb8d807270a5794bd5c95efcffde1e99191236f2083ec06753494f42ef62c, + 0x2b106a6d348f4c9145bdd8de625e838a1493a4d5c9509dc17a045457094efe6b, + 0x3706f2fdad22c24e00812c344445592d56eb816edc1d91605b7cdb0a326c2c3, + 0x2e35f13acf675aafe23b1c9de095b4628dd51257408ac699c0c295670706ebd4, + 0x1ed452023025003942dfe53f4495c9b91d5bf92fbd10accaf6c9efe478d5cfbb, + 0x8cfd5cb394dc5d91938178aef35c0df37530fcc02abfe5dd29c73e7e35194b0, + 0x9e448de8cc7c02c483776478d85e3aae6b94036f6f603530ba23e70260e3720, + ), + fqd12( + 0x18d3932adbcec9e3cc4d57be07f6791afbe42ff85e952de3e087c3380e62f985, + 0x18b1d452e6ed76947ceb883761753549bf10ed578c43875306bce038505f72f3, + 0x2deecb509b3461ca735e563eda95d31a8974bf3c6f37bdfc102b6da4d781b13, + 0x12213101e5a238db0b164c1dc5d9f485dde28f77ed5dbe99da6a0cefa7aeeb80, + 0x70fe9d13109bb26b983a5fb8500f52d1648137f463592b98ce2bbf2fd45a9a4, + 0x1c5b8ca592ce3778e86efbc7f6c2ad9eeb756d332fa2e7067556a9f37b88800f, + 0x788cee94fdbb882e905d73478eca3321c35d057929632954843b5e4d7fb74a3, + 0x2a66802b998b7a0dff32aea04e3b4fbfaaa0ced979a5315755f22c6fea7c709e, + 0x4cc6ec5206f515ed293163a35859545e004e86a4d5222d872267f3d16abd5e6, + 0x1d04b6fad6556cae629ce502ed5b705722b1c5e1e7c66438cc41769fa93ff230, + 0x22f2e68369c4599f4f2ba5a232bc1ce317ba28a661082f167a1ef5ec1f20b65f, + 0x8b441878479966280f948f558f2f56efffecc66fcecc4571543e72ed2ea8a21, + ), + fqd12( + 0xa6a4b6aa851e167e99ee5ee96bd82a5ad9d4a753d526ba86545dac9d9ba8b9, + 0x25f2f78f09abdf23e5613530787082ec9815af00e08880ea90c15a63171a7495, + 0x73975ee71f6f5f7bd2fb31ce2b5c5865a6b03ace26c11ace328fcf7e78129e5, + 0x4cb9bad0cad3b9a0b6e8ec318e0659ec3513e3a075c5f3a1a76ad81ecd8ec17, + 0x254a094ea953050c5e9d556b750efa6a4b46e2b21dcb1479da9fbb794261ad62, + 0x179ee3456f175de02bc746d2c54ed4370ee1ade64e39b0d1599891ea05557f5d, + 0x2cecdc675b154f832ac802de865224f483625182c23cb737b64010b615e1db9, + 0x15bfddff0270264caeeb31d96fd0daf861b28c8382c1515adbd6ec32862ca2d8, + 0x16d4eeba3f0b3c60190c8aecca2bcb5a3453d450182b072306c1478c5a0afab3, + 0xd3e24a6cd3a2a6bce5cb9c7739fc3f01063c1d1fe7822e67a645e9dd3c618da, + 0x1f763d18c611b31f4c08d3346ec9ea9ff8e5aeb8be4c6beb039607aecf278fcf, + 0x1aedfddc34ad172cd3480ec290a444d1fa1ec15327a0540df75cb2f146bd7c0e, + ), + fqd12( + 0x24ca7f744ddfe8059b6bcfc033356386b95f4d674d14f3c0c00fe0709576952c, + 0x2ff09d57e16736eb9000681ad5d8fc5c5dd7cb3ec9528fa91c1e6984fd83c662, + 0x29a21f64be23c8ea7141b4fb1b7f759834afb7bf567a1a627655a7963e7b93d7, + 0xf2392b166012024384aa632e98559181b071a8cd0ba700f5289e537e5d5965c, + 0x1331fbff963ab14569a73003ffb820da361745244ee9fa0ecf6ac6b6bc196632, + 0x1201cf602cf59142850f0b21d3ebdf37c0db2861b064e6f7005e3294e3a4cdb8, + 0x2309a054260b388fcbf0e1f8113c54223c3d56e114f51edef0bf2006965299a8, + 0x2be3ad13df633cc778a6d70d336f1945f98a62d4e759fb65513c6cb9197841ee, + 0x9dd0cd747a70640e79388ee59280a0bbeff76d538450b931c2e4d950ec8f7f0, + 0x27a79c7749c93e4c5908f8b2113f04de22c42c0d7042d510a8364ca79181280e, + 0x266bedec92ec2f8fc61b95a7aab7f0f0bf9f321b0f0679d38a44e22271210b49, + 0x152a531407928423e3efdeeaca0e199161efc9317c14f6b228fb3056bc2fe4d0, + ), + fqd12( + 0x1c0f3c8959c8b62727444a0763bb4d4255559f2b6c31dcff253ce3f72f643b2d, + 0x11c421fcaf062c5c770f1eb6e80aefc00c78820ef273b91cd45d66513e016301, + 0x5b36cee5e0ba86b54f5f7cb2275aed4942858028630ae985460193d2b5334b3, + 0x18b6aff35475ac4eccdd82c5401b8076e65d11136f216371b51a36bddebb92d0, + 0x280a14f96accdc4556b7c308bbb4262ae27893d534f0d6d410a7e497e90dcee6, + 0x4fbb1f79f203d67d1bbbf80c145d9a079d1aed20cbd912beb0c75ae4a810e10, + 0x42584923dd40b821783a01425f4c1cdc456ade065562578061bd7e01ea8f025, + 0x1ecb9a92a27c47d086467a30fb6e64896bd69b1cada152763b32670118abdc56, + 0x2b09662f9d302d245f5601ef61225621a0e968e27253def088017c8704744ddc, + 0x2ac5398555afd1eba3e95ec14f5c7a2917798439deb36d75a6bd00bf6be9e63d, + 0x1723a5e901e0e88b75910166cbbca268b9391b05dd2e56d1d49a1dffe29fe609, + 0x74978099ec63f5384a7e552c3c7c1022e2a1ac67160ace1808b8c324b144cb, + ), + fqd12( + 0x142cdaba615fb5822939c5e5fdd4d318b60627692cf173ff57dbf816a5e3957f, + 0xe37a604124d9a167cda3c097cbd3acc9981c82e444c05e8a435d0380c24a0b6, + 0x102d74be7e16602a7afeeb2057358720fe753e00ccddf805e98cea2c156f53c7, + 0x1024d35e986af1e941271e4f7536631af00b74e615c0dc3eb4d9226ee2b84294, + 0x68f5c1e169d29ee9b4d105fa0027b4fd80067c5b8f97881734ddf090bed91c1, + 0x2604b92d55d9c6b21cdacedb65f60f6b4231a26949d4e41081c6917a9ad9c285, + 0x20c5c394be02e0af2477374cd68e3396b9367191cb554e690d482ebd5930f775, + 0x14a58198b71949154c5fe22892ae1e076baf9bd00c2d44e406d36f97cd63e3e, + 0x18f191770339cc24723eb94b71f194815a370cc4545eb9c5f79be44087e333e1, + 0x95d8d0eb4d6d0f89ebc01b19d5a95165fe3f51b27fb17db01de100402b0b5ec, + 0x28bba039e12b5b154eb1b24b1046d16fbb22cb1ad416c846426cbc600cb7799e, + 0x2025759a9f6aad09ddbe0adc50c0fd3ea569890d72ab37ff5445fba9b694a0ab, + ), + fqd12( + 0x1062df6ae0dbdd425e09821527afea2c0b71ed0a9035f1af36d56844a7f1e8da, + 0x1ebdf7dd508339140fb7ca7f19edb48af992c1b426ea29c88a949bd1af4f906c, + 0x272600d0eb8b1f486d36be9380bea1d9cf39561fa7460cdac37b9469c9062c7e, + 0x4bddd3369b03802833f8b2e6b48914dca02e6892d7692c46890f66ce6cc2a5e, + 0x638eb0ec9fa09213c8642ec12b01ab2a230f6e83f04c92e5230f419d21d3b5b, + 0x2852002d75ae5da4a4805b008ff4b41ed62abe6a4895592478ab6a2eee39924f, + 0x20bdb980c2b2eff11fcff505223515b6672b8c484d2f84211c40ce4d4317d386, + 0x26f68cd1d652ea9606f6692aab4715fc14790a2e5ec80404ddb8501629162339, + 0x17e86dcded64d19c54dbc6297340204ecdc4f808bfe483ce27b549f6f0a5203a, + 0x13f118a928595989af8396c9f512bd119f76f1f4ab222804fdb048e429f606a6, + 0xe37e7ad4cd6b12cbaafffb65ceae982af09941a308afff03a711dcd821645d5, + 0x1d56e821effb243aef7bd9669c0aaa80ce2d43947a53b9a8c557264963668975, + ), + fqd12( + 0x21146d293e018a028dc78debaa79b26e9ecd17fa35088a5cb99a5a6dbe247e31, + 0x2d2f6b3075152067597d37028d7d6f3d054c87f1f42dde5eb6f2252f25442cf8, + 0x2afaf3be32336346c79fc5b39242c07cf8ab7396b71b538d05d1aa0390a33979, + 0x65c6d9e168b6959b5496d0d4e6f4422c8d744ca76c750c8316c8a9d5d38ef86, + 0x1b8bc7d0e01c8d385b219924e94acd0cf370ee29b953aec5f24620798a969097, + 0xcd9bcc3f4920d7e98c29054549da72da2dec67f8728d523047de4a1d7ae0f1f, + 0x19576f3a59eb536a76ca20b7bd178251324cf948f0f0c35f945d0d3570ef5f24, + 0x2ac12c4433d751b2d2e6b62af0ae8c084447982e3289e7584cb810609d443677, + 0xe350077b2ea69a645b8a0e890ff92bfaaa9077b7ac0e370ff1488519a3ee665, + 0x75827cd1ab4eeb69d114f7449b1f02e6cef8860a0c38c8ef672243234fd2eaf, + 0x1b81789f2da6055aa77667a49790bec2ffd63acd91201cf12f1294072653bfe8, + 0x17e1b38fd36afd5cda5d107de0c8b6301a62c1322f892815effcf31d0c0ccf, + ), + fqd12( + 0x1b330a90a5af66c56ddd437729d0b03f965e07f7b98263c7d859596a0a663ee7, + 0x1e287a2617e39dd14beeb64dfd85fd78c86ec6f86b76f3363da15090b33d8024, + 0x5bf22bd815e9b613f985e0972d37f50a8bb69d8a4ed8ce7a22de081d7201335, + 0x264fc26d1f84f39a630071b7b287d18eb1eb18722f680caf154ba8b37de3cc99, + 0x4fd1d8c54587bd1927630c0be2627c6678dce409c7fbedea884c70ce9304422, + 0x2dc65760190664f673cd5da8cc1464cab2fec5b74127d849b4e245fd52180e38, + 0x416476a0ca61873ad7109326e56df781d6cfa4d79c6ea3f17bf1dc422aeadd9, + 0x53d12ccc97db726d5b6bb2203ed1bfda6be22c94527bd28f0fb38300166ac9c, + 0x219ce323d6c11583c6eecc8e24ca5aa2cde29e3ea7d35b42c8085a3bc73dbe93, + 0x13344aa486aa7b3617d0ebe2a4626bac72194a225934f9757af3848901db0803, + 0x4d8ae3c15ace17a389edbd1e21c0aca9019fd04caa1866e6052640216ea7c5f, + 0x2f8aad55c3e76b63d616252695e5e3bc91966c766007af5daee1012095c526dd, + ), + fqd12( + 0x1958ab2d943a1197c87487886123b3b4de26a1d64dad66f0ca1f339cd30a9be2, + 0x2ac4c36791c1c1d93eb7930a4f98a1f7a28e7a392c07e228d0a89c46db6ad76a, + 0x64e5b06e9fcf56a0d63093c36a2bf12feceb6c809111963635745069b5ff6d1, + 0x2af241555d070d59dd1b7e3f4229b419851ead41d074274593064ca2ec9f470, + 0x250f11c98c6b2d4283ef49ae119ade2f976a059e450df15a65ca26f5e7ec4c3, + 0x17292e0dae6c1bbd0cafb29bff113bb64352b4be0a4c78b7ff60efd89033cb45, + 0xd3411657d046f794e79298cc07fe1990cf547ee9f7d6afaa7b688f064a13d65, + 0x229bc4094b1895d7189240c63376cfa8264b80f0b300680ce4ff5f3ad191a8a2, + 0x869295ec7ae96c58e97cac7113dbc0cc5cb4f11febb6c4e219fa0c7dcb1429d, + 0x29968a400dd43c7732ed823cafe830b2ff4650c7691a9c96c2a5535bc21b28e1, + 0x177b46f45db643d74a3b8da8bcc0604d9a417df2a33b0a2aceab2fff87001ec3, + 0x107e05ce14d0d095cd2ea0fe2021aad1839aa48068080ee6f430a4092877cb5c, + ), + fqd12( + 0x1cfd07ed2bc5ac6ad221cb5f05260bbc51f8e5c272d2f87103f4c6bf7e90c283, + 0x27fe56b03da231063f5fcd339707de292356929cee260dfe37aa3d93cd728b7e, + 0x2a4c93236363172903b03de79059a176875935633f0a65fac7a0e601b435b028, + 0x12f44d9bf78949ae4aa2e12f02600d369f3aa6cd0d7f1149682a0e1aed4d2294, + 0x138563e7abc627abece7c70075150fff687e6541143d8c9fd7260151f6947528, + 0x13b9d12c10de2fee8c12f5eccfe33d1f294b4453320859c7abff2d3d2fe8eadc, + 0x1220f8f4757392fbf3b646a43cd380a2992ee817ba6a783ea27b4860f0458734, + 0x139529c7abf16e7482dba84e9c43dcb94952c042ade5eff817db238fbe169b92, + 0x2557544521766cff96f7be43137cd8e6a1698334c1ad775ba800c0528d922514, + 0x63368c677b68cbd3f8814ae7a4313ce6383b653849549950ea8b5156653b402, + 0x2203671736b32dce27ee81cc108fefb7ea0f4c36a37bba7a8c589c92b3b0ade8, + 0x297402b80149f90941b8b3b6466dfcd2682d4999683fbb788a398947dc45dc54, + ), + fqd12( + 0x2dccd128178382a4cd18c17247e46fc31b2600dbd0a108e7547b3f8723afb2bb, + 0x291497965be1da1913c60ed2ce40cf41b997a899dedb4bfbd59189451a18fa8f, + 0x9c85aa8c9ff729540e2b70cbf8b4cf050bfb87cacd812bcaae39a0fd7b9d1c2, + 0x2c1c811d4ca5f953e5934520b2180d2c25723511aa64162cfc5e4c0621ef8f81, + 0x13a494d75e4d8b427426fa9f7be6f49a2152d5f31f5bda143d60c24914b44c1e, + 0x28a317909b9ca08511e494c9f0cc067012dee24661974d8da9f1a3d43d843e71, + 0x5281541958e567765dcd0ec40c9f1e168b6ec7b3b51d6b91c48cbd42c303d1a, + 0x26e7860da3601465434d2944e8a43bc429f850d6dc8918f2267691063791c936, + 0x165a2f993d3e76c02a0593df9655ecc3d0c54c61b7e0834864ac76df19c9e7ff, + 0x249dec9f1448d539b184ac855dc4ef19f8ace0a469f96e8eb3d00812d22621b1, + 0x16da4fa12c1b9c57d9b0749b00d06785c5adf1fd59ea99fd93e0688be65162c, + 0x1782c84c3e2d6f4216d7387917e7b519dc351a738261aef6204299333f73430, + ), + fqd12( + 0x25f5e99aec07db78a6f0409857e4fb936430794bbd202722405ee16d0005150e, + 0x1cc39f246969289599aeba701c6957b8cf1d86149f9f1612595ad9f66a0ff699, + 0x10257a038195e4268a3bf9b91478ae4e51275240b5570e3e3edf171abc2febe2, + 0x2b05171863e96187464fa9a5da4e94a358c86cacff4d4fe8de01cea168100cfc, + 0x197e7729f200b441ed3aceed91d7213b43a9790d67235f249ca55560b197e344, + 0x1189efe08cf043d84410a0a8a9a3ebb78994c1346912f61e145e0e03f68726b5, + 0x238e8e22dd10c90d7adac641f676e6de833bba6925849efa7eb4ef418467c0ff, + 0xa9a03b9a63d33717f91da30a5415ebe068ad0e172c575680228bf477d9e6d7d, + 0x1e59109c8665bacf83a5b70d50a0ef31d3d1de2bf6961e651c8849165af6c090, + 0x24792be52e2ec96a647e123a1351012acf4ba2323e2f51d79d44f8c14611f69a, + 0xd2810329fbfe13db485f5d8ae21d8f56d49d0f5f6609b9d7dfd990d846972e2, + 0x107c4ef82b44aa62ee11be95ae9ef3b5fde95e24bb7623d5eb1c8532f0911e5b, + ), + fqd12( + 0x4f6fc126fb3c654a38f2c26c3bc10d844f234ce8175a6008b3448e9f6192360, + 0x240709549243ee811c788039dca1c186c9c056259f9273602deaacb7a0e0cf5, + 0xa7bf9fbc209e409950ac4bde66aabc868a7b7025281fb9b6e34619c84439f7b, + 0x1fe5421acf72991bc596571a9f143abd53b6c121204e9da2f93a2eaa4a475a5a, + 0x2adb96e5288e42a62787ecc91c137e1cece6d4f3015c9b729ead58d1e96f49f9, + 0x2a41cc6438b45f867e2eb1e9da214457ce344f1bb029950f753660d70a5fc57a, + 0x2dcc96fa442e92f063b65ec47d530cce02e82cec9eef9d1caf75f8d65e4e1d23, + 0x1cb03532f469d806ca1425450fe8d5151742733a03049e5472d8df940fbc6218, + 0x28337c8d744698970c9cbbcd1831ba32f6ae8bc5dcdf8c5b1ba25d4cd4797e45, + 0x203be126c4e6a6cf47e3f082b24261300170f17ecb5a5e7907e66a3a8a4a8fa, + 0x216168df8ad406e251be03bc1dc5e39ae7e60303535602ef9e5c8439215a4f61, + 0xc4d0ac790aba7529b7513c6969a7cf51812505e689a97409edd01651f3f2972, + ), + fqd12( + 0x29c36b2f2866ba3e061114743ab092ee5b061a2e520d60e23474050ae2b47c78, + 0x20725a30f8b88fcb8546f1f52fb09812cd1e2ea8281f42ccba36d99c6493f823, + 0x19b77833fa770a9d1e76a574041f6ab9dd282ce6921c77355833ad30fa1a758e, + 0x268175f8fb2ac56922ef38213d31cfc02f1f0a283fc355ae9a1ace64cedf8154, + 0x6bccfbb73a5ffea00c436c069c833e7338664fcb89fa8a4f31010af05c97cf7, + 0x15654cd938c575a2d4cd8cd67e1af7230fdc2d359b1fca1c16ac6494a3dbefa8, + 0xe79959c14b531936f1382685d8c8cbf0178b444ee7411f62809844acbd89962, + 0x12aff977f614f9479e9dc812f72c970fa1865aa85355ec245ede8ba41e02d6, + 0x1a3df73b5bed7d3b8072980cbbc352fb1580cd2d569475b996457ecd841d087b, + 0x1329ed6800a8844487ffe03b93962dde543d8c2a909cd9d83f28e52390bab760, + 0x2e276f8f20ccbc65671eef869ee62ef3a9bafb73c7a04cb31c08cd3a48f16dc1, + 0x27a1b5366474384f11038a3f7a9c27e71dc74b7070d8c8d79227422923100bea, + ), + fqd12( + 0x45b8a64f1ff29082582fa97fb3ed038e168f35b764da9cdb9b15add86c783a8, + 0x2b23c8a41bd20d92555ec405e67157fff1efdce690a678cb24678fa366de67b2, + 0x277090d4c091c2b9dfee86a284ce99f054e2c9a78a576e5878693edcd5a617d0, + 0x2fb32767e26c49506ae6df8c4c79dfedc353960bfe309896cdd71fb2b947ae60, + 0x1d67ab3911357f5023c22a177eae4bcf4687a8b670fd7c8ca5394c3e0a58a522, + 0xf3eaf10b31d2a4872fc22380adf21e43ab70da7ef8abfa25bdb5228772f3b40, + 0x1450eaf7f8cd14b58b36e60f84039268937143c3dcbefc2e319d6a0111dd6bf9, + 0x2e723e5d466e3c0fd0ef35a9cdd6c1396904e8e990428a237f8186b3315504e1, + 0xa7ad7e733e7df57aaed62a4dd2301d56022a554b441879115c43347ceb7db8a, + 0x348043770203bcd1cf826fd959515ce4768d154d9cc2a14d0c852b3bedddf48, + 0x287a2897e9a69575ef2976ad9a948492792c463c7114b68dff2aa5166179cbc2, + 0x2c41af5e4b912cae4376c70fd396fc3fa420bd1f358dcb7ee22ad1fbe3d568e8, + ), + fqd12( + 0x12c9b29f9186be8040e43043c3180b5eb17ebc4a0dd12c50e9842ca5a298f909, + 0xd2c5177a22953cc9301d355a87fa2bffd9103c170912502011d226599d6034e, + 0x25c93fe0126970754a9f777d416fd4d888147f65358449e36930970b5a6b6fb5, + 0x25e0c3f25545d0b55cd3c18fda146e5b0ba41cfab800d14daccc7d88dcb2f96, + 0x49bc722b73ea5210786915ae10696d6fdc5b8620b3ed7aa0e94088454e7eac1, + 0x2b0c000a5d94989c6ed787c501895e8498a734c8a24633594108c75bb8f88220, + 0x11a79f1cf9fff6b81227ccac1bb6a23ce7758e15ad8345bf5e12c323f74b2f67, + 0x297a789564b94369a19445df9036f1f50a4ce9bf1442727dbd8e048f09c3c22f, + 0xc26b6ca4a928055ee361a15465d65c6e549b73dd9f02f4bfa56d6ff8a624a49, + 0xb884c4ea1bacfdbfe0720f1b53cc95b9808546459bc08a0577e039a972b5fb3, + 0x18608e7b81ada9e63278b53a574133ed58eeb506ea2d677803b9fc080084d799, + 0x174988f1d15006b4acfb79a96f8e37d67a3074ef903906a8a9c45697e2fe7745, + ), + fqd12( + 0x1b82295f24336c97ec077ee830dd6d9abb4a26c2d308edc843c72e4ed92b58d6, + 0x4f9286c19b3a68b1bb64befb4eb51aa71f8b1e262cfcafbfe5056624291d833, + 0x1ab6108f811d83658b1edd0b7d4c22ed4bbd56d4551a1f2cc2b6f9994163feaf, + 0x24a453bf44a33b0c0cde119d3d28f5ca213446e738d2a8408277f2157495b626, + 0x286f351757b3180f3aa3c0a99a4898412f13b139fd125c2977e15c1e09f522fb, + 0x561b18ad03d530a06d6b0dbb426e7a460e5a8dc8d2c77af7c5acda76db61567, + 0x1be6eaeda32be69dbc4fe8045e43a2131efd1e3a8cb344093ce9a599fe76dac9, + 0x2e9cb1dfed05324166fc9fd405f562ddae0d61ba2ebca979267af0f51b1066e7, + 0x1fbed99f66e5034fb584603ba2bfd57def929f1861b767f8b22a0cfb99108b84, + 0x1ddf090964c448e33e538069eee13ac57c7909b0c2b86ef50f579ef798d3a527, + 0x1beba3628e85178f637a171bcd786f4476b5f6ab19c7aaae3b3f44bef559351d, + 0x27b7a5e50a41b32996bfe2a22b644cbcdad303edfbf1b3db36583427726b08fa, + ), + fqd12( + 0x29af9868ab951ade8d681efc17a5c1090d216b53490565e69a6ea882967f7ee4, + 0x14eb3d491d679059e93f14d3a34c001a0fedd701085a548e75e0b194be3e2c54, + 0x2eb54f50c62afc5ac2ff7d2f4e8f0e9eb155e8ac2060caf5798c9727ffd19a48, + 0x2915e2c2a93424ea93ef9ac1da48336d9f05ef3ae197d9fdc7758118c9be45e0, + 0x18a8ef353c744343e0a1f56a8dd15dbed419d0b502d14d123eddc5ea0784f88e, + 0x1904c4b175503aad06f339c015b39ed94433408714e6ed5c8d639cd6cc2864db, + 0xad4215abb3feaf42bfca3cc677aee3acfcd6e9f5296ff4b91abedc3e6ffbe5f, + 0x1be1a3da5db217b9016d7e43c50b74aa2cc4d7d186d9865d5aa1fd78f3d4252, + 0x15726a15db7d789adfbaa227b6fa500318892c0c109a540a288c7e6c6cf69adc, + 0x49fae1fafb5604420c7984b2bb8a01e11c1f44c3abad941c84a8b63d2de9c66, + 0x19790529c54d94cf068d2e6dc1d66162805ffc7212a0fdc041ebf8a5b7c90866, + 0x235f36c1b86ced3c3e57fd146d48055554ff9f15c019ffe4afc4febd797a4aa8, + ), + fqd12( + 0x207ea85d623f2b18829bcdc692769da7fe5332bc040bff3ebf263d081e6251cd, + 0x20304db46cf05aeb47dc82d88de175451abfc288cd88c10d5b72a99164f331a8, + 0x2f2d0fb0977717f99ca82bb1bd785f147c6ca7897f5f1db224003baf96c0b6e8, + 0x2959900cf3e8e0d496c79887e14f96de0ffccac78021edf460b273103e89a2a5, + 0x2025e4fc8022d4ec27b48dc74772bf9299c0a9ae8e67e050d9b48faa12f0c549, + 0x1b6e571ff158180dacf7f62a3cf22c5136a6ce0b0be62a0a5f621b594a92cd4d, + 0xa2fbd355c647b7bbca77798f2b0d7364a5f4baca4186bdb11113b611797eb9a, + 0x2ea3a878c33cb12aa33ee8d7cd6083abb63664628099270e4c8e880f737864b6, + 0x1a9879ca77d5456eb4e56ef620f0df7825b3e259d82d6808f79c8bb8a4ad6f54, + 0x494964dd34f62d3b3cb218a6a82913acb8efdddb6ebe5c2f8a14c00e6d803bf, + 0x9b53800795129426f92791180eb145a110a7e73db25179439bb3d376af545f8, + 0x67796733c41964c49e344b4c697fc5c5e737a7e5562509a76d74315a397cf49, + ), + fqd12( + 0x288e729fd6bca2a38b9132ee7d6ab777a3b03c873d82d939b067b562392e206a, + 0xdcb629320bb1a3e98f378949a560b20e959d0b0d84df6131336a9ba5e43611a, + 0x1d0b30622e9a66394a921c797a08cf0098eff9954339d7d3c8d1b3fa90d85b22, + 0xad2adf1cdf1fe1ba5fe52d11353c9ebb40e6cb334cc831025001463cbfad403, + 0xec2a5cd04e5154f55b9ccd77e72f36374b07068677ae95e3e139521d13fd1e3, + 0x290ceec547b53cd27ac922b9dcb628ef2c413a791a7e1eac56f207c31f81a9af, + 0x1b5c16e2ed28921e11fc87604236693ec0c7e0cec1d0251bfac7c5b0b4b04b2c, + 0x190e4e7fbdf5b25943d14f116d092fc64c303f228037f423679eea0a93a90e8e, + 0x73e02a4c5353acd9599829a81c3e88533df10d1043026f32b9fb7f3f8aee3bb, + 0x262ece13764bb15adbf6ebe80bfe04b68e0aa795cff2407e2f15fbf4b12e9c2b, + 0x1cff14fda3f4d601f256731b02d6d97d80dc3f24debd827aab212d5ff31a49a, + 0x202b2926b9edd2e52aa18088f516c70c079064a3f601659ff243c0a7442f01e3, + ), + fqd12( + 0x267cd5fdc92019c7e90c71d9654c197cc43ab648e1416c63286ccaf25f69f988, + 0x286c4772318dc420c0b49151baebe6da950e55b2581408a47ccfb1bf50f593f8, + 0xde9d5f1d11a24d2433b6a92041d4a0f1a2b6bb0b1f30b127bc6fc9016aeb0b7, + 0x3034541a830b8f7df34dd70dbe7c0aee42fcb5ca3529472d30aacf0c3fd86234, + 0x2b04a6fa47c0932326e54fdac7df75da3373e8e154fb78748272c3c72a615edd, + 0x1823ee51c07c11a581ec89d766ad0883a2b695cd8a8227fb006b8b428fc32a4, + 0x2bc98da3b70e71d950e2b2aec626eff71224dc8b67eef6c2e5fae6ad15c5e651, + 0x18e1844a5510699b072d5b1ed6a2fc993099208b9e4ff5ba5a63bab60b0111dd, + 0x15d289ad23f1f21b1e536ba333d1601a1a28b5681803ebf13d40e296b3ee9fc6, + 0x9d07eb146f3fb7810850efa2dcad8da3ec14375d5c3b3853f59d9f79ffe055, + 0x350f987adefbff74e95c4e615a21b429a73ad4a80bc9a777f76bb8e1b3d89be, + 0x1757b9579a046594dfe7df4115c1626a33500acf7f75e08a6bfe41efefe2ab76, + ), + fqd12( + 0x2dbd7fb59ca663dd788fe74a7fe9a784a91e0210742cb583a9729d60a6a9a245, + 0x144448a26ae8a68d6eafb8c7cf21b991cb2cff24e60460462c3519a23d80ba9b, + 0x25dabaddea9d887cb686fea4ec64744ca7672788b1adadc38f9c28ff22c6df88, + 0x1b3c4b551641aed7a91a71c6e59053773652443f8d4a9d18f696187d1d4607ab, + 0x6ad42292a5ae5a87788a39b422e726410cd7a1cd34e2d1eb7572f294ed8ad50, + 0x14fc5dca139345ff28a9dc04b355e85e493c5496caf916f6c9b2e4dd586ffb7c, + 0xd1ebf36b15fc393318d3020ea0f3df0cc6884503db70216a69eb86537c4e9e5, + 0xdf2068b30589e4e65374268410d83dca5707727f61af8308a4500ac2500425, + 0x1f2718c714a3001e98fc95187572366bb18620f5b3c5492a8ec2c3eb018b30f6, + 0x1167ad357999598f9572ad6c20ec981ea04e1a8fdad94b12ecbe087ab4a2a4e1, + 0x18a75c213d6569f3df57b16d99d2b619e45e3af3cf5ccb32dab1285d92f561ae, + 0x1e6b19aae274ddeecd10b18259e35dbad63ca7316dae75b6642834ed006962d6, + ), + fqd12( + 0x157a79afa7bb5a9a27647de69a7a38c5ae5ccba38fac4c49c2758d56037f621c, + 0x24a8ec50a07cbb6b577a688953750f62ca6676e3b8340b08bc9ec5232ba5b632, + 0x140127ae4e40b1538631feb4bfd3d99065787c303f290da5987aa2d5af448933, + 0x2667fd9dcecffc2eb8c105beee7fd2a86d40a7f02cca897b7fc237258c314832, + 0x4db72167cb3476a94282c4b60828598deeb289c7d09e4f840ff3af69f10ea10, + 0xf570c3dd50ba80b1a2340ed3c5e02a5ceec8a38d542c68a41420cbce4e9b1b3, + 0x168fd2cd79238490592d5943ff6634df3b60fa0355c8a18bab7751f1bba483e3, + 0xaaea134ecfab9305b0d04b5065dbc6dcb8b5a9b6fb5af5963ff9127eae0565b, + 0x10ebc7c9262fb5d8ecf06c5b894aa6295471f1f45ea6bde235ec1c6174e3c3fd, + 0x14e62409e54ce3deba05ddea1a775516f5ed3bfe3f5ae797f77e098b0d7147cc, + 0x7125165dc325c3f1af9564eb0c22b299accf8dd01fe09a8e56840e2b5b6a106, + 0x8fdfbb9d64a6cb71ed7361dee31800963bb40c611743db7558695fcc1ec5a5d, + ), + fqd12( + 0x8f340462ad61b331f8d00b9a3310cbf80194f5b76580ef5461fc320da52bb1, + 0xcee61b94cb009187520db0678409858467188978d48c747f7f20cf813bf710f, + 0x14b4aed2b22153a2218f3dcaa9d6c7f44153056a4f34035c42854f42e7572e26, + 0x1cef18b937401cfc14e25b005e230efe0a07db5224dc6d2eb7e2db800071f1d7, + 0x2e0aff25752de08fead6e6aebd573b51b5c5bfc3e30b561694bd4d2d5b016f5, + 0x2fc247b665ae2495d731815bc6ba5d7a50b3f86f4178e75fb9ee4622d9bf09a6, + 0x2888cee0b389778c42bb1f6916e65e98d494dba34ac1b2d6a042b362c525fc07, + 0x2e5dc7cd569f0254408dc4c46edc6f1e9e2d0efa3638597ef84faee95090438b, + 0x25e1d1f28f61a3d14acf1c246d2fc775c698292a2284bd6ea5652f142126a83c, + 0x29530f29f99e47f9639e92dd7d855346f4517d7388a01dad1cd46e9083a11dd0, + 0x125c46e1c9040cdfabdf5efc6896262c454e129a66dc0f990c1733c812696cdd, + 0x20666331ee197e5d9eb4d73163262af8b912750b618c3d563898511b0100275c, + ), + fqd12( + 0x16bdfc0ac5241f0631f7b5159e302b31a4fc7f09538b66042aa72564877c2a9c, + 0x1906ff9c7f63dd745a029692494dbd8719efe76db88a0f8905e588877447dba6, + 0x83a2b927584b96850928bf2fc845f41b52da3335785d0e425238ae090a3db7f, + 0x4e9d3de2cda9f5e8bd56b7b5dbde229894e175c6582ca09b1711c47e4da3dba, + 0x52ed0769980b99b3978b9e1be51673b078efaeb8681bf7c8080579b2a50c857, + 0xa288f71356ab7b9b653add84e364c14ef40566e1230dc90ede8d361ef9bc577, + 0x1af22b3cefc1f62b85aec3995635c730acf64746fa955f63d71ead3e39802384, + 0x5b0a4d729d48d975079f64b774b10dd56d5b0744f320b536a34d9e95875a794, + 0x11e7d451966f7ca6c276f3c198c2b023419908152c7af50d1833a2cd108ffc4e, + 0x19a8b6c1d8b494aa676a5025dda9bd68c0749a83f942b43972a014c042a93067, + 0x2fc1b42e8793e7e547236e529706241104dfc4dee2e9a9429ea604fd1564dd62, + 0x21269191bef0885f843fb9bb281a154064c71266495688e432bce13bfad4a9e7, + ), + fqd12( + 0x671a0a98ec6e79bd823ca46a3ce4e8161a31d3fec57eb99630dc9f9fbfe6037, + 0x12567673391dc5dbbd8d422ecfb55a804aaec84391b27121c5a6a2fe3b91c2b2, + 0x8173c5f07c0f1005053607228ea776f33da1d236c60d6bf9e51bc8d91cdd8d1, + 0xf66c9750fca15eb39356ace563c8248f49aeef2777ada8704413dc86cdd83b8, + 0x1cf45e15e3c0fb30c80cd5ec11383b9de1e7450cec1082af86692131d37b8f0e, + 0x15ce7abd028b028d11813e34d6628d7521115c29c3276e6c2585d491b3e2e1b, + 0x11891c66cf946ab7a99d2a342907b671ab4ca6d08dcdd5bc45e68d7e772b1b7e, + 0x373824ff053fc424467b35510f592193283074db654f343fc9bf3d732df87f5, + 0x15f6adb5b93815ad252ef0ac000b88a8d719ec8d991c02f75580cb1582d2a0c8, + 0x994d44c052e5ee321adda180339787d843c00fa71b60e796fb78184c1be5d2f, + 0x2eff29957f405d49a980b8246141cff030d06a1b34ea36eee0fcda13c1a2f1f9, + 0xc606fce85fe418b85b0d64bce237a35e7cf0cb0119dad20be350576f27b6c8, + ), + fqd12( + 0x1719650903cdaa14cdd6a4f83d66dd895c4c422e261a5139d715fd048bb43b1f, + 0x30021362f042e689226b0f4ed0d95257c8035cc8266c63ddd15360e7b73c5597, + 0x432757ac0a63dfdbc4d938263701a1da5bc865c8c7ae2c7c60c6b5400e3bcfe, + 0x182e2c2641500155766c3486e6f8e0035ef525ffc08db000cd811fcfbaacbfd6, + 0x299440cb71dc23a86b381b9a6f5536ee525eb69b36155e2d5193436479cd522b, + 0xa2b26e43ffce13a83cd5ca3b38f8f8454e4f37b52dec3d0792d780f3d937acf, + 0x5f52453627f833f3d9d4588012c25333abe26cd81b7b6360ee6bd1252c1d54e, + 0x5c2b851946b3a72156cd644326d4f4918d0ec784a80b19c8d8eba700663d90, + 0x294b5265c427ae1e8d4b8356fba6b93802c66cdfc049744361ffc5fdb634402b, + 0x29a497cbb6b07cf28eaab683d5fe507a51492016feaca10b057aa8f158eb404, + 0x19bc52fe20815a5b79df10e2bd4ee2514275e9411999107643ee75c78228d0f6, + 0x1cca678df15e39bef86c7dc38c54295dc6942cfb51e641a93e60e292a1321622, + ), + fqd12( + 0x2d3595c785dec578971eebda59b642a17cb11c6a54ae6ee0a7df0319fead4c3f, + 0x1e344841a0a89c6771e74e473932867655917c7bb5cb93c762129416d54a97fa, + 0x8df9efc137905362694e184331438e618e9d1f274bd19dae050878a5f360cab, + 0x15756ad042af2577325ea26ccc6df18f533d6eced12371f3829f8ce841a8dd3, + 0x22b9fdd881041d1a919e167d608076dbb0a759720b552ca8587a844b7725cbf7, + 0x12e4d2a56b171b462fa46f2fa14dd1161d7fca86cd85be8fae875fb707b4ebe7, + 0x198cad507965b41745f6c4bcc5e0fc26bd4476cd23819dbfca1edc8830df9622, + 0x8d0f6bce4dac3985f97ba085680a974d723b99f10845123c7fc26c3f91c35e8, + 0x7cacc7612ee49afdc52a2ddd4fe91adacfacb59229f3f641f2a174f174a154c, + 0x25f1bde6778cee17a8bca03049dc4aa5d6f8af67ab40ed9f02b8e6ef81838a46, + 0x16185e9bbbd976732b0894b535e11fbde6c3ae0da6f65af085d80da0b19e49df, + 0x50b5b2f66583f3dda3f91b4b447ce8e82ba8c13f99d58568902585c03a833ed, + ), + fqd12( + 0x1355cacf611aaedd5c3921c36eb3e8af492709f2d3a26eca82dfd2432418cd17, + 0xa2ab9874ba079686e23b185efb82ff22570c7e0dcf1885b38b581b3cf79898c, + 0x212a3703e77089ff0ac7632b8204080674c0ec62746fbfea1c37b59ad91f9b5, + 0x2c510e1ab0f6dff3dfc31dd6753e3c225790e2a19b1edec9a794f090afc566a, + 0x106089a86986c3ca31a2ebcc4d024b93f0838c971aa0dfe74c6f4d95f4c2dea3, + 0x1e9b5a92d8ea02744767fa9bcdb48031ef20ff6457208f8ec87a23dbbe23fdc3, + 0x25c64d09fad7c663f547f54d8c3cc62f6af8937f38f9ab3eacb46e6c0e51c627, + 0x1fe2714bfcfd96af7745d61a8ab7b352af80929c646b07b6c4eb17082c42ab3d, + 0x1d6a34e730e92673033acd9596d77ed95fd68543af5b53cc4214a02c5f5a640, + 0x1724933f073447c2e13e2fd3a19f6e08bd681ad08fa14b3a4f6cc2eac9b33d85, + 0x1cfa39b80bb8418b906317d429fffbff0df7e31bf374a491ac8b23386527e1d1, + 0x3f0b8757c544b17d9cb37dadc9440b150393aed9220db605c2e2226e5fea652, + ), + fqd12( + 0x1296c1f2dd604549f4e6b46b96af9bd339b3872730f83fa338b4c8a932ebbf2c, + 0x12115d0afd3dbacab50761daf30bb56854cb1719df7f7f6f00883888f330346a, + 0x192bd88b1cbc605ad96a8e114f63ac2b1a45e5a4e566c72dbaa5d18dc24cadae, + 0xb82563b7aa7df4afc7f0e72bab0225b93eda61fa27bd3f6b3fc8c4eb605c4e4, + 0x110d46607952bc21b19e07055ab73fd93f81b38d1ecf66d1b20ea061620570a6, + 0x2d0754d3054428fe0e0b6c19111d71647677c0e653ecdd59207004044292d28a, + 0x1babff31aadf7f6aacbd68c8936c1a35c6846fe6e86bbb0c9dc8852ca6931477, + 0x2b7246cb166d1c3cf04ba62bd9d50d39578f18a79f03bb80e260e7fb31655da3, + 0xc3d088386044e3cfedd2932476cdbd1f48f219d2f6c31a69d42e56a1d43c765, + 0x25ca760c6492c2e7c1b6e3604d48cb1c8f078511a2a5dd49708a473ed6902df4, + 0x210f5eeb13643195b59638a2b3f31664e6579ccd496120cd906a5f906e8a1378, + 0x7cd317dba2785a85674ab6b6479a1415f0c607a1a70c56e5d702c8d76c42036, + ), + fqd12( + 0x976233f7be27ee5f9736355d58a1717d1b8fa00976495c1bc0f2516ec0dcb96, + 0xa2bd369bc6fa21f70cb6555320c70cd399b91da367deeca1851e072b7fe73ad, + 0x790d2d65fb2c21fea11906dd869bea63ecd8784915b86b086f498324faa9ff6, + 0x2c6737af5cc610f8d09ccad5d3449fdca8789e0bb8a7bd8e632a0475c47e956c, + 0x58a8e356c5b86ff9f4b836c9f46ca01ed93f6815e54351f0b453df3dccf4a62, + 0xca39d380dc5ca9a202525f5f2c71259b53b67318e58d863e2d6a5c610dfba18, + 0x58931921249cf3c0f34716243c3654392334b7648d7d41d24c3f926a4e1004c, + 0x141f17c7052eb184dab6cd6281d6b0a10c4249b9507fc2ff371065f875fb57d9, + 0x148bb8bbbed3d34a8664e4e62e2096929d9740b247259ff4375798f02f38829a, + 0x2ba1f6fbc6d265f57704543889de1dfefeed353525980ce52660386802e43724, + 0x2c000d3476064ccce4febf236fbf0c45d5289c327ff38b23ba0fa4c49729b9e7, + 0x28cfe25a8dddbe94b73cc0a9ce174082f5db984401d2873766160c9ee869dbf5, + ), + fqd12( + 0x2a7a61a1d3f76984e0101785d1b910462edd8a71e1afea4b486d56b98b2c3074, + 0x9245c23a399c24e399b8933912fde3638fc05856e231c8fd10022fa3661df81, + 0x187347709b5cdf12c42133dd8018a0a4a837d7415d1b1c69c41d3d7b52a32ded, + 0xb173f092545bbc4ccf0da2af7d4294fd6ab913a5da07a8c76c94120f6433680, + 0x2d939145988858dd5e14591c755b3c7cebde67ee3149bb408628a3712c906255, + 0x17d53feddf5202d8bd683522b2c6bc13148f410c1fa2fa86665f7a7e34b9b2dd, + 0x27862525978e7ff0e31435507a16001a67ec40925d4f6767851ca06e64e7166, + 0x2fd7b02455694e8b839cd1cda21d77845dc15fc7b2a62871aef9eb7c62fa1377, + 0x44610e85721f08d561154952d400a88a7612b2e22bc6be55e45b918e09d847b, + 0x228420770b627de6b1c29bcb87f4618c8a71fcef3b00ca3787e550ce342beb84, + 0x2ced8dc3fa5979a806cfea36ca2339ae05eaf75bdd2959177df0ea28e3791d56, + 0x1e048fc1cc82f7df3437577181684ce9259b48635b9d3f47b65832f03f95ad74, + ), + fqd12( + 0xfde537a32c40fc71f6211a2dd6d92f6d0d0ef7f7eb777dd1808d543058f224a, + 0x28163ab133f8a02d7095875ab4ac620e4fc7703a4a5f7ba8604a7c81b89fb037, + 0x133d6f76cf08f0a4ecc85220fd299694401797eff0ad131e0bd64c64e068e29e, + 0x14ed320632d9d4ed1186dee1c005c2544f859b66a6e1e43a59074f3a0b03a3c4, + 0x1ff349de11a8822e40c7b4dea18de6ed2a1a7bfe75b92ab2713c2915e96a7819, + 0x457a3433737885dee261c0e26f6876a13173d65dc45e27b1b0fe00b3cc8a566, + 0x27deb5d03c7f04469f2926c457f0a5ddd8b1c894b322262f11ee7631e195e9c0, + 0x2366e9f85c7d22e9ded4394274c0d975b24e7031598c08c6567967187f508dfb, + 0xd30863567aa66bd719a7ab4874173bc30904253bf4925036e28752981039163, + 0x2e1f299042a27605d50840bcfdbdda95128fecc2b0fbb3d98ba69d5b2bc288f4, + 0x1c867beb3fdf3ebb6dfc392fb34d460ad5b0d3a65d6bf2d99981b3d343b6e563, + 0x146ea1333f1402915a28d5aad31e4ea8083be4f13463770e481bdd6ffd8d96d9, + ), + fqd12( + 0x23f573ba6ff150872369ba0d62119aea58ee66178e96af05d8ccc9a1c46b26e8, + 0x18b49b8468032dfe53c77ddac5d77684039b1811542144666d1a58bb5e46ccc0, + 0x2bf3834c6d820cb3a23e11e5047a6334a59ca00e3b850a84b8503a514bab3808, + 0xc9c1e37231e306aa31de306f9afecfbc1b7eeefa76989199577795374ad0c84, + 0x6f2b75801c84b49cae57caec1429e4ea9e3cbeb1f7c3e6ba5035feec4085086, + 0x29dcb1d9f1fec2106878d1d54389ae65bb0d8c368848f9dfc0ec7ae8ec8d41f5, + 0xc79ca97cee11bab490d4c16df7299d6194d2a2c83abcea41df216c450f6003, + 0x2323370375940bf403eed3798608e7350a9da710882b2a218fc42649678a16c2, + 0x110166229c4f51c2585ebdbecfba177d6606a2c5e6a37564297a32c070f46d8a, + 0x2edd58dfbdf7b6b54bdd578d050d3886fd05adddeb5e2eecf9137f98be0f27dd, + 0x1cae21d27d089d792b481df3108b11463c1952c95ab9b6b70b0c93ba8cfaf251, + 0x27819acffcf76b7d9017a437295448d7f860932a292ce20b38e0a090dc84007c, + ), + fqd12( + 0x28dc4a3802c8cc88227f18868724ba5f97430b3eb37f6772f944efca37b05345, + 0x279cbb8075341a90c8c46c3d8272d99b8927a0693316fb907e8870073a2a8e6, + 0x2dcc8283643e70b5e67780eb47dcec1bf0d1e661ab1fa2d36d07b23287ca3dc6, + 0x15e859ea15753d56fe325f87806efb97c7d40dae29b7c5dcf9fee45e6257cf5c, + 0x26d432bdcfe0501eee7c80e49e0d797c2f5d6f0c524b55f7e9c690af8bf1a176, + 0x1f384098b7b2bba51bcbf147ac4785851a7768131ed8fd2828e68eedd7d3bd3b, + 0x17cba60b1d54c431cf61652600e788d27748d97c8c8750f03d2b5cbb3bd8a33d, + 0x2d6d80963e01029aba9b5567e642a42419e2602f1fe6c18f7113dac2b4220b7c, + 0x657172bc8e7ce4ca4f770aac565261e52c9e282cf057a451191b9c4eee30828, + 0xd81ddc3ea4dc4e3310f075eb658a2bfa9a360057e6956273dbd33121938b811, + 0x1580894266b34797c6cf1c2d2e5c80ec7d5941a5ad3188b1077de94798a76dd0, + 0x64dd5ee81261fc53e1b68669908839add2b26fb16f51e83dd3aac98f1d1642c, + ), + fqd12( + 0x1820825c5ef19623dfbd4980334bda17c32257896a100246c69a98438cfb7c2, + 0x172aef809f7487879852f27af1c5557c41d2c21d7c429837a2f49811ba4a696e, + 0x16556a07e4ce4baface068ed401632a3f4c58d62acd156278374d4bb08a4583f, + 0x209d6eae8b9e2d51aa78096ac21441adcb0b6d6b5f2daf976ad901bc5836cf5a, + 0x208d070517abc1d3a4ea7bb30ec1f52694d3e8d107f20f68b3956b9ab818381c, + 0x77e6f30d6f38c7222678afccd1d974f85e28610b1b2d0f24394d4853d3299fd, + 0x2f5b773660a33347087a9775924919606917d117c132f637b8a176687cae55f2, + 0x2365eb368b8077cdeb126351b174b7e8eaa31da6812a24365329320284b87d77, + 0xcd48fc0db0c9eec93aa530f674507ce4ab866d9b5b07bad841f1bd51e2a77bd, + 0x29b426b966312118789728bc3215c9eb5452d1edab5a342b73990bbcef53da6a, + 0x8830d94a72d7e49d2994101e2f4f89b2193da24cd7a8c49bc2d2dbc9627a39a, + 0x181523509e29400b96a2fcbe0230123a2cd1edee7f5252b3b739af6799bdc5fe, + ), + fqd12( + 0x1d82aefd6964989e0fa74da9396ca9374609a5e6686b03fcae119d1f1dbb3a4c, + 0x10819c6371ddd8b32393f6ece2965eeab5e7208cd0f12f6e82910101ac4cc491, + 0xf97f0be9c3eeafe3c5db3d938c1ae41cf5a3b5af8f125d760fc12ad2bba515f, + 0x2f782124738b3faba2d3d67d51459c8935603a6b19517070d6512b950d4d4be, + 0x1bbc806bb5e416c647f112a87486d8dde5b67747782516b90e2f0003e2a5c1a5, + 0xfe84f0da827e97eb84029c1cd735ac5721c89bc222c5c8ab1288a30c616a951, + 0x1a484bccc7bba64e023387f8c106973a1b80667317c8082e271ca3cd3c7c8551, + 0xafd672274fce8679901500f20e82b30ce782dcded2680100f4a47b9e7f8d0f4, + 0x1666a9939e28d1fa12a9478e68bfebba19842c7f84738b86873b20ffe89dff4e, + 0xcbfe9dd7c9aa681c80e0dad9aaa2b3b2c451c1f87639a9e40b2c9f2d028cbef, + 0x13380a59eda7e57b3de92a04caf3aa8b5e26a4b598cca5c48f3c926c6744468, + 0x150b3baf28d9ad063d1bd132586efa2ded13cf65a35f14a8ef7aa87522fff1d4, + ), + fqd12( + 0x1b9bc8233edf898de95c7cfcc72eb024d7374201e25364712f33261e2177e584, + 0x3e6c9a28a3af0e840f3ff57085bcaa10399ae9818399bde88eb051185f03a33, + 0x2215b97edb0b768683c707b7aa6bfe458a0180262eec1e8266c4bf1fb656b473, + 0x38a328c4daf0cc5298d26c797a67dfca4b5ba0113dd51734d6e445ee60c452b, + 0x1f11cd74f29de4fe01fe2576bac955578a303e69d9870ec72709ce6b093855ae, + 0x20ca926dd2cbbd3532503ed44234b16a93129763bd1b1d6e024271b3c0d1d512, + 0x15ead5d253491539a7ef95bc47c9e1d1ba92a7a4b852a127acf58221424b56e9, + 0x21be746d995802cbc21b01b493ddf2f8ec26038646e29e6f44aac029b67062ae, + 0x1ed63c4c3430f0f7bf154d64683d0db2b081c089e58c9184e30dae64d15fb2ab, + 0x865f693275e3565432e0b64020ce3468ecbd3581c7e59cadb265c98e8dda4d6, + 0x3056a037e685d837b414d1e7cf3fc1e7a2c0adc44732b6c5a5d275dbc9102f06, + 0x21aca72a7a70ac3c291c8e7870ae53d9edf56468331e3b5671ff0eda123d1288, + ), + fqd12( + 0x24714f3b0cd0eb5805d9fe4482f0383cb8a55878d9d417efaeac807166f83928, + 0x1061a0dd5a8d0b4a0aedd6d139d76c2870833c38d8fb4d893bf3bd63027230a3, + 0x2617f0170104e40e9529b2484de9275839df876ce10647db64752b3c8283d104, + 0x2e4b70cca69fa21c4c410cf173afbc619b6070931fae62bae880ee3e0d2b8f05, + 0x31b69a9bc4d9b15b6650155ac4deb57fe75ba5ecfe2d0b5fd82fd931729955a, + 0x22a20a2d6e564e6fb48ed0867bc29d08964d5682d2358d8298a16a5a079d3dd0, + 0x809166bd5cd5229a3a0b08deec996eae4fe6b836905982ee6f07918ca1e2ff9, + 0x476ae32443ba6265bfaabfc73b4f0a8a91368ce3f4dc62fbaf8bc6e034edb74, + 0x18a134cdaff097c84abcdfeb9eb8020cf4585460f4e06b49613cc9ff3950ffab, + 0x2377af3517a9c34e55ce2ba96441303d9b5eff16ba46faaddeb98c4dc715381b, + 0x295c8148774a3e8cf37e241d63f33d3ff45769a6e7974fe2acd432d0738c6940, + 0x404208ce10b890070814e721128c97e750602b283b44c9d80a7a4c089101f3c, + ), + fqd12( + 0x2d501cd97742a7e601e9522e3509f53060c5c02ade85c74d8c5d99a4951aa490, + 0xfe93c363193bea94ba9d61a514b5f27a9595eeea313606936e3bb5ac51d3f7c, + 0x2a71937f0165a317416d6330ac5adc0a9a1a8d70aa0902efcd78057d9a5a2f97, + 0x17253accb46fd9814402a01639ad53f019f5beb4d1370d48d8b93ee01ae8ff25, + 0x52524d9e31d29182707255d54c3c59266be08aeb5bdc8ef4bfcc427a0430dd1, + 0xffa4692b50afa07da841bdd766c94fbd7d064c01519a0e7b7ced7b9357251e0, + 0x7553b27f196c659df064c26bb49a748961fbbcb16e5b7bdb17b7949cf827e06, + 0x18702bd7f93299ea9af0ea96ef498037addb3092939145b362153f73eea398bf, + 0x1f87bd526d38825419b1f8816cc5fa6531a85ab4fd411dc208fc83877e6ab1ce, + 0x103e275d34a00f6edd5377e2b0bdbd00310712507465a7ab90acbd72f20d5fee, + 0x212beb9c1f905542f20c61bd39d9f49672ef4f39a7f277c1fa6fb3f8d615f012, + 0x422b3bcd3714fdcd8be60eb02a7021d7ac4d7728af31399e86fdeef85dd2090, + ), + fqd12( + 0x147be8ee0e6dcc518f3ad37c61e35e0c22dde4867bbb37ead2c8ddd9346d7872, + 0x5e516e66495ef33bd7bfc646fa0ab04e80791e0daa594f14ef1134913129e56, + 0x5c85a0e9958046817c5ef3ef5e746c5a419156954b86a470acb8687f8db89c3, + 0x97e0722a9684c6ae2b0411a1a1dd8cf4c94c8313c8257ea44f24f457a36c203, + 0x2a2b685e38baceb846aadff56d7bcd8c7c64f1896b7d7d8cd5e7a2e41fff6f92, + 0x28f8dbcf9b987c39611337def4347fa7d62865ffeffc4dadcfd8f69588607295, + 0x28112e64982a266a9deb41351af09774a26ed6bcfdf44696ebabfd73b3fbb126, + 0xb790a69fd17c533bb80ea3761a8c4e3037eaa447bbe9e6bc54e14ceeba420ac, + 0x14eab3474740650e88be6801121dcee2b2c20e18616d4a26425f2ab7cdf5d9bb, + 0x373a7742dd3a31e16d4a361549b8f68e590db51df833434b859ddf5af28cc21, + 0x2636f83a58b4a5e0c7b828a51290c8fe9ba1a6c3ea0f38f6bb9fde7750bb483d, + 0x9e6f6b4461dd0192d8d57635b46d84558eb28b187491e12eaaeb02dacf4dd97, + ), + fqd12( + 0x13f1c3f193839b1464f7411f50ea0e243a52f55e85245707c98ff6fbe828a609, + 0x2f601aff5b2fa3a095564ed064d381f2ea23ded41473e33818e23f9d66b21c, + 0x2fff14b9ea33bb7f809f4c02d76f11f6c18f27bc1cbcb39917caa700a83c38a8, + 0x858505508e9095078bc638556be7d691b07c90a29a3892a6ac594224242cb6d, + 0x24d160a3eb7be6188b3cf811de6a3efa8402bd09192113044e874a2200d723a7, + 0x1a1bad59810d538a85c4932747fd77378a354bb608fb3dca89f37ce2d925ecf0, + 0x25f50bf371f91c0568a968604c7000f3c0ed5ee7e5b7d30b8307ef3f633a4d0e, + 0xfedeef0b835c44f98520c12d729e6c3aa2880038bbe1098658d7719df7c1a38, + 0x2af1d0c4c61619b351bfd17927f18910ec22c911c65f4cd45e0e1f9ca9bbd728, + 0x8ba263d03f22ed794fef8bd9bef91bb3a5658431b38a326ba80a689ab91b98e, + 0x652438dd0ad1b38c454a33ee9497cad0d0db8109c73ba7be915ec924a6e49be, + 0xfaa0bba2cde4e5c802f41528e78d00e176fd4d73006248c724b1ac591171e6e, + ), + fqd12( + 0x1bcb81a680b95b398913c703bba04548d5df64568d80c463fc717c8ae304df7c, + 0x2cd523369aacb345600284cde759bb70fa2ad85193f9aa91ac89734dceebb76f, + 0x380b09fa066a8bb6f6d1c843b34050f9b0a125d7f71c5812827918eeb27c586, + 0x28f48838b1d863c4edb5a31779520bf5be6a4e311e221a892b3a3aaf2aab5615, + 0x48afafefdd4f939b0584f8ccb99a4b0ffd173b1b2ca837aac1ac460b82981e3, + 0x17f96ec1b17da5f668037aee0b13dd867f512829b15d05296ac97ef3f3aacade, + 0x9dca9720802636a30591a5415b98420a9d3aa8123d733989717a10082b3fb70, + 0x105bac6eb02607d51d493e07ce922594ef24f7c84b060824560430aabb162d9a, + 0x12104bd2ad92d2fa6dbecd5c705f31d5546dbf1e95f2360e8052d1caf5783dc9, + 0x164e95b44c8dda9d841950e20244d91f913d215160779d681106762635ba90c9, + 0x1098c6a63cf5fa94a1453bc1acf5d347303db6c467b28fcccb0deda37f1a817c, + 0x10eb1b4b878adadb751b4077bad5a03d0b0e2941504da8cb330d609042131ac2, + ), + fqd12( + 0x28b4012241919e0b8a3a610ad3d8b0deee79572210382f2eb9d27f51f680f5f, + 0xe0970194077c0a2dffbedca716f19543566a5b241431dca699f809e7fb045f5, + 0x2356d7084a23e4ac5bf9ddf77d2dcd6e42ad7f78de44cf0c9d696660fbae5a5f, + 0x13e0462bc0b0efbb55c1d03fa15176e303cb1cd721a0b1e3250441f85135cbfa, + 0x27a321eda3b829db4be8424558e8a0070b94b7d002b9bd86266976ebac1a14c8, + 0x277bf8cf5f719282fa47ecaa03141c37ed0cf8e86a613e5ff396cf34af4ac7e0, + 0x2eb0a1b0b86ef38ec0c7d4009dcbeecc2bdd37e840202cf409fe998ff592189a, + 0x65b55ba4325e5ea4d757a76743cd21281bd07ba280324512cf28fb4235702fa, + 0x1ee6bdac2f9581e3edac54c0440cfe6b314eff9cae00c97dd87921b395ee815a, + 0x1c91f5e3577081de99bc8713ecbb5bce19fe4542d2498ee22fe97128eb2709db, + 0x28bfa52acf920f68c8550da17719db5d97b9ac55b8cabe3f6a55bc9bca265324, + 0x20db36fbb4faa64e1746c5b7c32cd8b2caa0681f406d4f59eaf1873a9c99011e, + ), + fqd12(0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,), + fqd12(0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,), + ], + array![ + fq(0x2eaba74d26e416f98d334f333be2be50d444d7388366b8e9237baab4a09d832), + fq(0x1f926af74d97b4a1139d3a60f747ce1468e2922c41bfab466864df41a3455e68), + fq(0xf38463df3925e11809387f75fafaf3dcc89e70cd174df47fe09bc950864af87), + fq(0x16cc7d4df23dc5b5c3917011118ab1465c4845bec61c273b79090edc0e6d590d), + fq(0x116780d9e6fab0c2cd7f71ce428cc2d6fe34c11b57e13b8f826cbacdeccca144), + fq(0x3ed189fc81187a797cb38f604ff7bf163b00e9690bf6d04711a54c1cb68fb3), + fq(0x1996946c9b6ddaeb07e9f951ccec80520b4a08c284908c8769a32cf45a65b383), + fq(0x290d87215bccda5626b0b26620f6dd9aed3664a47998dce05c337825216af9fe), + fq(0x1119e88399a9ce186293c5171da4de8167cc575bf2e1fd4c17140aff182926f5), + fq(0x5f1619fe063c6e075ca750cf419625c44d4d9a00288cc38145d86360167c8b8), + fq(0x2288d10c5cc101ae9d6fdd65c07710c6ca73629c300efb7075aa9b8a2f36ce85), + fq(0x214d83c4a9eb37bcacb33cdc78e63b841bde738a13da11beeeb8c83b5cf70143), + fq(0x2bba0feeb1c1b380141f040c2c475ecfa4856afea160d8776a507776774807c), + fq(0x1653527c3144de954af339c68b54941b6686c1e4c39adcc7496811a28e604e22), + fq(0x1ad7edf63548e659b5b08d748d557e8a6aa7f0b95416586bd4a8ea5a311edf0e), + fq(0x20ec92b004381186d89358d29a453c092b6e5cdcdbfea3d3cbb76b2de7c9991), + fq(0x1eb719ccf9918e6b3ad01e97c3719b0584c994747bfff4922908132d630952d7), + fq(0x26759e3eb6055d607a39a347b84194219d048aaa7ef64d4b11d374f1c6c82712), + fq(0x14978ebd81998e6c2735c666a8e444bab8256ed6a4e6edb62c5f0713b1e00118), + fq(0x15ba0943aeb585d22d4320ae6f23d4c11c4de1025ad3763cc3e8ec6b844174bb), + fq(0x299e011bc6e5718fbd5d5ce4b76aece8a9887c76a4776d9fdd474b2d5bdfe069), + fq(0xe091837a1e0492be8d78e8ae6ee3fcaab58a45f762ab8833b40d81eca4dd70), + fq(0x4f9111e921b83ee918a934fabab4dcda4910a65dcffb81ecf98363abe5df4dc), + fq(0x945c834a1496abfb1de19621077bbc6a3bfd36e213e9f7fbf55b661522e7f74), + fq(0x931bc51f6564ac60341608f1f52b296a53b286fc757c204723457eb016842ce), + fq(0x20b452390bd92ff4e30a56840aabfe3ac90525faa8b23c7b86c0272dbd5c672a), + fq(0xf573817f12d00f5ca609c00f0d304fbfe3f42cb141649020a52c9bdb2911191), + fq(0x171c583c47b14fbd1cc83fb3c6e662f6d5991c8ebe531e57373e6ff2f52ce0d6), + fq(0xaef560225d8b63bb5aaea11fc4518d4b27dfbd276d31479c199ba04579e1896), + fq(0x2c08b9425f7aac86cadd2f3642d4666a6b105bc6b7921f486ee8674ea9afd8a3), + fq(0x4bb49d7c12fc82a58c194c764fa215e259799c53b757229c6e30f3e1018e878), + fq(0x1e18863e74e9504a5df3fa57ade26c6f783d8328aba6c870c17fd1b04a3432cf), + fq(0x2c43834cf8dbbf7eaad822c4da8f6cf2b3f2b91784ac0c72148653ab261fa2fc), + fq(0x131b8123a69a241ea574953bf03ace26c8e8b1832d3833139df617072c1fb0c0), + fq(0x5dd8ac8db5cbacbbcc9ca4ad457bb1bbdb930b695174ef891ce8c8f2258e683), + fq(0x23e59d69a3112e4ea24c0a309110779afba07d5433bcc761e0feca079fd6e82c), + fq(0x2b369efe32b9dd3119481b570cba2f24fd2231810da8b7aa1bf3cd1746896998), + fq(0x14312aed6c3823b7a61292e74b07b5153b68bab48bc29fe1247bfcd232bbb4e6), + fq(0x2a1fae834bbfb2d1e8445af35c2efe9613dde9835d52295bf101b43e06e87b66), + fq(0xfa71ab5942db8ca7fe26d801b2ed4c8997ad3988b2e98c68d9d60e1c125289d), + fq(0xf36178073860f6de426a2d1cbe591ad230ecea1223851d67295d3066a2d7874), + fq(0x1090183b6ffe4777b0ff09f4dbb0d93f2bef086298abc8306d4249c7c101cf4b), + fq(0xd10ed3528e7893cfbdb6923c84a6fa55ba190c4f9920d9866bdeb6f61a388de), + fq(0x146dcbfc5153c18cb0a4e27d5cc87177af169e0d994977e15b8a8ef71b8c1f92), + fq(0x25e2507223326d24a24a94e78f9e7ea31372f9103819dedbc2fd05ba14104f3), + fq(0x255899d739ef8387b2757d922cadb5f11011fd7ddec6493859686812efabbce5), + fq(0x21aec7e41b1fdaabc34371917a1b1d5f9956a76d00ca399cf006db6c99cf80e2), + fq(0x2172adce6f95ba879aa1bb0057b7af384ca1c2c506f69b45a962c309cf6e923d), + fq(0x2660cbc643fb87727602ff73964e7e28f4453f8edce620435f22857f66934989), + fq(0x290c44965f1cf6f0e882736ff642c491121f3659c76794a9d28b1dcc606f8ccd), + fq(0x36f539c8aa3c8b41cf536ec57599ee681cc53e11916aefbb753cd6fbd968a02), + fq(0x1fdc0d9ba3205fc29f139c129166977ee65203ff61dfafb79b148d92aa4cc10a), + fq(0xd47862dfbbfb17ba27005467eb762768fec997a3b5eb420676ceea0aa33d7c8), + fq(0xa1ec477ca83867513ec5bf668fcc20a8fc5af238b9a21b0a8d26a320409f3fc), + fq(0x1339479b6876922628cb7396e76826f8c99b80d4b5cfccb783693e7bbb8a01), + fq(0x1ace1a2cfaf59da4f4268385845ce885f7907c449bb77ed515b19d4110775b3f), + fq(0xa232a539085bf476a3addd21e7b5b7a15b9ada69f3f29fd29195e0adaa570e8), + fq(0x24a2bd41f4fdea1a5f19bb40060b35bd135a5717347fd705e7263d2fa98012f7), + fq(0x15c71d5bf327f0f3adf2f28d94c7d78664189a8031d20b88f6f4254b1dbdb7aa), + fq(0x2754925b8adec11faa8a1e3da4a032dd8d6186a953dfa9c19d48cf55b7f7de43), + fq(0x2f9146e07ccf79cf6dbac200dc8c0370df05144332dd90ede56b0789e04daece), + fq(0x2388b18ea210c78030e0ab7aef06b6b4d590421988ef56418eb95d9a71468f2a), + fq(0x1587f2ed5b0b80b54583d439820799b114af152d7456301f9b7d9c9551ca1840), + fq(0x1a4111c61e90190cec0fac9d152ea7642069ab5a3a943459f27362106a6f9b4b), + fq(0x6b4de3ee7d008b5bc62bdf70cc749a36f2324621e8b0a9cab3032f210be7c72), + fq(0x24ce0acc498c10fc938117cade3252079a0f8e4d23274abea071a4ef9769c0c6), + fq(0x1ed13039470c2aad301ed9f767d7999d55f7798d8a03823aacbff246a8da55a2), + fq(0x15b7c94d86106383b05b88a6d00ae0c3b50954377eb68ef8fa247a70ade40020), + fq(0x266e27cf4eb35e99e6246bebb33485b6dc23b5d6b6b948569d30f354a13912d7), + fq(0xf49cd46a74126652f23937fc20d5319ccad3d999fe07ba51d4d188a225189de), + fq(0x15a91935cc80cb4d0d16f887bdcb348622cbd8c2abd489e990939c5e09c53e0c), + fq(0xb2a719243bdbd634e7b11b53f4a05bc4e9abe65fe9225dad8088bf0bd5a774d), + fq(0x19eb9fe6c0e348a9b855c015f472b10afd1b33ebd3a803e20cbc58932fd23c77), + fq(0x22a870b0fa6d8c88d7214f19b4ac0464cc5095c13de6cbed8d8f7b46f04cbcf6), + fq(0xeb628201e2bc131df6a9d781b81f7ff07a8b9ce7c5f41ab8ce163606ea29092), + fq(0x18bc609d2ab72e7c08cfbb4229ac620d165222d76ea075d61b814d82b88ec6fe) + ], + ) +} From 898aef082ab912d1a18d8a6822e727130406f739 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 21 Jul 2024 06:19:11 +0530 Subject: [PATCH 72/97] fq12 direct extension utils/test --- .../src/pairing/schzip_miller.cairo | 46 +++--- .../src/pairing/schzip_miller_runner.cairo | 4 +- .../src/tests/fixtures/proof_fix.cairo | 138 +++++++++--------- packages/bn254_u256/src/tests/tests.cairo | 10 +- packages/bn254_u256/src/utils.cairo | 23 ++- 5 files changed, 122 insertions(+), 99 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 6ab7ab3..48d7fe1 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -3,7 +3,7 @@ use ec_groups::ECOperations; pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; use bn254_u256::print::{FqDisplay}; use bn254_u256::{ - fq, Fq, Fq2, Fq12, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, + fq, Fq, Fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ schzip_miller_runner::Miller_Bn254_U256, utils::{ @@ -35,9 +35,9 @@ fn schzip_miller< pi_b: PtG2, pi_c: PtG1, inputs: Array, - residue_witness: Fq12, - residue_witness_inv: Fq12, - setup: Groth16Circuit, + residue_witness: FqD12, + residue_witness_inv: FqD12, + setup: Groth16Circuit, schzip: TSchZip, schzip_acc: SZCommitmentAccumulator, ) -> SZAccumulator { // @@ -67,11 +67,11 @@ fn schzip_miller< ate_miller_loop(ref curve, precomp, q_acc) } -fn hasher_fq2(ref hasher: HashState, a: Fq2) { - hasher = hasher.update(a.c0.c0.low.into()); - hasher = hasher.update(a.c0.c0.high.into()); - hasher = hasher.update(a.c1.c0.low.into()); - hasher = hasher.update(a.c1.c0.high.into()); +fn hash_fq2(ref hasher: HashState, a: Fq, b: Fq) { + hasher = hasher.update(a.c0.low.into()); + hasher = hasher.update(a.c0.high.into()); + hasher = hasher.update(b.c0.low.into()); + hasher = hasher.update(b.c0.high.into()); } // Prepares SZ commitment @@ -86,24 +86,26 @@ fn hasher_fq2(ref hasher: HashState, a: Fq2) { // So Any changes in the remainders will change the RLC and equation will not be satisfiable with any QRLC. // Fiat Shamir for the final Schwartz Zippel includes all remainders and QRLC for soundness. pub fn prepare_sz_commitment( - ref curve: Bn254U256Curve, remainders: Array, qrlc: Array, + ref curve: Bn254U256Curve, remainders: Array, qrlc: Array, ) -> (SZCommitment, SZCommitmentAccumulator) { let mut rem_coeff_i = 0; let mut hasher = PoseidonImpl::new(); let rem_coeffs_count = remainders.len(); let rem_snap = @remainders; while rem_coeff_i != rem_coeffs_count { - let Fq12 { c0, c1 } = *(rem_snap[rem_coeff_i]); - - hasher_fq2(ref hasher, c0.c0); - hasher_fq2(ref hasher, c0.c1); - hasher_fq2(ref hasher, c0.c2); - hasher_fq2(ref hasher, c1.c0); - hasher_fq2(ref hasher, c1.c1); - hasher_fq2(ref hasher, c1.c2); + let rem: FqD12 = *rem_snap[rem_coeff_i]; + let ((r0, r1, r2, r3), (r4, r5, r6, r7), (r8, r9, r10, r11)) = rem; + + hash_fq2(ref hasher, r0, r1); + hash_fq2(ref hasher, r2, r3); + hash_fq2(ref hasher, r4, r5); + hash_fq2(ref hasher, r6, r7); + hash_fq2(ref hasher, r8, r9); + hash_fq2(ref hasher, r10, r11); rem_coeff_i += 1; }; let remainders_fiat_shamir_felt = hasher.finalize(); + println!("remainders_fiat_shamir_felt: {}", remainders_fiat_shamir_felt); let remainders_fiat_shamir: u256 = remainders_fiat_shamir_felt.into(); let mut qrlc_coeff_i = 0; @@ -155,11 +157,11 @@ pub fn schzip_verify( pi_b: PtG2, pi_c: PtG1, inputs: Array, - residue_witness: Fq12, - residue_witness_inv: Fq12, + residue_witness: FqD12, + residue_witness_inv: FqD12, cubic_scale: CubicScale, - setup: Groth16Circuit, - schzip_remainders: Array, + setup: Groth16Circuit, + schzip_remainders: Array, schzip_qrlc: Array, ) { // let p = fs_pow(ref curve, fq(2), 6); // println!("{} {} {} {} {} {}", p[0], p[1], p[2], p[3], p[4], p[5]); diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index f056de7..73c38f7 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,7 +1,7 @@ use pairing::{LineFn, LinesArrayGet, FixedPointLines}; use pairing::{PairingUtils}; -use bn254_u256::{Fq, Fq2, fq2, Fq12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; -use bn254_u256::print::{FqDisplay, Fq12Display, G2Display}; +use bn254_u256::{Fq, Fq2, fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; +use bn254_u256::print::{FqDisplay, G2Display}; use bn254_u256::pairing::utils::{ LnArrays, SZCommitment, SZCommitmentAccumulator, SZPreCompute, SZAccumulator as Accumulator, LnFn diff --git a/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo b/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo index 13ebe12..e07084d 100644 --- a/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo +++ b/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo @@ -1,8 +1,8 @@ use super::lines_fix::{gamma_lines, delta_lines}; -use bn254_u256::{CubicScale, PtG1, PtG2, Fq2, Fq12, fq2, fq12, g1, g2}; +use bn254_u256::{CubicScale, PtG1, PtG2, Fq2, FqD12, fq2, fqd12, g1, g2}; use bn254_u256::{Groth16Circuit, LnArrays, InputConstraintPoints}; -pub fn vk() -> (PtG1, PtG2, PtG2, PtG2, Fq12, Array) { +pub fn vk() -> (PtG1, PtG2, PtG2, PtG2, FqD12, Array) { let mut alpha = g1( 20491192805390485299153009773594534940189261866228447918068658471970481763042, 9383485363053290200918347156157836566562967994039712273449902621266178545958 @@ -35,54 +35,54 @@ pub fn vk() -> (PtG1, PtG2, PtG2, PtG2, Fq12, Array) { 10404924572941018678793755094259635830045501866471999610240845041996101882275 ) ]; - let _neg_albe_miller = fq12( - 0x27c20318505e03cea84a04223b8679a6c84c1e55e83957a21e8986c1b8140510, + let _neg_albe_miller = fqd12( + 0x2645aefce7c56d6cbd9233d460c1d39f138fdd9c9dffd2a164e43cf462c03751, + 0x1c45a9773bda2a2f56d0f41c8fe1d62f8cf240310b1037fe86d94b92f4b517e1, + 0x1f6e3ceda0dc22273ae55aeae6b922c90b69be7869929f68c57ca27f6cc6953b, + 0x135b9ddc8a8bffe5f4e9ae5b64b14e6f63e74bbb4742a13b4457edf5d2715fcf, + 0x11c15465527a13b394a010da891ca875384e68da5f36c94193600e8234a52524, + 0x290f56a13518e8cf22de5f63498d75f657b3f066126a46cd82e77c30aa8e99e3, 0x104bb1b78f934618c94ba0290a964c58f1400e450e9e19680c39a8aca6fa15f4, - 0x2e56f81476f8d79f0caef927ac110b77cec88490d0860c746d82583440bb8919, - 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, - 0x19bdc2cd81965796abc4dd1ac13a5941ce94ead67c26445a67ca63f07def54fa, - 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, - 0x159ad96d8a0f81d1e048379cb2dee2671581cb84e58de9cbf2d4ea8d11a5a262, 0xf63ca25374f5b91be7d57a067f1e5ec7a906be473fb01f091d1793fd999b926, - 0x231b22b4c91411c1aeb9724839622abf9d9297cad863a0312452df9f56e9872a, + 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, 0x2cc3c64540e5e5af46b3c583a7314a94fedb672da5da977c6ac70927247c73bb, - 0xbd670107051399799978f2a70d7a08ed0bb130d1fa74638dce3d81536701c96, + 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, 0x221446e74ef53a921abb7b8a0fa2afee56481780d136bc649916f1beeb52aaa ); - let _alphabeta_miller = fq12( - 0x27c20318505e03cea84a04223b8679a6c84c1e55e83957a21e8986c1b8140510, + let _alphabeta_miller = fqd12( + 0x2645aefce7c56d6cbd9233d460c1d39f138fdd9c9dffd2a164e43cf462c03751, + 0x141ea4fba55775fa617f5199f19f822e0a8f2a605d61928eb5474083e3c7e566, + 0x1f6e3ceda0dc22273ae55aeae6b922c90b69be7869929f68c57ca27f6cc6953b, + 0x1d08b09656a5a043c366975b1cd009ee339a1ed6212f2951f7c89e21060b9d78, + 0x11c15465527a13b394a010da891ca875384e68da5f36c94193600e8234a52524, + 0x754f7d1ac18b75a9571e65337f3e2673fcd7a2b560783bfb9390fe62dee6364, 0x104bb1b78f934618c94ba0290a964c58f1400e450e9e19680c39a8aca6fa15f4, - 0x2e56f81476f8d79f0caef927ac110b77cec88490d0860c746d82583440bb8919, - 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, - 0x19bdc2cd81965796abc4dd1ac13a5941ce94ead67c26445a67ca63f07def54fa, - 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, - 0x1ac9750557221e57d8080e19cea275f681ff9f0c82e3e0c1494ba189c6d75ae5, 0x2100844da9e24497f9d2ee16198f72711cf0feacf476c89caa4f12d6fee34421, - 0xd492bbe181d8e680996d36e481f2d9df9eed2c6900e2a5c17cdac778193761d, + 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, 0x3a0882da04bba7a719c8032da500dc898a60363c2973310d15982efb400898c, - 0x248dde6270e066921eb8b68c10a9b7cec6c6578448ca84545f3cb401a20ce0b1, + 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, 0x2e430a046c424c8096a48dfde0872d5eb21ce9195b5e5ec6f28f1cfae9c7d29d ); (alpha, beta, gamma, delta, _neg_albe_miller, ic) } -pub fn circuit_setup() -> Groth16Circuit { +pub fn circuit_setup() -> Groth16Circuit { let (_alpha, _beta, gamma, delta, _alphabeta_miller, _ic) = vk(); Groth16Circuit::< - PtG1, PtG2, LnArrays, InputConstraintPoints, Fq12 + PtG1, PtG2, LnArrays, InputConstraintPoints, FqD12 > { - alpha_beta: fq12( - 0x27c20318505e03cea84a04223b8679a6c84c1e55e83957a21e8986c1b8140510, + alpha_beta: fqd12( + 0x2645aefce7c56d6cbd9233d460c1d39f138fdd9c9dffd2a164e43cf462c03751, + 0x1c45a9773bda2a2f56d0f41c8fe1d62f8cf240310b1037fe86d94b92f4b517e1, + 0x1f6e3ceda0dc22273ae55aeae6b922c90b69be7869929f68c57ca27f6cc6953b, + 0x135b9ddc8a8bffe5f4e9ae5b64b14e6f63e74bbb4742a13b4457edf5d2715fcf, + 0x11c15465527a13b394a010da891ca875384e68da5f36c94193600e8234a52524, + 0x290f56a13518e8cf22de5f63498d75f657b3f066126a46cd82e77c30aa8e99e3, 0x104bb1b78f934618c94ba0290a964c58f1400e450e9e19680c39a8aca6fa15f4, - 0x2e56f81476f8d79f0caef927ac110b77cec88490d0860c746d82583440bb8919, - 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, - 0x19bdc2cd81965796abc4dd1ac13a5941ce94ead67c26445a67ca63f07def54fa, - 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, - 0x159ad96d8a0f81d1e048379cb2dee2671581cb84e58de9cbf2d4ea8d11a5a262, 0xf63ca25374f5b91be7d57a067f1e5ec7a906be473fb01f091d1793fd999b926, - 0x231b22b4c91411c1aeb9724839622abf9d9297cad863a0312452df9f56e9872a, + 0x1a814cb6d1fa262a5882e06c097fd68c05fdd1f27e2288f84726985dea9706e, 0x2cc3c64540e5e5af46b3c583a7314a94fedb672da5da977c6ac70927247c73bb, - 0xbd670107051399799978f2a70d7a08ed0bb130d1fa74638dce3d81536701c96, + 0xe328b63e1f95c3e6208878e9ca68fa49960e71588c6302c244b428b2cf5aa6, 0x221446e74ef53a921abb7b8a0fa2afee56481780d136bc649916f1beeb52aaa ), gamma: g2( @@ -115,7 +115,7 @@ pub fn circuit_setup() -> Groth16Circuit (PtG1, PtG2, PtG1, u256, Fq12) { +pub fn proof() -> (PtG1, PtG2, PtG1, u256, FqD12) { let pi_a = g1( 21869318927288279352976009554602485400194222893443965440964860860113038611333, 18311135712289946861315992474690361768373551919702286485795766144098633284656, @@ -131,68 +131,68 @@ pub fn proof() -> (PtG1, PtG2, PtG1, u256, Fq12) { 5611531129077709352565605843416215629032027923761887684873913606256162034924, ); let pub_input = 16941831391195391826097405368824996545623792600381113317588874714920518273658; - let miller_result = fq12( - 0x1bf4e21820e6cc2b2dbc9453733a8d7c48f05e73f90ecc8bdd80505d2d3b1715, + let miller_result = fqd12( + 0x15e90a8fd95c0ae0972e1c23aaeb7fda8ded8b18dea0a9099092d516d53de477, + 0x145561920c91a6a5025ac409f3346a8c71ab0e4898f5c19f70f1c538ce7664b0, + 0x28d2a980490a46eb71c44b540878fb16fc06c65e189f202e90fcbe7605a9fefe, + 0x968193a676e6ad1456586ea777c75fd68de2bccae58945cec73b5b58f286add, + 0x11896feeb4c1fd530ea2f1449072f95d8d95298b08b958b3bbf7963005f61166, + 0x22070fb56846e081f7ceb1c460db600f464d598a923e33893fc187b912cfea30, 0x264f54f6b719920c4ac00aafb3df29cc8a9ddc25e264bdee1ade5e36077d58d7, - 0xdb269e3cd7ed27d825bcbaaefb01023cf9b17beed6092f7b96eab87b571f3fe, - 0x25ce534442ee86a32c46b56d2bf289a0be5f8703fb05c260b2cb820f2b253cf, - 0x33fc62c521f4ffdcb362b12220db6c57f487906c0daf4dc9ba736f882a420e1, - 0xe8b074995703e92a7b9568c90ae160e4d5b81affe628dc1d790241de43d00d0, - 0x84e35bd0eea3430b350041d235bb394e338e3a9ed2f0a9a1ba7fe786d391de1, 0x244d38253da236f714cb763abf68f7829ee631b4cc5ede89b382e518d676d992, - 0x1ee0a098b62c76a9ebdf4d76c8dfc1586e3fcb6a01712cbda8d10d07b32c5af4, + 0x25ce534442ee86a32c46b56d2bf289a0be5f8703fb05c260b2cb820f2b253cf, 0xd23aeb23acacf931f02eca9eceee31ee9607ec003ff934694119a9c6cffc4bd, - 0x16558217bb9b1bcda995b123619808719cb8a282a190630e6d06d7d03e6333ca, + 0xe8b074995703e92a7b9568c90ae160e4d5b81affe628dc1d790241de43d00d0, 0x14354c051802f8704939c9948ef91d89db28fe9513ad7bbf58a4639af347ea86 ); (pi_a, pi_b, pi_c, pub_input, miller_result) } -pub fn residue_witness() -> (Fq12, Fq12, Fq12, (Fq2, Fq2, Fq2), CubicScale) { - let f = fq12( - 0x1bf4e21820e6cc2b2dbc9453733a8d7c48f05e73f90ecc8bdd80505d2d3b1715, +pub fn residue_witness() -> (FqD12, FqD12, FqD12, (Fq2, Fq2, Fq2), CubicScale) { + let f = fqd12( + 0x15e90a8fd95c0ae0972e1c23aaeb7fda8ded8b18dea0a9099092d516d53de477, + 0x145561920c91a6a5025ac409f3346a8c71ab0e4898f5c19f70f1c538ce7664b0, + 0x28d2a980490a46eb71c44b540878fb16fc06c65e189f202e90fcbe7605a9fefe, + 0x968193a676e6ad1456586ea777c75fd68de2bccae58945cec73b5b58f286add, + 0x11896feeb4c1fd530ea2f1449072f95d8d95298b08b958b3bbf7963005f61166, + 0x22070fb56846e081f7ceb1c460db600f464d598a923e33893fc187b912cfea30, 0x264f54f6b719920c4ac00aafb3df29cc8a9ddc25e264bdee1ade5e36077d58d7, - 0xdb269e3cd7ed27d825bcbaaefb01023cf9b17beed6092f7b96eab87b571f3fe, - 0x25ce534442ee86a32c46b56d2bf289a0be5f8703fb05c260b2cb820f2b253cf, - 0x33fc62c521f4ffdcb362b12220db6c57f487906c0daf4dc9ba736f882a420e1, - 0xe8b074995703e92a7b9568c90ae160e4d5b81affe628dc1d790241de43d00d0, - 0x84e35bd0eea3430b350041d235bb394e338e3a9ed2f0a9a1ba7fe786d391de1, 0x244d38253da236f714cb763abf68f7829ee631b4cc5ede89b382e518d676d992, - 0x1ee0a098b62c76a9ebdf4d76c8dfc1586e3fcb6a01712cbda8d10d07b32c5af4, + 0x25ce534442ee86a32c46b56d2bf289a0be5f8703fb05c260b2cb820f2b253cf, 0xd23aeb23acacf931f02eca9eceee31ee9607ec003ff934694119a9c6cffc4bd, - 0x16558217bb9b1bcda995b123619808719cb8a282a190630e6d06d7d03e6333ca, + 0xe8b074995703e92a7b9568c90ae160e4d5b81affe628dc1d790241de43d00d0, 0x14354c051802f8704939c9948ef91d89db28fe9513ad7bbf58a4639af347ea86 ); // residue witness c, - let c = fq12( - 0x1baf2a84eb47ce42094fd98972bc4bb0f2936ef400aea71eaff2c663e3a0fc4d, + let c = fqd12( + 0x2d83d9370d66921f9809f802228d8c2f94da4aed085b5e6435aef8af3152d659, + 0x14c0d3c1938d5033729aa4c043979713bfe3c9263e0a4e6c9c8eb8ddf9de2a0b, + 0x2b98462c830cdb18586b44167d1a3aa6d2f16a7212d6e42b66de6b2282d6228e, + 0x1b58a8c80b28d4b2ac484e7a1a985a40eb5220fd7da058b5e6590e8ac38f3639, + 0x16996f9c3c0cd922a9b5196d1eb8f3fc6f606e9ba47e67fb13af9147e61cf9ce, + 0x1675469e152e6aa37ecade2ec93ef0cc5946c1ce858a9c19c80ea152dbbd747f, 0x1386ba1f43d9bfa49764547c97cce737f86a88b32d9129370bdd1c3aaceae690, - 0x19ca8adfe0165968c479453ceac5d78d54beec199fd30af10476e46a7da56127, - 0x8c68ad81fefa3678a4c488228f6ec2e68fab44f5fc386a71edf490d13165baf, - 0xaa529ad6ed3d0a32aa2abd113ef97605f58eea5ace47a9a946899faefcb3895, - 0x1eeed7320d8c8646893377a138b1a265f171e37e7f73a58c52d4ec94e6bc0529, - 0x1e46a4ab1efe63cc304f321e79b74b5e52728df2fc3f3043dcdfcf9f816c568c, 0x2c12b2472cffc96ef1cd313aeae8462296f4ad7b8e6b06073c97b7f0ebf0ad31, - 0x5303c5eded61bd49638d9b64b23971f19c50bc4651ec93df1ee04c676cf5b77, + 0x8c68ad81fefa3678a4c488228f6ec2e68fab44f5fc386a71edf490d13165baf, 0x130ba50aed6232a4885ad91ee99e4a7b2c0d65e4f2ced84de31f0449ad05ca0a, - 0xa5aec882ca48f7ed31209c6ea95b0cd055cbd8c184715ce59c40ccf95c566cd, + 0x1eeed7320d8c8646893377a138b1a265f171e37e7f73a58c52d4ec94e6bc0529, 0x40837988d67f97256bb7e5e121802b523f460b3713e079588a5ff10659cfe2d ); - let c_inverse = fq12( - 0x5b9a079bc26832a0f6c91a8c3d52f0696e128c4dc02c2e7eccd6750879db37f, + let c_inverse = fqd12( + 0x18400abcb12c19de8040443a0558cc23c2f02e53d1fe8972ad6cedb00c2527d9, + 0xe96b53f8d6646ff2b74f71444e23d3d0c6b2450d8eeb5a587edcd9abc660481, + 0x233fdebd9833f6a3463efe169ae6e16566d3644396d79bac92570b73387bfa43, + 0x1d2b702c65f0ad3d2289a23eae1b9906d48c221093e22118a281d59a6536f88, + 0x2772a46a009712d660bdc73d9d40eaa265a65de30ab07d9e7cd1d37c68541c0d, + 0x1dbb5296730ca9b6f7e6743492afcb1131fbd4e55fdda1661509e97bae6635c4, 0x2e555f161b4d72f939ffdc89ec00f1933d46dbba698eb47dd16427d357fc293d, - 0x1b137f9bf629c0dbcdd8087034e1f3557ce533998e4e2566b9961515fe3e8874, - 0x9d878a403981d9dc63f4987d88df92f797412464f26753411b8e7500d316487, - 0x14e05eb80b6f7e23ecfa04a410cfa1cf8036f3161c7d586802b485fba82fa9e9, - 0x35039dc8c011db7eb2c0e91709001ba13c91c6b2a06f5ed32005c4990ed64cb, - 0xb67955a9eed460c7fe5f21790cb806e1a6faa832e5ed9751f4c769b94f233d4, 0x1a87d2b49b7fe718a8aaed495061c6c7ab0f83010aa102badce3b5f057717586, - 0x1426dbe6a25c91a8d3ac59a34c4ea7d7e0075ef206a5dd08a33d1998b58651c1, + 0x9d878a403981d9dc63f4987d88df92f797412464f26753411b8e7500d316487, 0x27acb2e47242c471014d129c1a37d0fb662480c13480796cdc381735384a6c5a, - 0x7459382fd7b5f159e32ae6eb1f5a1ac9adde6e0e347011855cc9f8b5bc89021, + 0x35039dc8c011db7eb2c0e91709001ba13c91c6b2a06f5ed32005c4990ed64cb, 0x2884f79cd78dbef6b64fd2a8af7abbb9cb36d280c0c63074e74f0287d3b2eb2d ); diff --git a/packages/bn254_u256/src/tests/tests.cairo b/packages/bn254_u256/src/tests/tests.cairo index aef1377..19b70d1 100644 --- a/packages/bn254_u256/src/tests/tests.cairo +++ b/packages/bn254_u256/src/tests/tests.cairo @@ -1,15 +1,16 @@ -use super::fixtures::{circuit_setup, residue_witness, proof}; +use super::fixtures::{circuit_setup, residue_witness, proof, schzip}; use bn254_u256::{schzip_verify, bn254_curve, Bn254SchwartzZippelSteps,}; #[test] +#[available_gas(10000000000)] fn verify() { let mut curve = bn254_curve(); let (pi_a, pi_b, pi_c, input, _) = proof(); let circuit = circuit_setup(); let (_f, residue_witness, residue_witness_inv, _, cubic_scale) = residue_witness(); - let remainders = array![]; - let q_rlc_sum = array![]; - let verify = schzip_verify( + let (remainders, q_rlc_sum) = schzip(); + + schzip_verify( ref curve, pi_a, pi_b, @@ -22,6 +23,5 @@ fn verify() { remainders, q_rlc_sum ); - println!("verify: {:?}", verify); assert(true, ''); } diff --git a/packages/bn254_u256/src/utils.cairo b/packages/bn254_u256/src/utils.cairo index 7975f11..58651ed 100644 --- a/packages/bn254_u256/src/utils.cairo +++ b/packages/bn254_u256/src/utils.cairo @@ -1,5 +1,5 @@ use core::traits::Into; -use bn254_u256::{Fq, Fq2, Fq6, Fq12, U256IntoFq, PtG1, PtG2}; +use bn254_u256::{Fq, Fq2, Fq6, Fq12, FqD12, U256IntoFq, PtG1, PtG2}; pub fn g1(x: u256, y: u256) -> PtG1 { let x = x.into(); @@ -33,6 +33,27 @@ pub fn fq(c0: u256) -> Fq { c0.into() } +pub fn fqd12( + r0: u256, + r1: u256, + r2: u256, + r3: u256, + r4: u256, + r5: u256, + r6: u256, + r7: u256, + r8: u256, + r9: u256, + r10: u256, + r11: u256 +) -> FqD12 { + ( + (r0.into(), r1.into(), r2.into(), r3.into(),), + (r4.into(), r5.into(), r6.into(), r7.into(),), + (r8.into(), r9.into(), r10.into(), r11.into(),), + ) +} + pub fn fq2(c0: u256, c1: u256) -> Fq2 { Fq2 { c0: c0.into(), c1: c1.into() } } From dc1a71b379c7dab24bf6698741b6783c7cb8eb69 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 21 Jul 2024 06:20:17 +0530 Subject: [PATCH 73/97] fix failed setting up runner --- packages/bn254_u256/src/pairing/schzip_miller.cairo | 2 ++ packages/bn254_u256/src/pairing/schzip_miller_runner.cairo | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 48d7fe1..cee51f3 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -88,6 +88,7 @@ fn hash_fq2(ref hasher: HashState, a: Fq, b: Fq) { pub fn prepare_sz_commitment( ref curve: Bn254U256Curve, remainders: Array, qrlc: Array, ) -> (SZCommitment, SZCommitmentAccumulator) { + core::internal::revoke_ap_tracking(); let mut rem_coeff_i = 0; let mut hasher = PoseidonImpl::new(); let rem_coeffs_count = remainders.len(); @@ -107,6 +108,7 @@ pub fn prepare_sz_commitment( let remainders_fiat_shamir_felt = hasher.finalize(); println!("remainders_fiat_shamir_felt: {}", remainders_fiat_shamir_felt); let remainders_fiat_shamir: u256 = remainders_fiat_shamir_felt.into(); + core::internal::revoke_ap_tracking(); let mut qrlc_coeff_i = 0; let qrlc_count = qrlc.len(); diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index 73c38f7..530ff26 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -30,6 +30,7 @@ pub impl Miller_Bn254_U256< fn miller_bit_o( ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator ) { // + core::internal::revoke_ap_tracking(); let g16 = runner.g16; let ppc = g16.ppc; @@ -40,6 +41,7 @@ pub impl Miller_Bn254_U256< // 1 bit fn miller_bit_p(ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator) { + core::internal::revoke_ap_tracking(); let g16 = runner.g16; let ppc = g16.ppc; let pi_b = runner.g16.q.pi_b; @@ -56,6 +58,7 @@ pub impl Miller_Bn254_U256< fn miller_bit_n( ref self: Curve, runner: @PreCompute, i: u32, ref acc: Accumulator ) { // + core::internal::revoke_ap_tracking(); let g16 = runner.g16; let ppc = g16.ppc; // use neg q @@ -71,6 +74,7 @@ pub impl Miller_Bn254_U256< // last step fn miller_last(ref self: Curve, runner: @PreCompute, ref acc: Accumulator) { // + core::internal::revoke_ap_tracking(); let g16 = runner.g16; let ppc = g16.ppc; let pi_b = runner.g16.q.pi_b; From c65b4e901b7bc6014f57f73b2405d25e382bfe37 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Sun, 21 Jul 2024 06:22:44 +0530 Subject: [PATCH 74/97] schwartz zippel minor cleanup --- packages/bn254_u256/src/pairing/schzip_steps.cairo | 1 - packages/schwartz_zippel/src/lib.cairo | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index d424389..856896a 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -9,7 +9,6 @@ type SZCAcc = SZCommitmentAccumulator; pub impl Bn254SchwartzZippelSteps of SchZipSteps { fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) {} - fn sz_sqr(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) {} fn sz_zero_bit( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12, lines: Lines ) { diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index f35941b..cf0e331 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -10,7 +10,6 @@ pub type Residue = (CubicScale, Fq12, Fq12); pub trait SchZipSteps { fn sz_init(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12); - fn sz_sqr(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12); fn sz_zero_bit( ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12, lines: Lines> ); From 9dd48f11d98576b7b97615ae8e9a3b4120d12d9e Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 04:37:35 +0530 Subject: [PATCH 75/97] legacy print tweak --- legacy/bn_legacy/src/groth16/schzip/base.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legacy/bn_legacy/src/groth16/schzip/base.cairo b/legacy/bn_legacy/src/groth16/schzip/base.cairo index 067f2a8..4661f51 100644 --- a/legacy/bn_legacy/src/groth16/schzip/base.cairo +++ b/legacy/bn_legacy/src/groth16/schzip/base.cairo @@ -64,7 +64,7 @@ pub impl SchZipMockSteps of SchZipSteps { #[inline(always)] fn sz_init(self: @SchZipMock, ref f: Fq12, f_nz: NonZero) { if *self.print { - println!("from schzip_runner import fq12, f034, fq6, sz_print, sz_inv_verify",); + println!("from schzip_runner import fq12, f034, fq6, sz_finalize, sz_inv_verify",); println!( "from schzip_runner import sz_zero_bit, sz_nz_bit, sz_last_step, sz_post_miller" ); From 06d20dd1b4920ca2eb0087c2544cae2d75037e0e Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 04:40:29 +0530 Subject: [PATCH 76/97] miller functions refactor --- .../src/pairing/schzip_miller.cairo | 25 +++++++++++++------ packages/bn254_u256/src/pairing/utils.cairo | 2 +- packages/schwartz_zippel/src/eval.cairo | 7 ++---- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index cee51f3..1f393b3 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -18,7 +18,7 @@ use pairing::{LineFn, StepLinesGet, LinesArrayGet}; use pairing::{PairingUtils, CubicScale}; use core::hash::HashStateTrait; use core::poseidon::{PoseidonImpl, HashState}; -use schwartz_zippel::SchZipSteps; +use schwartz_zippel::{SchZipSteps, Residue}; pub type InputConstraintPoints = Array; @@ -40,9 +40,9 @@ fn schzip_miller< setup: Groth16Circuit, schzip: TSchZip, schzip_acc: SZCommitmentAccumulator, -) -> SZAccumulator { // +) -> (FqD12, SZAccumulator) { // // Compute k from ic and public_inputs - let Groth16Circuit { alpha_beta: _, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; + let Groth16Circuit { alpha_beta, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; let k: PtG1 = curve.process_inputs_and_ic(ic, inputs); @@ -64,7 +64,8 @@ fn schzip_miller< f: residue_witness_inv, g2: q, line_index: 0, schzip: schzip_acc }; - ate_miller_loop(ref curve, precomp, q_acc) + let q_acc = ate_miller_loop(ref curve, precomp, q_acc); + (alpha_beta, q_acc) } fn hash_fq2(ref hasher: HashState, a: Fq, b: Fq) { @@ -106,7 +107,7 @@ pub fn prepare_sz_commitment( rem_coeff_i += 1; }; let remainders_fiat_shamir_felt = hasher.finalize(); - println!("remainders_fiat_shamir_felt: {}", remainders_fiat_shamir_felt); + // println!("remainders_fiat_shamir_felt: {}", remainders_fiat_shamir_felt); let remainders_fiat_shamir: u256 = remainders_fiat_shamir_felt.into(); core::internal::revoke_ap_tracking(); @@ -132,7 +133,7 @@ pub fn prepare_sz_commitment( SZCommitment { remainders, fiat_shamir_powers, - rem_fiat_shamir_powers: fs_pow(ref curve, fq(remainders_fiat_shamir), 68), + rlc_fiat_shamir: fs_pow(ref curve, fq(remainders_fiat_shamir), 68), p12_x, qrlc }, @@ -168,9 +169,19 @@ pub fn schzip_verify( ) { // let p = fs_pow(ref curve, fq(2), 6); // println!("{} {} {} {} {} {}", p[0], p[1], p[2], p[3], p[4], p[5]); let (sz, sz_acc) = prepare_sz_commitment(ref curve, schzip_remainders, schzip_qrlc); + let sz_snap = @sz; // miller loop result - schzip_miller( + let (alpha_beta, mut acc) = schzip_miller( ref curve, pi_a, pi_b, pi_c, inputs, residue_witness, residue_witness_inv, setup, sz, sz_acc ); + + curve + .sz_verify( + sz_snap, + ref acc.schzip, + acc.f, + alpha_beta, + (cubic_scale, residue_witness, residue_witness_inv,) + ); } diff --git a/packages/bn254_u256/src/pairing/utils.cairo b/packages/bn254_u256/src/pairing/utils.cairo index 8534618..47173c3 100644 --- a/packages/bn254_u256/src/pairing/utils.cairo +++ b/packages/bn254_u256/src/pairing/utils.cairo @@ -8,7 +8,7 @@ use bn254_u256::{Bn254U256Curve}; pub struct SZCommitment { pub remainders: Array, pub qrlc: Array, - pub rem_fiat_shamir_powers: Array, + pub rlc_fiat_shamir: Array, pub fiat_shamir_powers: Array, pub p12_x: Fq, } diff --git a/packages/schwartz_zippel/src/eval.cairo b/packages/schwartz_zippel/src/eval.cairo index f1db322..dce15fc 100644 --- a/packages/schwartz_zippel/src/eval.cairo +++ b/packages/schwartz_zippel/src/eval.cairo @@ -16,10 +16,8 @@ pub impl SchZipEval< +Drop > of SchZipEvalTrait { fn eval_fq12(ref self: TCurve, a: Fq12Direct, fiat_shamir: @Array) -> TFq { - let ((a0, a1, a2, a3), (a4, a5, a6, a7), (a8, a9, a10, a11)) = a; - - // First term doesn't require multiplication - let mut acc = a0; + let ((mut acc, a1, a2, a3), (a4, a5, a6, a7), (a8, a9, a10, a11)) = a; + // First term a0 doesn't require multiplication and is used as accumulator // terms 1 to 11 let term_1 = self.mul((*fiat_shamir[1]), a1); @@ -66,7 +64,6 @@ pub impl SchZipEval< acc = self.add(acc, term_3); acc = self.add(acc, term_7); acc = self.add(acc, term_9); - acc } From 10b1fb22d548ad75bbc5e859cd8a453bdb5d5ced Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 04:42:01 +0530 Subject: [PATCH 77/97] bn254 contract and schzip fq12 direct --- packages/bn254_u256_contract/src/lib.cairo | 28 +++++++++++----------- packages/schwartz_zippel/src/lib.cairo | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/bn254_u256_contract/src/lib.cairo b/packages/bn254_u256_contract/src/lib.cairo index bf73a62..d131988 100644 --- a/packages/bn254_u256_contract/src/lib.cairo +++ b/packages/bn254_u256_contract/src/lib.cairo @@ -1,25 +1,25 @@ pub use bn254_u256::{ - schzip_verify, PtG1, PtG2, Fq, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, bn254_curve, + schzip_verify, PtG1, PtG2, Fq, FqD12, CubicScale, Groth16Circuit, Bn254U256Curve, bn254_curve, LnArrays, InputConstraintPoints }; #[starknet::interface] trait IBN_Pairing { - // fn final_exponentiation(self: @T, a: Fq12) -> Fq12; - // fn final_exponentiation_bench(self: @T) -> Fq12; - // fn pairing_bench(self: @T) -> Fq12; - // fn miller_bench(self: @T) -> Fq12; + // fn final_exponentiation(self: @T, a: FqD12) -> FqD12; + // fn final_exponentiation_bench(self: @T) -> FqD12; + // fn pairing_bench(self: @T) -> FqD12; + // fn miller_bench(self: @T) -> FqD12; fn verify( ref self: T, pi_a: PtG1, pi_b: PtG2, pi_c: PtG1, inputs: Array, - residue_witness: Fq12, - residue_witness_inv: Fq12, + residue_witness: FqD12, + residue_witness_inv: FqD12, cubic_scale: CubicScale, - setup: Groth16Circuit, - schzip_remainders: Array, + setup: Groth16Circuit, + schzip_remainders: Array, schzip_qrlc: Array, ); } @@ -29,7 +29,7 @@ mod BN_Pairing { use super::{ schzip_verify, bn254_curve, { - PtG1, PtG2, Fq, Fq12, CubicScale, Groth16Circuit, Bn254U256Curve, LnArrays, + PtG1, PtG2, Fq, FqD12, CubicScale, Groth16Circuit, Bn254U256Curve, LnArrays, InputConstraintPoints } }; @@ -48,11 +48,11 @@ mod BN_Pairing { pi_b: PtG2, pi_c: PtG1, inputs: Array, - residue_witness: Fq12, - residue_witness_inv: Fq12, + residue_witness: FqD12, + residue_witness_inv: FqD12, cubic_scale: CubicScale, - setup: Groth16Circuit, - schzip_remainders: Array, + setup: Groth16Circuit, + schzip_remainders: Array, schzip_qrlc: Array, ) { let mut curve = bn254_curve(); diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index cf0e331..01d4c37 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -1,12 +1,12 @@ pub mod eval; pub use eval::{SchZipEvalTrait, SchZipEval}; -pub use fq_types::{Fq2, Fq3, F12S034 as FS034, Fq12}; +pub use fq_types::{Fq2, Fq3, F12S034 as FS034, Fq12Direct}; use pairing::CubicScale; pub type Lines = (FS034, FS034, FS034); pub type F034X2 = (FS034, FS034); pub type LinesDbl = (F034X2, F034X2, F034X2); -pub type Residue = (CubicScale, Fq12, Fq12); +pub type Residue = (CubicScale, Fq12Direct, Fq12Direct); pub trait SchZipSteps { fn sz_init(ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12); From 2713d7b31bea201d73247518a499da576a4a46bd Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 04:42:58 +0530 Subject: [PATCH 78/97] schzip step utils --- .../bn254_u256/src/pairing/schzip_steps.cairo | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index 856896a..cda9fcd 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -1,3 +1,5 @@ +use schwartz_zippel::eval::SchZipEvalTrait; +use bn254_u256::print::{FqDisplay}; use bn254_u256::{ Fq, Fq2, Fq3, Fq12, FqD12, FqD4, scale_9, Bn254U256Curve, Bn254FqOps, SZCommitment, SZCommitmentAccumulator @@ -7,6 +9,36 @@ use schwartz_zippel::{SchZipSteps, SchZipEval, Lines, FS034, F034X2, LinesDbl, R type Curve = Bn254U256Curve; type SZCAcc = SZCommitmentAccumulator; +fn acc_mul_eval_12(ref self: Curve, a: FqD12, ref acc: Fq, fiat_shamir: @Array) { + acc = self.mul(acc, self.eval_fq12(a, fiat_shamir)); +} + +fn acc_mul_eval_034_x3(ref self: Curve, lines: Lines, ref acc: Fq, fiat_shamir: @Array) { + let (l1, l2, l3) = lines; + acc = self.mul(acc, self.eval_f1379(direct_f034(ref self, l1), fiat_shamir)); + acc = self.mul(acc, self.eval_f1379(direct_f034(ref self, l2), fiat_shamir)); + acc = self.mul(acc, self.eval_f1379(direct_f034(ref self, l3), fiat_shamir)); +} + +fn acc_equation_eval(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, mut eval: Fq) { + // multiply fiat shamir for rlc + eval = self.mul(eval, *sz.rlc_fiat_shamir.at(sz_acc.index)); + + // accumulate + sz_acc.rhs_lhs = self.add(sz_acc.rhs_lhs, eval); + sz_acc.index += 1; +} + +fn acc_equation_lhs_rem(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, mut eval: Fq) { + // evaluate remainder and cache it for later + sz_acc.rem_cache = self.eval_fq12(*(sz.remainders.at(sz_acc.index)), sz.fiat_shamir_powers); + + // sub remainder from accumulator + eval = self.sub(eval, sz_acc.rem_cache); + + acc_equation_eval(ref self, sz, ref sz_acc, eval) +} + pub impl Bn254SchwartzZippelSteps of SchZipSteps { fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) {} fn sz_zero_bit( From 548869aa50987aea613bcd7724dfe3e26f06121f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 04:43:24 +0530 Subject: [PATCH 79/97] schzip steps --- .../bn254_u256/src/pairing/schzip_steps.cairo | 88 ++++++++++++++++--- packages/schwartz_zippel/src/lib.cairo | 2 +- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index cda9fcd..3cc8aee 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -40,12 +40,28 @@ fn acc_equation_lhs_rem(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, } pub impl Bn254SchwartzZippelSteps of SchZipSteps { - fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) {} + fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) { // + // Compute next remainder + } fn sz_zero_bit( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12, lines: Lines ) { - let (_l1, _l2, _l3) = lines; - let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); + // equation equivalence with p12 = x^12 + 18x^6 + 82 + // f * f * lines = q * p12 + remainder + // all quotients are combined with rlc, so we isolate q and check equivalence at the end + // thus the equation becomes, + // f * f * lines - remainder = q * p12 + // remainder here is f for the next equation so we use it with sz_acc.rem_cache + // at the end we multiply it with rem_fiat_shmir for RLC + + // init eval as a square of previous remainder evaluation cache + let mut eval: Fq = self.sqr(sz_acc.rem_cache); + + // eval and accumulate lines + acc_mul_eval_034_x3(ref self, lines, ref eval, sz.fiat_shamir_powers); + + // accumulate equation and remainder + acc_equation_lhs_rem(ref self, sz, ref sz_acc, eval) } fn sz_nz_bit( @@ -56,17 +72,53 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps, witness: FqD12 ) { - let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); - let _wit_eval: Fq = self.eval_fq12(witness, sz.fiat_shamir_powers); + // equation equivalence with p12 = x^12 + 18x^6 + 82 + // f * f * lines * witness = q * p12 + remainder + // all quotients are combined with rlc, so we isolate q and check equivalence at the end + // thus the equation becomes, + // f * f * lines * witness - remainder = q * p12 + // remainder here is f for the next equation so we use it with sz_acc.rem_cache + // at the end we multiply it with rem_fiat_shmir for RLC + + // init eval as a square of previous remainder evaluation cache + let mut eval: Fq = self.sqr(sz_acc.rem_cache); + + // eval and accumulate lines + let ((l10, l11), (l20, l21), (l30, l31)) = lines; + acc_mul_eval_034_x3(ref self, (l10, l20, l30), ref eval, sz.fiat_shamir_powers); + acc_mul_eval_034_x3(ref self, (l11, l21, l31), ref eval, sz.fiat_shamir_powers); + + // eval and accumulate witness + acc_mul_eval_12(ref self, witness, ref eval, sz.fiat_shamir_powers); + + // accumulate equation and remainder + acc_equation_lhs_rem(ref self, sz, ref sz_acc, eval) } fn sz_last_step( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12, lines: LinesDbl ) { - let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); + // equation equivalence with p12 = x^12 + 18x^6 + 82 + // f * f * lines = q * p12 + remainder + // all quotients are combined with rlc, so we isolate q and check equivalence at the end + // thus the equation becomes, + // f * f * lines - remainder = q * p12 + // remainder here is f for the next equation so we use it with sz_acc.rem_cache + // at the end we multiply it with rem_fiat_shmir for RLC + + // init eval as a square of previous remainder evaluation cache + let mut eval: Fq = self.sqr(sz_acc.rem_cache); + + // eval and accumulate lines + let ((l10, l11), (l20, l21), (l30, l31)) = lines; + acc_mul_eval_034_x3(ref self, (l10, l20, l30), ref eval, sz.fiat_shamir_powers); + acc_mul_eval_034_x3(ref self, (l11, l21, l31), ref eval, sz.fiat_shamir_powers); + + // accumulate equation and remainder + acc_equation_lhs_rem(ref self, sz, ref sz_acc, eval) } - fn sz_post_miller( + fn sz_verify( ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, @@ -74,9 +126,25 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps ) -> bool { - let _f_eval: Fq = self.eval_fq12(f, sz.fiat_shamir_powers); - let _albe_eval: Fq = self.eval_fq12(alpha_beta, sz.fiat_shamir_powers); - false + // println!("sz_verify: {} {} {}", sz_acc.index, sz_acc.rhs_lhs, sz_acc.rem_cache); + + let (cubic_scale, witness, witness_inv) = residue; + + // final step, + // f * alpha_beta * cubic_scale + // * ```F(x) * RQ(x) * RInvQ2(x) * RQ3(x) * CubicScale(x) = R(x) + Q(x) * P12(x)``` + + let mut eval: Fq = self.sqr(sz_acc.rem_cache); + acc_mul_eval_12(ref self, witness, ref eval, sz.fiat_shamir_powers); + + // witness * witness_inv = 1 + q * p12 + // or, isolating q again, + // witness * witness_inv - 1 = q * p12 + let mut eval = self.eval_fq12(witness, sz.fiat_shamir_powers); // witness + acc_mul_eval_12(ref self, witness_inv, ref eval, sz.fiat_shamir_powers); // witness_inv + eval = self.sub(eval, 1_u256.into()); + // This is a separate verification and shouldn't change remainder + acc_equation_eval(ref self, sz, ref sz_acc, eval); } } diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index 01d4c37..d1df499 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -25,7 +25,7 @@ pub trait SchZipSteps { ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12, lines: LinesDbl> ); - fn sz_post_miller( + fn sz_verify( ref self: TCurve, sz: @T, ref sz_acc: TAcc, From 43f36b087fa5e5ce552c5d692d354055fd56d8eb Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 05:11:17 +0530 Subject: [PATCH 80/97] bn254 27th roots --- packages/bn254_u256/src/curve.cairo | 38 ++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/bn254_u256/src/curve.cairo b/packages/bn254_u256/src/curve.cairo index 5ffb62d..8d51aa8 100644 --- a/packages/bn254_u256/src/curve.cairo +++ b/packages/bn254_u256/src/curve.cairo @@ -1,4 +1,4 @@ -use bn254_u256::{Fq, U256IntoFq, Fq2, fq2, fq3, Bn254FqOps, Bn254FqUtils}; +use bn254_u256::{Fq, U256IntoFq, Fq2, FqD12, fq2, fq3, Bn254FqOps, Bn254FqUtils}; use ec_groups::{Affine, ECGroupUtils}; pub use ec_groups::AffineOpsBn; pub use pairing::CubicScale; @@ -32,3 +32,39 @@ impl PtG2One of ECGroupUtils { } } } + +pub const FQ_0: Fq = Fq { c0: 0x0 }; +pub const ROOT_27TH: FqD12 = + ( + (FQ_0, FQ_0, FQ_0, FQ_0), + ( + Fq { c0: 0x778f7e113269a67bd294b9c757d6f7aa4c634773692b9376d090b20e5ccfca }, + FQ_0, + FQ_0, + FQ_0 + ), + ( + FQ_0, + FQ_0, + Fq { c0: 0x279a0a9dbd98089c184dac0e71909eb223ea52bfc24790f6d545aed52a2fbdb8 }, + FQ_0 + ), + ); + + +pub const ROOT_27TH_SQ: FqD12 = + ( + ( + FQ_0, + FQ_0, + Fq { c0: 0x2d47bdc1ad79a2d8f25dc130d86b34cb0fbe750ec2778d80388a54eae80e565b }, + FQ_0 + ), + (FQ_0, FQ_0, FQ_0, FQ_0), + ( + Fq { c0: 0x10bd041a04b5422922463bd8b6519b59af036109a228aa43fdb7f215226ece12 }, + FQ_0, + FQ_0, + FQ_0 + ), + ); From 9d0fd6d60f6ab8c639e11fb10d0f1231123a7368 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 05:41:33 +0530 Subject: [PATCH 81/97] new sz final and verify --- .../bn254_u256/src/pairing/schzip_steps.cairo | 57 +++++++++++++++++-- packages/schwartz_zippel/src/lib.cairo | 13 ++++- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index 3cc8aee..1066924 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -43,6 +43,14 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps ) { @@ -64,6 +72,13 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps ) { @@ -118,15 +139,26 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps - ) -> bool { - // println!("sz_verify: {} {} {}", sz_acc.index, sz_acc.rhs_lhs, sz_acc.rem_cache); + r_pow_q: FqD12, + r_inv_q2: FqD12, + r_pow_q3: FqD12, + cubic_scale: CubicScale + ) { let (cubic_scale, witness, witness_inv) = residue; @@ -137,6 +169,21 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps bool { // witness * witness_inv = 1 + q * p12 // or, isolating q again, // witness * witness_inv - 1 = q * p12 diff --git a/packages/schwartz_zippel/src/lib.cairo b/packages/schwartz_zippel/src/lib.cairo index d1df499..763c102 100644 --- a/packages/schwartz_zippel/src/lib.cairo +++ b/packages/schwartz_zippel/src/lib.cairo @@ -25,12 +25,19 @@ pub trait SchZipSteps { ref self: TCurve, sz: @T, ref sz_acc: TAcc, ref f: TFq12, lines: LinesDbl> ); - fn sz_verify( + fn sz_final( ref self: TCurve, sz: @T, ref sz_acc: TAcc, - f: TFq12, + ref f: TFq12, alpha_beta: TFq12, - residue: Residue + r_pow_q: TFq12, + r_inv_q2: TFq12, + r_pow_q3: TFq12, + cubic_scale: CubicScale + ); + + fn sz_verify( + ref self: TCurve, sz: @T, ref sz_acc: TAcc, f: TFq12, witness: TFq12, witness_inv: TFq12, ) -> bool; } From 9865deee3577ed61483a1a3b1bb1cce47fa8f13f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 05:42:01 +0530 Subject: [PATCH 82/97] calls for new sz functions --- .../src/pairing/schzip_miller.cairo | 48 +++++++++++++------ packages/bn_ate_loop/src/ate_loop.cairo | 6 +-- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 1f393b3..41b0573 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -37,10 +37,11 @@ fn schzip_miller< inputs: Array, residue_witness: FqD12, residue_witness_inv: FqD12, + cubic_scale: CubicScale, setup: Groth16Circuit, schzip: TSchZip, schzip_acc: SZCommitmentAccumulator, -) -> (FqD12, SZAccumulator) { // +) -> SZAccumulator { // // Compute k from ic and public_inputs let Groth16Circuit { alpha_beta, gamma, gamma_neg, delta, delta_neg, lines, ic, } = setup; @@ -64,8 +65,24 @@ fn schzip_miller< f: residue_witness_inv, g2: q, line_index: 0, schzip: schzip_acc }; - let q_acc = ate_miller_loop(ref curve, precomp, q_acc); - (alpha_beta, q_acc) + let mut q_acc = ate_miller_loop(ref curve, @precomp, q_acc); + + let r_pow_q = residue_witness; // @TODO forbenius map q + let r_inv_q2 = residue_witness_inv; // @TODO forbenius map q2 + let r_pow_q3 = residue_witness; // @TODO forbenius map q3 + + curve + .sz_final( + @precomp.schzip, + ref q_acc.schzip, + ref q_acc.f, + alpha_beta, + r_pow_q, + r_inv_q2, + r_pow_q3, + cubic_scale + ); + q_acc } fn hash_fq2(ref hasher: HashState, a: Fq, b: Fq) { @@ -122,7 +139,7 @@ pub fn prepare_sz_commitment( qrlc_coeff_i += 1; }; let fiat_shamir: u256 = hasher.finalize().into(); - let fiat_shamir_powers = fs_pow(ref curve, fq(fiat_shamir), 40); + let fiat_shamir_powers = fs_pow(ref curve, fq(fiat_shamir), 76); // x^12 - 18x^6 + 82 let _18x6 = curve.mul(fq(18), *fiat_shamir_powers[6]); // 18x^6 @@ -172,16 +189,19 @@ pub fn schzip_verify( let sz_snap = @sz; // miller loop result - let (alpha_beta, mut acc) = schzip_miller( - ref curve, pi_a, pi_b, pi_c, inputs, residue_witness, residue_witness_inv, setup, sz, sz_acc + let mut acc = schzip_miller( + ref curve, + pi_a, + pi_b, + pi_c, + inputs, + residue_witness, + residue_witness_inv, + cubic_scale, + setup, + sz, + sz_acc ); - curve - .sz_verify( - sz_snap, - ref acc.schzip, - acc.f, - alpha_beta, - (cubic_scale, residue_witness, residue_witness_inv,) - ); + curve.sz_verify(sz_snap, ref acc.schzip, acc.f, residue_witness, residue_witness_inv,); } diff --git a/packages/bn_ate_loop/src/ate_loop.cairo b/packages/bn_ate_loop/src/ate_loop.cairo index bd02ae1..ec3858c 100644 --- a/packages/bn_ate_loop/src/ate_loop.cairo +++ b/packages/bn_ate_loop/src/ate_loop.cairo @@ -23,12 +23,12 @@ pub fn ate_miller_loop< +Drop, +Drop >( - ref curve: TCurve, runner: TRunner, mut q_acc: TAccumulator + ref curve: TCurve, runner: @TRunner, mut q_acc: TAccumulator ) -> TAccumulator { core::internal::revoke_ap_tracking(); - _loop_inner_1_of_2(@runner, ref curve, ref q_acc); - _loop_inner_2_of_2(@runner, ref curve, ref q_acc); + _loop_inner_1_of_2(runner, ref curve, ref q_acc); + _loop_inner_2_of_2(runner, ref curve, ref q_acc); q_acc } From daf149474b58a54fc69408f1d07d999a4b61b55c Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 05:42:21 +0530 Subject: [PATCH 83/97] sz steps done --- .../bn254_u256/src/pairing/schzip_steps.cairo | 53 ++++++++++++++----- packages/schwartz_zippel/src/eval.cairo | 4 +- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index 1066924..bd80bc1 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -1,10 +1,12 @@ use schwartz_zippel::eval::SchZipEvalTrait; +use bn254_u256::curve::{ROOT_27TH, ROOT_27TH_SQ}; use bn254_u256::print::{FqDisplay}; use bn254_u256::{ Fq, Fq2, Fq3, Fq12, FqD12, FqD4, scale_9, Bn254U256Curve, Bn254FqOps, SZCommitment, SZCommitmentAccumulator }; use schwartz_zippel::{SchZipSteps, SchZipEval, Lines, FS034, F034X2, LinesDbl, Residue}; +use pairing::{CubicScale}; type Curve = Bn254U256Curve; type SZCAcc = SZCommitmentAccumulator; @@ -63,7 +65,7 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps ) { // equation equivalence with p12 = x^12 + 18x^6 + 82 - // f * f * lines = q * p12 + remainder + // f * lines = q * p12 + remainder // all quotients are combined with rlc, so we isolate q and check equivalence at the end // thus the equation becomes, - // f * f * lines - remainder = q * p12 + // f * lines - remainder = q * p12 // remainder here is f for the next equation so we use it with sz_acc.rem_cache // at the end we multiply it with rem_fiat_shmir for RLC - // init eval as a square of previous remainder evaluation cache - let mut eval: Fq = self.sqr(sz_acc.rem_cache); + // init eval from previous remainder evaluation cache + let mut eval: Fq = sz_acc.rem_cache; // eval and accumulate lines let ((l10, l11), (l20, l21), (l30, l31)) = lines; @@ -159,15 +161,38 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps {}, + CubicScale::One => { + let ((_, _, _, _), (c4, _, _, _), (_, _, c10, _),) = ROOT_27TH; + let cubic_scale = self + .add(self.mul(c4, *fiat_shamir[4]), self.mul(c10, *fiat_shamir[10])); + eval = self.mul(eval, cubic_scale); + }, + CubicScale::Two => { + let ((_, _, c2, _), (_, _, _, _), (c8, _, _, _),) = ROOT_27TH_SQ; + let cubic_scale = self + .add(self.mul(c2, *fiat_shamir[2]), self.mul(c8, *fiat_shamir[8])); + eval = self.mul(eval, cubic_scale); + }, + }; - let mut eval: Fq = self.sqr(sz_acc.rem_cache); - acc_mul_eval_12(ref self, witness, ref eval, sz.fiat_shamir_powers); + // accumulate equation and remainder + // remainder is one + eval = self.sub(eval, 1_u256.into()); + // This is a separate verification and shouldn't change remainder + acc_equation_eval(ref self, sz, ref sz_acc, eval); + } // Handles Schwartz Zippel witness invert verification // * F, FInv ∈ Fq12, miller loop aggregation @@ -184,6 +209,7 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps bool { + // println!("sz_verify: {}", sz_acc.index); // witness * witness_inv = 1 + q * p12 // or, isolating q again, // witness * witness_inv - 1 = q * p12 @@ -192,6 +218,9 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps { fn eval_fq12(ref self: TCurve, a: Fq12Direct, fiat_shamir: @Array) -> TFq; fn eval_f1379(ref self: TCurve, a: Fq4Direct, fiat_shamir: @Array) -> TFq; - fn eval_poly(ref self: TCurve, a: Array, fiat_shamir: @Array) -> TFq; + fn eval_poly(ref self: TCurve, a: @Array, fiat_shamir: @Array) -> TFq; } pub impl SchZipEval< TCurve, @@ -67,7 +67,7 @@ pub impl SchZipEval< acc } - fn eval_poly(ref self: TCurve, a: Array, fiat_shamir: @Array) -> TFq { + fn eval_poly(ref self: TCurve, a: @Array, fiat_shamir: @Array) -> TFq { let len = a.len(); if len == 0 { From f03daea096839e49c8fbf19afd5e6743d73abc47 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Tue, 23 Jul 2024 18:04:16 +0530 Subject: [PATCH 84/97] fq2/3 conjugate and scale --- packages/fq_types/src/common.cairo | 46 ++++++++++++++++++++++++++++++ packages/fq_types/src/lib.cairo | 4 ++- packages/pairing/src/utils.cairo | 29 ++++++------------- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/packages/fq_types/src/common.cairo b/packages/fq_types/src/common.cairo index da1a9db..94d3354 100644 --- a/packages/fq_types/src/common.cairo +++ b/packages/fq_types/src/common.cairo @@ -252,3 +252,49 @@ pub impl Fq3Ops< Fq3 { c0: new_c0, c1: new_c1, c2: new_c2 } } } + +pub fn fq3_scale, +Drop, +Copy>( + ref curve: TCurve, a: Fq3, x: TFq +) -> Fq3 { + let Fq3 { c0, c1, c2 } = a; + Fq3 { + c0: FqOps::mul(ref curve, x, c0), + c1: FqOps::mul(ref curve, x, c1), + c2: FqOps::mul(ref curve, x, c2), + } +} + +pub fn fq2_scale, +Drop, +Copy>( + ref curve: TCurve, a: Fq2, x: TFq +) -> Fq2 { + let Fq2 { c0, c1 } = a; + Fq2 { c0: FqOps::mul(ref curve, x, c0), c1: FqOps::mul(ref curve, x, c1), } +} + +pub fn fq2_conjugate, +Drop>( + ref curve: TCurve, a: Fq2 +) -> Fq2 { + let Fq2 { c0, c1 } = a; + Fq2 { c0, c1: FqOps::neg(ref curve, c1) } +} + +// Field operation for β = -1 +// More efficient as it replaces mul nr with neg +pub fn fq2_sqr_nbeta, +Drop, +Copy>( + ref self: TCurve, lhs: Fq2 +) -> Fq2 { + // Complex squaring + let Fq2 { c0: a0, c1: a1 } = lhs; + // v = a0 * a1; + let v = FqOps::mul(ref self, a0, a1); // a0 * a1 + + // (a0 + a1) * (a0 + βa1) - v - βv + let t0 = FqOps::add(ref self, a0, a1); // a0 + a1 + let a1_nr = FqOps::neg(ref self, a1); // βa1 + let t1 = FqOps::add(ref self, a0, a1_nr); // a0 + βa1 + let c0 = FqOps::mul(ref self, t0, t1); // (a0 + a1) * (a0 + βa1) + // c0 = (a0 + a1) * (a0 + βa1) - v - βv, but β = -1 so - v - βv cancels out + // c1 = v + v; + let c1 = FqOps::add(ref self, v, v); // 2v + Fq2 { c0, c1 } +} diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index d8e850d..48d3e8c 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -78,4 +78,6 @@ pub type Fq4Direct = (T, T, T, T); pub type Fq12Direct = (Fq4Direct, Fq4Direct, Fq4Direct); pub type F12S01234Direct = ((T, T, T, T, T), (T, T, T, T, T)); -pub use common::{Fq2Ops, Fq2PartialEq, Fq3Ops, Fq3PartialEq}; +pub use common::{ + Fq2Ops, Fq2PartialEq, Fq3Ops, Fq3PartialEq, fq2_scale, fq3_scale, fq2_conjugate, fq2_sqr_nbeta +}; diff --git a/packages/pairing/src/utils.cairo b/packages/pairing/src/utils.cairo index 24a1aba..38350f6 100644 --- a/packages/pairing/src/utils.cairo +++ b/packages/pairing/src/utils.cairo @@ -1,4 +1,4 @@ -use fq_types::{FieldOps, FieldUtils, Fq2, F12S034}; +use fq_types::{FieldOps, FieldUtils, Fq2, F12S034, fq2_scale, fq2_conjugate}; use ec_groups::{Affine, ECOperations}; use pairing::{PPrecompute, LineFn}; @@ -12,8 +12,6 @@ pub trait PairingUtilsTrait { fn point_and_slope_at_p( ref self: TCurve, slope: Fq2, s: Affine>, ppc: @PPrecompute ) -> F034; - fn scale_fq2(ref self: TCurve, a: Fq2, x: TFq) -> Fq2; - fn conjugate_fq2(ref self: TCurve, a: Fq2) -> Fq2; // region point operations fn step_dbl_add( @@ -71,8 +69,8 @@ pub impl PairingUtils< #[inline(always)] fn line_fn_at_p(ref self: TCurve, line: LineFn>, ppc: @PPrecompute) -> F034 { F034 { - c3: self.scale_fq2(line.slope, *ppc.neg_x_over_y), - c4: self.scale_fq2(line.c, *ppc.y_inv), + c3: fq2_scale(ref self, line.slope, *ppc.neg_x_over_y), + c4: fq2_scale(ref self, line.c, *ppc.y_inv), } } @@ -83,21 +81,11 @@ pub impl PairingUtils< // 𝝺x - y let c = self.sub(self.mul(slope, s.x), s.y); F034 { - c3: self.scale_fq2(slope, *ppc.neg_x_over_y), // 𝝺x/y - c4: self.scale_fq2(c, *ppc.y_inv), // c/y + c3: fq2_scale(ref self, slope, *ppc.neg_x_over_y), // 𝝺x/y + c4: fq2_scale(ref self, c, *ppc.y_inv), // c/y } } - // Maybe there's a better place for these functions, here for now - fn scale_fq2(ref self: TCurve, a: Fq2, x: TFq) -> Fq2 { - let Fq2 { c0, c1 } = a; - Fq2 { c0: self.mul(x, c0), c1: self.mul(x, c1) } - } - fn conjugate_fq2(ref self: TCurve, a: Fq2) -> Fq2 { - let Fq2 { c0, c1 } = a; - Fq2 { c0, c1: self.neg(c1) } - } - // https://eprint.iacr.org/2022/1162 (Section 6.1) // computes acc = acc + q + acc and line evals for p // returns product of line evaluations to multiply with f @@ -177,13 +165,14 @@ pub impl PairingUtils< // πₚ(x,y) = (xp,yp) // Q1 = π(Q) let q1 = Affine { - x: self.mul(self.conjugate_fq2(q.x), pi_map.PiQ1X2), - y: self.mul(self.conjugate_fq2(q.y), pi_map.PiQ1X3), + x: self.mul(fq2_conjugate(ref self, q.x), pi_map.PiQ1X2), + y: self.mul(fq2_conjugate(ref self, q.y), pi_map.PiQ1X3), }; // Q2 = -π²(Q) let q2 = Affine { - x: self.scale_fq2(q.x, pi_map.PiQ2X2), y: self.neg(self.scale_fq2(q.y, pi_map.PiQ2X3)), + x: fq2_scale(ref self, q.x, pi_map.PiQ2X2), + y: self.neg(fq2_scale(ref self, q.y, pi_map.PiQ2X3)), }; // Line 10: if u < 0 then T ← −T, f ← fp6 From 7c581d69895c7620ccef14b2547fb9de3ca4f82a Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 04:56:39 +0530 Subject: [PATCH 85/97] fq_types: frobenius trait --- packages/fq_types/src/frobenius.cairo | 27 +++++++++++++++++++++++++++ packages/fq_types/src/lib.cairo | 3 +++ 2 files changed, 30 insertions(+) create mode 100644 packages/fq_types/src/frobenius.cairo diff --git a/packages/fq_types/src/frobenius.cairo b/packages/fq_types/src/frobenius.cairo new file mode 100644 index 0000000..34059f9 --- /dev/null +++ b/packages/fq_types/src/frobenius.cairo @@ -0,0 +1,27 @@ +use fq_types::{Fq2, Fq3, FieldOps, FieldUtils, fq2_conjugate, fq2_scale}; + +#[derive(Drop)] +pub struct FrobeniusFq12Maps { + pub frob1_c1: Fq2, + pub frob2_c1: Fq2, + pub frob3_c1: Fq2, + pub fq6: FrobeniusFq6Maps, +} + +#[derive(Drop)] +pub struct FrobeniusFq6Maps { + pub frob1_c1: Fq2, + pub frob1_c2: Fq2, + pub frob2_c1: Fq2, + pub frob2_c2: Fq2, + pub frob3_c1: Fq2, + pub frob3_c2: Fq2, +} + + +pub trait Frobenius1To3 { + fn frob1(ref self: TCurve, a: TFq, maps: @TFrobMap) -> TFq; + fn frob2(ref self: TCurve, a: TFq, maps: @TFrobMap) -> TFq; + fn frob3(ref self: TCurve, a: TFq, maps: @TFrobMap) -> TFq; +} + diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index 48d3e8c..57c76a8 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -1,4 +1,7 @@ pub mod common; +pub mod frobenius; + +pub use frobenius::{Frobenius1To3, FrobeniusFq12Maps, FrobeniusFq6Maps}; #[derive(Copy, Drop, Serde)] pub struct Fq2 { From 92d898bbc0564c4b69789d3fdfc21081d2d3f4cc Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 04:57:14 +0530 Subject: [PATCH 86/97] bn254 frobenius maps --- packages/bn254_u256/src/curve.cairo | 46 ++++++++++++++ packages/bn254_u256/src/lib.cairo | 14 ++--- packages/fq_types/src/frobenius.cairo | 87 +++++++++++++++++++++++++++ packages/fq_types/src/lib.cairo | 1 + 4 files changed, 140 insertions(+), 8 deletions(-) diff --git a/packages/bn254_u256/src/curve.cairo b/packages/bn254_u256/src/curve.cairo index 8d51aa8..8d44aa9 100644 --- a/packages/bn254_u256/src/curve.cairo +++ b/packages/bn254_u256/src/curve.cairo @@ -1,4 +1,5 @@ use bn254_u256::{Fq, U256IntoFq, Fq2, FqD12, fq2, fq3, Bn254FqOps, Bn254FqUtils}; +use fq_types::{FrobeniusFq12Maps, FrobeniusFq6Maps}; use ec_groups::{Affine, ECGroupUtils}; pub use ec_groups::AffineOpsBn; pub use pairing::CubicScale; @@ -68,3 +69,48 @@ pub const ROOT_27TH_SQ: FqD12 = FQ_0 ), ); + +pub fn fq12_frobenius_map() -> FrobeniusFq12Maps { + FrobeniusFq12Maps { + frob1_c1: fq2( + 8376118865763821496583973867626364092589906065868298776909617916018768340080, + 16469823323077808223889137241176536799009286646108169935659301613961712198316 + ), + frob2_c1: fq2( + 21888242871839275220042445260109153167277707414472061641714758635765020556617, 0 + ), + frob3_c1: fq2( + 11697423496358154304825782922584725312912383441159505038794027105778954184319, + 303847389135065887422783454877609941456349188919719272345083954437860409601 + ), + fq6: FrobeniusFq6Maps { + frob1_c1: fq2( + 21575463638280843010398324269430826099269044274347216827212613867836435027261, + 10307601595873709700152284273816112264069230130616436755625194854815875713954 + ), + frob1_c2: fq2( + 2581911344467009335267311115468803099551665605076196740867805258568234346338, + 19937756971775647987995932169929341994314640652964949448313374472400716661030 + ), + frob2_c1: fq2( + 21888242871839275220042445260109153167277707414472061641714758635765020556616, 0 + ), + frob2_c2: fq2(2203960485148121921418603742825762020974279258880205651966, 0), + frob3_c1: fq2( + 3772000881919853776433695186713858239009073593817195771773381919316419345261, + 2236595495967245188281701248203181795121068902605861227855261137820944008926 + ), + frob3_c2: fq2( + 5324479202449903542726783395506214481928257762400643279780343368557297135718, + 16208900380737693084919495127334387981393726419856888799917914180988844123039 + ), + } + } +} + +pub fn bn254_curve() -> Bn254U256Curve { + Bn254U256Curve { + q: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, + qnz: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, + } +} diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 8e7f78a..2065f7a 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -19,7 +19,12 @@ mod tests { use fq_types::{ Fq2 as Fq2Gen, Fq3, F12S034, Fq12Direct, Fq4Direct, fq3, Fq2PartialEq, Fq3PartialEq, }; -pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale}; +pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale, bn254_curve}; + +// Frobenius maps +pub use curve::fq12_frobenius_map; +pub use fq_types::frobenius_bn254::{FrobFq12, FrobFq6}; + pub use fq_1::{ {U256IntoFq, FqPartialEq, Bn254FqOps, Bn254FqUtils}, {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, @@ -45,10 +50,3 @@ pub use pairing::{ schzip_steps::Bn254SchwartzZippelSteps, schzip_miller_runner::{Miller_Bn254_U256, PiMapping, pi_mapping}, }; - -pub fn bn254_curve() -> Bn254U256Curve { - Bn254U256Curve { - q: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, - qnz: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, - } -} diff --git a/packages/fq_types/src/frobenius.cairo b/packages/fq_types/src/frobenius.cairo index 34059f9..d7ad6ca 100644 --- a/packages/fq_types/src/frobenius.cairo +++ b/packages/fq_types/src/frobenius.cairo @@ -25,3 +25,90 @@ pub trait Frobenius1To3 { fn frob3(ref self: TCurve, a: TFq, maps: @TFrobMap) -> TFq; } +pub mod frobenius_bn254 { + use super::{Frobenius1To3, FrobeniusFq6Maps, FrobeniusFq12Maps,}; + use fq_types::{Fq2, Fq3, FieldOps, Fq2Ops, FieldUtils, fq2_conjugate, fq2_scale, fq3_scale}; + type Fq6 = Fq3>; + + pub impl FrobFq6< + TCurve, + TFq, + +FieldOps>, + +FieldOps, + +Copy, + +Drop, + +Drop, + > of Frobenius1To3, FrobeniusFq6Maps> { + fn frob1(ref self: TCurve, a: Fq6, maps: @FrobeniusFq6Maps) -> Fq6 { + let Fq3 { c0, c1, c2 } = a; + Fq3 { + c0: fq2_conjugate(ref self, c0), + c1: self.mul(fq2_conjugate(ref self, c1), *maps.frob1_c1), + c2: self.mul(fq2_conjugate(ref self, c2), *maps.frob1_c2), + } + } + + fn frob2(ref self: TCurve, a: Fq6, maps: @FrobeniusFq6Maps) -> Fq6 { + let Fq3 { c0, c1, c2 } = a; + Fq3 { // + c0: c0, + c1: fq2_scale(ref self, c1, *maps.frob2_c1.c0), // maps.frob2_c1.c1 is zero + c2: fq2_scale(ref self, c2, *maps.frob2_c2.c0), // maps.frob2_c2.c1 is zero + } + } + + fn frob3(ref self: TCurve, a: Fq6, maps: @FrobeniusFq6Maps) -> Fq6 { + let Fq3 { c0, c1, c2 } = a; + Fq3 { + c0: fq2_conjugate(ref self, c0), + c1: self.mul(fq2_conjugate(ref self, c1), *maps.frob3_c1), + c2: self.mul(fq2_conjugate(ref self, c2), *maps.frob3_c2), + } + } + } + + pub impl FrobFq12< + TCurve, + TFq, + +FieldOps>, + +FieldOps, + +Copy, + +Drop, + +Drop, + > of Frobenius1To3>, FrobeniusFq12Maps> { + fn frob1( + ref self: TCurve, a: Fq2>, maps: @FrobeniusFq12Maps + ) -> Fq2> { + let Fq2 { c0, c1 } = a; + Fq2 { // + c0: self.frob1(c0, maps.fq6), + c1: fq3_scale(ref self, self.frob1(c1, maps.fq6), *maps.frob1_c1), + } + } + + fn frob2( + ref self: TCurve, a: Fq2>, maps: @FrobeniusFq12Maps + ) -> Fq2> { + let Fq2 { c0, c1 } = a; + let Fq3 { c0: b0, c1: b1, c2: b2 } = self.frob2(c1, maps.fq6); + Fq2 { // + c0: self.frob2(c0, maps.fq6), // + c1: Fq3 { + c0: fq2_scale(ref self, b0, *maps.frob2_c1.c0), + c1: fq2_scale(ref self, b1, *maps.frob2_c1.c0), + c2: fq2_scale(ref self, b2, *maps.frob2_c1.c0), + }, + } + } + + fn frob3( + ref self: TCurve, a: Fq2>, maps: @FrobeniusFq12Maps + ) -> Fq2> { + let Fq2 { c0, c1 } = a; + Fq2 { // + c0: self.frob3(c0, maps.fq6), // + c1: fq3_scale(ref self, self.frob3(c1, maps.fq6), *maps.frob3_c1), + } + } + } +} diff --git a/packages/fq_types/src/lib.cairo b/packages/fq_types/src/lib.cairo index 57c76a8..0b57fab 100644 --- a/packages/fq_types/src/lib.cairo +++ b/packages/fq_types/src/lib.cairo @@ -2,6 +2,7 @@ pub mod common; pub mod frobenius; pub use frobenius::{Frobenius1To3, FrobeniusFq12Maps, FrobeniusFq6Maps}; +pub use frobenius::frobenius_bn254; #[derive(Copy, Drop, Serde)] pub struct Fq2 { From 1cc87fa70762e652e717340d59bbe0b9532f14e1 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 04:59:45 +0530 Subject: [PATCH 87/97] frobenius tests --- packages/bn254_u256/src/lib.cairo | 1 + packages/bn254_u256/src/tests/curve.cairo | 83 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 packages/bn254_u256/src/tests/curve.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 2065f7a..ac06e09 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -11,6 +11,7 @@ pub mod pairing { #[cfg(test)] mod tests { + pub mod curve; pub mod tests; pub mod test_pairing_utils; pub mod fixtures; diff --git a/packages/bn254_u256/src/tests/curve.cairo b/packages/bn254_u256/src/tests/curve.cairo new file mode 100644 index 0000000..d6bc5a7 --- /dev/null +++ b/packages/bn254_u256/src/tests/curve.cairo @@ -0,0 +1,83 @@ +use bn254_u256::{bn254_curve, fq12, fq12_frobenius_map, Bn254U256Curve, FrobFq12}; + +#[test] +fn frobenius() { + let mut curve = bn254_curve(); + let map = fq12_frobenius_map(); + let a = fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ); + let b = fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x19CA8ADFE0165968C479453CEAC5D78D54BEEC199FD30AF10476E46A7DA56127, + 0x8C68AD81FEFA3678A4C488228F6EC2E68FAB44F5FC386A71EDF490D13165BAF, + 0xAA529AD6ED3D0A32AA2ABD113EF97605F58EEA5ACE47A9A946899FAEFCB3895, + 0x1EEED7320D8C8646893377A138B1A265F171E37E7F73A58C52D4EC94E6BC0529, + 0x1E46A4AB1EFE63CC304F321E79B74B5E52728DF2FC3F3043DCDFCF9F816C568C, + 0x2C12B2472CFFC96EF1CD313AEAE8462296F4AD7B8E6B06073C97B7F0EBF0AD31, + 0x5303C5EDED61BD49638D9B64B23971F19C50BC4651EC93DF1EE04C676CF5B77, + 0x130BA50AED6232A4885AD91EE99E4A7B2C0D65E4F2CED84DE31F0449AD05CA0A, + 0xA5AEC882CA48F7ED31209C6EA95B0CD055CBD8C184715CE59C40CCF95C566CD, + 0x40837988D67F97256BB7E5E121802B523F460B3713E079588A5FF10659CFE2D, + ); + + let (fr1, fr2, fr3) = ( + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x20EEF5CC5E42D307E50692C958066CA5A3A8ED6FEE3160F6ABC64438080D40A, + 0x22B901CC05A276A352A5B2E4CDB0801F1090D7C3C00D2AEE133E58FA9A08166F, + 0x21EF1182C5982045BE5086E98B702B8E0A020B05DA08615B4C56898BBE7AD627, + 0x166EAB18F982D529D9716951CA8C8E8CF7B4D6C2A33842B1EFD2E91C51974C9C, + 0x8C971EE7EA3190056BBC580A3E30D71EF9CF0F366E413B66A934308B1886943, + 0x962D2942749B2BEE17E3DD2A4A816798AB7526991EF4468A2D609EFF8E3243E, + 0x1AE755CAD670294BAE38E1E0872ED365362CE44BF436B195C74307B1E70F8EB0, + 0x28686F32DCB94F6A1BEF9B430E2CE391AA94642EF1B5E3E17D9C550BA13CF604, + 0x1FCA3FF372CF4F024EDC0012FE4421C27DE8EA9E57B7B41E56B90F17253042A1, + 0x1FD2DA899094D7186E11DBBCE1945254ACCD99C25A18496E63C82D8575E53835, + 0x10EF17E4EB1A799E6520665B6E568135518530CF27E473403FE4DAE5B3ABB359, + ), + fq12( + 0x1BAF2A84EB47CE42094FD98972BC4BB0F2936EF400AEA71EAFF2C663E3A0FC4D, + 0x1386BA1F43D9BFA49764547C97CCE737F86A88B32D9129370BDD1C3AACEAE690, + 0x18DD43EA981DFD93157DBCEEDAF779FE595DC591D7B55399BBC5E47F5774B57A, + 0x1F537ED6F41E14535DBD02F9A5AF0AFC9C78DA96DD0D5D7484B839007937E68, + 0x4BA271695233F366E472A1C648D0510041758D9480D7FE6F6A4E44DF153A37, + 0x1F90E59A7A3D55FE7985237FEE00013683931CD744B16D404B5768484ABA36, + 0x62D7AC8EE4A4E5489932505F2885972FA3FD80858C41DDBE7BCEFD9314FB68D, + 0x20E7B3EC5432216AF93B6D014DECEE713B348509C387B2C5928E23CE9222EF13, + 0x2B341214025B845522176C00365DC13E7DBC5ECD0353014F4A32875061ADA1D0, + 0x1D58A967F3CF6D852FF56C9797E30DE26B7404AC75A2F23F590187CD2B77333D, + 0x1F3E350F37FAAABA1D67362947B40D26255F0E14B41CFE18990D23ED58B27918, + 0xCA343F03A5AAD483087E7C6F5826CB3E93CF2D4C93DA1A9C833CABFDB03D201, + ), + fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x20EEF5CC5E42D307E50692C958066CA5A3A8ED6FEE3160F6ABC64438080D40A, + 0x2EFA89E47856A8F39D582FDE1312FF29A7AAE4AD63655041E01CF6D457345DEB, + 0x19CF56ADBFF74C0AD339512436BC207ADBE3B43F6CE4EF20576B1D0850ACDCF8, + 0x1D3542951E75687996BD1D838717C3CB9691CB50E26751389E7BA1FF5EF22C5A, + 0x20D75AA79FEBE682EF974AE30FC5549BA7C2F59ED89BF28421C1419E1776E408, + 0x2E8AF76D1B428356E369E25853B8DE1BB216E0D36375AD58B7BDB88E309DFEEA, + 0x24D25C217E024DBDA4702D65A478A50E480D73C92B391C6584715863E7F043D4, + 0x7FBDF40047850BF9C60AA73735474CBECED066276BBE6ABBE84370B37400743, + 0x109A0E7F6E625127697445A3833D369B19987FF310BA166EE5677CFFB34CBAA6, + 0x38804B1BD6745B6A9D6C78C0C99126A0ED3A44EBD22083E6C7EA8A5C05A0127, + 0x88A86135288468A418988363D1908045E6E8F5B15068DA601BA68E41384F5F2, + ), + ); + assert(fr1 == curve.frob1(a, @map), ''); + assert(fr2 == curve.frob2(b, @map), ''); + assert(fr3 == curve.frob3(a, @map), ''); +} From d72207ed46f56371fdd855e624fd1cd64b1dfdcb Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 05:24:52 +0530 Subject: [PATCH 88/97] tower <> direct conversion utils --- packages/bn254_u256/src/lib.cairo | 4 +- .../bn254_u256/src/pairing/schzip_steps.cairo | 41 +-------------- packages/bn254_u256/src/utils.cairo | 51 ++++++++++++++++++- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index ac06e09..51d1cd6 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -30,7 +30,9 @@ pub use fq_1::{ {U256IntoFq, FqPartialEq, Bn254FqOps, Bn254FqUtils}, {scale_9, Fq, FieldOps, FieldOpsExtended, FieldUtils}, }; -pub use utils::{g1, g2, fqd12, fq12, fq2, fq}; +pub use utils::{ + g1, g2, fqd12, fq12, fq2, fq, tower_to_direct_fq12, direct_to_tower_fq12, direct_f034 +}; pub type Fq2 = Fq2Gen; pub type Fq6 = Fq3; diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index bd80bc1..35ace8d 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -2,8 +2,8 @@ use schwartz_zippel::eval::SchZipEvalTrait; use bn254_u256::curve::{ROOT_27TH, ROOT_27TH_SQ}; use bn254_u256::print::{FqDisplay}; use bn254_u256::{ - Fq, Fq2, Fq3, Fq12, FqD12, FqD4, scale_9, Bn254U256Curve, Bn254FqOps, SZCommitment, - SZCommitmentAccumulator + direct_f034, Fq, Fq2, Fq3, Fq6, Fq12, FqD12, FqD4, scale_9, Bn254U256Curve, Bn254FqOps, + SZCommitment, SZCommitmentAccumulator }; use schwartz_zippel::{SchZipSteps, SchZipEval, Lines, FS034, F034X2, LinesDbl, Residue}; use pairing::{CubicScale}; @@ -223,40 +223,3 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps FqD12 { - let Fq12 { // - c0: Fq3 { // - c0: Fq2 { c0: a0, c1: a1 }, // - c1: Fq2 { c0: a2, c1: a3 }, // - c2: Fq2 { c0: a4, c1: a5 } // - }, // - c1: Fq3 { // - c0: Fq2 { c0: a6, c1: a7 }, // - c1: Fq2 { c0: a8, c1: a9 }, // - c2: Fq2 { c0: a10, c1: a11 } // - } // - } = - a; - ( - ( - curve.sub(a0, scale_9(ref curve, a1)), - curve.sub(a6, scale_9(ref curve, a7)), - curve.sub(a2, scale_9(ref curve, a3)), - curve.sub(a8, scale_9(ref curve, a9)), - ), - (curve.sub(a4, scale_9(ref curve, a5)), curve.sub(a10, scale_9(ref curve, a11)), a1, a7,), - (a3, a9, a5, a11,) - ) -} - -fn direct_f034(ref curve: Curve, a: FS034) -> FqD4 { - let FS034:: { c3: Fq2 { c0: a6, c1: a7 }, c4: Fq2 { c0: a8, c1: a9 } } = a; - - ( - curve.sub(a6, scale_9(ref curve, a7)), // c1 - curve.sub(a8, scale_9(ref curve, a9)), // c3 - a7, // c7 - a9, // c9 - ) -} diff --git a/packages/bn254_u256/src/utils.cairo b/packages/bn254_u256/src/utils.cairo index 58651ed..2c646fe 100644 --- a/packages/bn254_u256/src/utils.cairo +++ b/packages/bn254_u256/src/utils.cairo @@ -1,5 +1,7 @@ use core::traits::Into; -use bn254_u256::{Fq, Fq2, Fq6, Fq12, FqD12, U256IntoFq, PtG1, PtG2}; +use bn254_u256::{Bn254U256Curve, Fq, Fq2, Fq6, Fq12, FqD12, PtG1, PtG2, F034, FqD4}; +use bn254_u256::{U256IntoFq, Bn254FqOps, scale_9}; +use fq_types::fq2 as fq2_from_fq; pub fn g1(x: u256, y: u256) -> PtG1 { let x = x.into(); @@ -57,3 +59,50 @@ pub fn fqd12( pub fn fq2(c0: u256, c1: u256) -> Fq2 { Fq2 { c0: c0.into(), c1: c1.into() } } + +pub fn tower_to_direct_fq12(ref curve: Bn254U256Curve, a: Fq12) -> FqD12 { + let Fq12 { // + c0: Fq6 { // + c0: Fq2 { c0: a0, c1: a1 }, c1: Fq2 { c0: a2, c1: a3 }, c2: Fq2 { c0: a4, c1: a5 } }, + c1: Fq6 { // + c0: Fq2 { c0: a6, c1: a7 }, c1: Fq2 { c0: a8, c1: a9 }, c2: Fq2 { c0: a10, c1: a11 } } // + } = + a; + ( + ( + curve.sub(a0, scale_9(ref curve, a1)), + curve.sub(a6, scale_9(ref curve, a7)), + curve.sub(a2, scale_9(ref curve, a3)), + curve.sub(a8, scale_9(ref curve, a9)), + ), + (curve.sub(a4, scale_9(ref curve, a5)), curve.sub(a10, scale_9(ref curve, a11)), a1, a7,), + (a3, a9, a5, a11,) + ) +} + +pub fn direct_to_tower_fq12(ref curve: Bn254U256Curve, a: FqD12) -> Fq12 { + let ((a0, a1, a2, a3), (a4, a5, a6, a7), (a8, a9, a10, a11)) = a; + + Fq12 { + c0: Fq6 { + c0: fq2_from_fq(curve.add(a0, scale_9(ref curve, a6)), a6), + c1: fq2_from_fq(curve.add(a2, scale_9(ref curve, a8)), a8), + c2: fq2_from_fq(curve.add(a4, scale_9(ref curve, a10)), a10), + }, + c1: Fq6 { + c0: fq2_from_fq(curve.add(a1, scale_9(ref curve, a7)), a7), + c1: fq2_from_fq(curve.add(a3, scale_9(ref curve, a9)), a9), + c2: fq2_from_fq(curve.add(a5, scale_9(ref curve, a11)), a11), + } + } +} + +pub fn direct_f034(ref curve: Bn254U256Curve, a: F034) -> FqD4 { + let F034 { c3: Fq2 { c0: a6, c1: a7 }, c4: Fq2 { c0: a8, c1: a9 } } = a; + ( + curve.sub(a6, scale_9(ref curve, a7)), // c1 + curve.sub(a8, scale_9(ref curve, a9)), // c3 + a7, // c7 + a9, // c9 + ) +} From 0e2448ee29c351206dd79cfd05e20dfa715d3cb0 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 05:28:29 +0530 Subject: [PATCH 89/97] frob maps in miller loop --- .../bn254_u256/src/pairing/schzip_miller.cairo | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 41b0573..1f354f1 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -11,6 +11,7 @@ use bn254_u256::{ ICArrayInput }, }, + {fq12_frobenius_map, FrobFq12, direct_to_tower_fq12, tower_to_direct_fq12}, // Frobenius Bn254SchwartzZippelSteps, }; use bn_ate_loop::{ate_miller_loop}; @@ -67,9 +68,13 @@ fn schzip_miller< let mut q_acc = ate_miller_loop(ref curve, @precomp, q_acc); - let r_pow_q = residue_witness; // @TODO forbenius map q - let r_inv_q2 = residue_witness_inv; // @TODO forbenius map q2 - let r_pow_q3 = residue_witness; // @TODO forbenius map q3 + core::internal::revoke_ap_tracking(); + let frobenius_maps = fq12_frobenius_map(); + let witness_dir = direct_to_tower_fq12(ref curve, residue_witness); + let witness_inv_dir = direct_to_tower_fq12(ref curve, residue_witness_inv); + let r_pow_q = curve.frob1(witness_dir, @frobenius_maps); + let r_inv_q2 = curve.frob2(witness_inv_dir, @frobenius_maps); + let r_pow_q3 = curve.frob3(witness_dir, @frobenius_maps); curve .sz_final( @@ -77,9 +82,9 @@ fn schzip_miller< ref q_acc.schzip, ref q_acc.f, alpha_beta, - r_pow_q, - r_inv_q2, - r_pow_q3, + tower_to_direct_fq12(ref curve, r_pow_q), + tower_to_direct_fq12(ref curve, r_inv_q2), + tower_to_direct_fq12(ref curve, r_pow_q3), cubic_scale ); q_acc From 3c5034f9c7d61c0653779b49ff754aad6eb00ea6 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 07:59:54 +0530 Subject: [PATCH 90/97] pow bug fixes and tweaks --- packages/bn254_u256/src/pairing/schzip_miller.cairo | 10 ++++------ .../bn254_u256/src/pairing/schzip_miller_runner.cairo | 3 ++- packages/bn254_u256/src/print.cairo | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 1f354f1..7265192 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,7 +1,7 @@ use fq_types::FieldOps; use ec_groups::ECOperations; pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; -use bn254_u256::print::{FqDisplay}; +use bn254_u256::print::{FqDisplay, G1Display, G2Display}; use bn254_u256::{ fq, Fq, Fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ @@ -48,8 +48,6 @@ fn schzip_miller< let k: PtG1 = curve.process_inputs_and_ic(ic, inputs); - let pi_a = curve.pt_neg(pi_a); - // build precompute let p = Groth16MillerG1 { pi_a, pi_c, k, }; let q = Groth16MillerG2 { pi_b, gamma, delta }; @@ -129,7 +127,6 @@ pub fn prepare_sz_commitment( rem_coeff_i += 1; }; let remainders_fiat_shamir_felt = hasher.finalize(); - // println!("remainders_fiat_shamir_felt: {}", remainders_fiat_shamir_felt); let remainders_fiat_shamir: u256 = remainders_fiat_shamir_felt.into(); core::internal::revoke_ap_tracking(); @@ -164,7 +161,7 @@ pub fn prepare_sz_commitment( } pub fn fs_pow(ref curve: Bn254U256Curve, x: Fq, powers: u32) -> Array { - let mut arr: Array = array![0_u256.into(), x]; + let mut arr: Array = array![1_u256.into(), x]; let mut i = 1; let powers = powers / 2; while i != powers { @@ -188,7 +185,8 @@ pub fn schzip_verify( setup: Groth16Circuit, schzip_remainders: Array, schzip_qrlc: Array, -) { // let p = fs_pow(ref curve, fq(2), 6); +) { + // let p = fs_pow(ref curve, fq(2), 6); // println!("{} {} {} {} {} {}", p[0], p[1], p[2], p[3], p[4], p[5]); let (sz, sz_acc) = prepare_sz_commitment(ref curve, schzip_remainders, schzip_qrlc); let sz_snap = @sz; diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo index 530ff26..e2910c5 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo @@ -1,7 +1,7 @@ use pairing::{LineFn, LinesArrayGet, FixedPointLines}; use pairing::{PairingUtils}; use bn254_u256::{Fq, Fq2, fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; -use bn254_u256::print::{FqDisplay, G2Display}; +use bn254_u256::print::{FqDisplay, G2Display, G1Display}; use bn254_u256::pairing::utils::{ LnArrays, SZCommitment, SZCommitmentAccumulator, SZPreCompute, SZAccumulator as Accumulator, LnFn @@ -21,6 +21,7 @@ pub impl Miller_Bn254_U256< fn miller_bit_1_2( ref self: Curve, runner: @PreCompute, i: (u32, u32), ref acc: Accumulator ) { // + self.sz_init(runner.schzip, ref acc.schzip, ref acc.f); let (i1, i2) = i; self.miller_bit_o(runner, i1, ref acc); self.miller_bit_n(runner, i2, ref acc); diff --git a/packages/bn254_u256/src/print.cairo b/packages/bn254_u256/src/print.cairo index 04c7e3d..ab51d1d 100644 --- a/packages/bn254_u256/src/print.cairo +++ b/packages/bn254_u256/src/print.cairo @@ -68,7 +68,7 @@ pub impl Fq2Display of Display { pub impl G1Display of Display { fn fmt(self: @PtG1, ref f: Formatter) -> Result<(), Error> { - write!(f, "g2({},{}\n),", self.x, self.y) + write!(f, "g1({},{}\n),", self.x, self.y) } } From ba93becafb2aa8b62fdbef3ff501ade366095214 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 16:26:34 +0530 Subject: [PATCH 91/97] fix final expo frob maps --- .../bn254_u256/src/pairing/schzip_miller.cairo | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip_miller.cairo index 7265192..e656dd2 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip_miller.cairo @@ -1,7 +1,7 @@ use fq_types::FieldOps; use ec_groups::ECOperations; pub use pairing::{PPrecompute, Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit}; -use bn254_u256::print::{FqDisplay, G1Display, G2Display}; +use bn254_u256::print::{FqDisplay, Fq12Display, G1Display, G2Display}; use bn254_u256::{ fq, Fq, Fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ @@ -68,11 +68,11 @@ fn schzip_miller< core::internal::revoke_ap_tracking(); let frobenius_maps = fq12_frobenius_map(); - let witness_dir = direct_to_tower_fq12(ref curve, residue_witness); - let witness_inv_dir = direct_to_tower_fq12(ref curve, residue_witness_inv); - let r_pow_q = curve.frob1(witness_dir, @frobenius_maps); - let r_inv_q2 = curve.frob2(witness_inv_dir, @frobenius_maps); - let r_pow_q3 = curve.frob3(witness_dir, @frobenius_maps); + let witness_fq12 = direct_to_tower_fq12(ref curve, residue_witness); + let witness_inv_fq12 = direct_to_tower_fq12(ref curve, residue_witness_inv); + let r_pow_q = curve.frob1(witness_inv_fq12, @frobenius_maps); + let r_inv_q2 = curve.frob2(witness_fq12, @frobenius_maps); + let r_pow_q3 = curve.frob3(witness_inv_fq12, @frobenius_maps); curve .sz_final( @@ -185,7 +185,7 @@ pub fn schzip_verify( setup: Groth16Circuit, schzip_remainders: Array, schzip_qrlc: Array, -) { +) -> bool { // let p = fs_pow(ref curve, fq(2), 6); // println!("{} {} {} {} {} {}", p[0], p[1], p[2], p[3], p[4], p[5]); let (sz, sz_acc) = prepare_sz_commitment(ref curve, schzip_remainders, schzip_qrlc); @@ -206,5 +206,5 @@ pub fn schzip_verify( sz_acc ); - curve.sz_verify(sz_snap, ref acc.schzip, acc.f, residue_witness, residue_witness_inv,); + curve.sz_verify(sz_snap, ref acc.schzip, acc.f, residue_witness, residue_witness_inv,) } From 84d5691eaddfbce14f70cecdf6f1adce77e2fb5f Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 18:30:15 +0530 Subject: [PATCH 92/97] fix qrlc mul p12_x --- .../bn254_u256/src/pairing/schzip_steps.cairo | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip_steps.cairo index 35ace8d..8723af8 100644 --- a/packages/bn254_u256/src/pairing/schzip_steps.cairo +++ b/packages/bn254_u256/src/pairing/schzip_steps.cairo @@ -1,9 +1,9 @@ use schwartz_zippel::eval::SchZipEvalTrait; use bn254_u256::curve::{ROOT_27TH, ROOT_27TH_SQ}; -use bn254_u256::print::{FqDisplay}; +use bn254_u256::print::{FqDisplay, F034Display, Fq12Display, FqD12Display}; use bn254_u256::{ - direct_f034, Fq, Fq2, Fq3, Fq6, Fq12, FqD12, FqD4, scale_9, Bn254U256Curve, Bn254FqOps, - SZCommitment, SZCommitmentAccumulator + direct_f034, direct_to_tower_fq12, Fq, Fq2, Fq3, Fq6, Fq12, FqD12, FqD4, scale_9, + Bn254U256Curve, Bn254FqOps, SZCommitment, SZCommitmentAccumulator }; use schwartz_zippel::{SchZipSteps, SchZipEval, Lines, FS034, F034X2, LinesDbl, Residue}; use pairing::{CubicScale}; @@ -43,7 +43,8 @@ fn acc_equation_lhs_rem(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, pub impl Bn254SchwartzZippelSteps of SchZipSteps { fn sz_init(ref self: Curve, sz: @SZCommitment, ref sz_acc: SZCAcc, ref f: FqD12) { // - // Compute next remainder + // Compute remainder for the first step + sz_acc.rem_cache = self.eval_fq12(f, sz.fiat_shamir_powers); } // Handles Schwartz Zippel verification for zero `O` bits, @@ -137,8 +138,9 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps {}, CubicScale::One => { @@ -186,7 +187,6 @@ pub impl Bn254SchwartzZippelSteps of SchZipSteps bool { - // println!("sz_verify: {}", sz_acc.index); // witness * witness_inv = 1 + q * p12 // or, isolating q again, // witness * witness_inv - 1 = q * p12 let mut eval = self.eval_fq12(witness, sz.fiat_shamir_powers); // witness acc_mul_eval_12(ref self, witness_inv, ref eval, sz.fiat_shamir_powers); // witness_inv + eval = self.sub(eval, 1_u256.into()); // This is a separate verification and shouldn't change remainder acc_equation_eval(ref self, sz, ref sz_acc, eval); let qrlc = self.eval_poly(sz.qrlc, sz.fiat_shamir_powers); + let qrlc = self.mul(qrlc, *sz.p12_x); sz_acc.rhs_lhs == qrlc } } From cfe88d7027d5a5eb3139eef914b7fe789905e0dd Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 22:32:37 +0530 Subject: [PATCH 93/97] fixtures outside tests mod --- .../src/{tests => }/fixtures/lines_fix.cairo | 0 .../src/{tests => }/fixtures/proof_fix.cairo | 0 .../src/{tests => }/fixtures/schzip_fix.cairo | 0 packages/bn254_u256/src/lib.cairo | 10 +++++++++- packages/bn254_u256/src/tests/fixtures.cairo | 5 ----- 5 files changed, 9 insertions(+), 6 deletions(-) rename packages/bn254_u256/src/{tests => }/fixtures/lines_fix.cairo (100%) rename packages/bn254_u256/src/{tests => }/fixtures/proof_fix.cairo (100%) rename packages/bn254_u256/src/{tests => }/fixtures/schzip_fix.cairo (100%) delete mode 100644 packages/bn254_u256/src/tests/fixtures.cairo diff --git a/packages/bn254_u256/src/tests/fixtures/lines_fix.cairo b/packages/bn254_u256/src/fixtures/lines_fix.cairo similarity index 100% rename from packages/bn254_u256/src/tests/fixtures/lines_fix.cairo rename to packages/bn254_u256/src/fixtures/lines_fix.cairo diff --git a/packages/bn254_u256/src/tests/fixtures/proof_fix.cairo b/packages/bn254_u256/src/fixtures/proof_fix.cairo similarity index 100% rename from packages/bn254_u256/src/tests/fixtures/proof_fix.cairo rename to packages/bn254_u256/src/fixtures/proof_fix.cairo diff --git a/packages/bn254_u256/src/tests/fixtures/schzip_fix.cairo b/packages/bn254_u256/src/fixtures/schzip_fix.cairo similarity index 100% rename from packages/bn254_u256/src/tests/fixtures/schzip_fix.cairo rename to packages/bn254_u256/src/fixtures/schzip_fix.cairo diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 51d1cd6..7948c48 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -9,12 +9,20 @@ pub mod pairing { pub mod schzip_steps; } +pub mod fixtures { + pub mod lines_fix; + pub mod proof_fix; + pub mod schzip_fix; + pub use proof_fix::{circuit_setup, residue_witness, proof}; + pub use schzip_fix::{schzip}; +} + #[cfg(test)] mod tests { pub mod curve; pub mod tests; pub mod test_pairing_utils; - pub mod fixtures; + pub use super::fixtures; } use fq_types::{ diff --git a/packages/bn254_u256/src/tests/fixtures.cairo b/packages/bn254_u256/src/tests/fixtures.cairo deleted file mode 100644 index dccd8b7..0000000 --- a/packages/bn254_u256/src/tests/fixtures.cairo +++ /dev/null @@ -1,5 +0,0 @@ -pub mod lines_fix; -pub mod proof_fix; -pub mod schzip_fix; -pub use proof_fix::{circuit_setup, residue_witness, proof}; -pub use schzip_fix::{schzip}; From f12028a495af0d5430c7db5f40c2de39f1a5ecad Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Wed, 24 Jul 2024 22:33:19 +0530 Subject: [PATCH 94/97] verification and tower/direct test --- packages/bn254_u256/src/tests/curve.cairo | 21 ++++++++++++++++ packages/bn254_u256/src/tests/tests.cairo | 4 +-- packages/bn254_u256_contract/src/lib.cairo | 29 ++++++++++++---------- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/packages/bn254_u256/src/tests/curve.cairo b/packages/bn254_u256/src/tests/curve.cairo index d6bc5a7..1fa0ad9 100644 --- a/packages/bn254_u256/src/tests/curve.cairo +++ b/packages/bn254_u256/src/tests/curve.cairo @@ -1,4 +1,25 @@ use bn254_u256::{bn254_curve, fq12, fq12_frobenius_map, Bn254U256Curve, FrobFq12}; +use bn254_u256::{tower_to_direct_fq12, direct_to_tower_fq12}; + +#[test] +fn tower_direct_conversions() { + let mut curve = bn254_curve(); + let a = fq12( + 0x5B9A079BC26832A0F6C91A8C3D52F0696E128C4DC02C2E7ECCD6750879DB37F, + 0x2E555F161B4D72F939FFDC89EC00F1933D46DBBA698EB47DD16427D357FC293D, + 0x1B137F9BF629C0DBCDD8087034E1F3557CE533998E4E2566B9961515FE3E8874, + 0x9D878A403981D9DC63F4987D88DF92F797412464F26753411B8E7500D316487, + 0x14E05EB80B6F7E23ECFA04A410CFA1CF8036F3161C7D586802B485FBA82FA9E9, + 0x35039DC8C011DB7EB2C0E91709001BA13C91C6B2A06F5ED32005C4990ED64CB, + 0xB67955A9EED460C7FE5F21790CB806E1A6FAA832E5ED9751F4C769B94F233D4, + 0x1A87D2B49B7FE718A8AAED495061C6C7AB0F83010AA102BADCE3B5F057717586, + 0x1426DBE6A25C91A8D3AC59A34C4EA7D7E0075EF206A5DD08A33D1998B58651C1, + 0x27ACB2E47242C471014D129C1A37D0FB662480C13480796CDC381735384A6C5A, + 0x7459382FD7B5F159E32AE6EB1F5A1AC9ADDE6E0E347011855CC9F8B5BC89021, + 0x2884F79CD78DBEF6B64FD2A8AF7ABBB9CB36D280C0C63074E74F0287D3B2EB2D, + ); + assert(direct_to_tower_fq12(ref curve, tower_to_direct_fq12(ref curve, a)) == a, '') +} #[test] fn frobenius() { diff --git a/packages/bn254_u256/src/tests/tests.cairo b/packages/bn254_u256/src/tests/tests.cairo index 19b70d1..9074b50 100644 --- a/packages/bn254_u256/src/tests/tests.cairo +++ b/packages/bn254_u256/src/tests/tests.cairo @@ -10,7 +10,7 @@ fn verify() { let (_f, residue_witness, residue_witness_inv, _, cubic_scale) = residue_witness(); let (remainders, q_rlc_sum) = schzip(); - schzip_verify( + let _verified = schzip_verify( ref curve, pi_a, pi_b, @@ -23,5 +23,5 @@ fn verify() { remainders, q_rlc_sum ); - assert(true, ''); + assert(_verified, 'verification failed'); } diff --git a/packages/bn254_u256_contract/src/lib.cairo b/packages/bn254_u256_contract/src/lib.cairo index d131988..1514306 100644 --- a/packages/bn254_u256_contract/src/lib.cairo +++ b/packages/bn254_u256_contract/src/lib.cairo @@ -56,19 +56,22 @@ mod BN_Pairing { schzip_qrlc: Array, ) { let mut curve = bn254_curve(); - schzip_verify( - ref curve, - pi_a, - pi_b, - pi_c, - inputs, - residue_witness, - residue_witness_inv, - cubic_scale, - setup, - schzip_remainders, - schzip_qrlc, - ) + assert( + schzip_verify( + ref curve, + pi_a, + pi_b, + pi_c, + inputs, + residue_witness, + residue_witness_inv, + cubic_scale, + setup, + schzip_remainders, + schzip_qrlc, + ), + 'verification failed' + ); } } } From c4b466800477d3d31e994d7165312cceee11006e Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Thu, 25 Jul 2024 20:06:22 +0530 Subject: [PATCH 95/97] groth16 entrypoint no input --- packages/bn254_u256_contract/src/lib.cairo | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/bn254_u256_contract/src/lib.cairo b/packages/bn254_u256_contract/src/lib.cairo index 1514306..cb71d4c 100644 --- a/packages/bn254_u256_contract/src/lib.cairo +++ b/packages/bn254_u256_contract/src/lib.cairo @@ -22,6 +22,7 @@ trait IBN_Pairing { schzip_remainders: Array, schzip_qrlc: Array, ); + fn groth16_verification(ref self: T); } #[starknet::contract] @@ -33,6 +34,7 @@ mod BN_Pairing { InputConstraintPoints } }; + use bn254_u256::fixtures::{circuit_setup, residue_witness, proof, schzip}; #[storage] struct Storage {} @@ -73,5 +75,28 @@ mod BN_Pairing { 'verification failed' ); } + + fn groth16_verification(ref self: ContractState,) { + let mut curve = bn254_curve(); + let (pi_a, pi_b, pi_c, input, _) = proof(); + let circuit = circuit_setup(); + let (_f, residue_witness, residue_witness_inv, _, cubic_scale) = residue_witness(); + let (remainders, q_rlc_sum) = schzip(); + + let _verified = schzip_verify( + ref curve, + pi_a, + pi_b, + pi_c, + array![input], + residue_witness, + residue_witness_inv, + cubic_scale, + circuit, + remainders, + q_rlc_sum + ); + assert(_verified, 'verification failed'); + } } } From 185140314efe995eb1b0b1883405547bb37429a5 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Fri, 26 Jul 2024 02:41:07 +0530 Subject: [PATCH 96/97] schzip stuff in pairing/schzip --- packages/bn254_u256/src/lib.cairo | 14 ++++++++------ .../{schzip_miller.cairo => schzip/miller.cairo} | 2 +- .../miller_runner.cairo} | 0 .../{schzip_steps.cairo => schzip/steps.cairo} | 0 4 files changed, 9 insertions(+), 7 deletions(-) rename packages/bn254_u256/src/pairing/{schzip_miller.cairo => schzip/miller.cairo} (99%) rename packages/bn254_u256/src/pairing/{schzip_miller_runner.cairo => schzip/miller_runner.cairo} (100%) rename packages/bn254_u256/src/pairing/{schzip_steps.cairo => schzip/steps.cairo} (100%) diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 7948c48..1290304 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -4,9 +4,11 @@ pub mod utils; pub mod print; pub mod pairing { pub mod utils; - pub mod schzip_miller_runner; - pub mod schzip_miller; - pub mod schzip_steps; + pub mod schzip { + pub mod miller_runner; + pub mod miller; + pub mod steps; + } } pub mod fixtures { @@ -54,10 +56,10 @@ pub use pairing::{ {ICProcess, ICArrayInput, LnArrays}, {SZCommitment, SZPreCompute, SZAccumulator, SZCommitmentAccumulator} }, - schzip_miller::{ + schzip::miller::{ schzip_verify, InputConstraintPoints, PPrecompute, {Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit} }, - schzip_steps::Bn254SchwartzZippelSteps, - schzip_miller_runner::{Miller_Bn254_U256, PiMapping, pi_mapping}, + schzip::steps::Bn254SchwartzZippelSteps, + schzip::miller_runner::{Miller_Bn254_U256, PiMapping, pi_mapping}, }; diff --git a/packages/bn254_u256/src/pairing/schzip_miller.cairo b/packages/bn254_u256/src/pairing/schzip/miller.cairo similarity index 99% rename from packages/bn254_u256/src/pairing/schzip_miller.cairo rename to packages/bn254_u256/src/pairing/schzip/miller.cairo index e656dd2..e69083b 100644 --- a/packages/bn254_u256/src/pairing/schzip_miller.cairo +++ b/packages/bn254_u256/src/pairing/schzip/miller.cairo @@ -5,7 +5,7 @@ use bn254_u256::print::{FqDisplay, Fq12Display, G1Display, G2Display}; use bn254_u256::{ fq, Fq, Fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve, pairing::{ - schzip_miller_runner::Miller_Bn254_U256, + schzip::miller_runner::Miller_Bn254_U256, utils::{ SZCommitment, SZPreCompute, SZCommitmentAccumulator, SZAccumulator, LnArrays, ICArrayInput diff --git a/packages/bn254_u256/src/pairing/schzip_miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip/miller_runner.cairo similarity index 100% rename from packages/bn254_u256/src/pairing/schzip_miller_runner.cairo rename to packages/bn254_u256/src/pairing/schzip/miller_runner.cairo diff --git a/packages/bn254_u256/src/pairing/schzip_steps.cairo b/packages/bn254_u256/src/pairing/schzip/steps.cairo similarity index 100% rename from packages/bn254_u256/src/pairing/schzip_steps.cairo rename to packages/bn254_u256/src/pairing/schzip/steps.cairo From 695cb1e291e089118e1870c411889dc8990653ff Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Fri, 26 Jul 2024 13:49:46 +0530 Subject: [PATCH 97/97] pi mapping in curve mod --- packages/bn254_u256/src/curve.cairo | 42 +++++++++++++- packages/bn254_u256/src/lib.cairo | 6 +- .../src/pairing/schzip/miller_runner.cairo | 55 +++---------------- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/packages/bn254_u256/src/curve.cairo b/packages/bn254_u256/src/curve.cairo index 8d44aa9..172ee2f 100644 --- a/packages/bn254_u256/src/curve.cairo +++ b/packages/bn254_u256/src/curve.cairo @@ -2,7 +2,7 @@ use bn254_u256::{Fq, U256IntoFq, Fq2, FqD12, fq2, fq3, Bn254FqOps, Bn254FqUtils} use fq_types::{FrobeniusFq12Maps, FrobeniusFq6Maps}; use ec_groups::{Affine, ECGroupUtils}; pub use ec_groups::AffineOpsBn; -pub use pairing::CubicScale; +pub use pairing::{CubicScale, PiMapping}; #[derive(Drop, Serde)] pub struct Bn254U256Curve { @@ -34,6 +34,46 @@ impl PtG2One of ECGroupUtils { } } +pub fn pi_mapping() -> PiMapping { + // π (Pi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves + // ----------------------------------------------------------------- + // BN254_Snarks is a D-Twist: pi1_coef1 = ξ^((p-1)/6) + // https://github.com/mratsim/constantine/blob/976c8bb215a3f0b21ce3d05f894eb506072a6285/constantine/math/constants/bn254_snarks_frobenius.nim#L131 + // In the link above this is referred to as ψ (Psi) + + // pi2_coef3 is always -1 (mod p^m) with m = embdeg/twdeg + // Recap, with ξ (xi) the sextic non-residue for D-Twist or 1/SNR for M-Twist + // pi_2 ≡ ξ^((p-1)/6)^2 ≡ ξ^(2(p-1)/6) ≡ ξ^((p-1)/3) + // pi_3 ≡ pi_2 * ξ^((p-1)/6) ≡ ξ^((p-1)/3) * ξ^((p-1)/6) ≡ ξ^((p-1)/2) + + // ----------------------------------------------------------------- + // for πₚ mapping + + // Fp2::NONRESIDUE^(2((q^1) - 1) / 6) + let Q1X2_0 = 0x2fb347984f7911f74c0bec3cf559b143b78cc310c2c3330c99e39557176f553d; + let Q1X2_1 = 0x16c9e55061ebae204ba4cc8bd75a079432ae2a1d0b7c9dce1665d51c640fcba2; + + // Fp2::NONRESIDUE^(3((q^1) - 1) / 6) + let Q1X3_0 = 0x63cf305489af5dcdc5ec698b6e2f9b9dbaae0eda9c95998dc54014671a0135a; + let Q1X3_1 = 0x7c03cbcac41049a0704b5a7ec796f2b21807dc98fa25bd282d37f632623b0e3; + + // ----------------------------------------------------------------- + // for π² mapping + + // Fp2::NONRESIDUE^(2(p^2-1)/6) + let PiQ2X2: Fq = 0x30644e72e131a0295e6dd9e7e0acccb0c28f069fbb966e3de4bd44e5607cfd48_u256.into(); + // Fp2::NONRESIDUE^(3(p^2-1)/6) + let PiQ2X3: Fq = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46_u256.into(); + + PiMapping { + PiQ1X2: fq2(Q1X2_0, Q1X2_1,), // Fp2::NONRESIDUE^(2((q^1) - 1) / 6) + PiQ1X3: fq2(Q1X3_0, Q1X3_1,), // Fp2::NONRESIDUE^(3((q^1) - 1) / 6) + // for π² mapping + PiQ2X2, // Fp2::NONRESIDUE^(2(p^2-1)/6) + PiQ2X3, // Fp2::NONRESIDUE^(3(p^2-1)/6) + } +} + pub const FQ_0: Fq = Fq { c0: 0x0 }; pub const ROOT_27TH: FqD12 = ( diff --git a/packages/bn254_u256/src/lib.cairo b/packages/bn254_u256/src/lib.cairo index 1290304..a6d0c95 100644 --- a/packages/bn254_u256/src/lib.cairo +++ b/packages/bn254_u256/src/lib.cairo @@ -30,7 +30,8 @@ mod tests { use fq_types::{ Fq2 as Fq2Gen, Fq3, F12S034, Fq12Direct, Fq4Direct, fq3, Fq2PartialEq, Fq3PartialEq, }; -pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale, bn254_curve}; +pub use curve::{Bn254U256Curve, PtG1, PtG2, AffineOpsBn, CubicScale, PiMapping}; +pub use curve::{bn254_curve, pi_mapping}; // Frobenius maps pub use curve::fq12_frobenius_map; @@ -60,6 +61,5 @@ pub use pairing::{ schzip_verify, InputConstraintPoints, PPrecompute, {Groth16MillerG1, Groth16MillerG2, Groth16PreCompute, Groth16Circuit} }, - schzip::steps::Bn254SchwartzZippelSteps, - schzip::miller_runner::{Miller_Bn254_U256, PiMapping, pi_mapping}, + schzip::steps::Bn254SchwartzZippelSteps, schzip::miller_runner::Miller_Bn254_U256 }; diff --git a/packages/bn254_u256/src/pairing/schzip/miller_runner.cairo b/packages/bn254_u256/src/pairing/schzip/miller_runner.cairo index e2910c5..d7a179e 100644 --- a/packages/bn254_u256/src/pairing/schzip/miller_runner.cairo +++ b/packages/bn254_u256/src/pairing/schzip/miller_runner.cairo @@ -1,12 +1,13 @@ use pairing::{LineFn, LinesArrayGet, FixedPointLines}; -use pairing::{PairingUtils}; -use bn254_u256::{Fq, Fq2, fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve}; -use bn254_u256::print::{FqDisplay, G2Display, G1Display}; -use bn254_u256::pairing::utils::{ - LnArrays, SZCommitment, SZCommitmentAccumulator, SZPreCompute, SZAccumulator as Accumulator, - LnFn +use pairing::{PairingUtils, PiMapping}; +use bn254_u256::{ + {Fq, Fq2, fq2, FqD12, PtG1, PtG2, Bn254FqOps, Bn254U256Curve as Curve,}, + print::{FqDisplay, G2Display, G1Display}, pi_mapping, + pairing::utils::{ + LnArrays, LnFn, + {SZCommitment, SZCommitmentAccumulator, SZPreCompute, SZAccumulator as Accumulator} + } }; -pub use pairing::PiMapping; use bn_ate_loop::MillerRunner; use schwartz_zippel::SchZipSteps; @@ -86,43 +87,3 @@ pub impl Miller_Bn254_U256< self.sz_last_step(runner.schzip, ref acc.schzip, ref acc.f, (l1, l2, l3)); } } - -pub fn pi_mapping() -> PiMapping { - // π (Pi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves - // ----------------------------------------------------------------- - // BN254_Snarks is a D-Twist: pi1_coef1 = ξ^((p-1)/6) - // https://github.com/mratsim/constantine/blob/976c8bb215a3f0b21ce3d05f894eb506072a6285/constantine/math/constants/bn254_snarks_frobenius.nim#L131 - // In the link above this is referred to as ψ (Psi) - - // pi2_coef3 is always -1 (mod p^m) with m = embdeg/twdeg - // Recap, with ξ (xi) the sextic non-residue for D-Twist or 1/SNR for M-Twist - // pi_2 ≡ ξ^((p-1)/6)^2 ≡ ξ^(2(p-1)/6) ≡ ξ^((p-1)/3) - // pi_3 ≡ pi_2 * ξ^((p-1)/6) ≡ ξ^((p-1)/3) * ξ^((p-1)/6) ≡ ξ^((p-1)/2) - - // ----------------------------------------------------------------- - // for πₚ mapping - - // Fp2::NONRESIDUE^(2((q^1) - 1) / 6) - let Q1X2_0 = 0x2fb347984f7911f74c0bec3cf559b143b78cc310c2c3330c99e39557176f553d; - let Q1X2_1 = 0x16c9e55061ebae204ba4cc8bd75a079432ae2a1d0b7c9dce1665d51c640fcba2; - - // Fp2::NONRESIDUE^(3((q^1) - 1) / 6) - let Q1X3_0 = 0x63cf305489af5dcdc5ec698b6e2f9b9dbaae0eda9c95998dc54014671a0135a; - let Q1X3_1 = 0x7c03cbcac41049a0704b5a7ec796f2b21807dc98fa25bd282d37f632623b0e3; - - // ----------------------------------------------------------------- - // for π² mapping - - // Fp2::NONRESIDUE^(2(p^2-1)/6) - let PiQ2X2: Fq = 0x30644e72e131a0295e6dd9e7e0acccb0c28f069fbb966e3de4bd44e5607cfd48_u256.into(); - // Fp2::NONRESIDUE^(3(p^2-1)/6) - let PiQ2X3: Fq = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46_u256.into(); - - PiMapping { - PiQ1X2: fq2(Q1X2_0, Q1X2_1,), // Fp2::NONRESIDUE^(2((q^1) - 1) / 6) - PiQ1X3: fq2(Q1X3_0, Q1X3_1,), // Fp2::NONRESIDUE^(3((q^1) - 1) / 6) - // for π² mapping - PiQ2X2, // Fp2::NONRESIDUE^(2(p^2-1)/6) - PiQ2X3, // Fp2::NONRESIDUE^(3(p^2-1)/6) - } -}