From 357bf84e1f795b463c90553199e882c34c4902ff Mon Sep 17 00:00:00 2001 From: green Date: Thu, 26 Dec 2024 21:47:47 -0500 Subject: [PATCH 01/13] Support branches with ZK opcodes --- Cargo.lock | 688 ++++++++++-------- Cargo.toml | 22 +- forc-plugins/forc-client/src/op/run/mod.rs | 1 + forc-plugins/forc-client/src/util/account.rs | 42 +- forc-plugins/forc-client/src/util/aws.rs | 6 +- forc-test/src/execute.rs | 1 + forc-test/src/lib.rs | 4 +- sway-core/src/asm_generation/finalized_asm.rs | 2 + test/src/e2e_vm_tests/harness.rs | 2 +- 9 files changed, 433 insertions(+), 335 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d6df20e9c24..d2769a48722 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,6 +71,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + [[package]] name = "allocator-api2" version = "0.2.20" @@ -396,12 +402,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "ascii" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" - [[package]] name = "asn1_der" version = "0.7.6" @@ -1314,7 +1314,7 @@ dependencies = [ "k256", "serde", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1330,7 +1330,7 @@ dependencies = [ "pbkdf2 0.12.2", "rand", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1350,7 +1350,7 @@ dependencies = [ "serde_derive", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1369,19 +1369,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "combine" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" -dependencies = [ - "ascii", - "byteorder", - "either", - "memchr", - "unreachable", -] - [[package]] name = "comma" version = "1.0.0" @@ -1401,7 +1388,7 @@ dependencies = [ "mime", "mime_guess", "rand", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1482,9 +1469,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cookie" -version = "0.17.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "percent-encoding", "time", @@ -1493,12 +1480,13 @@ dependencies = [ [[package]] name = "cookie_store" -version = "0.20.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" dependencies = [ "cookie", - "idna 0.3.0", + "document-features", + "idna", "log", "publicsuffix", "serde", @@ -1533,15 +1521,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "counter" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d458e66999348f56fd3ffcfbb7f7951542075ca8359687c703de6500c1ddccd" -dependencies = [ - "num-traits", -] - [[package]] name = "countme" version = "3.0.1" @@ -1738,42 +1717,57 @@ dependencies = [ [[package]] name = "cynic" -version = "2.2.8" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1afa0591b1021e427e548a1f0f147fe6168f6c7c7f7006bace77f28856051b8" +checksum = "17334136b717249d58b05739a825e2c83f53b0beee0e1f714c332cf48eee7023" dependencies = [ "cynic-proc-macros", - "reqwest 0.11.27", + "ref-cast", + "reqwest", "serde", "serde_json", "static_assertions", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "cynic-codegen" -version = "2.2.8" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a1bb05cc554f46079d0fa72abe995a2d32d0737d410a41da75b31e3f7ef768" +checksum = "5aa0d13b24fe724349a8363f04183d4ee0dc2ab5e40c574f8f8ee2edbc0d344d" dependencies = [ - "counter", - "darling 0.13.4", - "graphql-parser", + "cynic-parser", + "darling", "once_cell", + "ouroboros", "proc-macro2", "quote", "strsim 0.10.0", - "syn 1.0.109", + "syn 2.0.87", + "thiserror 1.0.69", +] + +[[package]] +name = "cynic-parser" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86a21da88ae46f2be6a622880a72f968d05c50b5a797e525332d0c988f693f70" +dependencies = [ + "indexmap 2.6.0", + "lalrpop-util", + "logos 0.14.4", ] [[package]] name = "cynic-proc-macros" -version = "2.2.8" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa595c4ed7a5374e0e58c5c34f9d93bd6b7d45062790963bd4b4c3c0bf520c4d" +checksum = "046126da74af834da9b8b6e9c2a8e56bf85bc4f2b871550586008237b64ff6bb" dependencies = [ "cynic-codegen", - "syn 1.0.109", + "darling", + "quote", + "syn 2.0.87", ] [[package]] @@ -1784,17 +1778,7 @@ checksum = "35c7fc89d334ab745ba679f94c7314c9b17ecdcd923c111df6206e9fd7729fa9" dependencies = [ "serde", "serde_json", - "thiserror", -] - -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core 0.13.4", - "darling_macro 0.13.4", + "thiserror 1.0.69", ] [[package]] @@ -1803,22 +1787,8 @@ version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] @@ -1835,24 +1805,13 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core 0.13.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.10", + "darling_core", "quote", "syn 2.0.87", ] @@ -1967,7 +1926,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling 0.20.10", + "darling", "proc-macro2", "quote", "syn 2.0.87", @@ -2043,7 +2002,7 @@ dependencies = [ "console", "shell-words", "tempfile", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -2165,6 +2124,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + [[package]] name = "downcast-rs" version = "1.2.1" @@ -2236,12 +2204,24 @@ version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f" dependencies = [ - "enum-ordinalize", + "enum-ordinalize 3.1.15", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize 4.3.0", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "either" version = "1.13.0" @@ -2345,6 +2325,26 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "enumn" version = "0.1.14" @@ -2447,7 +2447,7 @@ dependencies = [ "serde_json", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", "uuid 0.8.2", ] @@ -2594,7 +2594,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fe00b427b7c4835f8b82170eb7b9a63634376b63d73b9a9093367e82570bbaa" dependencies = [ "regex", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2604,7 +2604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.69", "winapi", ] @@ -2798,7 +2798,7 @@ dependencies = [ "sway-core", "sway-features", "sway-types", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -2874,7 +2874,7 @@ dependencies = [ "ipfs-api-backend-hyper", "petgraph", "regex", - "reqwest 0.12.9", + "reqwest", "semver 1.0.23", "serde", "serde_ignored", @@ -2944,7 +2944,7 @@ dependencies = [ "fuel-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2979,8 +2979,7 @@ dependencies = [ [[package]] name = "forc-wallet" version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed94e0de4d8265fe744704544932bf1285ffa16ee5feb18062194904d299f9f" +source = "git+https://github.com/FuelLabs/forc-wallet/?branch=feature/zk-opcodes#7a48841d282ee3246a453136f0d14677d7a8891b" dependencies = [ "anyhow", "clap", @@ -3055,14 +3054,14 @@ dependencies = [ "serde", "serde_json", "syn 2.0.87", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "fuel-asm" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f325971bf9047ec70004f80a989e03456316bc19cbef3ff3a39a38b192ab56e" +checksum = "885617a606218680114122f4e1107ed5c9424e42dec05de84843e4a3a99e2cd7" dependencies = [ "bitflags 2.6.0", "fuel-types", @@ -3072,9 +3071,8 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990db3029efd3766c4ae7c92a53c159ae66abf6f568ac6a3d58354f11400e6e2" +version = "0.40.2" +source = "git+https://github.com/FuelLabs/fuel-core?branch=add_zk_opcodes#cb31e487d32b99015286020643eef0924af11372" dependencies = [ "anyhow", "bech32", @@ -3092,9 +3090,8 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09b3a35e82226d77b10653829beb508dc4bcf698fbdaa96610faf894e794444" +version = "0.40.2" +source = "git+https://github.com/FuelLabs/fuel-core?branch=add_zk_opcodes#cb31e487d32b99015286020643eef0924af11372" dependencies = [ "anyhow", "base64 0.22.1", @@ -3106,20 +3103,19 @@ dependencies = [ "hex", "hyper-rustls 0.24.2", "itertools 0.12.1", - "reqwest 0.11.27", + "reqwest", "schemafy_lib", "serde", "serde_json", "tai64", - "thiserror", + "thiserror 1.0.69", "tracing", ] [[package]] name = "fuel-core-metrics" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a1c3eb92040d95d27f7c658801bb5c04ad4aaf67de380cececbeed5aab6e61" +version = "0.40.2" +source = "git+https://github.com/FuelLabs/fuel-core?branch=add_zk_opcodes#cb31e487d32b99015286020643eef0924af11372" dependencies = [ "once_cell", "parking_lot", @@ -3133,9 +3129,8 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f6f78fa31dc56b9458e3ca9a7058b4bea381e16e49fcab0db49923be8a30f9c" +version = "0.40.2" +source = "git+https://github.com/FuelLabs/fuel-core?branch=add_zk_opcodes#cb31e487d32b99015286020643eef0924af11372" dependencies = [ "anyhow", "async-trait", @@ -3152,9 +3147,8 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8312b598da4b9a6503c9263c1c2a7ea58d34ab1f86e7f345490e12d309fb29bb" +version = "0.40.2" +source = "git+https://github.com/FuelLabs/fuel-core?branch=add_zk_opcodes#cb31e487d32b99015286020643eef0924af11372" dependencies = [ "anyhow", "async-trait", @@ -3168,9 +3162,8 @@ dependencies = [ [[package]] name = "fuel-core-storage" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda9242ebc9e8ef3251b9eae85f4ce5cdb376348baa30925606f3ce602db7ec5" +version = "0.40.2" +source = "git+https://github.com/FuelLabs/fuel-core?branch=add_zk_opcodes#cb31e487d32b99015286020643eef0924af11372" dependencies = [ "anyhow", "derive_more 0.99.18", @@ -3190,9 +3183,8 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee3a95b189bf729d21354a761862bb481298cbd883550adc3fef1bc7beb0b67" +version = "0.40.2" +source = "git+https://github.com/FuelLabs/fuel-core?branch=add_zk_opcodes#cb31e487d32b99015286020643eef0924af11372" dependencies = [ "anyhow", "bs58", @@ -3208,9 +3200,9 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e318850ca64890ff123a99b6b866954ef49da94ab9bc6827cf6ee045568585" +checksum = "8e5643d6c281369825854bbc96d5d1648fe49ddcc3443961c633270f65e6c4b6" dependencies = [ "coins-bip32", "coins-bip39", @@ -3229,9 +3221,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" +checksum = "8703ee10001e6a52ad9a0d8411ca5a92098de978ccfbdddd0ba185f3a7405b4c" dependencies = [ "proc-macro2", "quote", @@ -3252,7 +3244,7 @@ dependencies = [ "serde", "serde_json", "sha3", - "thiserror", + "thiserror 1.0.69", "uint", ] @@ -3278,7 +3270,7 @@ version = "0.3.1-dev" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7eed51e8869a40529c44dc6d971f3509f2a3aa55dc9b213d6f88ee2da38a3d44" dependencies = [ - "educe", + "educe 0.4.23", "indexmap 1.9.3", "quote", "serde", @@ -3288,9 +3280,9 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79eca6a452311c70978a5df796c0f99f27e474b69719e0db4c1d82e68800d07" +checksum = "7446f9cc1885ede3af88cf567931f96fd1feda3146e9052c09b1b260fbd56173" dependencies = [ "derive_more 0.99.18", "digest 0.10.7", @@ -3303,19 +3295,19 @@ dependencies = [ [[package]] name = "fuel-storage" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0c46b5d76b3e11197bd31e036cd8b1cb46c4d822cacc48836638080c6d2b76" +checksum = "01f810b544f0930fc68e1311ea078fad9af6912d5215a9ae9febda67206e34e5" [[package]] name = "fuel-tx" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6723bb8710ba2b70516ac94d34459593225870c937670fb3afaf82e0354667ac" +checksum = "806498d953bc989995425f1bb7c17890f5538a3664c6ec3b5d8a77c63d617421" dependencies = [ "bitflags 2.6.0", - "derivative", - "derive_more 0.99.18", + "derive_more 1.0.0", + "educe 0.6.0", "fuel-asm", "fuel-crypto", "fuel-merkle", @@ -3331,9 +3323,9 @@ dependencies = [ [[package]] name = "fuel-types" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982265415a99b5bd6277bc24194a233bb2e18764df11c937b3dbb11a02c9e545" +checksum = "d0d46d41db59c131195e6d842cc1e50f0b8adeadf2a840519e8b57b78e57a0bf" dependencies = [ "fuel-derive", "hex", @@ -3343,16 +3335,16 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.58.2" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b5362d7d072c72eec20581f67fc5400090c356a7f3ae77c79880b3b177b667" +checksum = "9bcf74f636cc01a1ab035458628f925945bb4df9da653058c6ab2b26fa25f087" dependencies = [ "anyhow", "async-trait", "backtrace", "bitflags 2.6.0", - "derivative", "derive_more 0.99.18", + "educe 0.6.0", "ethnum", "fuel-asm", "fuel-crypto", @@ -3372,14 +3364,14 @@ dependencies = [ "sha3", "static_assertions", "strum 0.24.1", + "substrate-bn", "tai64", ] [[package]] name = "fuels" version = "0.66.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bf359dceffcbab4163bca473a03658b912686c3aa81a223f828260729dd474" +source = "git+https://github.com/FuelLabs/fuels-rs/?branch=feature/zk-opcodes#3b2d741e4226ba22b20aba545ae14794006bdd18" dependencies = [ "fuel-core-client", "fuel-crypto", @@ -3394,8 +3386,7 @@ dependencies = [ [[package]] name = "fuels-accounts" version = "0.66.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0b09d6ce3a12196f6944c74bdd795c39950d32ebaaf56b2943741a5e4308a1" +source = "git+https://github.com/FuelLabs/fuels-rs/?branch=feature/zk-opcodes#3b2d741e4226ba22b20aba545ae14794006bdd18" dependencies = [ "async-trait", "chrono", @@ -3412,7 +3403,7 @@ dependencies = [ "rand", "semver 1.0.23", "tai64", - "thiserror", + "thiserror 1.0.69", "tokio", "zeroize", ] @@ -3420,8 +3411,7 @@ dependencies = [ [[package]] name = "fuels-code-gen" version = "0.66.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bf5f7b37ec598514fb3767abdae5372a9fa0919d350703f5d627ec2eb33456" +source = "git+https://github.com/FuelLabs/fuels-rs/?branch=feature/zk-opcodes#3b2d741e4226ba22b20aba545ae14794006bdd18" dependencies = [ "Inflector", "fuel-abi-types", @@ -3436,8 +3426,7 @@ dependencies = [ [[package]] name = "fuels-core" version = "0.66.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab66cdf52fa6ef98dbc9cc7b4ce19c6a340b2a4710c5d5f87eae39ffb868bad7" +source = "git+https://github.com/FuelLabs/fuels-rs/?branch=feature/zk-opcodes#3b2d741e4226ba22b20aba545ae14794006bdd18" dependencies = [ "async-trait", "bech32", @@ -3458,15 +3447,14 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "uint", ] [[package]] name = "fuels-macros" version = "0.66.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1471d221453d13d4643c9a698212781f0e8ac40f515a8566538db87409e30752" +source = "git+https://github.com/FuelLabs/fuels-rs/?branch=feature/zk-opcodes#3b2d741e4226ba22b20aba545ae14794006bdd18" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -3478,8 +3466,7 @@ dependencies = [ [[package]] name = "fuels-programs" version = "0.66.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a854561a68ef4088972119cf31023d2d1afd58584da203bcb7dfbd1e84dd8fc" +source = "git+https://github.com/FuelLabs/fuels-rs/?branch=feature/zk-opcodes#3b2d741e4226ba22b20aba545ae14794006bdd18" dependencies = [ "async-trait", "fuel-abi-types", @@ -3497,8 +3484,7 @@ dependencies = [ [[package]] name = "fuels-test-helpers" version = "0.66.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a7b428c35a54e4d667343b4051f07a7397e6039bd110411c37647db4478086e" +source = "git+https://github.com/FuelLabs/fuels-rs/?branch=feature/zk-opcodes#3b2d741e4226ba22b20aba545ae14794006bdd18" dependencies = [ "fuel-core-chain-config", "fuel-core-client", @@ -3641,8 +3627,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -3689,7 +3677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" dependencies = [ "faster-hex", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3702,7 +3690,7 @@ dependencies = [ "gix-trace", "home", "once_cell", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3722,7 +3710,7 @@ dependencies = [ "gix-path", "home", "serde", - "thiserror", + "thiserror 1.0.69", "url", ] @@ -3753,17 +3741,7 @@ checksum = "3a6ad932c6dd3cfaf16b66754a42f87bbeefd591530c4b6a8334270a7df3e853" dependencies = [ "ahash 0.8.11", "petgraph", - "thiserror", -] - -[[package]] -name = "graphql-parser" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" -dependencies = [ - "combine", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3837,7 +3815,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4139,7 +4117,7 @@ dependencies = [ "rustls-native-certs", "tokio", "tokio-rustls 0.24.1", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] @@ -4157,6 +4135,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.0", "tower-service", + "webpki-roots 0.26.7", ] [[package]] @@ -4353,16 +4332,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "1.0.3" @@ -4571,7 +4540,7 @@ dependencies = [ "hyper 0.14.31", "hyper-multipart-rfc7578", "ipfs-api-prelude", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4592,7 +4561,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-util", "tracing", @@ -4736,6 +4705,15 @@ dependencies = [ "libc", ] +[[package]] +name = "lalrpop-util" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feee752d43abd0f4807a921958ab4131f692a44d4d599733d4419c5d586176ce" +dependencies = [ + "rustversion", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -4794,7 +4772,7 @@ dependencies = [ "multihash 0.19.2", "quick-protobuf", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "tracing", "zeroize", ] @@ -4925,6 +4903,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + [[package]] name = "lock_api" version = "0.4.12" @@ -4947,7 +4931,31 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf8b031682c67a8e3d5446840f9573eb7fe26efe7ec8d195c9ac4c0647c502f1" dependencies = [ - "logos-derive", + "logos-derive 0.12.1", +] + +[[package]] +name = "logos" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458" +dependencies = [ + "logos-derive 0.14.4", +] + +[[package]] +name = "logos-codegen" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax 0.8.5", + "syn 2.0.87", ] [[package]] @@ -4964,6 +4972,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "logos-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d" +dependencies = [ + "logos-codegen", +] + [[package]] name = "lsp-types" version = "0.94.1" @@ -5587,6 +5604,31 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "ouroboros" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944fa20996a25aded6b4795c6d63f10014a7a83f8be9828a11860b08c5fc4a67" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39b0deead1528fd0e5947a8546a9642a9777c25f6e1e26f34c97b204bbb465bd" +dependencies = [ + "heck 0.4.1", + "itertools 0.12.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.87", +] + [[package]] name = "outref" version = "0.5.1" @@ -5741,7 +5783,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] @@ -6022,7 +6064,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "thiserror", + "thiserror 1.0.69", "toml 0.5.11", ] @@ -6089,6 +6131,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "version_check", + "yansi 1.0.1", +] + [[package]] name = "prometheus-client" version = "0.22.3" @@ -6173,7 +6228,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" dependencies = [ - "idna 1.0.3", + "idna", "psl-types", ] @@ -6219,6 +6274,58 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.0.0", + "rustls 0.23.17", + "socket2", + "thiserror 2.0.9", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +dependencies = [ + "bytes", + "getrandom", + "rand", + "ring", + "rustc-hash 2.0.0", + "rustls 0.23.17", + "rustls-pki-types", + "slab", + "thiserror 2.0.9", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "quote" version = "1.0.37" @@ -6355,7 +6462,27 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox 0.1.3", - "thiserror", + "thiserror 1.0.69", +] + +[[package]] +name = "ref-cast" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] @@ -6417,49 +6544,6 @@ dependencies = [ "bytecheck", ] -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "cookie", - "cookie_store", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.31", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration 0.5.1", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", -] - [[package]] name = "reqwest" version = "0.12.9" @@ -6468,6 +6552,8 @@ checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", + "cookie", + "cookie_store", "encoding_rs", "futures-core", "futures-util", @@ -6487,19 +6573,24 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", + "rustls 0.23.17", "rustls-pemfile 2.2.0", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration 0.6.1", + "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls 0.26.0", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots 0.26.7", "windows-registry", ] @@ -6589,7 +6680,7 @@ dependencies = [ "nix 0.25.1", "regex", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -6839,6 +6930,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" dependencies = [ "once_cell", + "ring", "rustls-pki-types", "rustls-webpki 0.102.8", "subtle", @@ -6880,6 +6972,9 @@ name = "rustls-pki-types" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" @@ -7249,7 +7344,7 @@ version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ - "darling 0.20.10", + "darling", "proc-macro2", "quote", "syn 2.0.87", @@ -7371,7 +7466,7 @@ dependencies = [ "async-trait", "cfg-if 1.0.0", "rustyline", - "thiserror", + "thiserror 1.0.69", "tokio", "version_check", "yansi 0.5.1", @@ -7686,7 +7781,7 @@ dependencies = [ "sway-types", "sway-utils", "sysinfo", - "thiserror", + "thiserror 1.0.69", "tracing", "uint", "vec1", @@ -7702,7 +7797,7 @@ dependencies = [ "smallvec", "strsim 0.11.1", "sway-types", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7785,7 +7880,7 @@ dependencies = [ "swayfmt", "syn 2.0.87", "tempfile", - "thiserror", + "thiserror 1.0.69", "tikv-jemallocator", "tokio", "toml_edit", @@ -7823,7 +7918,7 @@ dependencies = [ "sway-ast", "sway-error", "sway-types", - "thiserror", + "thiserror 1.0.69", "unicode-bidi", "unicode-xid", ] @@ -7844,7 +7939,7 @@ dependencies = [ "rustc-hash 1.1.0", "serde", "sway-utils", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7875,7 +7970,7 @@ dependencies = [ "sway-types", "sway-utils", "test-macros", - "thiserror", + "thiserror 1.0.69", "toml 0.8.19", ] @@ -7957,7 +8052,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror", + "thiserror 1.0.69", "walkdir", "yaml-rust", ] @@ -7977,17 +8072,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys 0.5.0", -] - [[package]] name = "system-configuration" version = "0.6.1" @@ -7996,17 +8080,7 @@ checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.6.0", "core-foundation", - "system-configuration-sys 0.6.0", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "system-configuration-sys", ] [[package]] @@ -8021,9 +8095,9 @@ dependencies = [ [[package]] name = "tai64" -version = "4.1.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "014639506e4f425c78e823eabf56e71c093f940ae55b43e58f682e7bc2f5887a" +checksum = "ed7401421025f4132e6c1f7af5e7f8287383969f36e6628016cd509b8d3da9dc" dependencies = [ "serde", ] @@ -8045,12 +8119,12 @@ dependencies = [ "either", "globset", "itertools 0.10.5", - "logos", + "logos 0.12.1", "once_cell", "rowan", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "time", "tracing", ] @@ -8216,7 +8290,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +dependencies = [ + "thiserror-impl 2.0.9", ] [[package]] @@ -8230,6 +8313,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -8313,7 +8407,7 @@ dependencies = [ "rand", "rustc-hash 1.1.0", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "unicode-normalization", "wasm-bindgen", "zeroize", @@ -8795,15 +8889,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -[[package]] -name = "unreachable" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -dependencies = [ - "void", -] - [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -8835,7 +8920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", - "idna 1.0.3", + "idna", "percent-encoding", "serde", ] @@ -9083,12 +9168,31 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-roots" version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "which" version = "6.0.3" @@ -9339,16 +9443,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - [[package]] name = "winsafe" version = "0.0.19" diff --git a/Cargo.toml b/Cargo.toml index 402b7679c42..b11250c1393 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,24 +84,24 @@ fuel-abi-types = "0.7" # Although ALL verions are "X.Y", we need the complete semver for # fuel-core-client as the GitHub Actions workflow parses this value to pull down # the correct tarball -fuel-core-client = { version = "0.40.0", default-features = false } -fuel-core-types = { version = "0.40", default-features = false } +fuel-core-client = { version = "0.40.2", default-features = false, git = "https://github.com/FuelLabs/fuel-core", branch = "add_zk_opcodes" } +fuel-core-types = { version = "0.40.2", default-features = false, git = "https://github.com/FuelLabs/fuel-core", branch = "add_zk_opcodes" } # Dependencies from the `fuels-rs` repository: -fuels = "0.66.10" -fuels-core = "0.66.10" -fuels-accounts = "0.66.10" +fuels = { version = "0.66.10", git = "https://github.com/FuelLabs/fuels-rs/", branch = "feature/zk-opcodes" } +fuels-core = { version = "0.66.10", git = "https://github.com/FuelLabs/fuels-rs/", branch = "feature/zk-opcodes" } +fuels-accounts = { version = "0.66.10", git = "https://github.com/FuelLabs/fuels-rs/", branch = "feature/zk-opcodes" } # Dependencies from the `fuel-vm` repository: -fuel-asm = "0.58" -fuel-crypto = "0.58" -fuel-types = "0.58" -fuel-tx = "0.58" -fuel-vm = "0.58" +fuel-asm = "0.59.1" +fuel-crypto = "0.59.1" +fuel-types = "0.59.1" +fuel-tx = "0.59.1" +fuel-vm = "0.59.1" # Dependencies from the `forc-wallet` repository: -forc-wallet = "0.11" +forc-wallet = { version = "0.11", git = "https://github.com/FuelLabs/forc-wallet/", branch = "feature/zk-opcodes" } # # External dependencies diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index 7d21d439e8c..36d67eaf2ab 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -30,6 +30,7 @@ use sway_core::language::parsed::TreeType; use sway_core::BuildTarget; use tokio::time::timeout; use tracing::info; +use fuels_accounts::ViewOnlyAccount; use self::encode::ScriptCallHandler; diff --git a/forc-plugins/forc-client/src/util/account.rs b/forc-plugins/forc-client/src/util/account.rs index 17ecc6781b8..b129ce95b2d 100644 --- a/forc-plugins/forc-client/src/util/account.rs +++ b/forc-plugins/forc-client/src/util/account.rs @@ -22,28 +22,7 @@ pub enum ForcClientAccount { KmsSigner(AwsSigner), } -#[async_trait] impl Account for ForcClientAccount { - async fn get_asset_inputs_for_amount( - &self, - asset_id: AssetId, - amount: u64, - excluded_coins: Option>, - ) -> Result> { - match self { - ForcClientAccount::Wallet(wallet) => { - wallet - .get_asset_inputs_for_amount(asset_id, amount, excluded_coins) - .await - } - ForcClientAccount::KmsSigner(account) => { - account - .get_asset_inputs_for_amount(asset_id, amount, excluded_coins) - .await - } - } - } - fn add_witnesses(&self, tb: &mut Tb) -> Result<()> { tb.add_signer(self.clone())?; @@ -51,6 +30,7 @@ impl Account for ForcClientAccount { } } +#[async_trait] impl ViewOnlyAccount for ForcClientAccount { fn address(&self) -> &Bech32Address { match self { @@ -67,6 +47,26 @@ impl ViewOnlyAccount for ForcClientAccount { ForcClientAccount::KmsSigner(account) => Ok(account.provider()), } } + + async fn get_asset_inputs_for_amount( + &self, + asset_id: AssetId, + amount: u64, + excluded_coins: Option>, + ) -> Result> { + match self { + ForcClientAccount::Wallet(wallet) => { + wallet + .get_asset_inputs_for_amount(asset_id, amount, excluded_coins) + .await + } + ForcClientAccount::KmsSigner(account) => { + account + .get_asset_inputs_for_amount(asset_id, amount, excluded_coins) + .await + } + } + } } #[async_trait] diff --git a/forc-plugins/forc-client/src/util/aws.rs b/forc-plugins/forc-client/src/util/aws.rs index 90da533815c..df022553e84 100644 --- a/forc-plugins/forc-client/src/util/aws.rs +++ b/forc-plugins/forc-client/src/util/aws.rs @@ -241,6 +241,7 @@ impl Signer for AwsSigner { } } +#[async_trait] impl ViewOnlyAccount for AwsSigner { fn address(&self) -> &Bech32Address { &self.bech @@ -249,10 +250,7 @@ impl ViewOnlyAccount for AwsSigner { fn try_provider(&self) -> Result<&Provider> { Ok(&self.provider) } -} -#[async_trait] -impl Account for AwsSigner { async fn get_asset_inputs_for_amount( &self, asset_id: AssetId, @@ -267,3 +265,5 @@ impl Account for AwsSigner { .collect::>()) } } + +impl Account for AwsSigner {} diff --git a/forc-test/src/execute.rs b/forc-test/src/execute.rs index a0423caba12..9b3d899a326 100644 --- a/forc-test/src/execute.rs +++ b/forc-test/src/execute.rs @@ -120,6 +120,7 @@ impl TestExecutor { gas_price, consensus_params.gas_costs(), consensus_params.fee_params(), + None, ) .map_err(|e| anyhow::anyhow!("{e:?}"))?; diff --git a/forc-test/src/lib.rs b/forc-test/src/lib.rs index bccc4cc0209..4f50b2436dd 100644 --- a/forc-test/src/lib.rs +++ b/forc-test/src/lib.rs @@ -230,7 +230,7 @@ impl PackageWithDeploymentToTest { .map(|(contract_id, tx)| { // Transact the deployment transaction constructed for this contract dependency. let tx = tx - .into_ready(gas_price, params.gas_costs(), params.fee_params()) + .into_ready(gas_price, params.gas_costs(), params.fee_params(), None) .unwrap(); interpreter.transact(tx).map_err(anyhow::Error::msg)?; Ok(contract_id) @@ -247,7 +247,7 @@ impl PackageWithDeploymentToTest { ¶ms, ); let root_contract_tx = root_contract_tx - .into_ready(gas_price, params.gas_costs(), params.fee_params()) + .into_ready(gas_price, params.gas_costs(), params.fee_params(), None) .unwrap(); // Deploy the root contract. interpreter diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index 936127d7554..7c1a9f543f7 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -595,6 +595,8 @@ fn print_instruction(op: &Instruction) { Instruction::ECAL(x) => f("ECAL", x.unpack()), Instruction::BSIZ(x) => f("BSIZ", x.unpack()), Instruction::BLDD(x) => f("BLDD", x.unpack()), + Instruction::ECOP(x) => f("ECOP", x.unpack()), + Instruction::EPAR(x) => f("EPAR", x.unpack()), } } diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index 31dbcda4b48..deb185d15d7 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -203,7 +203,7 @@ pub(crate) fn runs_in_vm( let tx = tb .finalize_checked(block_height) - .into_ready(gas_price, params.gas_costs(), params.fee_params()) + .into_ready(gas_price, params.gas_costs(), params.fee_params(), None) .map_err(|e| anyhow::anyhow!("{e:?}"))?; let mem_instance = MemoryInstance::new(); From d39e08c10a90945a40d5301b9d12832908603d44 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Tue, 31 Dec 2024 14:06:02 +0530 Subject: [PATCH 02/13] complete sway ASM support for the new zk opcodes --- forc-plugins/forc-client/src/op/run/mod.rs | 2 +- sway-core/src/asm_lang/allocated_ops.rs | 22 +++++++++++ sway-core/src/asm_lang/mod.rs | 10 +++++ sway-core/src/asm_lang/virtual_ops.rs | 46 ++++++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index 36d67eaf2ab..43324f7a250 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -22,6 +22,7 @@ use fuels::{ transaction_builders::{BuildableTransaction, VariableOutputPolicy}, }, }; +use fuels_accounts::ViewOnlyAccount; use fuels_accounts::{provider::Provider, Account}; use pkg::BuiltPackage; use std::time::Duration; @@ -30,7 +31,6 @@ use sway_core::language::parsed::TreeType; use sway_core::BuildTarget; use tokio::time::timeout; use tracing::info; -use fuels_accounts::ViewOnlyAccount; use self::encode::ScriptCallHandler; diff --git a/sway-core/src/asm_lang/allocated_ops.rs b/sway-core/src/asm_lang/allocated_ops.rs index b817afd3c32..23a5cc88a55 100644 --- a/sway-core/src/asm_lang/allocated_ops.rs +++ b/sway-core/src/asm_lang/allocated_ops.rs @@ -267,6 +267,18 @@ pub(crate) enum AllocatedOpcode { ), K256(AllocatedRegister, AllocatedRegister, AllocatedRegister), S256(AllocatedRegister, AllocatedRegister, AllocatedRegister), + ECOP( + AllocatedRegister, + AllocatedRegister, + AllocatedRegister, + AllocatedRegister, + ), + EPAR( + AllocatedRegister, + AllocatedRegister, + AllocatedRegister, + AllocatedRegister, + ), /* Other Instructions */ FLAG(AllocatedRegister), @@ -392,6 +404,8 @@ impl AllocatedOpcode { ED19(_r1, _r2, _r3, _r4) => vec![], K256(_r1, _r2, _r3) => vec![], S256(_r1, _r2, _r3) => vec![], + ECOP(_r1, _r2, _r3, _r4) => vec![], + EPAR(r1, _r2, _r3, _r4) => vec![r1], /* Other Instructions */ FLAG(_r1) => vec![], @@ -521,6 +535,8 @@ impl fmt::Display for AllocatedOpcode { ED19(a, b, c, d) => write!(fmtr, "ed19 {a} {b} {c} {d}"), K256(a, b, c) => write!(fmtr, "k256 {a} {b} {c}"), S256(a, b, c) => write!(fmtr, "s256 {a} {b} {c}"), + ECOP(a, b, c, d) => write!(fmtr, "ecop {a} {b} {c} {d}"), + EPAR(a, b, c, d) => write!(fmtr, "epar {a} {b} {c} {d}"), /* Other Instructions */ FLAG(a) => write!(fmtr, "flag {a}"), @@ -731,6 +747,12 @@ impl AllocatedOp { } K256(a, b, c) => op::K256::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id()).into(), S256(a, b, c) => op::S256::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id()).into(), + ECOP(a, b, c, d) => { + op::ECOP::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.to_reg_id()).into() + } + EPAR(a, b, c, d) => { + op::EPAR::new(a.to_reg_id(), b.to_reg_id(), c.to_reg_id(), d.to_reg_id()).into() + } /* Other Instructions */ FLAG(a) => op::FLAG::new(a.to_reg_id()).into(), diff --git a/sway-core/src/asm_lang/mod.rs b/sway-core/src/asm_lang/mod.rs index 71e09cc2290..27c4d9bef82 100644 --- a/sway-core/src/asm_lang/mod.rs +++ b/sway-core/src/asm_lang/mod.rs @@ -659,6 +659,14 @@ impl Op { let (r1, r2, r3) = three_regs(handler, args, immediate, whole_op_span)?; VirtualOp::S256(r1, r2, r3) } + "ecop" => { + let (r1, r2, r3, r4) = four_regs(handler, args, immediate, whole_op_span)?; + VirtualOp::ECOP(r1, r2, r3, r4) + } + "epar" => { + let (r1, r2, r3, r4) = four_regs(handler, args, immediate, whole_op_span)?; + VirtualOp::EPAR(r1, r2, r3, r4) + } /* Other Instructions */ "flag" => { @@ -1239,6 +1247,8 @@ impl fmt::Display for VirtualOp { ED19(a, b, c, d) => write!(fmtr, "ed19 {a} {b} {c} {d}"), K256(a, b, c) => write!(fmtr, "k256 {a} {b} {c}"), S256(a, b, c) => write!(fmtr, "s256 {a} {b} {c}"), + ECOP(a, b, c, d) => write!(fmtr, "ecop {a} {b} {c} {d}"), + EPAR(a, b, c, d) => write!(fmtr, "epar {a} {b} {c} {d}"), /* Other Instructions */ FLAG(a) => write!(fmtr, "flag {a}"), diff --git a/sway-core/src/asm_lang/virtual_ops.rs b/sway-core/src/asm_lang/virtual_ops.rs index 3d041713a4f..377c5bd4ccc 100644 --- a/sway-core/src/asm_lang/virtual_ops.rs +++ b/sway-core/src/asm_lang/virtual_ops.rs @@ -218,6 +218,18 @@ pub(crate) enum VirtualOp { ), K256(VirtualRegister, VirtualRegister, VirtualRegister), S256(VirtualRegister, VirtualRegister, VirtualRegister), + ECOP( + VirtualRegister, + VirtualRegister, + VirtualRegister, + VirtualRegister, + ), + EPAR( + VirtualRegister, + VirtualRegister, + VirtualRegister, + VirtualRegister, + ), /* Other Instructions */ FLAG(VirtualRegister), @@ -339,6 +351,8 @@ impl VirtualOp { ED19(r1, r2, r3, r4) => vec![r1, r2, r3, r4], K256(r1, r2, r3) => vec![r1, r2, r3], S256(r1, r2, r3) => vec![r1, r2, r3], + ECOP(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + EPAR(r1, r2, r3, r4) => vec![r1, r2, r3, r4], /* Other Instructions */ FLAG(r1) => vec![r1], @@ -407,6 +421,7 @@ impl VirtualOp { | TIME(_, _) | GM(_, _) | GTF(_, _, _) + | EPAR(_, _, _, _) // Virtual OPs | LoadDataId(_, _) | AddrDataId(_, _) @@ -463,6 +478,7 @@ impl VirtualOp { | ED19(_, _, _, _) | K256(_, _, _) | S256(_, _, _) + | ECOP(_, _, _, _) | FLAG(_) // Virtual OPs | BLOB(_) @@ -570,6 +586,8 @@ impl VirtualOp { | TRO(_, _, _, _) | K256(_, _, _) | S256(_, _, _) + | ECOP(_, _, _, _) + | EPAR(_, _, _, _) | GM(_, _) | GTF(_, _, _) | BLOB(_) @@ -687,6 +705,8 @@ impl VirtualOp { ED19(r1, r2, r3, r4) => vec![r1, r2, r3, r4], K256(r1, r2, r3) => vec![r1, r2, r3], S256(r1, r2, r3) => vec![r1, r2, r3], + ECOP(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + EPAR(_r1, r2, r3, r4) => vec![r2, r3, r4], /* Other Instructions */ FLAG(r1) => vec![r1], @@ -809,6 +829,8 @@ impl VirtualOp { ED19(_r1, _r2, _r3, _r4) => vec![], K256(_r1, _r2, _r3) => vec![], S256(_r1, _r2, _r3) => vec![], + ECOP(_r1, _r2, _r3, _r4) => vec![], + EPAR(r1, _r2, _r3, _r4) => vec![r1], /* Other Instructions */ FLAG(_r1) => vec![], @@ -1256,6 +1278,18 @@ impl VirtualOp { update_reg(reg_to_reg_map, r2), update_reg(reg_to_reg_map, r3), ), + ECOP(r1, r2, r3, r4) => Self::ECOP( + update_reg(reg_to_reg_map, r1), + update_reg(reg_to_reg_map, r2), + update_reg(reg_to_reg_map, r3), + update_reg(reg_to_reg_map, r4), + ), + EPAR(r1, r2, r3, r4) => Self::EPAR( + update_reg(reg_to_reg_map, r1), + update_reg(reg_to_reg_map, r2), + update_reg(reg_to_reg_map, r3), + update_reg(reg_to_reg_map, r4), + ), /* Other Instructions */ FLAG(r1) => Self::FLAG(update_reg(reg_to_reg_map, r1)), @@ -1737,6 +1771,18 @@ impl VirtualOp { map_reg(&mapping, reg2), map_reg(&mapping, reg3), ), + ECOP(reg1, reg2, reg3, reg4) => AllocatedOpcode::ECOP( + map_reg(&mapping, reg1), + map_reg(&mapping, reg2), + map_reg(&mapping, reg3), + map_reg(&mapping, reg4), + ), + EPAR(reg1, reg2, reg3, reg4) => AllocatedOpcode::EPAR( + map_reg(&mapping, reg1), + map_reg(&mapping, reg2), + map_reg(&mapping, reg3), + map_reg(&mapping, reg4), + ), /* Other Instructions */ FLAG(reg) => AllocatedOpcode::FLAG(map_reg(&mapping, reg)), From c681835d4427b8c36d9f340c8d4340aaa03591e6 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Tue, 31 Dec 2024 14:43:13 +0530 Subject: [PATCH 03/13] add compile only test --- sway-ast/src/expr/op_code.rs | 2 ++ sway-parse/src/expr/op_code.rs | 12 ++++++++++++ .../should_pass/language/zk_opcodes/Forc.lock | 13 +++++++++++++ .../should_pass/language/zk_opcodes/Forc.toml | 8 ++++++++ .../should_pass/language/zk_opcodes/src/main.sw | 14 ++++++++++++++ .../should_pass/language/zk_opcodes/test.toml | 1 + 6 files changed, 50 insertions(+) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/test.toml diff --git a/sway-ast/src/expr/op_code.rs b/sway-ast/src/expr/op_code.rs index acfc54411eb..49dac07e435 100644 --- a/sway-ast/src/expr/op_code.rs +++ b/sway-ast/src/expr/op_code.rs @@ -329,6 +329,8 @@ define_op_codes!( (Ed19, Ed19Opcode, "ed19", (addr: reg, sig: reg, hash: reg, len: reg)), (K256, K256Opcode, "k256", (addr: reg, data: reg, size: reg)), (S256, S256Opcode, "s256", (addr: reg, data: reg, size: reg)), + (ECOP, ECOPOpcode, "ecop", (dst_addr: reg, curve: reg, operation: reg, src_addr: reg)), + (EPAR, EPAROpcode, "epar", (ret: reg, curve: reg, groups_of_points: reg, addr: reg)), /* Other Instructions */ (Flag, FlagOpcode, "flag", (value: reg)), (Gm, GmOpcode, "gm", (ret: reg, op: imm)), diff --git a/sway-parse/src/expr/op_code.rs b/sway-parse/src/expr/op_code.rs index 1281ca4bae3..29ad8918111 100644 --- a/sway-parse/src/expr/op_code.rs +++ b/sway-parse/src/expr/op_code.rs @@ -124,6 +124,18 @@ define_op_codes!( (Ed19, Ed19Opcode, "ed19", (addr, sig, hash, len)), (K256, K256Opcode, "k256", (addr, data, size)), (S256, S256Opcode, "s256", (addr, data, size)), + ( + ECOP, + ECOPOpcode, + "ecop", + (dst_addr, curve, operation, src_addr) + ), + ( + EPAR, + EPAROpcode, + "epar", + (ret, curve, groups_of_points, addr) + ), /* Other Instructions */ (Flag, FlagOpcode, "flag", (value)), (Gm, GmOpcode, "gm", (ret, op)), diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.lock new file mode 100644 index 00000000000..249dfc40045 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-11C3CFAE4942D9B7" + +[[package]] +name = "std" +source = "path+from-root-11C3CFAE4942D9B7" +dependencies = ["core"] + +[[package]] +name = "zk_opcodes" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.toml new file mode 100644 index 00000000000..398b5b6b1a5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "zk_opcodes" + +[dependencies] +std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/src/main.sw new file mode 100644 index 00000000000..db00a0f0090 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/src/main.sw @@ -0,0 +1,14 @@ +script; + +fn main() -> bool { + let src_addr: [u64; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let dst_addr: [u64; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + asm(dst_addr: dst_addr, curve: 0, op: 0, src_addr: src_addr) { + ecop dst_addr curve op src_addr; + } + + asm(res, curve: 0, group_of_points: 1, addr: dst_addr) { + epar res curve group_of_points addr; + res: bool + } +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/test.toml new file mode 100644 index 00000000000..e816041d3f8 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/zk_opcodes/test.toml @@ -0,0 +1 @@ +category = "compile" From 74a1db2054aac62d29d7d2a15de9a5ef0a94b866 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 14 Jan 2025 11:27:35 +0100 Subject: [PATCH 04/13] Add Point2d, Scalar, and Zk module --- sway-lib-std/src/crypto.sw | 5 + sway-lib-std/src/crypto/point2d.sw | 229 +++++++++++++++++++++++++++++ sway-lib-std/src/crypto/scalar.sw | 125 ++++++++++++++++ sway-lib-std/src/crypto/zk.sw | 143 ++++++++++++++++++ 4 files changed, 502 insertions(+) create mode 100644 sway-lib-std/src/crypto.sw create mode 100644 sway-lib-std/src/crypto/point2d.sw create mode 100644 sway-lib-std/src/crypto/scalar.sw create mode 100644 sway-lib-std/src/crypto/zk.sw diff --git a/sway-lib-std/src/crypto.sw b/sway-lib-std/src/crypto.sw new file mode 100644 index 00000000000..6ffe2cf155c --- /dev/null +++ b/sway-lib-std/src/crypto.sw @@ -0,0 +1,5 @@ +library; + +pub mod point2d; +pub mod scalar; +pub mod zk; diff --git a/sway-lib-std/src/crypto/point2d.sw b/sway-lib-std/src/crypto/point2d.sw new file mode 100644 index 00000000000..2d5026837b3 --- /dev/null +++ b/sway-lib-std/src/crypto/point2d.sw @@ -0,0 +1,229 @@ +library; + +use ::convert::{From, TryFrom}; +use ::bytes::{Bytes, *}; +use ::option::Option::{self, *}; +use ::primitive_conversions::u256::*; + +pub struct Point2D { + x: Bytes, + y: Bytes, +} + +impl Eq for Point2D { + fn eq(self, other: Self) -> bool { + // All points must be of length 32 + if self.x.len() != 32 || self.y.len() != 32 || other.x.len() != 32 || other.y.len() != 32 { + return false; + } + + let mut iter = 0; + while iter < 32 { + if self.x.get(iter).unwrap() != other.x.get(iter).unwrap() { + return false; + } else if self.y.get(iter).unwrap() != other.y.get(iter).unwrap() { + return false; + } + + iter += 1; + } + true + } +} + +impl Point2D { + pub fn new() -> Self { + Self { + x: Bytes::new(), + y: Bytes::new(), + } + } + + pub fn zero() -> Self { + Self { + x: Bytes::from(b256::zero()), + y: Bytes::from(b256::zero()), + } + } + + pub fn is_zero(self) -> bool { + self == Self::zero() + } + + pub fn min() -> Self { + Self { + x: Bytes::from(b256::zero()), + y: Bytes::from(b256::zero()), + } + } + + pub fn max() -> Self { + Self { + x: Bytes::from(b256::max()), + y: Bytes::from(b256::max()), + } + } + + pub fn x(self) -> Bytes { + self.x + } + + pub fn y(self) -> Bytes { + self.y + } +} + +impl From<[u256; 2]> for Point2D { + fn from(bytes: [u256; 2]) -> Self { + Self { + x: Bytes::from(bytes[0].as_b256()), + y: Bytes::from(bytes[1].as_b256()), + } + } +} + +impl From<[b256; 2]> for Point2D { + fn from(bytes: [b256; 2]) -> Self { + Self { + x: Bytes::from(bytes[0]), + y: Bytes::from(bytes[1]), + } + } +} + +impl From<(b256, b256)> for Point2D { + fn from(bytes: (b256, b256)) -> Self { + Self { + x: Bytes::from(bytes.0), + y: Bytes::from(bytes.1), + } + } +} + +impl From<(u256, u256)> for Point2D { + fn from(bytes: (u256, u256)) -> Self { + Self { + x: Bytes::from(bytes.0.as_b256()), + y: Bytes::from(bytes.1.as_b256()), + } + } +} + +impl From<[u8; 64]> for Point2D { + fn from(bytes: [u8; 64]) -> Self { + let mut x = Bytes::with_capacity(32); + let mut y = Bytes::with_capacity(32); + + let mut iter = 0; + while iter < 32 { + x.push(bytes[iter]); + y.push(bytes[iter + 32]); + iter += 1; + } + + Self { + x: x, + y: y, + } + } +} + +impl TryFrom for (u256, u256) { + /// # Example + /// + /// ```sway + /// fn foo(point: Point2D) { + /// let (x, y) = <(u256, u256) as TryFrom>::try_from(point).unwrap(); + /// } + /// ``` + fn try_from(point: Point2D) -> Option { + if point.x.len() != 32 || point.y.len() != 32 { + return None; + } + + let mut value_x = 0x0000000000000000000000000000000000000000000000000000000000000000_u256; + let mut value_y = 0x0000000000000000000000000000000000000000000000000000000000000000_u256; + let ptr_x = __addr_of(value_x); + let ptr_y = __addr_of(value_y); + + point.x.ptr().copy_to::(ptr_x, 1); + point.y.ptr().copy_to::(ptr_y, 1); + + Some((value_x, value_y)) + } +} + +impl TryFrom for [u256; 2] { + /// # Example + /// + /// ```sway + /// fn foo(point: Point2D) { + /// let array = <[u256; 2] as TryFrom>::try_from(point).unwrap(); + /// } + /// ``` + fn try_from(point: Point2D) -> Option { + if point.x.len() != 32 || point.y.len() != 32 { + return None; + } + + let mut value_x = 0x0000000000000000000000000000000000000000000000000000000000000000_u256; + let mut value_y = 0x0000000000000000000000000000000000000000000000000000000000000000_u256; + let ptr_x = __addr_of(value_x); + let ptr_y = __addr_of(value_y); + + point.x.ptr().copy_to::(ptr_x, 1); + point.y.ptr().copy_to::(ptr_y, 1); + + Some([value_x, value_y]) + } +} + +impl TryFrom for (b256, b256) { + /// # Example + /// + /// ```sway + /// fn foo(point: Point2D) { + /// let (x, y) = <(b256, b256) as TryFrom>::try_from(point).unwrap(); + /// } + /// ``` + fn try_from(point: Point2D) -> Option { + if point.x.len() != 32 || point.y.len() != 32 { + return None; + } + + let mut value_x = 0x0000000000000000000000000000000000000000000000000000000000000000; + let mut value_y = 0x0000000000000000000000000000000000000000000000000000000000000000; + let ptr_x = __addr_of(value_x); + let ptr_y = __addr_of(value_y); + + point.x.ptr().copy_to::(ptr_x, 1); + point.y.ptr().copy_to::(ptr_y, 1); + + Some((value_x, value_y)) + } +} + +impl TryFrom for [b256; 2] { + /// # Example + /// + /// ```sway + /// fn foo(point: Point2D) { + /// let array = <[b256; 2] as TryFrom>::try_from(point).unwrap(); + /// } + /// ``` + fn try_from(point: Point2D) -> Option { + if point.x.len() != 32 || point.y.len() != 32 { + return None; + } + + let mut value_x = 0x0000000000000000000000000000000000000000000000000000000000000000; + let mut value_y = 0x0000000000000000000000000000000000000000000000000000000000000000; + let ptr_x = __addr_of(value_x); + let ptr_y = __addr_of(value_y); + + point.x.ptr().copy_to::(ptr_x, 1); + point.y.ptr().copy_to::(ptr_y, 1); + + Some([value_x, value_y]) + } +} diff --git a/sway-lib-std/src/crypto/scalar.sw b/sway-lib-std/src/crypto/scalar.sw new file mode 100644 index 00000000000..f62055cab94 --- /dev/null +++ b/sway-lib-std/src/crypto/scalar.sw @@ -0,0 +1,125 @@ +library; + +use ::convert::{From, TryFrom}; +use ::bytes::{Bytes, *}; +use ::option::Option::{self, *}; +use ::primitive_conversions::u256::*; + +pub struct Scalar { + bytes: Bytes +} + +impl Eq for Scalar { + fn eq(self, other: Self) -> bool { + // All points must be of length 32 + if self.bytes.len() != 32 || other.bytes.len() != 32 { + return false; + } + + let mut iter = 0; + while iter < 32 { + if self.bytes.get(iter).unwrap() != other.bytes.get(iter).unwrap() { + return false; + } + + iter += 1; + } + true + } +} + +impl Scalar { + pub fn new() -> Self { + Self { + bytes: Bytes::new(), + } + } + + pub fn zero() -> Self { + Self { + bytes: Bytes::from(b256::zero()), + } + } + + pub fn min() -> Self { + Self { + bytes: Bytes::from(b256::zero()), + } + } + + pub fn max() -> Self { + Self { + bytes: Bytes::from(b256::max()), + } + } + + pub fn is_zero(self) -> bool { + self == Self::zero() + } + + pub fn bytes(self) -> Bytes { + self.bytes + } +} + +impl From for Scalar { + fn from(bytes: u256) -> Self { + Self { + bytes: Bytes::from(bytes.as_b256()), + } + } +} + +impl From for Scalar { + fn from(bytes: b256) -> Self { + Self { + bytes: Bytes::from(bytes), + } + } +} + +impl From<[u8; 32]> for Scalar { + fn from(bytes_array: [u8; 32]) -> Self { + let mut bytes = Bytes::with_capacity(32); + + let mut iter = 0; + while iter < 32 { + bytes.push(bytes_array[iter]); + iter += 1; + } + + Self { + bytes: bytes, + } + } +} + +impl TryFrom for u256 { + fn try_from(scalar: Scalar) -> Option { + if scalar.bytes.len() != 32 { + return None; + } + + let mut value = 0x0000000000000000000000000000000000000000000000000000000000000000_u256; + let ptr = __addr_of(value); + + scalar.bytes.ptr().copy_to::(ptr, 1); + + Some(value) + } +} + +impl TryFrom for b256 { + fn try_from(scalar: Scalar) -> Option { + if scalar.bytes.len() != 32 { + return None; + } + + let mut value = 0x0000000000000000000000000000000000000000000000000000000000000000; + let ptr = __addr_of(value); + + scalar.bytes.ptr().copy_to::(ptr, 1); + + Some(value) + } +} diff --git a/sway-lib-std/src/crypto/zk.sw b/sway-lib-std/src/crypto/zk.sw new file mode 100644 index 00000000000..4cd3096850a --- /dev/null +++ b/sway-lib-std/src/crypto/zk.sw @@ -0,0 +1,143 @@ +library; + +use ::result::Result::{self, *}; +use ::vec::*; +use ::convert::{From, TryFrom}; +use ::bytes::{Bytes, *}; +use ::option::Option::{self, *}; +use ::primitive_conversions::u256::*; +use ::revert::require; +use ::crypto::{point2d::*, scalar::*}; +use ::alloc::alloc; + +pub enum EllipicCurveError { + UnsupportedCurve: (), + InvalidEllipticCurvePoint: (), + InvalidEllipticCurveScalar: (), + PointPairingCheckFailed: (), +} + +pub enum CurveType { + AltBN128: (), +} + +pub fn ec_mul(curve_type: CurveType, point: Point2D, scalar: Scalar) -> Point2D { + let curve = match curve_type { + CurveType::AltBN128 => { + require(valid_alt_bn128_point(point), EllipicCurveError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_scalar(scalar), EllipicCurveError::InvalidEllipticCurveScalar); + + 0 + } + }; + + // 1P = ([32 bytes], [32 bytes]) + let mut result = [b256::zero(), b256::zero()]; + // 1P1S = (X, Y), Z = ([32 bytes], [32 bytes]), [32 bytes] = 3 * 32 bytes + let mut ptr = alloc::(3); + point.x().ptr().copy_to::(ptr.add::(0), 1); + point.y().ptr().copy_to::(ptr.add::(1), 1); + scalar.bytes().ptr().copy_to::(ptr.add::(2), 1); + + asm(buffer: result, curve: curve, operation: 1, scalar: ptr) { + ecop buffer curve operation scalar; + }; + + Point2D::from(result) +} + +pub fn ec_add(curve_type: CurveType, point_1: Point2D, point_2: Point2D) -> Point2D { + let curve = match curve_type { + CurveType::AltBN128 => { + require(valid_alt_bn128_point(point_1), EllipicCurveError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(point_2), EllipicCurveError::InvalidEllipticCurvePoint); + + 0 + } + }; + + // 1P = ([32 bytes], [32 bytes]) + let mut result = [b256::zero(), b256::zero()]; + // 1P1P = (X, Y), (X, Y) = ([32 bytes], [32 bytes]), ([32 bytes], [32 bytes]) = 4 * 32 bytes + let mut points_ptr = alloc::(4); + point_1.x().ptr().copy_to::(points_ptr.add::(0), 1); + point_1.y().ptr().copy_to::(points_ptr.add::(1), 1); + point_2.x().ptr().copy_to::(points_ptr.add::(2), 1); + point_2.y().ptr().copy_to::(points_ptr.add::(3), 1); + + asm(buffer: result, curve: curve, operation: 0, points: points_ptr) { + ecop buffer curve operation points; + }; + + Point2D::from(result) +} + +pub fn ec_pairing_check(curve_type: CurveType, points: Vec<(Point2D, [Point2D; 2])>) -> bool { + // Total bytes is (P1, (G1, G2)) = ([32 bytes, 32 bytes], ([32 bytes, 32 bytes], [32 bytes, 32 bytes])) = 6 * 32 bytes * length + let mut points_ptr = alloc::(points.len() * 6); + + let curve = match curve_type { + CurveType::AltBN128 => { + let mut iter = 0; + while iter < points.len() { + let p1 = points.get(iter).unwrap().0; + let p2 = points.get(iter).unwrap().1[0]; + let p3 = points.get(iter).unwrap().1[1]; + + require(valid_alt_bn128_point(p1), EllipicCurveError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(p2), EllipicCurveError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(p3), EllipicCurveError::InvalidEllipticCurvePoint); + + // Copy all 6 32 byte length points to the single slice + p1.x().ptr().copy_to::(points_ptr.add::(iter * 6), 1); + p1.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 1), 1); + p2.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 2), 1); + p2.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 3), 1); + p3.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 4), 1); + p3.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 5), 1); + + iter += 1; + } + + 0 + } + }; + + // Result is bool + asm(buffer, curve: curve, length: points.len(), points: points_ptr) { + epar buffer curve length points; + buffer: bool + } +} + +fn valid_alt_bn128_point(point: Point2D) -> bool { + // 1P = ([32 bytes], [32 bytes]) + point.x().len() == 32 && point.y().len() == 32 + + // y**2 = x**3 + 3 + // p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 + + // let p = u256::from(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47); + // let res = <(u256, u256) as TryFrom>::try_from(point); + // let (x, y) = match res { + // Some((x, y)) => (x, y), + // None => return false, + // }; + + // // Ensure x and y are within the field range + // if x > p || y > p { + // return false; + // } + + // // Compute y^2 mod p + // let y_squared = (y * y); + // // // Compute x^3 + 3 + // let x_cubed = (x * x * x); + + // y_squared == (x_cubed + 3) % p +} + +fn valid_alt_bn128_scalar(scalar: Scalar) -> bool { + // 1S = [32 bytes] + scalar.bytes().len() == 32 +} From e86b19c5ac10fab8e9271bc12a0a6b03249c3350 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 14 Jan 2025 11:27:58 +0100 Subject: [PATCH 05/13] Add in language tests --- sway-lib-std/src/lib.sw | 1 + test/src/in_language_tests/Forc.toml | 3 + .../crypto_point2d_inline_tests/Forc.toml | 9 + .../crypto_point2d_inline_tests/src/main.sw | 300 ++++++++++++++++++ .../crypto_scalar_inline_tests/Forc.toml | 9 + .../crypto_scalar_inline_tests/src/main.sw | 151 +++++++++ .../crypto_zk_inline_tests/Forc.toml | 9 + .../crypto_zk_inline_tests/src/main.sw | 247 ++++++++++++++ 8 files changed, 729 insertions(+) create mode 100644 test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/Forc.toml create mode 100644 test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw create mode 100644 test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/Forc.toml create mode 100644 test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw create mode 100644 test/src/in_language_tests/test_programs/crypto_zk_inline_tests/Forc.toml create mode 100644 test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw diff --git a/sway-lib-std/src/lib.sw b/sway-lib-std/src/lib.sw index fc09e123cd6..7ba778f291e 100644 --- a/sway-lib-std/src/lib.sw +++ b/sway-lib-std/src/lib.sw @@ -19,6 +19,7 @@ pub mod math; pub mod u128; pub mod b512; pub mod primitive_conversions; +pub mod crypto; pub mod alias; pub mod hash; pub mod asset_id; diff --git a/test/src/in_language_tests/Forc.toml b/test/src/in_language_tests/Forc.toml index b2f198bf2f7..ddcb37b245e 100644 --- a/test/src/in_language_tests/Forc.toml +++ b/test/src/in_language_tests/Forc.toml @@ -10,6 +10,9 @@ members = [ "test_programs/bytes_inline_tests", "test_programs/contract_id_inline_tests", "test_programs/contract_id_contract_tests", + "test_programs/crypto_point2d_inline_tests", + "test_programs/crypto_scalar_inline_tests", + "test_programs/crypto_zk_inline_tests", "test_programs/ecr_inline_tests", "test_programs/flags_inline_tests", "test_programs/hash_inline_tests", diff --git a/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/Forc.toml b/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/Forc.toml new file mode 100644 index 00000000000..bd16f5461bd --- /dev/null +++ b/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "crypto_point2d_inline_tests" + +[dependencies] +core = { path = "../../../../../sway-lib-core" } +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw new file mode 100644 index 00000000000..d51f91d7b19 --- /dev/null +++ b/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw @@ -0,0 +1,300 @@ +library; + +use std::crypto::point2d::*; + +#[test] +fn point2d_new() { + let new_point = Point2D::new(); + + assert(new_point.x().len() == 0); + assert(new_point.y().len() == 0); +} + +#[test] +fn point2d_zero() { + let zero_point = Point2D::zero(); + + assert(zero_point.x().len() == 32); + assert(zero_point.y().len() == 32); + + assert(b256::try_from(zero_point.x()).unwrap() == b256::zero()); + assert(b256::try_from(zero_point.y()).unwrap() == b256::zero()); +} + +#[test] +fn point2d_is_zero() { + let zero_point = Point2D::zero(); + assert(zero_point.is_zero()); + + let other_point = Point2D::from((b256::zero(), b256::zero())); + assert(other_point.is_zero()); + + let not_zero_point = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000001)); + assert(!not_zero_point.is_zero()); +} + +#[test] +fn point2d_min() { + let min_point = Point2D::min(); + + assert(min_point.x().len() == 32); + assert(min_point.y().len() == 32); + + assert(b256::try_from(min_point.x()).unwrap() == b256::zero()); + assert(b256::try_from(min_point.y()).unwrap() == b256::zero()); +} + +#[test] +fn point2d_max() { + let max_point = Point2D::max(); + + assert(max_point.x().len() == 32); + assert(max_point.y().len() == 32); + + assert(b256::try_from(max_point.x()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(b256::try_from(max_point.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn point2d_x() { + let zero_point = Point2D::zero(); + + let zero_x = zero_point.x(); + assert(zero_x.len() == 32); + assert(zero_x.capacity() == 32); + + let point_1 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000001)); + let point_1_x = point_1.x(); + assert(point_1_x.len() == 32); + assert(point_1_x.capacity() == 32); + + let point_2 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000001)); + let point_2_x = point_2.x(); + assert(point_2_x.len() == 32); + assert(point_2_x.capacity() == 32); +} + +#[test] +fn point2d_y() { + let zero_point = Point2D::zero(); + let zero_y = zero_point.y(); + assert(zero_y.len() == 32); + assert(zero_y.capacity() == 32); + + let point_1 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000001)); + let point_1_y = point_1.y(); + assert(point_1_y.len() == 32); + assert(point_1_y.capacity() == 32); + + let point_2 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000001)); + let point_2_y = point_2.y(); + assert(point_2_y.len() == 32); + assert(point_2_y.capacity() == 32); +} + +#[test] +fn point2d_from_u256_array() { + let min = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0x0000000000000000000000000000000000000000000000000000000000000000_u256]); + assert(min.x().len() == 32); + assert(min.y().len() == 32); + assert(min.x().capacity() == 32); + assert(min.y().capacity() == 32); + assert(b256::try_from(min.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(min.y()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Point2D::from([0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256]); + assert(max.x().len() == 32); + assert(max.y().len() == 32); + assert(max.x().capacity() == 32); + assert(max.y().capacity() == 32); + assert(b256::try_from(max.x()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(b256::try_from(max.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256]); + assert(other.x().len() == 32); + assert(other.y().len() == 32); + assert(other.x().capacity() == 32); + assert(other.y().capacity() == 32); + assert(b256::try_from(other.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(other.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn point2d_from_b256_array() { + let min = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + assert(min.x().len() == 32); + assert(min.y().len() == 32); + assert(min.x().capacity() == 32); + assert(min.y().capacity() == 32); + assert(b256::try_from(min.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(min.y()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Point2D::from([0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]); + assert(max.x().len() == 32); + assert(max.y().len() == 32); + assert(max.x().capacity() == 32); + assert(max.y().capacity() == 32); + assert(b256::try_from(max.x()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(b256::try_from(max.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]); + assert(other.x().len() == 32); + assert(other.y().len() == 32); + assert(other.x().capacity() == 32); + assert(other.y().capacity() == 32); + assert(b256::try_from(other.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(other.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn point2d_from_u256_tuple() { + let min = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0x0000000000000000000000000000000000000000000000000000000000000000_u256)); + assert(min.x().len() == 32); + assert(min.y().len() == 32); + assert(min.x().capacity() == 32); + assert(min.y().capacity() == 32); + assert(b256::try_from(min.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(min.y()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Point2D::from((0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256)); + assert(max.x().len() == 32); + assert(max.y().len() == 32); + assert(max.x().capacity() == 32); + assert(max.y().capacity() == 32); + assert(b256::try_from(max.x()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(b256::try_from(max.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256)); + assert(other.x().len() == 32); + assert(other.y().len() == 32); + assert(other.x().capacity() == 32); + assert(other.y().capacity() == 32); + assert(b256::try_from(other.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(other.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn point2d_from_b256_tuple() { + let min = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000)); + assert(min.x().len() == 32); + assert(min.y().len() == 32); + assert(min.x().capacity() == 32); + assert(min.y().capacity() == 32); + assert(b256::try_from(min.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(min.y()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Point2D::from((0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); + assert(max.x().len() == 32); + assert(max.y().len() == 32); + assert(max.x().capacity() == 32); + assert(max.y().capacity() == 32); + assert(b256::try_from(max.x()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(b256::try_from(max.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); + assert(other.x().len() == 32); + assert(other.y().len() == 32); + assert(other.x().capacity() == 32); + assert(other.y().capacity() == 32); + assert(b256::try_from(other.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(other.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn point2d_from_u8_array() { + let min = Point2D::from([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]); + assert(min.x().len() == 32); + assert(min.y().len() == 32); + assert(min.x().capacity() == 32); + assert(min.y().capacity() == 32); + assert(b256::try_from(min.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(min.y()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Point2D::from([255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8]); + assert(max.x().len() == 32); + assert(max.y().len() == 32); + assert(max.x().capacity() == 32); + assert(max.y().capacity() == 32); + assert(b256::try_from(max.x()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(b256::try_from(max.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Point2D::from([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8]); + assert(other.x().len() == 32); + assert(other.y().len() == 32); + assert(other.x().capacity() == 32); + assert(other.y().capacity() == 32); + assert(b256::try_from(other.x()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(b256::try_from(other.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn point2d_u256_tuple_try_from() { + let min = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0x0000000000000000000000000000000000000000000000000000000000000000_u256)); + let (x, y) = <(u256, u256) as TryFrom>::try_from(min).unwrap(); + assert(x == 0x0000000000000000000000000000000000000000000000000000000000000000_u256); + assert(y == 0x0000000000000000000000000000000000000000000000000000000000000000_u256); + + let max = Point2D::from((0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256)); + let (x, y) = <(u256, u256) as TryFrom>::try_from(max).unwrap(); + assert(x == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + assert(y == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + + let other = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256)); + let (x, y) = <(u256, u256) as TryFrom>::try_from(other).unwrap(); + assert(x == 0x0000000000000000000000000000000000000000000000000000000000000000_u256); + assert(y == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); +} + +#[test] +fn point2d_u256_array_try_from() { + let min = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0x0000000000000000000000000000000000000000000000000000000000000000_u256]); + let array = <[u256; 2] as TryFrom>::try_from(min).unwrap(); + assert(array[0] == 0x0000000000000000000000000000000000000000000000000000000000000000_u256); + assert(array[1] == 0x0000000000000000000000000000000000000000000000000000000000000000_u256); + + let max = Point2D::from([0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256]); + let array = <[u256; 2] as TryFrom>::try_from(max).unwrap(); + assert(array[0] == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + assert(array[1] == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + + let other = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000_u256, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256]); + let array = <[u256; 2] as TryFrom>::try_from(other).unwrap(); + assert(array[0] == 0x0000000000000000000000000000000000000000000000000000000000000000_u256); + assert(array[1] == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); +} + +#[test] +fn point2d_b256_tuple_try_from() { + let min = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000)); + let (x, y) = <(b256, b256) as TryFrom>::try_from(min).unwrap(); + assert(x == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(y == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Point2D::from((0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); + let (x, y) = <(b256, b256) as TryFrom>::try_from(max).unwrap(); + assert(x == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(y == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000000, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); + let (x, y) = <(b256, b256) as TryFrom>::try_from(other).unwrap(); + assert(x == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(y == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn point2d_b256_array_try_from() { + let min = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + let array = <[b256; 2] as TryFrom>::try_from(min).unwrap(); + assert(array[0] == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(array[1] == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Point2D::from([0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]); + let array = <[b256; 2] as TryFrom>::try_from(max).unwrap(); + assert(array[0] == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(array[1] == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]); + let array = <[b256; 2] as TryFrom>::try_from(other).unwrap(); + assert(array[0] == 0x0000000000000000000000000000000000000000000000000000000000000000); + assert(array[1] == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} diff --git a/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/Forc.toml b/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/Forc.toml new file mode 100644 index 00000000000..24231de833a --- /dev/null +++ b/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "crypto_scalar_inline_tests" + +[dependencies] +core = { path = "../../../../../sway-lib-core" } +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw new file mode 100644 index 00000000000..e9ba8f7aa64 --- /dev/null +++ b/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw @@ -0,0 +1,151 @@ +library; + +use std::crypto::scalar::*; + +#[test] +fn scalar_new() { + let new_scalar = Scalar::new(); + + assert(new_scalar.bytes().len() == 0); + assert(new_scalar.bytes().capacity() == 0); +} + +#[test] +fn scalar_zero() { + let zero_scalar = Scalar::zero(); + + assert(zero_scalar.bytes().len() == 32); + + assert(b256::try_from(zero_scalar.bytes()).unwrap() == b256::zero()); +} + +#[test] +fn scalar_is_zero() { + let zero_scalar = Scalar::zero(); + assert(zero_scalar.is_zero()); + + let other_scalar = Scalar::from(b256::zero()); + assert(other_scalar.is_zero()); + + let not_zero_scalar = Scalar::from(0x0000000000000000000000000000000000000000000000000000000000000001); + assert(!not_zero_scalar.is_zero()); +} + +#[test] +fn scalar_min() { + let min_scalar = Scalar::min(); + + assert(min_scalar.bytes().len() == 32); + assert(b256::try_from(min_scalar.bytes()).unwrap() == b256::zero()); +} + +#[test] +fn scalar_max() { + let max_scalar = Scalar::max(); + + assert(max_scalar.bytes().len() == 32); + assert(b256::try_from(max_scalar.bytes()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +} + +#[test] +fn scalar_bytes() { + let zero_scalar = Scalar::zero(); + + let zero_bytes = zero_scalar.bytes(); + assert(zero_bytes.len() == 32); + assert(zero_bytes.capacity() == 32); + + let scalar_1 = Scalar::from(0x0000000000000000000000000000000000000000000000000000000000000001); + let scalar_1_bytes = scalar_1.bytes(); + assert(scalar_1_bytes.len() == 32); + assert(scalar_1_bytes.capacity() == 32); + + let scalar_2 = Scalar::from(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + let scalar_2_bytes = scalar_2.bytes(); + assert(scalar_2_bytes.len() == 32); + assert(scalar_2_bytes.capacity() == 32); +} + +#[test] +fn scalar_from_u256() { + let min = Scalar::from(0x0000000000000000000000000000000000000000000000000000000000000000_u256); + assert(min.bytes().len() == 32); + assert(min.bytes().capacity() == 32); + assert(b256::try_from(min.bytes()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Scalar::from(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + assert(max.bytes().len() == 32); + assert(max.bytes().capacity() == 32); + assert(b256::try_from(max.bytes()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Scalar::from(0x0000000000000000000000000000000000000000000000000000000000000000_u256); + assert(other.bytes().len() == 32); + assert(other.bytes().capacity() == 32); + assert(b256::try_from(other.bytes()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); +} + +#[test] +fn scalar_from_b256() { + let min = Scalar::from(0x0000000000000000000000000000000000000000000000000000000000000000); + assert(min.bytes().len() == 32); + assert(min.bytes().capacity() == 32); + assert(b256::try_from(min.bytes()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Scalar::from(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + assert(max.bytes().len() == 32); + assert(max.bytes().capacity() == 32); + assert(b256::try_from(max.bytes()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Scalar::from(0x1000000000000000000000000000000000000000000000000000000000000000); + assert(other.bytes().len() == 32); + assert(other.bytes().capacity() == 32); + assert(b256::try_from(other.bytes()).unwrap() == 0x1000000000000000000000000000000000000000000000000000000000000000); +} + +#[test] +fn scalar_from_u8_array() { + let min = Scalar::from([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]); + assert(min.bytes().len() == 32); + assert(min.bytes().capacity() == 32); + assert(b256::try_from(min.bytes()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Scalar::from([255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8]); + assert(max.bytes().len() == 32); + assert(max.bytes().capacity() == 32); + assert(b256::try_from(max.bytes()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Scalar::from([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8]); + assert(other.bytes().len() == 32); + assert(other.bytes().capacity() == 32); + assert(b256::try_from(other.bytes()).unwrap() == 0x0000000000000000000000000000000000000000000000000000000000000001); +} + +#[test] +fn scalar_u256_try_from() { + let min = Scalar::from(0x0000000000000000000000000000000000000000000000000000000000000000_u256); + let res_min = u256::try_from(min).unwrap(); + assert(res_min == 0x0000000000000000000000000000000000000000000000000000000000000000_u256); + + let max = Scalar::from(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + let res_max = u256::try_from(max).unwrap(); + assert(res_max == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + + let other = Scalar::from(0x1000000000000000000000000000000000000000000000000000000000000001_u256); + let other_u256 = u256::try_from(other).unwrap(); + assert(other_u256 == 0x1000000000000000000000000000000000000000000000000000000000000001_u256); +} + +#[test] +fn scalar_b256_try_from() { + let min = Scalar::from(0x0000000000000000000000000000000000000000000000000000000000000000_u256); + let res_min = b256::try_from(min).unwrap(); + assert(res_min == 0x0000000000000000000000000000000000000000000000000000000000000000); + + let max = Scalar::from(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256); + let res_max = b256::try_from(max).unwrap(); + assert(res_max == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + let other = Scalar::from(0x1000000000000000000000000000000000000000000000000000000000000001_u256); + let other_u256 = b256::try_from(other).unwrap(); + assert(other_u256 == 0x1000000000000000000000000000000000000000000000000000000000000001); +} diff --git a/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/Forc.toml b/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/Forc.toml new file mode 100644 index 00000000000..6cc65199560 --- /dev/null +++ b/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "crypto_zk_inline_tests" + +[dependencies] +core = { path = "../../../../../sway-lib-core" } +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw new file mode 100644 index 00000000000..0196dd5b62f --- /dev/null +++ b/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw @@ -0,0 +1,247 @@ +library; + +use std::crypto::{point2d::*, scalar::*, zk::{ec_add, ec_mul, CurveType, ec_pairing_check}}; + +#[test] +fn zk_ec_add() { + // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs + let p1_1 = Point2D::from([0x18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9, 0x063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f37266]); + let p2_1 = Point2D::from([0x07c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed, 0x06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7]); + let expected_point_1 = Point2D::from([0x2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703, 0x301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915]); + + let result_1 = ec_add(CurveType::AltBN128, p1_1, p2_1); + assert(result_1 == expected_point_1); + + // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs + let p1_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + let p2_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + let expected_point_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + + let result_2 = ec_add(CurveType::AltBN128, p1_2, p2_2); + assert(result_2 == expected_point_2); + + // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge2/ecadd_1145-3932_2969-1336_21000_128.json + let p1_3 = Point2D::from([0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9, 0x01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c]); + let p2_3 = Point2D::from([0x039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869, 0x073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98]); + let expected_point_3 = Point2D::from([0x15bf2bb17880144b5d1cd2b1f46eff9d617bffd1ca57c37fb5a49bd84e53cf66, 0x049c797f9ce0d17083deb32b5e36f2ea2a212ee036598dd7624c168993d1355f]); + + let result_3 = ec_add(CurveType::AltBN128, p1_3, p2_3); + assert(result_3 == expected_point_3); + + // From https://github.com/matter-labs/era-compiler-tests/blob/2253941334797eb2a997941845fb9eb0d436558b/yul/precompiles/ecadd.yul#L123 + let p1_4 = Point2D::from([0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9, 0x01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c]); + let p2_4 = Point2D::from([0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9, 0x2e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb]); + let expected_point_4 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + + let result_4 = ec_add(CurveType::AltBN128, p1_4, p2_4); + assert(result_4 == expected_point_4); + + // From https://github.com/poanetwork/parity-ethereum/blob/2ea4265b0083c4148571b21e1079c641d5f31dc2/ethcore/benches/builtin.rs#L486 + let p1_5 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002]); + let p2_5 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002]); + let expected_point_5 = Point2D::from([0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3, 0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4]); + + let result_5 = ec_add(CurveType::AltBN128, p1_5, p2_5); + assert(result_5 == expected_point_5); +} + +#[test(should_revert)] +fn revert_zk_ec_add_fail() { + // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs + let p1 = Point2D::from([0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111]); + let p2 = Point2D::from([0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111]); + + let _result = ec_add(CurveType::AltBN128, p1, p2); +} + +// TODO: Uncomment and implement test when another curve is supported +// #[test(should_revert)] +// fn revert_zk_ec_add_invalid_point() { +// // This needs to be an invalid point +// let p1 = Point2D::from(); +// let p2 = Point2D::from(); + +// let _result = ec_add(CurveType::AltBN128, p1, p2); +// } + +#[test] +fn zk_ec_mul() { + // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs + let p1_1 = Point2D::from([0x2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb7, 0x21611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204]); + let scalar_1 = Scalar::from(0x00000000000000000000000000000000000000000000000011138ce750fa15c2); + let expected_point_1 = Point2D::from([0x070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c, 0x031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc]); + + let result_1 = ec_mul(CurveType::AltBN128, p1_1, scalar_1); + assert(result_1 == expected_point_1); + + // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs + let p1_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + let scalar_2 = Scalar::from(0x0200000000000000000000000000000000000000000000000000000000000000); + let expected_point_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + + let result_2 = ec_mul(CurveType::AltBN128, p1_2, scalar_2); + assert(result_2 == expected_point_2); + + // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecmul_7827-6598_1456_21000_96.json + let p1_3 = Point2D::from([0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3, 0x1a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6]); + let scalar_3 = Scalar::from(0x0000000000000000000000000000000100000000000000000000000000000000); + let expected_point_3 = Point2D::from([0x1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0, 0x135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b]); + + let result_3 = ec_mul(CurveType::AltBN128, p1_3, scalar_3); + assert(result_3 == expected_point_3); + + // From https://github.com/matter-labs/era-compiler-tests/blob/2253941334797eb2a997941845fb9eb0d436558b/yul/precompiles/ecmul.yul#L185C21-L185C98 + let p1_4 = Point2D::from([0x1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3, 0x1a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6]); + let scalar_4 = Scalar::from(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001); + let expected_point_4 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); + + let result_4 = ec_mul(CurveType::AltBN128, p1_4, scalar_4); + assert(result_4 == expected_point_4); + + // From https://github.com/poanetwork/parity-ethereum/blob/2ea4265b0083c4148571b21e1079c641d5f31dc2/ethcore/benches/builtin.rs#L516 + let p1_5 = Point2D::from([0x2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb7, 0x21611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204]); + let scalar_5 = Scalar::from(0x00000000000000000000000000000000000000000000000011138ce750fa15c2); + let expected_point_5 = Point2D::from([0x070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c, 0x031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc]); + + let result_5 = ec_mul(CurveType::AltBN128, p1_5, scalar_5); + assert(result_5 == expected_point_5); +} + +#[test(should_revert)] +fn revert_zk_ec_mul_fail() { + // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs + let p = Point2D::from([0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111]); + let scalar = Scalar::from(0x0f00000000000000000000000000000000000000000000000000000000000000); + + let _result = ec_mul(CurveType::AltBN128, p, scalar); +} + +// TODO: Uncomment and implement test when another curve is supported +// #[test(should_revert)] +// fn revert_zk_ec_mul_invalid_point() { +// // This should be an invalid point +// let p = Point2D::from(); +// let scalar = Scalar::from(0x00000000000000000000000000000000000000000000000011138ce750fa15c2); + +// let _result = ec_mul(CurveType::AltBN128, p, scalar); +// } + +// TODO: Uncomment and implement test when another curve is supported +// #[test(should_revert)] +// fn revert_zk_ec_mul_invalid_scalar() { +// // This should be an invalid scalar +// let p = Point2D::from([0x2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb7, 0x21611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204]); +// let scalar = Scalar::from(); + +// let _result = ec_mul(CurveType::AltBN128, p, scalar); +// } + +#[test] +fn zk_ec_pairing_check() { + // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs + let mut points_vec_1: Vec<(Point2D, [Point2D; 2])> = Vec::new(); + let p1_1_1 = Point2D::from((0x1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59, 0x3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41)); + let g1_1_1 = Point2D::from((0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678)); + let g2_1_1 = Point2D::from((0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550)); + points_vec_1.push((p1_1_1, [g1_1_1, g2_1_1])); + + let p1_2_1 = Point2D::from((0x111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c, 0x2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411)); + let g1_2_1 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_2_1 = Point2D::from((0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)); + points_vec_1.push((p1_2_1, [g1_2_1, g2_2_1])); + + assert(ec_pairing_check(CurveType::AltBN128, points_vec_1)); + + // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecpairing_three_point_match_1.json + let mut points_vec_2: Vec<(Point2D, [Point2D; 2])> = Vec::new(); + let p1_1_2 = Point2D::from((0x105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf1016, 0x0cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc)); + let g1_1_2 = Point2D::from((0x0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd, 0x3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa1)); + let g2_1_2 = Point2D::from((0x14c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a21, 0x01b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427)); + points_vec_2.push((p1_1_2, [g1_1_2, g2_1_2])); + + let p1_2_2 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_2_2 = Point2D::from((0x1a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7, 0x290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f)); + let g2_2_2 = Point2D::from((0x2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb9, 0x29d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75)); + points_vec_2.push((p1_2_2, [g1_2_2, g2_2_2])); + + assert(ec_pairing_check(CurveType::AltBN128, points_vec_2)); + + // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecpairing_three_point_fail_1.json + let mut points_vec_3: Vec<(Point2D, [Point2D; 2])> = Vec::new(); + let p1_1_3 = Point2D::from((0x105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf1016, 0x0cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc)); + let g1_1_3 = Point2D::from((0x0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd, 0x3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa1)); + let g2_1_3 = Point2D::from((0x14c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a21, 0x01b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427)); + points_vec_3.push((p1_1_3, [g1_1_3, g2_1_3])); + + let p1_2_3 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_2_3 = Point2D::from((0x1a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7, 0x290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f)); + let g2_2_3 = Point2D::from((0x00cacf3523caf879d7d05e30549f1e6fdce364cbb8724b0329c6c2a39d4f018e, 0x0692e55db067300e6e3fe56218fa2f940054e57e7ef92bf7d475a9d8a8502fd2)); + points_vec_3.push((p1_2_3, [g1_2_3, g2_2_3])); + + assert(!ec_pairing_check(CurveType::AltBN128, points_vec_3)); + + // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecpairing_three_point_fail_1.json + let mut points_vec_4: Vec<(Point2D, [Point2D; 2])> = Vec::new(); + let p1_1_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_1_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_1_4 = Point2D::from((0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)); + points_vec_4.push((p1_1_4, [g1_1_4, g2_1_4])); + + let p1_2_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_2_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_2_4 = Point2D::from((0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec, 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d)); + points_vec_4.push((p1_2_4, [g1_2_4, g2_2_4])); + + let p1_3_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_3_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_3_4 = Point2D::from((0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)); + points_vec_4.push((p1_3_4, [g1_3_4, g2_3_4])); + + let p1_4_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_4_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_4_4 = Point2D::from((0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec, 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d)); + points_vec_4.push((p1_4_4, [g1_4_4, g2_4_4])); + + let p1_5_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_5_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_5_4 = Point2D::from((0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)); + points_vec_4.push((p1_5_4, [g1_5_4, g2_5_4])); + + let p1_6_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_6_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_6_4 = Point2D::from((0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec, 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d)); + points_vec_4.push((p1_6_4, [g1_6_4, g2_6_4])); + + let p1_7_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_7_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_7_4 = Point2D::from((0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)); + points_vec_4.push((p1_7_4, [g1_7_4, g2_7_4])); + + let p1_8_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_8_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_8_4 = Point2D::from((0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec, 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d)); + points_vec_4.push((p1_8_4, [g1_8_4, g2_8_4])); + + let p1_9_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_9_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_9_4 = Point2D::from((0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)); + points_vec_4.push((p1_9_4, [g1_9_4, g2_9_4])); + + let p1_10_4 = Point2D::from((0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002)); + let g1_10_4 = Point2D::from((0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)); + let g2_10_4 = Point2D::from((0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec, 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d)); + points_vec_4.push((p1_10_4, [g1_10_4, g2_10_4])); + + assert(ec_pairing_check(CurveType::AltBN128, points_vec_4)); +} + +#[test(should_revert)] +fn revert_zk_ec_pairing_check() { + let mut points_vec: Vec<(Point2D, [Point2D; 2])> = Vec::new(); + let p1_1 = Point2D::from((0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111)); + let g1_1 = Point2D::from((0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111)); + let g2_1 = Point2D::from((0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111)); + points_vec.push((p1_1, [g1_1, g2_1])); + + let _ = ec_pairing_check(CurveType::AltBN128, points_vec); +} From e118692da0a695fcf511ee10dcbe9684aa29e8f4 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 14 Jan 2025 14:44:21 +0100 Subject: [PATCH 06/13] Add inline docmumentation and create errors file --- sway-lib-std/src/crypto/errors.sw | 11 +++ sway-lib-std/src/crypto/point2d.sw | 113 +++++++++++++++++++++++++++-- sway-lib-std/src/crypto/scalar.sw | 90 +++++++++++++++++++++-- sway-lib-std/src/crypto/zk.sw | 108 ++++++++++++++++++++++----- 4 files changed, 287 insertions(+), 35 deletions(-) create mode 100644 sway-lib-std/src/crypto/errors.sw diff --git a/sway-lib-std/src/crypto/errors.sw b/sway-lib-std/src/crypto/errors.sw new file mode 100644 index 00000000000..02c6adf2fab --- /dev/null +++ b/sway-lib-std/src/crypto/errors.sw @@ -0,0 +1,11 @@ +library; + +/// The error type used when performing elliptic curve operations for Zero Knowledge cryptography. +pub enum ZKError { + /// An unsupported curve was used. + UnsupportedCurve: (), + /// The elliptic curve point used was invalid. + InvalidEllipticCurvePoint: (), + /// The elliptice curve scalar used was invalid. + InvalidEllipticCurveScalar: (), +} diff --git a/sway-lib-std/src/crypto/point2d.sw b/sway-lib-std/src/crypto/point2d.sw index 2d5026837b3..be010682eb4 100644 --- a/sway-lib-std/src/crypto/point2d.sw +++ b/sway-lib-std/src/crypto/point2d.sw @@ -3,10 +3,17 @@ library; use ::convert::{From, TryFrom}; use ::bytes::{Bytes, *}; use ::option::Option::{self, *}; -use ::primitive_conversions::u256::*; +// NOTE: Bytes are use to support numbers greater than 32 bytes for future curves. +/// A 2D point on a field. +/// +/// # Additional Information +/// +/// The Point2D type only supports positive integer points. pub struct Point2D { + /// The x point on the field. x: Bytes, + /// The y point on the field. y: Bytes, } @@ -32,6 +39,21 @@ impl Eq for Point2D { } impl Point2D { + /// Returns a new, uninitialized Point2D. + /// + /// # Returns + /// + /// * [Point2D] - The new Point2D. + /// + /// # Examples + /// + /// ```sway + /// use std::point2d::Point2D; + /// + /// fn foo() { + /// let new_point = Point2D::new(); + /// } + /// ``` pub fn new() -> Self { Self { x: Bytes::new(), @@ -39,6 +61,23 @@ impl Point2D { } } + /// Returns a zeroed Point2D. + /// + /// # Returns + /// + /// * [Point2D] - The new zeroed Point2D. + /// + /// # Examples + /// + /// ```sway + /// use std::point2d::Point2D; + /// + /// fn foo() { + /// let zero_point = Point2D::zero(); + /// assert(b256::try_from(new_point.x()).unwrap() == b256::zero()); + /// assert(b256::try_from(new_point.y()).unwrap() == b256::zero()); + /// } + /// ``` pub fn zero() -> Self { Self { x: Bytes::from(b256::zero()), @@ -46,10 +85,43 @@ impl Point2D { } } + /// Returns true if the point is (0, 0), otherwise false. + /// + /// # Returns + /// + // * [bool] - The boolean representing whether the point is zero. + /// + /// # Examples + /// + /// ```sway + /// use std::point2d::Point2D; + /// + /// fn foo() { + /// let zero_point = Point2D::zero(); + /// assert(zero_point.is_zero()); + /// } + /// ``` pub fn is_zero(self) -> bool { self == Self::zero() } + /// Returns the minimum point. + /// + /// # Returns + /// + /// * [Point2D] - The new minimum Point2D. + /// + /// # Examples + /// + /// ```sway + /// use std::point2d::Point2D; + /// + /// fn foo() { + /// let zero_point = Point2D::zero(); + /// assert(b256::try_from(new_point.x()).unwrap() == b256::zero()); + /// assert(b256::try_from(new_point.y()).unwrap() == b256::zero()); + /// } + /// ``` pub fn min() -> Self { Self { x: Bytes::from(b256::zero()), @@ -57,17 +129,42 @@ impl Point2D { } } - pub fn max() -> Self { - Self { - x: Bytes::from(b256::max()), - y: Bytes::from(b256::max()), - } - } - + /// Returns the underlying x point as bytes. + /// + /// # Returns + /// + /// * [Bytes] - The x point represented as bytes. + /// + /// # Examples + /// + /// ```sway + /// use std::point2d::Point2D; + /// + /// fn foo(point: Point2D) { + /// let x = point.x(); + /// assert(x.len() != 0); + /// } + /// ``` pub fn x(self) -> Bytes { self.x } + /// Returns the underlying y point as bytes. + /// + /// # Returns + /// + /// * [Bytes] - The y point represented as bytes. + /// + /// # Examples + /// + /// ```sway + /// use std::point2d::Point2D; + /// + /// fn foo(point: Point2D) { + /// let y = point.y(); + /// assert(y.len() != 0); + /// } + /// ``` pub fn y(self) -> Bytes { self.y } diff --git a/sway-lib-std/src/crypto/scalar.sw b/sway-lib-std/src/crypto/scalar.sw index f62055cab94..ad86dc6c48a 100644 --- a/sway-lib-std/src/crypto/scalar.sw +++ b/sway-lib-std/src/crypto/scalar.sw @@ -3,15 +3,16 @@ library; use ::convert::{From, TryFrom}; use ::bytes::{Bytes, *}; use ::option::Option::{self, *}; -use ::primitive_conversions::u256::*; +// NOTE: Bytes are use to support numbers greater than 32 bytes for future curves. +/// The Scalar type used in cryptographic operations. pub struct Scalar { bytes: Bytes } impl Eq for Scalar { fn eq(self, other: Self) -> bool { - // All points must be of length 32 + // All scalars must be of length 32 if self.bytes.len() != 32 || other.bytes.len() != 32 { return false; } @@ -29,34 +30,107 @@ impl Eq for Scalar { } impl Scalar { + /// Returns a new, uninitialized Scalar. + /// + /// # Returns + /// + /// * [Scalar] - The new Scalar. + /// + /// # Examples + /// + /// ```sway + /// use std::scalar::Scalar; + /// + /// fn foo() { + /// let new_scalar = Scalar::new(); + /// } + /// ``` pub fn new() -> Self { Self { bytes: Bytes::new(), } } + /// Returns a zeroed Scalar. + /// + /// # Returns + /// + /// * [Scalar] - The new zeroed Scalar. + /// + /// # Examples + /// + /// ```sway + /// use std::scalar::Scalar; + /// + /// fn foo() { + /// let zero_scalar = Scalar::zero(); + /// assert(b256::try_from(new_scalar.bytes()).unwrap() == b256::zero()); + /// } + /// ``` pub fn zero() -> Self { Self { bytes: Bytes::from(b256::zero()), } } + /// Returns the minimum scalar. + /// + /// # Returns + /// + /// * [Scalar] - The new minimum Scalar. + /// + /// # Examples + /// + /// ```sway + /// use std::scalar::Scalar; + /// + /// fn foo() { + /// let zero_scalar = Scalar::zero(); + /// assert(b256::try_from(new_scalar.bytes()).unwrap() == b256::zero()); + /// } + /// ``` pub fn min() -> Self { Self { bytes: Bytes::from(b256::zero()), } } - pub fn max() -> Self { - Self { - bytes: Bytes::from(b256::max()), - } - } - + /// Returns true if the scalae is zero, otherwise false. + /// + /// # Returns + /// + // * [bool] - The boolean representing whether the scalar is zero. + /// + /// # Examples + /// + /// ```sway + /// use std::scalar::Scalar; + /// + /// fn foo() { + /// let zero_scalar = Scalar::zero(); + /// assert(zero_scalar.is_zero()); + /// } + /// ``` pub fn is_zero(self) -> bool { self == Self::zero() } + /// Returns the underlying bytes of the scalar. + /// + /// # Returns + /// + /// * [Bytes] - The scalar represented as bytes. + /// + /// # Examples + /// + /// ```sway + /// use std::scalar::Scalar; + /// + /// fn foo(scalar: Scalar) { + /// let bytes = scalar.bytes(); + /// assert(bytes.len() != 0); + /// } + /// ``` pub fn bytes(self) -> Bytes { self.bytes } diff --git a/sway-lib-std/src/crypto/zk.sw b/sway-lib-std/src/crypto/zk.sw index 4cd3096850a..adef0f9221b 100644 --- a/sway-lib-std/src/crypto/zk.sw +++ b/sway-lib-std/src/crypto/zk.sw @@ -1,31 +1,48 @@ library; -use ::result::Result::{self, *}; use ::vec::*; -use ::convert::{From, TryFrom}; use ::bytes::{Bytes, *}; -use ::option::Option::{self, *}; -use ::primitive_conversions::u256::*; use ::revert::require; -use ::crypto::{point2d::*, scalar::*}; +use ::crypto::{point2d::*, scalar::*, errors::ZKError}; use ::alloc::alloc; -pub enum EllipicCurveError { - UnsupportedCurve: (), - InvalidEllipticCurvePoint: (), - InvalidEllipticCurveScalar: (), - PointPairingCheckFailed: (), -} - +/// The curve types supported by the Fuel VM. pub enum CurveType { + /// The Alt BN128 curve. AltBN128: (), } +/// Performs an elliptic curve multiplication with a given curve, point, and scalar. +/// +/// # Additional Information +/// +/// The Fuel VM currently only supports the Alt BN128 curve. +/// +/// # Arguments +/// +/// * `curve_type`: [CurveType] - The type of curve which the multiplication should be performed. +/// * `point`: [Point2D] - The point used to perform the multiplication. +/// * `scalar`: [Scalar] - The scalar used perform the multiplication. +/// +/// # Returns +/// +/// * [Point2D] - The resulting computed point. +/// +/// # Examples +/// +/// ```sway +/// use std::{point2d::Point2D, scalar::Scalar, zk::ec_mul}; +/// +/// fn foo(curve_type: CurveType, point: Point2D, scalar: Scalar) { +/// let result = ec_mul(curve_type, point, scalar); +/// assert(!result.is_zero()); +/// } +/// ``` pub fn ec_mul(curve_type: CurveType, point: Point2D, scalar: Scalar) -> Point2D { let curve = match curve_type { CurveType::AltBN128 => { - require(valid_alt_bn128_point(point), EllipicCurveError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_scalar(scalar), EllipicCurveError::InvalidEllipticCurveScalar); + require(valid_alt_bn128_point(point), ZKError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_scalar(scalar), ZKError::InvalidEllipticCurveScalar); 0 } @@ -46,11 +63,37 @@ pub fn ec_mul(curve_type: CurveType, point: Point2D, scalar: Scalar) -> Point2D Point2D::from(result) } +/// Performs an elliptic curve additions with a given curve and 2 points. +/// +/// # Additional Information +/// +/// The Fuel VM currently only supports the Alt BN128 curve. +/// +/// # Arguments +/// +/// * `curve_type`: [CurveType] - The type of curve which the addition should be performed. +/// * `point_1`: [Point2D] - The first point used to perform the addition. +/// * `point_2`: [Point2D] - The second point used to perform the addition. +/// +/// # Returns +/// +/// * [Point2D] - The resulting computed point. +/// +/// # Examples +/// +/// ```sway +/// use std::{point2d::Point2D, scalar::Scalar, zk::ec_mul}; +/// +/// fn foo(curve_type: CurveType, point_1: Point2D, point_2: Point2D) { +/// let result = ec_add(curve_type, point_1, point_2); +/// assert(!result.is_zero()); +/// } +/// ``` pub fn ec_add(curve_type: CurveType, point_1: Point2D, point_2: Point2D) -> Point2D { let curve = match curve_type { CurveType::AltBN128 => { - require(valid_alt_bn128_point(point_1), EllipicCurveError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(point_2), EllipicCurveError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(point_1), ZKError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(point_2), ZKError::InvalidEllipticCurvePoint); 0 } @@ -72,6 +115,31 @@ pub fn ec_add(curve_type: CurveType, point_1: Point2D, point_2: Point2D) -> Poin Point2D::from(result) } +/// Performs an elliptic curve paring check with a given curve and 3 points. +/// +/// # Additional Information +/// +/// The Fuel VM currently only supports the Alt BN128 curve. +/// +/// # Arguments +/// +/// * `curve_type`: [CurveType] - The type of curve which the addition should be performed. +/// * `points`: [Vec<(Point2D, [Point2D; 2])>] - The points used to perform the pairing check. +/// +/// # Returns +/// +/// * [bool] - True if the pairing is valid, false otherwise. +/// +/// # Examples +/// +/// ```sway +/// use std::{point2d::Point2D, scalar::Scalar, zk::ec_mul}; +/// +/// fn foo(curve_type: CurveType, points: Vec<(Point2D, [Point2D; 2])>) { +/// let result = ec_pairing_check(curve_type, points); +/// assert(result); +/// } +/// ``` pub fn ec_pairing_check(curve_type: CurveType, points: Vec<(Point2D, [Point2D; 2])>) -> bool { // Total bytes is (P1, (G1, G2)) = ([32 bytes, 32 bytes], ([32 bytes, 32 bytes], [32 bytes, 32 bytes])) = 6 * 32 bytes * length let mut points_ptr = alloc::(points.len() * 6); @@ -84,9 +152,9 @@ pub fn ec_pairing_check(curve_type: CurveType, points: Vec<(Point2D, [Point2D; 2 let p2 = points.get(iter).unwrap().1[0]; let p3 = points.get(iter).unwrap().1[1]; - require(valid_alt_bn128_point(p1), EllipicCurveError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(p2), EllipicCurveError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(p3), EllipicCurveError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(p1), ZKError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(p2), ZKError::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(p3), ZKError::InvalidEllipticCurvePoint); // Copy all 6 32 byte length points to the single slice p1.x().ptr().copy_to::(points_ptr.add::(iter * 6), 1); @@ -110,6 +178,7 @@ pub fn ec_pairing_check(curve_type: CurveType, points: Vec<(Point2D, [Point2D; 2 } } +// Returns true if the point is in valid alt bn128 format. fn valid_alt_bn128_point(point: Point2D) -> bool { // 1P = ([32 bytes], [32 bytes]) point.x().len() == 32 && point.y().len() == 32 @@ -137,6 +206,7 @@ fn valid_alt_bn128_point(point: Point2D) -> bool { // y_squared == (x_cubed + 3) % p } +// Returns true if the scalar is in valid alt bn128 format. fn valid_alt_bn128_scalar(scalar: Scalar) -> bool { // 1S = [32 bytes] scalar.bytes().len() == 32 From ade2f1e37ba70f98a08c731b9082f38c999ad020 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 14 Jan 2025 14:44:34 +0100 Subject: [PATCH 07/13] Remove max() tests --- .../crypto_point2d_inline_tests/src/main.sw | 11 ----------- .../crypto_scalar_inline_tests/src/main.sw | 8 -------- 2 files changed, 19 deletions(-) diff --git a/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw index d51f91d7b19..cb3d458551e 100644 --- a/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/crypto_point2d_inline_tests/src/main.sw @@ -44,17 +44,6 @@ fn point2d_min() { assert(b256::try_from(min_point.y()).unwrap() == b256::zero()); } -#[test] -fn point2d_max() { - let max_point = Point2D::max(); - - assert(max_point.x().len() == 32); - assert(max_point.y().len() == 32); - - assert(b256::try_from(max_point.x()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - assert(b256::try_from(max_point.y()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); -} - #[test] fn point2d_x() { let zero_point = Point2D::zero(); diff --git a/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw index e9ba8f7aa64..eaccc7f9adb 100644 --- a/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/crypto_scalar_inline_tests/src/main.sw @@ -39,14 +39,6 @@ fn scalar_min() { assert(b256::try_from(min_scalar.bytes()).unwrap() == b256::zero()); } -#[test] -fn scalar_max() { - let max_scalar = Scalar::max(); - - assert(max_scalar.bytes().len() == 32); - assert(b256::try_from(max_scalar.bytes()).unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); -} - #[test] fn scalar_bytes() { let zero_scalar = Scalar::zero(); From fb1bc8f794b9500f670514b670c7d2a1fb289878 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 14 Jan 2025 15:04:52 +0100 Subject: [PATCH 08/13] Remove curve type argument from operations --- sway-lib-std/src/crypto.sw | 2 +- .../src/crypto/{zk.sw => alt_bn128.sw} | 112 +++++++----------- sway-lib-std/src/crypto/errors.sw | 11 -- .../crypto_zk_inline_tests/src/main.sw | 60 +++++----- 4 files changed, 77 insertions(+), 108 deletions(-) rename sway-lib-std/src/crypto/{zk.sw => alt_bn128.sw} (55%) delete mode 100644 sway-lib-std/src/crypto/errors.sw diff --git a/sway-lib-std/src/crypto.sw b/sway-lib-std/src/crypto.sw index 6ffe2cf155c..76c3627ef17 100644 --- a/sway-lib-std/src/crypto.sw +++ b/sway-lib-std/src/crypto.sw @@ -2,4 +2,4 @@ library; pub mod point2d; pub mod scalar; -pub mod zk; +pub mod alt_bn128; diff --git a/sway-lib-std/src/crypto/zk.sw b/sway-lib-std/src/crypto/alt_bn128.sw similarity index 55% rename from sway-lib-std/src/crypto/zk.sw rename to sway-lib-std/src/crypto/alt_bn128.sw index adef0f9221b..cadd4440c0a 100644 --- a/sway-lib-std/src/crypto/zk.sw +++ b/sway-lib-std/src/crypto/alt_bn128.sw @@ -3,13 +3,15 @@ library; use ::vec::*; use ::bytes::{Bytes, *}; use ::revert::require; -use ::crypto::{point2d::*, scalar::*, errors::ZKError}; +use ::crypto::{point2d::*, scalar::*}; use ::alloc::alloc; -/// The curve types supported by the Fuel VM. -pub enum CurveType { - /// The Alt BN128 curve. - AltBN128: (), +/// The error type used when performing elliptic curve operations for the Alt BN128 curve. +pub enum AltBn128Error { + /// The elliptic curve point used was invalid. + InvalidEllipticCurvePoint: (), + /// The elliptice curve scalar used was invalid. + InvalidEllipticCurveScalar: (), } /// Performs an elliptic curve multiplication with a given curve, point, and scalar. @@ -20,7 +22,6 @@ pub enum CurveType { /// /// # Arguments /// -/// * `curve_type`: [CurveType] - The type of curve which the multiplication should be performed. /// * `point`: [Point2D] - The point used to perform the multiplication. /// * `scalar`: [Scalar] - The scalar used perform the multiplication. /// @@ -31,22 +32,16 @@ pub enum CurveType { /// # Examples /// /// ```sway -/// use std::{point2d::Point2D, scalar::Scalar, zk::ec_mul}; +/// use std::{point2d::Point2D, scalar::Scalar, alt_bn128::alt_bn128_mul}; /// -/// fn foo(curve_type: CurveType, point: Point2D, scalar: Scalar) { -/// let result = ec_mul(curve_type, point, scalar); +/// fn foo(point: Point2D, scalar: Scalar) { +/// let result = alt_bn128_mul(point, scalar); /// assert(!result.is_zero()); /// } /// ``` -pub fn ec_mul(curve_type: CurveType, point: Point2D, scalar: Scalar) -> Point2D { - let curve = match curve_type { - CurveType::AltBN128 => { - require(valid_alt_bn128_point(point), ZKError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_scalar(scalar), ZKError::InvalidEllipticCurveScalar); - - 0 - } - }; +pub fn alt_bn128_mul(point: Point2D, scalar: Scalar) -> Point2D { + require(valid_alt_bn128_point(point), AltBn128Error::InvalidEllipticCurvePoint); + require(valid_alt_bn128_scalar(scalar), AltBn128Error::InvalidEllipticCurveScalar); // 1P = ([32 bytes], [32 bytes]) let mut result = [b256::zero(), b256::zero()]; @@ -56,7 +51,7 @@ pub fn ec_mul(curve_type: CurveType, point: Point2D, scalar: Scalar) -> Point2D point.y().ptr().copy_to::(ptr.add::(1), 1); scalar.bytes().ptr().copy_to::(ptr.add::(2), 1); - asm(buffer: result, curve: curve, operation: 1, scalar: ptr) { + asm(buffer: result, curve: 0, operation: 1, scalar: ptr) { ecop buffer curve operation scalar; }; @@ -71,7 +66,6 @@ pub fn ec_mul(curve_type: CurveType, point: Point2D, scalar: Scalar) -> Point2D /// /// # Arguments /// -/// * `curve_type`: [CurveType] - The type of curve which the addition should be performed. /// * `point_1`: [Point2D] - The first point used to perform the addition. /// * `point_2`: [Point2D] - The second point used to perform the addition. /// @@ -82,22 +76,16 @@ pub fn ec_mul(curve_type: CurveType, point: Point2D, scalar: Scalar) -> Point2D /// # Examples /// /// ```sway -/// use std::{point2d::Point2D, scalar::Scalar, zk::ec_mul}; +/// use std::{point2d::Point2D, scalar::Scalar, alt_bn128::alt_bn128_add}; /// -/// fn foo(curve_type: CurveType, point_1: Point2D, point_2: Point2D) { -/// let result = ec_add(curve_type, point_1, point_2); +/// fn foo(point_1: Point2D, point_2: Point2D) { +/// let result = alt_bn128_add(point_1, point_2); /// assert(!result.is_zero()); /// } /// ``` -pub fn ec_add(curve_type: CurveType, point_1: Point2D, point_2: Point2D) -> Point2D { - let curve = match curve_type { - CurveType::AltBN128 => { - require(valid_alt_bn128_point(point_1), ZKError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(point_2), ZKError::InvalidEllipticCurvePoint); - - 0 - } - }; +pub fn alt_bn128_add(point_1: Point2D, point_2: Point2D) -> Point2D { + require(valid_alt_bn128_point(point_1), AltBn128Error::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(point_2), AltBn128Error::InvalidEllipticCurvePoint); // 1P = ([32 bytes], [32 bytes]) let mut result = [b256::zero(), b256::zero()]; @@ -108,7 +96,7 @@ pub fn ec_add(curve_type: CurveType, point_1: Point2D, point_2: Point2D) -> Poin point_2.x().ptr().copy_to::(points_ptr.add::(2), 1); point_2.y().ptr().copy_to::(points_ptr.add::(3), 1); - asm(buffer: result, curve: curve, operation: 0, points: points_ptr) { + asm(buffer: result, curve: 0, operation: 0, points: points_ptr) { ecop buffer curve operation points; }; @@ -123,7 +111,6 @@ pub fn ec_add(curve_type: CurveType, point_1: Point2D, point_2: Point2D) -> Poin /// /// # Arguments /// -/// * `curve_type`: [CurveType] - The type of curve which the addition should be performed. /// * `points`: [Vec<(Point2D, [Point2D; 2])>] - The points used to perform the pairing check. /// /// # Returns @@ -133,46 +120,39 @@ pub fn ec_add(curve_type: CurveType, point_1: Point2D, point_2: Point2D) -> Poin /// # Examples /// /// ```sway -/// use std::{point2d::Point2D, scalar::Scalar, zk::ec_mul}; +/// use std::{point2d::Point2D, scalar::Scalar, alt_bn128::alt_bn128_pairing_check}; /// -/// fn foo(curve_type: CurveType, points: Vec<(Point2D, [Point2D; 2])>) { -/// let result = ec_pairing_check(curve_type, points); +/// fn foo(points: Vec<(Point2D, [Point2D; 2])>) { +/// let result = alt_bn128_pairing_check(points); /// assert(result); /// } /// ``` -pub fn ec_pairing_check(curve_type: CurveType, points: Vec<(Point2D, [Point2D; 2])>) -> bool { +pub fn alt_bn128_pairing_check(points: Vec<(Point2D, [Point2D; 2])>) -> bool { // Total bytes is (P1, (G1, G2)) = ([32 bytes, 32 bytes], ([32 bytes, 32 bytes], [32 bytes, 32 bytes])) = 6 * 32 bytes * length let mut points_ptr = alloc::(points.len() * 6); - - let curve = match curve_type { - CurveType::AltBN128 => { - let mut iter = 0; - while iter < points.len() { - let p1 = points.get(iter).unwrap().0; - let p2 = points.get(iter).unwrap().1[0]; - let p3 = points.get(iter).unwrap().1[1]; - - require(valid_alt_bn128_point(p1), ZKError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(p2), ZKError::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(p3), ZKError::InvalidEllipticCurvePoint); - - // Copy all 6 32 byte length points to the single slice - p1.x().ptr().copy_to::(points_ptr.add::(iter * 6), 1); - p1.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 1), 1); - p2.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 2), 1); - p2.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 3), 1); - p3.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 4), 1); - p3.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 5), 1); - - iter += 1; - } - - 0 - } - }; + let mut iter = 0; + while iter < points.len() { + let p1 = points.get(iter).unwrap().0; + let p2 = points.get(iter).unwrap().1[0]; + let p3 = points.get(iter).unwrap().1[1]; + + require(valid_alt_bn128_point(p1), AltBn128Error::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(p2), AltBn128Error::InvalidEllipticCurvePoint); + require(valid_alt_bn128_point(p3), AltBn128Error::InvalidEllipticCurvePoint); + + // Copy all 6 32 byte length points to the single slice + p1.x().ptr().copy_to::(points_ptr.add::(iter * 6), 1); + p1.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 1), 1); + p2.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 2), 1); + p2.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 3), 1); + p3.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 4), 1); + p3.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 5), 1); + + iter += 1; + } // Result is bool - asm(buffer, curve: curve, length: points.len(), points: points_ptr) { + asm(buffer, curve: 0, length: points.len(), points: points_ptr) { epar buffer curve length points; buffer: bool } diff --git a/sway-lib-std/src/crypto/errors.sw b/sway-lib-std/src/crypto/errors.sw deleted file mode 100644 index 02c6adf2fab..00000000000 --- a/sway-lib-std/src/crypto/errors.sw +++ /dev/null @@ -1,11 +0,0 @@ -library; - -/// The error type used when performing elliptic curve operations for Zero Knowledge cryptography. -pub enum ZKError { - /// An unsupported curve was used. - UnsupportedCurve: (), - /// The elliptic curve point used was invalid. - InvalidEllipticCurvePoint: (), - /// The elliptice curve scalar used was invalid. - InvalidEllipticCurveScalar: (), -} diff --git a/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw index 0196dd5b62f..42b813e2e2f 100644 --- a/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/crypto_zk_inline_tests/src/main.sw @@ -1,15 +1,15 @@ library; -use std::crypto::{point2d::*, scalar::*, zk::{ec_add, ec_mul, CurveType, ec_pairing_check}}; +use std::crypto::{point2d::*, scalar::*, alt_bn128::{alt_bn128_add, alt_bn128_mul, alt_bn128_pairing_check}}; #[test] -fn zk_ec_add() { +fn zk_alt_bn128_add() { // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs let p1_1 = Point2D::from([0x18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9, 0x063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f37266]); let p2_1 = Point2D::from([0x07c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed, 0x06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7]); let expected_point_1 = Point2D::from([0x2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703, 0x301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915]); - let result_1 = ec_add(CurveType::AltBN128, p1_1, p2_1); + let result_1 = alt_bn128_add(p1_1, p2_1); assert(result_1 == expected_point_1); // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs @@ -17,7 +17,7 @@ fn zk_ec_add() { let p2_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); let expected_point_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); - let result_2 = ec_add(CurveType::AltBN128, p1_2, p2_2); + let result_2 = alt_bn128_add(p1_2, p2_2); assert(result_2 == expected_point_2); // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge2/ecadd_1145-3932_2969-1336_21000_128.json @@ -25,7 +25,7 @@ fn zk_ec_add() { let p2_3 = Point2D::from([0x039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869, 0x073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98]); let expected_point_3 = Point2D::from([0x15bf2bb17880144b5d1cd2b1f46eff9d617bffd1ca57c37fb5a49bd84e53cf66, 0x049c797f9ce0d17083deb32b5e36f2ea2a212ee036598dd7624c168993d1355f]); - let result_3 = ec_add(CurveType::AltBN128, p1_3, p2_3); + let result_3 = alt_bn128_add(p1_3, p2_3); assert(result_3 == expected_point_3); // From https://github.com/matter-labs/era-compiler-tests/blob/2253941334797eb2a997941845fb9eb0d436558b/yul/precompiles/ecadd.yul#L123 @@ -33,7 +33,7 @@ fn zk_ec_add() { let p2_4 = Point2D::from([0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9, 0x2e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb]); let expected_point_4 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); - let result_4 = ec_add(CurveType::AltBN128, p1_4, p2_4); + let result_4 = alt_bn128_add(p1_4, p2_4); assert(result_4 == expected_point_4); // From https://github.com/poanetwork/parity-ethereum/blob/2ea4265b0083c4148571b21e1079c641d5f31dc2/ethcore/benches/builtin.rs#L486 @@ -41,37 +41,37 @@ fn zk_ec_add() { let p2_5 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000000000000000002]); let expected_point_5 = Point2D::from([0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3, 0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4]); - let result_5 = ec_add(CurveType::AltBN128, p1_5, p2_5); + let result_5 = alt_bn128_add(p1_5, p2_5); assert(result_5 == expected_point_5); } #[test(should_revert)] -fn revert_zk_ec_add_fail() { +fn revert_zk_alt_bn128_add_fail() { // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs let p1 = Point2D::from([0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111]); let p2 = Point2D::from([0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111]); - let _result = ec_add(CurveType::AltBN128, p1, p2); + let _result = alt_bn128_add(p1, p2); } // TODO: Uncomment and implement test when another curve is supported // #[test(should_revert)] -// fn revert_zk_ec_add_invalid_point() { +// fn revert_zk_alt_bn128_add_invalid_point() { // // This needs to be an invalid point // let p1 = Point2D::from(); // let p2 = Point2D::from(); -// let _result = ec_add(CurveType::AltBN128, p1, p2); +// let _result = alt_bn128_add(p1, p2); // } #[test] -fn zk_ec_mul() { +fn zk_alt_bn128_mul() { // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs let p1_1 = Point2D::from([0x2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb7, 0x21611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204]); let scalar_1 = Scalar::from(0x00000000000000000000000000000000000000000000000011138ce750fa15c2); let expected_point_1 = Point2D::from([0x070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c, 0x031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc]); - let result_1 = ec_mul(CurveType::AltBN128, p1_1, scalar_1); + let result_1 = alt_bn128_mul(p1_1, scalar_1); assert(result_1 == expected_point_1); // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs @@ -79,7 +79,7 @@ fn zk_ec_mul() { let scalar_2 = Scalar::from(0x0200000000000000000000000000000000000000000000000000000000000000); let expected_point_2 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); - let result_2 = ec_mul(CurveType::AltBN128, p1_2, scalar_2); + let result_2 = alt_bn128_mul(p1_2, scalar_2); assert(result_2 == expected_point_2); // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecmul_7827-6598_1456_21000_96.json @@ -87,7 +87,7 @@ fn zk_ec_mul() { let scalar_3 = Scalar::from(0x0000000000000000000000000000000100000000000000000000000000000000); let expected_point_3 = Point2D::from([0x1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0, 0x135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b]); - let result_3 = ec_mul(CurveType::AltBN128, p1_3, scalar_3); + let result_3 = alt_bn128_mul(p1_3, scalar_3); assert(result_3 == expected_point_3); // From https://github.com/matter-labs/era-compiler-tests/blob/2253941334797eb2a997941845fb9eb0d436558b/yul/precompiles/ecmul.yul#L185C21-L185C98 @@ -95,7 +95,7 @@ fn zk_ec_mul() { let scalar_4 = Scalar::from(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001); let expected_point_4 = Point2D::from([0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000]); - let result_4 = ec_mul(CurveType::AltBN128, p1_4, scalar_4); + let result_4 = alt_bn128_mul(p1_4, scalar_4); assert(result_4 == expected_point_4); // From https://github.com/poanetwork/parity-ethereum/blob/2ea4265b0083c4148571b21e1079c641d5f31dc2/ethcore/benches/builtin.rs#L516 @@ -103,41 +103,41 @@ fn zk_ec_mul() { let scalar_5 = Scalar::from(0x00000000000000000000000000000000000000000000000011138ce750fa15c2); let expected_point_5 = Point2D::from([0x070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c, 0x031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc]); - let result_5 = ec_mul(CurveType::AltBN128, p1_5, scalar_5); + let result_5 = alt_bn128_mul(p1_5, scalar_5); assert(result_5 == expected_point_5); } #[test(should_revert)] -fn revert_zk_ec_mul_fail() { +fn revert_zk_alt_bn128_mul_fail() { // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs let p = Point2D::from([0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111]); let scalar = Scalar::from(0x0f00000000000000000000000000000000000000000000000000000000000000); - let _result = ec_mul(CurveType::AltBN128, p, scalar); + let _result = alt_bn128_mul(p, scalar); } // TODO: Uncomment and implement test when another curve is supported // #[test(should_revert)] -// fn revert_zk_ec_mul_invalid_point() { +// fn revert_zk_alt_bn128_mul_invalid_point() { // // This should be an invalid point // let p = Point2D::from(); // let scalar = Scalar::from(0x00000000000000000000000000000000000000000000000011138ce750fa15c2); -// let _result = ec_mul(CurveType::AltBN128, p, scalar); +// let _result = alt_bn128_mul(p, scalar); // } // TODO: Uncomment and implement test when another curve is supported // #[test(should_revert)] -// fn revert_zk_ec_mul_invalid_scalar() { +// fn revert_zk_alt_bn128_mul_invalid_scalar() { // // This should be an invalid scalar // let p = Point2D::from([0x2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb7, 0x21611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204]); // let scalar = Scalar::from(); -// let _result = ec_mul(CurveType::AltBN128, p, scalar); +// let _result = alt_bn128_mul(p, scalar); // } #[test] -fn zk_ec_pairing_check() { +fn zk_alt_bn128_pairing_check() { // From https://github.com/bluealloy/revm/blob/main/crates/precompile/src/bn128.rs let mut points_vec_1: Vec<(Point2D, [Point2D; 2])> = Vec::new(); let p1_1_1 = Point2D::from((0x1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59, 0x3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41)); @@ -150,7 +150,7 @@ fn zk_ec_pairing_check() { let g2_2_1 = Point2D::from((0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)); points_vec_1.push((p1_2_1, [g1_2_1, g2_2_1])); - assert(ec_pairing_check(CurveType::AltBN128, points_vec_1)); + assert(alt_bn128_pairing_check(points_vec_1)); // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecpairing_three_point_match_1.json let mut points_vec_2: Vec<(Point2D, [Point2D; 2])> = Vec::new(); @@ -164,7 +164,7 @@ fn zk_ec_pairing_check() { let g2_2_2 = Point2D::from((0x2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb9, 0x29d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75)); points_vec_2.push((p1_2_2, [g1_2_2, g2_2_2])); - assert(ec_pairing_check(CurveType::AltBN128, points_vec_2)); + assert(alt_bn128_pairing_check(points_vec_2)); // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecpairing_three_point_fail_1.json let mut points_vec_3: Vec<(Point2D, [Point2D; 2])> = Vec::new(); @@ -178,7 +178,7 @@ fn zk_ec_pairing_check() { let g2_2_3 = Point2D::from((0x00cacf3523caf879d7d05e30549f1e6fdce364cbb8724b0329c6c2a39d4f018e, 0x0692e55db067300e6e3fe56218fa2f940054e57e7ef92bf7d475a9d8a8502fd2)); points_vec_3.push((p1_2_3, [g1_2_3, g2_2_3])); - assert(!ec_pairing_check(CurveType::AltBN128, points_vec_3)); + assert(!alt_bn128_pairing_check(points_vec_3)); // From https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stZeroKnowledge/ecpairing_three_point_fail_1.json let mut points_vec_4: Vec<(Point2D, [Point2D; 2])> = Vec::new(); @@ -232,16 +232,16 @@ fn zk_ec_pairing_check() { let g2_10_4 = Point2D::from((0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec, 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d)); points_vec_4.push((p1_10_4, [g1_10_4, g2_10_4])); - assert(ec_pairing_check(CurveType::AltBN128, points_vec_4)); + assert(alt_bn128_pairing_check(points_vec_4)); } #[test(should_revert)] -fn revert_zk_ec_pairing_check() { +fn revert_zk_alt_bn128_pairing_check() { let mut points_vec: Vec<(Point2D, [Point2D; 2])> = Vec::new(); let p1_1 = Point2D::from((0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111)); let g1_1 = Point2D::from((0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111)); let g2_1 = Point2D::from((0x1111111111111111111111111111111111111111111111111111111111111111, 0x1111111111111111111111111111111111111111111111111111111111111111)); points_vec.push((p1_1, [g1_1, g2_1])); - let _ = ec_pairing_check(CurveType::AltBN128, points_vec); + let _ = alt_bn128_pairing_check(points_vec); } From abef4dfb7aa692f9eac40de0a379a1325c37d7c9 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 21 Jan 2025 13:57:39 +0100 Subject: [PATCH 09/13] Manual formatting --- sway-lib-std/src/crypto/alt_bn128.sw | 107 +++++++++++++++++---------- sway-lib-std/src/crypto/point2d.sw | 11 +-- sway-lib-std/src/crypto/scalar.sw | 9 +-- 3 files changed, 78 insertions(+), 49 deletions(-) diff --git a/sway-lib-std/src/crypto/alt_bn128.sw b/sway-lib-std/src/crypto/alt_bn128.sw index cadd4440c0a..b06c0d86e48 100644 --- a/sway-lib-std/src/crypto/alt_bn128.sw +++ b/sway-lib-std/src/crypto/alt_bn128.sw @@ -40,8 +40,14 @@ pub enum AltBn128Error { /// } /// ``` pub fn alt_bn128_mul(point: Point2D, scalar: Scalar) -> Point2D { - require(valid_alt_bn128_point(point), AltBn128Error::InvalidEllipticCurvePoint); - require(valid_alt_bn128_scalar(scalar), AltBn128Error::InvalidEllipticCurveScalar); + require( + valid_alt_bn128_point(point), + AltBn128Error::InvalidEllipticCurvePoint + ); + require( + valid_alt_bn128_scalar(scalar), + AltBn128Error::InvalidEllipticCurveScalar + ); // 1P = ([32 bytes], [32 bytes]) let mut result = [b256::zero(), b256::zero()]; @@ -84,17 +90,35 @@ pub fn alt_bn128_mul(point: Point2D, scalar: Scalar) -> Point2D { /// } /// ``` pub fn alt_bn128_add(point_1: Point2D, point_2: Point2D) -> Point2D { - require(valid_alt_bn128_point(point_1), AltBn128Error::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(point_2), AltBn128Error::InvalidEllipticCurvePoint); + require( + valid_alt_bn128_point(point_1), + AltBn128Error::InvalidEllipticCurvePoint + ); + require( + valid_alt_bn128_point(point_2), + AltBn128Error::InvalidEllipticCurvePoint + ); // 1P = ([32 bytes], [32 bytes]) let mut result = [b256::zero(), b256::zero()]; // 1P1P = (X, Y), (X, Y) = ([32 bytes], [32 bytes]), ([32 bytes], [32 bytes]) = 4 * 32 bytes let mut points_ptr = alloc::(4); - point_1.x().ptr().copy_to::(points_ptr.add::(0), 1); - point_1.y().ptr().copy_to::(points_ptr.add::(1), 1); - point_2.x().ptr().copy_to::(points_ptr.add::(2), 1); - point_2.y().ptr().copy_to::(points_ptr.add::(3), 1); + point_1 + .x() + .ptr() + .copy_to::(points_ptr.add::(0), 1); + point_1 + .y() + .ptr() + .copy_to::(points_ptr.add::(1), 1); + point_2 + .x() + .ptr() + .copy_to::(points_ptr.add::(2), 1); + point_2 + .y() + .ptr() + .copy_to::(points_ptr.add::(3), 1); asm(buffer: result, curve: 0, operation: 0, points: points_ptr) { ecop buffer curve operation points; @@ -136,17 +160,44 @@ pub fn alt_bn128_pairing_check(points: Vec<(Point2D, [Point2D; 2])>) -> bool { let p2 = points.get(iter).unwrap().1[0]; let p3 = points.get(iter).unwrap().1[1]; - require(valid_alt_bn128_point(p1), AltBn128Error::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(p2), AltBn128Error::InvalidEllipticCurvePoint); - require(valid_alt_bn128_point(p3), AltBn128Error::InvalidEllipticCurvePoint); + require( + valid_alt_bn128_point(p1), + AltBn128Error::InvalidEllipticCurvePoint + ); + require( + valid_alt_bn128_point(p2), + AltBn128Error::InvalidEllipticCurvePoint + ); + require( + valid_alt_bn128_point(p3), + AltBn128Error::InvalidEllipticCurvePoint + ); // Copy all 6 32 byte length points to the single slice - p1.x().ptr().copy_to::(points_ptr.add::(iter * 6), 1); - p1.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 1), 1); - p2.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 2), 1); - p2.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 3), 1); - p3.x().ptr().copy_to::(points_ptr.add::((iter * 6) + 4), 1); - p3.y().ptr().copy_to::(points_ptr.add::((iter * 6) + 5), 1); + p1 + .x() + .ptr() + .copy_to::(points_ptr.add::(iter * 6), 1); + p1 + .y() + .ptr() + .copy_to::(points_ptr.add::((iter * 6) + 1), 1); + p2 + .x() + .ptr() + .copy_to::(points_ptr.add::((iter * 6) + 2), 1); + p2 + .y() + .ptr() + .copy_to::(points_ptr.add::((iter * 6) + 3), 1); + p3 + .x() + .ptr() + .copy_to::(points_ptr.add::((iter * 6) + 4), 1); + p3 + .y() + .ptr() + .copy_to::(points_ptr.add::((iter * 6) + 5), 1); iter += 1; } @@ -162,28 +213,6 @@ pub fn alt_bn128_pairing_check(points: Vec<(Point2D, [Point2D; 2])>) -> bool { fn valid_alt_bn128_point(point: Point2D) -> bool { // 1P = ([32 bytes], [32 bytes]) point.x().len() == 32 && point.y().len() == 32 - - // y**2 = x**3 + 3 - // p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 - - // let p = u256::from(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47); - // let res = <(u256, u256) as TryFrom>::try_from(point); - // let (x, y) = match res { - // Some((x, y)) => (x, y), - // None => return false, - // }; - - // // Ensure x and y are within the field range - // if x > p || y > p { - // return false; - // } - - // // Compute y^2 mod p - // let y_squared = (y * y); - // // // Compute x^3 + 3 - // let x_cubed = (x * x * x); - - // y_squared == (x_cubed + 3) % p } // Returns true if the scalar is in valid alt bn128 format. diff --git a/sway-lib-std/src/crypto/point2d.sw b/sway-lib-std/src/crypto/point2d.sw index be010682eb4..82033ecf3cb 100644 --- a/sway-lib-std/src/crypto/point2d.sw +++ b/sway-lib-std/src/crypto/point2d.sw @@ -20,7 +20,11 @@ pub struct Point2D { impl Eq for Point2D { fn eq(self, other: Self) -> bool { // All points must be of length 32 - if self.x.len() != 32 || self.y.len() != 32 || other.x.len() != 32 || other.y.len() != 32 { + if self.x.len() != 32 + || self.y.len() != 32 + || other.x.len() != 32 + || other.y.len() != 32 + { return false; } @@ -218,10 +222,7 @@ impl From<[u8; 64]> for Point2D { iter += 1; } - Self { - x: x, - y: y, - } + Self { x: x, y: y } } } diff --git a/sway-lib-std/src/crypto/scalar.sw b/sway-lib-std/src/crypto/scalar.sw index ad86dc6c48a..659ec13395b 100644 --- a/sway-lib-std/src/crypto/scalar.sw +++ b/sway-lib-std/src/crypto/scalar.sw @@ -7,7 +7,7 @@ use ::option::Option::{self, *}; // NOTE: Bytes are use to support numbers greater than 32 bytes for future curves. /// The Scalar type used in cryptographic operations. pub struct Scalar { - bytes: Bytes + bytes: Bytes, } impl Eq for Scalar { @@ -19,7 +19,8 @@ impl Eq for Scalar { let mut iter = 0; while iter < 32 { - if self.bytes.get(iter).unwrap() != other.bytes.get(iter).unwrap() { + if self.bytes.get(iter).unwrap() != other.bytes.get(iter).unwrap() + { return false; } @@ -162,9 +163,7 @@ impl From<[u8; 32]> for Scalar { iter += 1; } - Self { - bytes: bytes, - } + Self { bytes: bytes } } } From 0e8fcfda682a519cbde22a3bb8e7748046f218fc Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 21 Jan 2025 16:29:47 +0100 Subject: [PATCH 10/13] Empty-Commit From 08f15fb44c1b2d8afc90517afcf6fe4a4b915ee7 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Tue, 21 Jan 2025 16:43:57 +0100 Subject: [PATCH 11/13] Format 2 --- sway-lib-std/src/crypto/alt_bn128.sw | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sway-lib-std/src/crypto/alt_bn128.sw b/sway-lib-std/src/crypto/alt_bn128.sw index b06c0d86e48..522e232465f 100644 --- a/sway-lib-std/src/crypto/alt_bn128.sw +++ b/sway-lib-std/src/crypto/alt_bn128.sw @@ -42,11 +42,11 @@ pub enum AltBn128Error { pub fn alt_bn128_mul(point: Point2D, scalar: Scalar) -> Point2D { require( valid_alt_bn128_point(point), - AltBn128Error::InvalidEllipticCurvePoint + AltBn128Error::InvalidEllipticCurvePoint, ); require( valid_alt_bn128_scalar(scalar), - AltBn128Error::InvalidEllipticCurveScalar + AltBn128Error::InvalidEllipticCurveScalar, ); // 1P = ([32 bytes], [32 bytes]) @@ -92,11 +92,11 @@ pub fn alt_bn128_mul(point: Point2D, scalar: Scalar) -> Point2D { pub fn alt_bn128_add(point_1: Point2D, point_2: Point2D) -> Point2D { require( valid_alt_bn128_point(point_1), - AltBn128Error::InvalidEllipticCurvePoint + AltBn128Error::InvalidEllipticCurvePoint, ); require( valid_alt_bn128_point(point_2), - AltBn128Error::InvalidEllipticCurvePoint + AltBn128Error::InvalidEllipticCurvePoint, ); // 1P = ([32 bytes], [32 bytes]) @@ -162,15 +162,15 @@ pub fn alt_bn128_pairing_check(points: Vec<(Point2D, [Point2D; 2])>) -> bool { require( valid_alt_bn128_point(p1), - AltBn128Error::InvalidEllipticCurvePoint + AltBn128Error::InvalidEllipticCurvePoint, ); require( valid_alt_bn128_point(p2), - AltBn128Error::InvalidEllipticCurvePoint + AltBn128Error::InvalidEllipticCurvePoint, ); require( valid_alt_bn128_point(p3), - AltBn128Error::InvalidEllipticCurvePoint + AltBn128Error::InvalidEllipticCurvePoint, ); // Copy all 6 32 byte length points to the single slice From defe529b138e6d90cd32e3408124a2e1f9f11536 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Wed, 5 Feb 2025 11:18:44 -0300 Subject: [PATCH 12/13] Resolve merge conflicts --- sway-lib-std/src/lib.sw | 1 - 1 file changed, 1 deletion(-) diff --git a/sway-lib-std/src/lib.sw b/sway-lib-std/src/lib.sw index ab0c5784228..fee5ce151cf 100644 --- a/sway-lib-std/src/lib.sw +++ b/sway-lib-std/src/lib.sw @@ -19,7 +19,6 @@ pub mod math; pub mod u128; pub mod b512; pub mod primitive_conversions; -pub mod crypto; pub mod alias; pub mod hash; pub mod asset_id; From 2e26426a04043ae1d7bc3b6e6ba27c38912eded1 Mon Sep 17 00:00:00 2001 From: bitzoic Date: Wed, 5 Feb 2025 12:35:47 -0300 Subject: [PATCH 13/13] Resolve PR comments --- sway-lib-std/src/crypto/alt_bn128.sw | 2 +- sway-lib-std/src/crypto/point2d.sw | 2 +- sway-lib-std/src/crypto/scalar.sw | 4 ++-- sway-lib-std/src/crypto/signature_error.sw | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sway-lib-std/src/crypto/alt_bn128.sw b/sway-lib-std/src/crypto/alt_bn128.sw index 522e232465f..55b0390e256 100644 --- a/sway-lib-std/src/crypto/alt_bn128.sw +++ b/sway-lib-std/src/crypto/alt_bn128.sw @@ -10,7 +10,7 @@ use ::alloc::alloc; pub enum AltBn128Error { /// The elliptic curve point used was invalid. InvalidEllipticCurvePoint: (), - /// The elliptice curve scalar used was invalid. + /// The elliptic curve scalar used was invalid. InvalidEllipticCurveScalar: (), } diff --git a/sway-lib-std/src/crypto/point2d.sw b/sway-lib-std/src/crypto/point2d.sw index 82033ecf3cb..2d3e29fc970 100644 --- a/sway-lib-std/src/crypto/point2d.sw +++ b/sway-lib-std/src/crypto/point2d.sw @@ -4,7 +4,7 @@ use ::convert::{From, TryFrom}; use ::bytes::{Bytes, *}; use ::option::Option::{self, *}; -// NOTE: Bytes are use to support numbers greater than 32 bytes for future curves. +// NOTE: Bytes are used to support numbers greater than 32 bytes for future curves. /// A 2D point on a field. /// /// # Additional Information diff --git a/sway-lib-std/src/crypto/scalar.sw b/sway-lib-std/src/crypto/scalar.sw index 659ec13395b..65b5f5574cf 100644 --- a/sway-lib-std/src/crypto/scalar.sw +++ b/sway-lib-std/src/crypto/scalar.sw @@ -4,7 +4,7 @@ use ::convert::{From, TryFrom}; use ::bytes::{Bytes, *}; use ::option::Option::{self, *}; -// NOTE: Bytes are use to support numbers greater than 32 bytes for future curves. +// NOTE: Bytes are used to support numbers greater than 32 bytes for future curves. /// The Scalar type used in cryptographic operations. pub struct Scalar { bytes: Bytes, @@ -96,7 +96,7 @@ impl Scalar { } } - /// Returns true if the scalae is zero, otherwise false. + /// Returns true if the scalar is zero, otherwise false. /// /// # Returns /// diff --git a/sway-lib-std/src/crypto/signature_error.sw b/sway-lib-std/src/crypto/signature_error.sw index 53bd82b8b00..78f5a79fa02 100644 --- a/sway-lib-std/src/crypto/signature_error.sw +++ b/sway-lib-std/src/crypto/signature_error.sw @@ -8,6 +8,6 @@ pub enum SignatureError { InvalidPublicKey: (), /// The error variant used when signature verification fails. InvalidSignature: (), - /// The error varient used when an invalid operation was performed. + /// The error variant used when an invalid operation was performed. InvalidOperation: (), }