diff --git a/CHANGELOG.md b/CHANGELOG.md index edf550a..4ac5a7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.5.0 + +- Implemented Monero cryptographic operations. + ## 3.4.0 - Stellar Address Support: Add support for stellar Contract address. diff --git a/example/lib/main.dart b/example/lib/main.dart index 7030fcb..b3c9d50 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -85,9 +85,9 @@ import 'package:example/test/schnorrkel/schnorrkel_key.dart'; import 'package:example/test/schnorrkel/sign.dart'; import 'package:example/test/schnorrkel/vrf.dart'; import 'package:example/test/secure_storage.dart'; -import 'package:example/test/signer/ethereum_test.dart'; -import 'package:example/test/signer/tron_test.dart'; -import 'package:example/test/signer/xrp_test.dart'; +import 'package:example/test/signer/ethereum.dart'; +import 'package:example/test/signer/tron.dart'; +import 'package:example/test/signer/xrp.dart'; import 'package:example/test/ss58/ss58.dart'; import 'package:example/test/substrate/scale.dart'; import 'package:example/test/substrate/substrate.dart'; diff --git a/example/lib/test/bip/bip44/bip44.dart b/example/lib/test/bip/bip44/bip44.dart index 4df7ccd..c938f55 100644 --- a/example/lib/test/bip/bip44/bip44.dart +++ b/example/lib/test/bip/bip44/bip44.dart @@ -27,7 +27,7 @@ void bip44Test() { assert(account.publicKey.toExtended == accountInfo["account_public"]); if (coin == Bip44Coins.moneroEd25519Slip || coin == Bip44Coins.moneroSecp256k1) { - final addrClass = Monero.fromBip44PrivateKey(account.privateKey.raw); + final addrClass = MoneroAccount.fromBip44PrivateKey(account.privateKey.raw); assert(addrClass.primaryAddress == accountInfo["address"]); continue; } diff --git a/example/lib/test/ecdsa/ed.dart b/example/lib/test/ecdsa/ed.dart index 1b39cae..63d22ec 100644 --- a/example/lib/test/ecdsa/ed.dart +++ b/example/lib/test/ecdsa/ed.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/privatekey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/privatekey.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/crypto/crypto/hash/hash.dart'; import 'package:example/test/quick_hex.dart'; diff --git a/example/lib/test/monero/monero.dart b/example/lib/test/monero/monero.dart index 0e5adcf..11216de 100644 --- a/example/lib/test/monero/monero.dart +++ b/example/lib/test/monero/monero.dart @@ -11,7 +11,7 @@ void moneroTest() { final coin = MoneroCoins.values.firstWhere((element) => element.name.toLowerCase() == (i["coin"] as String).replaceAll("_", "").toLowerCase()); - final w = Monero.fromSeed(seed, coinType: coin); + final w = MoneroAccount.fromSeed(seed, coinType: coin); assert(w.privateSpendKey.raw.toHex() == i["private_sky"]); assert(w.privateViewKey.raw.toHex() == i["private_vkey"]); assert(w.publicSpendKey.compressed.toHex() == i["public_sky"]); diff --git a/example/lib/test/signer/ethereum_test.dart b/example/lib/test/signer/ethereum.dart similarity index 100% rename from example/lib/test/signer/ethereum_test.dart rename to example/lib/test/signer/ethereum.dart diff --git a/example/lib/test/signer/tron_test.dart b/example/lib/test/signer/tron.dart similarity index 100% rename from example/lib/test/signer/tron_test.dart rename to example/lib/test/signer/tron.dart diff --git a/example/lib/test/signer/xrp_test.dart b/example/lib/test/signer/xrp.dart similarity index 100% rename from example/lib/test/signer/xrp_test.dart rename to example/lib/test/signer/xrp.dart diff --git a/example/pubspec.lock b/example/pubspec.lock index c52feb6..f366471 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,18 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.7.0" args: dependency: transitive description: @@ -39,7 +44,7 @@ packages: path: ".." relative: true source: path - version: "3.3.0" + version: "3.5.0" boolean_selector: dependency: transitive description: @@ -76,34 +81,34 @@ packages: dependency: transitive description: name: coverage - sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" + sha256: c1fb2dce3c0085f39dc72668e85f8e0210ec7de05345821ff58530567df345a5 url: "https://pub.dev" source: hosted - version: "1.7.2" + version: "1.9.2" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.8" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -181,6 +186,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -209,10 +222,10 @@ packages: dependency: transitive description: name: mime - sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "2.0.0" node_preamble: dependency: transitive description: @@ -273,18 +286,18 @@ packages: dependency: transitive description: name: shelf_static - sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.3" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -294,10 +307,10 @@ packages: dependency: transitive description: name: source_map_stack_trace - sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" source_maps: dependency: transitive description: @@ -318,10 +331,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -334,10 +347,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" term_glyph: dependency: transitive description: @@ -350,26 +363,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" url: "https://pub.dev" source: hosted - version: "1.25.2" + version: "1.25.8" test_api: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.3" test_core: dependency: transitive description: name: test_core - sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.5" typed_data: dependency: transitive description: @@ -390,10 +403,10 @@ packages: dependency: transitive description: name: vm_service - sha256: a75f83f14ad81d5fe4b3319710b90dec37da0e22612326b696c9e1b8f34bbf48 + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.0" + version: "14.3.0" watcher: dependency: transitive description: @@ -406,18 +419,26 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "3.0.1" webkit_inspection_protocol: dependency: transitive description: @@ -435,4 +456,4 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.4.0 <4.0.0" diff --git a/example/test/test_test.dart b/example/test/test_test.dart index 5be5ec1..77c27fe 100644 --- a/example/test/test_test.dart +++ b/example/test/test_test.dart @@ -1,220 +1,221 @@ -// // ignore_for_file: avoid_print +// // // ignore_for_file: avoid_print -import 'package:example/test/address/ada_shelly/ada_shelly.dart'; -import 'package:example/test/address/algo/algo.dart'; -import 'package:example/test/address/aptos/aptos.dart'; -import 'package:example/test/address/atom/atom.dart'; -import 'package:example/test/address/avax/avax.dart'; -import 'package:example/test/address/bch_p2pkh/bch_p2pkh.dart'; -import 'package:example/test/address/bch_p2sh/bch_p2sh.dart'; -import 'package:example/test/address/egld/egld.dart'; -import 'package:example/test/address/eos/eos.dart'; -import 'package:example/test/address/ergo/ergo.dart'; -import 'package:example/test/address/eth/eth.dart'; -import 'package:example/test/address/fil/fil.dart'; -import 'package:example/test/address/icx/icx.dart'; -import 'package:example/test/address/inj/inj.dart'; -import 'package:example/test/address/nano/nano.dart'; -import 'package:example/test/address/near/near.dart'; -import 'package:example/test/address/neo/neo.dart'; -import 'package:example/test/address/okex/okex.dart'; -import 'package:example/test/address/one/one.dart'; -import 'package:example/test/address/p2pkh/p2pkh.dart'; -import 'package:example/test/address/p2sh/p2sh.dart'; -import 'package:example/test/address/p2tr/p2tr.dart'; -import 'package:example/test/address/p2wpkh/p2wpkh.dart'; -import 'package:example/test/address/sol/sol.dart'; -import 'package:example/test/address/substrate/substrate.dart'; -import 'package:example/test/address/trx/trx.dart'; -import 'package:example/test/address/xlm/xml.dart'; -import 'package:example/test/address/xmr/xmr.dart'; -import 'package:example/test/address/xrp/xrp.dart'; -import 'package:example/test/address/xtz/xtz.dart'; -import 'package:example/test/address/zil/zil.dart'; -import 'package:example/test/algorand/mnemonic.dart'; -import 'package:example/test/base58/base58.dart'; -import 'package:example/test/base58/base58_xmr.dart'; -import 'package:example/test/bech32/bch_bech32.dart'; -import 'package:example/test/bech32/bech32.dart'; -import 'package:example/test/bech32/segwit_bech32.dart'; -import 'package:example/test/bip/bip32/ed25519/ed25519.dart'; -import 'package:example/test/bip/bip32/ed25519_blake2b/ed25519_blake2b.dart'; -import 'package:example/test/bip/bip32/ed25519_khalow/ed25519_khalow.dart'; -import 'package:example/test/bip/bip32/nist256p1/nist256p1.dart'; -import 'package:example/test/bip/bip32/secp256k1/secp256k1.dart'; -import 'package:example/test/bip/bip38/bip38_addr.dart'; -import 'package:example/test/bip/bip38/bip38_ec.dart'; -import 'package:example/test/bip/bip38/bip38_no_ec.dart'; -import 'package:example/test/bip/bip39/bip39.dart'; -import 'package:example/test/bip/bip44/bip44.dart'; -import 'package:example/test/bip/bip49/bip49.dart'; -import 'package:example/test/bip/bip84/bip84.dart'; -import 'package:example/test/bip/bip86/bip86.dart'; -import 'package:example/test/cardano/bip32/icarus.dart'; -import 'package:example/test/cardano/bip32/legacy.dart'; -import 'package:example/test/cardano/byron/byron_lagacy.dart'; -import 'package:example/test/cardano/cip1852/cip1852.dart'; -import 'package:example/test/cardano/mnemonic/mnemonic.dart'; -import 'package:example/test/cardano/shelly/shelly.dart'; -import 'package:example/test/cbor.dart'; -import 'package:example/test/crypto/aes/aes_ctr.dart'; -import 'package:example/test/crypto/blake2b/blake2b.dart'; -import 'package:example/test/crypto/chacha20_poly1305/chacha20_poly1305.dart'; -import 'package:example/test/crypto/crc32/crc32.dart'; -import 'package:example/test/crypto/hmac/hmac.dart'; -import 'package:example/test/crypto/keccack/keccack.dart'; -import 'package:example/test/crypto/md4/md4.dart'; -import 'package:example/test/crypto/md5/md5.dart'; -import 'package:example/test/crypto/pbkdf2/pbkdf2.dart'; -import 'package:example/test/crypto/ripemd/ripemd.dart'; -import 'package:example/test/crypto/scrypt/scrypt.dart'; -import 'package:example/test/crypto/sha1/sha1.dart'; -import 'package:example/test/crypto/sha256/sha256.dart'; -import 'package:example/test/crypto/sha3/sha3.dart'; -import 'package:example/test/crypto/sha512/sha512.dart'; -import 'package:example/test/crypto/sha512_256/sha512_256.dart'; -import 'package:example/test/crypto/shake/shake.dart'; -import 'package:example/test/crypto/x_modem_crc/x_modem_crc.dart'; -import 'package:example/test/ecdsa/ed.dart'; -import 'package:example/test/ecdsa/projective.dart'; -import 'package:example/test/elctrum/mnemonic/mnemonic.dart'; -import 'package:example/test/elctrum/v1/v1.dart'; -import 'package:example/test/elctrum/v2/v2.dart'; -import 'package:example/test/monero/mnemonic/monero_mnemonic.dart'; -import 'package:example/test/monero/monero.dart'; -import 'package:example/test/schnorrkel/derive.dart'; -import 'package:example/test/schnorrkel/schnorrkel_key.dart'; -import 'package:example/test/schnorrkel/sign.dart'; -import 'package:example/test/schnorrkel/vrf.dart'; -import 'package:example/test/secure_storage.dart'; -import 'package:example/test/ss58/ss58.dart'; -import 'package:example/test/substrate/scale.dart'; -import 'package:example/test/substrate/substrate.dart'; -import 'package:example/test/uuid.dart'; -import 'package:example/test/wif/wif.dart'; -import 'package:flutter/foundation.dart'; +// import 'package:example/test/address/ada_shelly/ada_shelly.dart'; +// import 'package:example/test/address/algo/algo.dart'; +// import 'package:example/test/address/aptos/aptos.dart'; +// import 'package:example/test/address/atom/atom.dart'; +// import 'package:example/test/address/avax/avax.dart'; +// import 'package:example/test/address/bch_p2pkh/bch_p2pkh.dart'; +// import 'package:example/test/address/bch_p2sh/bch_p2sh.dart'; +// import 'package:example/test/address/egld/egld.dart'; +// import 'package:example/test/address/eos/eos.dart'; +// import 'package:example/test/address/ergo/ergo.dart'; +// import 'package:example/test/address/eth/eth.dart'; +// import 'package:example/test/address/fil/fil.dart'; +// import 'package:example/test/address/icx/icx.dart'; +// import 'package:example/test/address/inj/inj.dart'; +// import 'package:example/test/address/nano/nano.dart'; +// import 'package:example/test/address/near/near.dart'; +// import 'package:example/test/address/neo/neo.dart'; +// import 'package:example/test/address/okex/okex.dart'; +// import 'package:example/test/address/one/one.dart'; +// import 'package:example/test/address/p2pkh/p2pkh.dart'; +// import 'package:example/test/address/p2sh/p2sh.dart'; +// import 'package:example/test/address/p2tr/p2tr.dart'; +// import 'package:example/test/address/p2wpkh/p2wpkh.dart'; +// import 'package:example/test/address/sol/sol.dart'; +// import 'package:example/test/address/substrate/substrate.dart'; +// import 'package:example/test/address/trx/trx.dart'; +// import 'package:example/test/address/xlm/xml.dart'; +// import 'package:example/test/address/xmr/xmr.dart'; +// import 'package:example/test/address/xrp/xrp.dart'; +// import 'package:example/test/address/xtz/xtz.dart'; +// import 'package:example/test/address/zil/zil.dart'; +// import 'package:example/test/algorand/mnemonic.dart'; +// import 'package:example/test/base58/base58.dart'; +// import 'package:example/test/base58/base58_xmr.dart'; +// import 'package:example/test/bech32/bch_bech32.dart'; +// import 'package:example/test/bech32/bech32.dart'; +// import 'package:example/test/bech32/segwit_bech32.dart'; +// import 'package:example/test/bip/bip32/ed25519/ed25519.dart'; +// import 'package:example/test/bip/bip32/ed25519_blake2b/ed25519_blake2b.dart'; +// import 'package:example/test/bip/bip32/ed25519_khalow/ed25519_khalow.dart'; +// import 'package:example/test/bip/bip32/nist256p1/nist256p1.dart'; +// import 'package:example/test/bip/bip32/secp256k1/secp256k1.dart'; +// import 'package:example/test/bip/bip38/bip38_addr.dart'; +// import 'package:example/test/bip/bip38/bip38_ec.dart'; +// import 'package:example/test/bip/bip38/bip38_no_ec.dart'; +// import 'package:example/test/bip/bip39/bip39.dart'; +// import 'package:example/test/bip/bip44/bip44.dart'; +// import 'package:example/test/bip/bip49/bip49.dart'; +// import 'package:example/test/bip/bip84/bip84.dart'; +// import 'package:example/test/bip/bip86/bip86.dart'; +// import 'package:example/test/cardano/bip32/icarus.dart'; +// import 'package:example/test/cardano/bip32/legacy.dart'; +// import 'package:example/test/cardano/byron/byron_lagacy.dart'; +// import 'package:example/test/cardano/cip1852/cip1852.dart'; +// import 'package:example/test/cardano/mnemonic/mnemonic.dart'; +// import 'package:example/test/cardano/shelly/shelly.dart'; +// import 'package:example/test/cbor.dart'; +// import 'package:example/test/crypto/aes/aes_ctr.dart'; +// import 'package:example/test/crypto/blake2b/blake2b.dart'; +// import 'package:example/test/crypto/chacha20_poly1305/chacha20_poly1305.dart'; +// import 'package:example/test/crypto/crc32/crc32.dart'; +// import 'package:example/test/crypto/hmac/hmac.dart'; +// import 'package:example/test/crypto/keccack/keccack.dart'; +// import 'package:example/test/crypto/md4/md4.dart'; +// import 'package:example/test/crypto/md5/md5.dart'; +// import 'package:example/test/crypto/pbkdf2/pbkdf2.dart'; +// import 'package:example/test/crypto/ripemd/ripemd.dart'; +// import 'package:example/test/crypto/scrypt/scrypt.dart'; +// import 'package:example/test/crypto/sha1/sha1.dart'; +// import 'package:example/test/crypto/sha256/sha256.dart'; +// import 'package:example/test/crypto/sha3/sha3.dart'; +// import 'package:example/test/crypto/sha512/sha512.dart'; +// import 'package:example/test/crypto/sha512_256/sha512_256.dart'; +// import 'package:example/test/crypto/shake/shake.dart'; +// import 'package:example/test/crypto/x_modem_crc/x_modem_crc.dart'; +// import 'package:example/test/ecdsa/ed.dart'; +// import 'package:example/test/ecdsa/projective.dart'; +// import 'package:example/test/elctrum/mnemonic/mnemonic.dart'; +// import 'package:example/test/elctrum/v1/v1.dart'; +// import 'package:example/test/elctrum/v2/v2.dart'; +// import 'package:example/test/monero/mnemonic/monero_mnemonic.dart'; +// import 'package:example/test/monero/monero.dart'; +// import 'package:example/test/schnorrkel/derive.dart'; +// import 'package:example/test/schnorrkel/schnorrkel_key.dart'; +// import 'package:example/test/schnorrkel/sign.dart'; +// import 'package:example/test/schnorrkel/vrf.dart'; +// import 'package:example/test/secure_storage.dart'; +// import 'package:example/test/ss58/ss58.dart'; +// import 'package:example/test/substrate/scale.dart'; +// import 'package:example/test/substrate/substrate.dart'; +// import 'package:example/test/uuid.dart'; +// import 'package:example/test/wif/wif.dart'; +// import 'package:flutter/foundation.dart'; -void main() { - _testAll(); -} +// void main() { +// _testAll(); +// } -typedef TestMethod = void Function(); +// typedef TestMethod = void Function(); -/// its very slow in web debugging -/// if you want to test this method on the web should remove the condition -void _web() { - if (kIsWeb) return; - _test("bip38 No Ecdsa", bip38NoEcdsaTest); - _test("bip38 ECDSA", bip38ECDSATest); - _test("scrypt", testScrypt); - _test("pbkdf2", pbkdf2Test); - _test("secure storage", testSecureStorage); -} +// /// its very slow in web debugging +// /// if you want to test this method on the web should remove the condition +// void _web() { +// if (kIsWeb) return; +// _test("bip38 No Ecdsa", bip38NoEcdsaTest); +// _test("bip38 ECDSA", bip38ECDSATest); +// _test("scrypt", testScrypt); +// _test("pbkdf2", pbkdf2Test); +// _test("secure storage", testSecureStorage); +// } -void _test(String name, TestMethod process) { - try { - process(); - print("success $name"); - } catch (e) { - print("failed $name $e"); - throw Exception(); - } -} +// void _test(String name, TestMethod process) { +// try { +// process(); +// print("success $name"); +// } catch (e) { +// print("failed $name $e"); +// throw Exception(); +// } +// } -void _testAll() async { - final DateTime start = DateTime.now(); - _encodeDecodeAddrTest(); - _test("UUID", testUUID); - _test("bech32", bech32Test); - _test("wif", wifTest); - _test("substrate scale", substrateScaleTest); - _test("ss58", ss58Test); - _test("bip38 ", bip38Test); - _test("segwit Bech32 ", segwitBech32Test); - _test("bch bech32", bchBech32Test); - _test("base58 xmr", testBase58XMR); - _test("base58", testBase58); - _test("bip49", bip49Test); - _test("bip44", bip44Test); - _test("algorandMnemonic and derive address", algorandMnemonicAndAddressTest); - _test("substrate derive", substrateDeriveTest); - _test("monero mnemonic", moneroMnemonucTest); - _test("monero", moneroTest); - _test("electrum v2", electrumV2Test); - _test("electrum v1", electrumV1Test); - _test("electrum mnemonic", electrumMnemonicTest); - _test("cardano shelly", cardanoShellyTest); - _test("cardano mnemonic", cardanoMnemonicTest); - _test("cardano cip1852", cip1852Test); - _test("byron legacy", byronLegacyTest); - _test("cardano icarus", cardanoIcarusTest); - _test("cardano legacy", cardanoLegacyTest); - _test("bip86", bip86Test); - _test("bip84", bip84Test); - _test("bip39", testBip39); - _test("secp256k1", secpTest); - _test("nist", nistTest); - _test("ed25519-blake2b", edBlake2bTest); - _test("ed25519-khalow", edKhalowTest); - _test("ed25519", edTest); - _test("schnorr", schnoorTestDerive); - _test("vrf sigh", vrfSignTest); - _test("schnorrkel keys", schnoorKeyTest); - _test("schnorrkel-sign", testSchnoor); - _test("ecdsa", testECDSA); - _test("eddsa", testEDDSa); - _test("sha1", testSha1); - _test("ripemd", testRipemd); - _test("md5", md5Test); - _test("md4", md4Test); - _test("keccack", testKecc); - _test("hmac", testHmac); - _test("crc", crcTest); - _test("chacha-poly1305", chachaTest); - _test("aes", testAes); - _test("blake2b", blake2bTest); - _test("sha256", testSha256); - _test("sha512", testSha512); - _test("sha3", testSha3); - _test("sha512/256", testSha512256); - _test("modemCrc", testModemCrc); - _test("shake digest", testShakeDigest); - _test("cbor test", cborTest); - _web(); - final DateTime end = DateTime.now(); - print("end: ${end.difference(start).inMilliseconds}"); -} +// void _testAll() async { +// final DateTime start = DateTime.now(); +// _encodeDecodeAddrTest(); +// _test("UUID", testUUID); +// _test("bech32", bech32Test); +// _test("wif", wifTest); +// _test("substrate scale", substrateScaleTest); +// _test("ss58", ss58Test); +// _test("bip38 ", bip38Test); +// _test("segwit Bech32 ", segwitBech32Test); +// _test("bch bech32", bchBech32Test); +// _test("base58 xmr", testBase58XMR); +// _test("base58", testBase58); +// _test("bip49", bip49Test); +// _test("bip44", bip44Test); +// _test("algorandMnemonic and derive address", algorandMnemonicAndAddressTest); +// _test("substrate derive", substrateDeriveTest); +// _test("monero mnemonic", moneroMnemonucTest); +// _test("monero", moneroTest); +// _test("electrum v2", electrumV2Test); +// _test("electrum v1", electrumV1Test); +// _test("electrum mnemonic", electrumMnemonicTest); +// _test("cardano shelly", cardanoShellyTest); +// _test("cardano mnemonic", cardanoMnemonicTest); +// _test("cardano cip1852", cip1852Test); +// _test("byron legacy", byronLegacyTest); +// _test("cardano icarus", cardanoIcarusTest); +// _test("cardano legacy", cardanoLegacyTest); +// _test("bip86", bip86Test); +// _test("bip84", bip84Test); +// _test("bip39", testBip39); +// _test("secp256k1", secpTest); +// _test("nist", nistTest); +// _test("ed25519-blake2b", edBlake2bTest); +// _test("ed25519-khalow", edKhalowTest); +// _test("ed25519", edTest); +// _test("schnorr", schnoorTestDerive); +// _test("vrf sigh", vrfSignTest); +// _test("schnorrkel keys", schnoorKeyTest); +// _test("schnorrkel-sign", testSchnoor); +// _test("ecdsa", testECDSA); +// _test("eddsa", testEDDSa); +// _test("sha1", testSha1); +// _test("ripemd", testRipemd); +// _test("md5", md5Test); +// _test("md4", md4Test); +// _test("keccack", testKecc); +// _test("hmac", testHmac); +// _test("crc", crcTest); +// _test("chacha-poly1305", chachaTest); +// _test("aes", testAes); +// _test("blake2b", blake2bTest); +// _test("sha256", testSha256); +// _test("sha512", testSha512); +// _test("sha3", testSha3); +// _test("sha512/256", testSha512256); +// _test("modemCrc", testModemCrc); +// _test("shake digest", testShakeDigest); +// _test("cbor test", cborTest); +// _web(); +// final DateTime end = DateTime.now(); +// print("end: ${end.difference(start).inMilliseconds}"); +// } -void _encodeDecodeAddrTest() { - _test("zil Address", zilAddressTest); - _test("xtz Address", xtzAddressTest); - _test("xrp Address", xrpAddressTest); - _test("xmr Address", xmrAddressTest); - _test("xlm Address", xlmAddressTest); - _test("trx Address", trxAddressTest); - _test("substrate Address", substrateAddressTest); - _test("sol Address", solAddressTest); - _test("p2wpkh Address", p2wpkhAddressTest); - _test("p2tr Address", p2trAddressTest); - _test("p2sh Address", p2shAddressTest); - _test("p2pkh Address", p2pkhAddressTest); - _test("one Address", oneAddressTest); - _test("okex Address", okexAddressTest); - _test("neo Address", neoAddressTest); - _test("near Address", nearAddressTest); - _test("nano Address", nanoAddressTest); - _test("injAddressTest", injAddressTest); - _test("icx Address", icxAddressTest); - _test("fil Address", filAddressTest); - _test("ethereum Address", ethereumAddressTest); - _test("ergo Address", ergoAddressTest); - _test("eos Address", eosAddrTest); - _test("egld Address", egldAddrTest); - _test("bchP2sh Address", bchP2shAddressTest); - _test("bchP2pkh Address", bchP2pkhTest); - _test("avax Address", avaxAddrTest); - _test("atom Address", atomAddressTest); - _test("aptos Address", aptosAddressTest); - _test("algo Address", algoAddressTest); - _test("ada Shelly Address", adaShellyAddrTest); -} +// void _encodeDecodeAddrTest() { +// _test("zil Address", zilAddressTest); +// _test("xtz Address", xtzAddressTest); +// _test("xrp Address", xrpAddressTest); +// _test("xmr Address", xmrAddressTest); +// _test("xlm Address", xlmAddressTest); +// _test("trx Address", trxAddressTest); +// _test("substrate Address", substrateAddressTest); +// _test("sol Address", solAddressTest); +// _test("p2wpkh Address", p2wpkhAddressTest); +// _test("p2tr Address", p2trAddressTest); +// _test("p2sh Address", p2shAddressTest); +// _test("p2pkh Address", p2pkhAddressTest); +// _test("one Address", oneAddressTest); +// _test("okex Address", okexAddressTest); +// _test("neo Address", neoAddressTest); +// _test("near Address", nearAddressTest); +// _test("nano Address", nanoAddressTest); +// _test("injAddressTest", injAddressTest); +// _test("icx Address", icxAddressTest); +// _test("fil Address", filAddressTest); +// _test("ethereum Address", ethereumAddressTest); +// _test("ergo Address", ergoAddressTest); +// _test("eos Address", eosAddrTest); +// _test("egld Address", egldAddrTest); +// _test("bchP2sh Address", bchP2shAddressTest); +// _test("bchP2pkh Address", bchP2pkhTest); +// _test("avax Address", avaxAddrTest); +// _test("atom Address", atomAddressTest); +// _test("aptos Address", aptosAddressTest); +// _test("algo Address", algoAddressTest); +// _test("ada Shelly Address", adaShellyAddrTest); +// } +void main() {} diff --git a/lib/bip/address/ada/ada_byron_addr.dart b/lib/bip/address/ada/ada_byron_addr.dart index 222b2b1..7a2663e 100644 --- a/lib/bip/address/ada/ada_byron_addr.dart +++ b/lib/bip/address/ada/ada_byron_addr.dart @@ -81,12 +81,6 @@ import 'network.dart'; /// - `redemption`: Represents the address type for redemption addresses. /// /// Each address type is associated with a unique integer value for identification. -/// -/// Example Usage: -/// ```dart -/// final addressType = ADAByronAddrTypes.publicKey; -/// print('Address Type: $addressType'); // Output: Address Type: ADAByronAddrTypes.publicKey -/// ``` class ADAByronAddrTypes { /// Represents the address type for public keys. static const ADAByronAddrTypes publicKey = diff --git a/lib/bip/address/xmr_addr.dart b/lib/bip/address/xmr_addr.dart index b17f701..53b6819 100644 --- a/lib/bip/address/xmr_addr.dart +++ b/lib/bip/address/xmr_addr.dart @@ -58,6 +58,7 @@ import 'package:blockchain_utils/bip/address/decoder.dart'; import 'package:blockchain_utils/bip/address/encoder.dart'; import 'package:blockchain_utils/bip/ecc/keys/ed25519_keys.dart'; import 'package:blockchain_utils/crypto/quick_crypto.dart'; +import 'package:blockchain_utils/helper/helper.dart'; import 'package:blockchain_utils/utils/utils.dart'; import 'exception/exception.dart'; import 'addr_key_validator.dart'; @@ -69,6 +70,57 @@ class XmrAddrConst { /// The length of payment ID bytes used in XMR addresses. static const int paymentIdByteLen = 8; + + static const int prefixLength = 1; +} + +class XmrAddressType { + final String name; + final List prefixes; + const XmrAddressType._({required this.name, required this.prefixes}); + static const XmrAddressType primaryAddress = + XmrAddressType._(name: "Primary", prefixes: [0x12, 0x18, 0x35]); + static const XmrAddressType integrated = + XmrAddressType._(name: "Integrated", prefixes: [0x19, 0x36, 0x13]); + static const XmrAddressType subaddress = + XmrAddressType._(name: "Subaddress", prefixes: [0x24, 0x3F, 0x2A]); + static const List values = [ + primaryAddress, + integrated, + subaddress + ]; + static XmrAddressType fromPrefix(int? prefix) { + return values.firstWhere( + (e) => e.prefixes.contains(prefix), + orElse: () => throw AddressConverterException( + "Invalid monero address prefix.", + details: {"prefix": prefix}), + ); + } + + @override + String toString() { + return "XmrAddressType.$name"; + } +} + +class XmrAddressDecodeResult { + final List publicViewKey; + final List publicSpendKey; + final List? paymentId; + final int netVersion; + final XmrAddressType type; + XmrAddressDecodeResult( + {required List publicViewKey, + required List publicSpendKey, + List? paymentId, + required this.netVersion, + required this.type}) + : publicViewKey = publicViewKey.asImmutableBytes, + publicSpendKey = publicSpendKey.asImmutableBytes, + paymentId = paymentId?.asImmutableBytes; + List get keyBytes => + List.from([...publicSpendKey, ...publicViewKey]); } /// Class container for Monero address utility functions. @@ -79,10 +131,9 @@ class _XmrAddrUtils { .sublist(0, XmrAddrConst.checksumByteLen); } - /// Decode bytes from a Monero address to bytes. - static List decodeAddr( - String addr, - List netVerBytes, { + static XmrAddressDecodeResult decodeAddress( + String addr, { + List? netVerBytes, List? paymentIdBytes, }) { final addrDecBytes = Base58XmrDecoder.decode(addr); @@ -96,81 +147,122 @@ class _XmrAddrUtils { /// Validate and remove prefix final payloadBytesWithoutPrefix = - AddrDecUtils.validateAndRemovePrefixBytes(payloadBytes, netVerBytes); - - try { - /// Validate length without payment ID - AddrDecUtils.validateBytesLength( - payloadBytesWithoutPrefix, - Ed25519KeysConst.pubKeyByteLen * 2, - ); - } catch (ex) { - /// Validate length with payment ID - AddrDecUtils.validateBytesLength( - payloadBytesWithoutPrefix, - (Ed25519KeysConst.pubKeyByteLen * 2) + XmrAddrConst.paymentIdByteLen, - ); - - /// Check payment ID - if (paymentIdBytes == null || - paymentIdBytes.length != XmrAddrConst.paymentIdByteLen) { - throw const AddressConverterException('Invalid payment ID'); - } + payloadBytes.sublist(XmrAddrConst.prefixLength); - final paymentIdGotBytes = payloadBytesWithoutPrefix.sublist( - payloadBytesWithoutPrefix.length - XmrAddrConst.paymentIdByteLen); - if (!BytesUtils.bytesEqual(paymentIdBytes, paymentIdGotBytes)) { - throw AddressConverterException( - 'Invalid payment ID (expected ${BytesUtils.toHexString(paymentIdBytes)}, ' - 'got ${BytesUtils.toHexString(paymentIdGotBytes)})'); + final int netVersion = payloadBytes[0]; + if (netVerBytes != null) { + if (netVerBytes.length != XmrAddrConst.prefixLength || + netVerBytes[0] != netVersion) { + throw AddressConverterException("Invalid address prefix.", + details: {"excepted": netVersion, "network_version": netVersion}); } } + // AddrDecUtils.validateAndRemovePrefixBytes(payloadBytes, netVerBytes); + + final addrType = XmrAddressType.fromPrefix(netVersion); + + List? paymentBytes; + switch (addrType) { + case XmrAddressType.integrated: + + /// Validate length with payment ID + AddrDecUtils.validateBytesLength( + payloadBytesWithoutPrefix, + (Ed25519KeysConst.pubKeyByteLen * 2) + + XmrAddrConst.paymentIdByteLen); + + /// Check payment ID + if (paymentIdBytes != null && + paymentIdBytes.length != XmrAddrConst.paymentIdByteLen) { + throw const AddressConverterException('Invalid provided payment ID.'); + } + + paymentBytes = payloadBytesWithoutPrefix.sublist( + payloadBytesWithoutPrefix.length - XmrAddrConst.paymentIdByteLen); + + if (paymentIdBytes != null && + !BytesUtils.bytesEqual(paymentIdBytes, paymentBytes)) { + throw AddressConverterException('Invalid payment ID.', details: { + "excepted": BytesUtils.toHexString(paymentIdBytes), + "payment_id": BytesUtils.toHexString(paymentBytes) + }); + } + break; + default: + AddrDecUtils.validateBytesLength( + payloadBytesWithoutPrefix, Ed25519KeysConst.pubKeyByteLen * 2); + if (paymentIdBytes != null) { + throw AddressConverterException('Invalid address type.', details: { + "excepted": XmrAddressType.integrated.toString(), + "type": addrType.toString() + }); + } + break; + } + /// Validate public spend key final pubSpendKeyBytes = payloadBytesWithoutPrefix.sublist(0, Ed25519KeysConst.pubKeyByteLen); - // AddrDecUtils.validatePubKey(pubSpendKeyBytes, Ed25519MoneroPublicKey); + // AddrDecUtils.validatePubKey(pubSpendKeyBytes, MoneroPublicKey); // Validate public view key final pubViewKeyBytes = payloadBytesWithoutPrefix.sublist( - Ed25519KeysConst.pubKeyByteLen, - Ed25519KeysConst.pubKeyByteLen * 2, - ); - // AddrDecUtils.validatePubKey(pubViewKeyBytes, Ed25519MoneroPublicKey); - - return List.from(pubSpendKeyBytes + pubViewKeyBytes); + Ed25519KeysConst.pubKeyByteLen, Ed25519KeysConst.pubKeyByteLen * 2); + return XmrAddressDecodeResult( + publicViewKey: pubViewKeyBytes, + publicSpendKey: pubSpendKeyBytes, + netVersion: netVersion, + type: addrType, + paymentId: paymentBytes); } static String encodeKey( - List pubSkey, - List pubVkey, - List netVerBytes, { - List? paymentIdBytes, - }) { + List pubSkey, List pubVkey, List netVerBytes, + {List? paymentIdBytes}) { if (paymentIdBytes != null && paymentIdBytes.length != XmrAddrConst.paymentIdByteLen) { throw const AddressConverterException('Invalid payment ID length'); } - - final paymentIdBytesSafe = paymentIdBytes ?? List.from([]); + if (netVerBytes.length != XmrAddrConst.prefixLength) { + throw const AddressConverterException('Invalid network version prefix.'); + } + final type = XmrAddressType.fromPrefix(netVerBytes.first); + if (type == XmrAddressType.integrated) { + if (paymentIdBytes == null) { + throw const AddressConverterException( + 'A payment ID is required for an integrated address.'); + } + } else { + if (paymentIdBytes != null) { + throw const AddressConverterException( + 'A payment ID is required only for integrated addresses.'); + } + } final pubSpendKeyObj = AddrKeyValidator.validateAndGetEd25519MoneroKey(pubSkey); final pubViewKeyObj = AddrKeyValidator.validateAndGetEd25519MoneroKey(pubVkey); - final payloadBytes = List.from( - netVerBytes + - pubSpendKeyObj.compressed + - pubViewKeyObj.compressed + - paymentIdBytesSafe, - ); + final payloadBytes = List.unmodifiable([ + ...netVerBytes, + ...pubSpendKeyObj.compressed, + ...pubViewKeyObj.compressed, + ...paymentIdBytes ?? [] + ]); + final checksum = computeChecksum(payloadBytes); - return Base58XmrEncoder.encode( - List.from(payloadBytes + computeChecksum(payloadBytes))); + return Base58XmrEncoder.encode([...payloadBytes, ...checksum]); } } /// Implementation of the [BlockchainAddressDecoder] for Monero (XMR) blockchain addresses. class XmrAddrDecoder implements BlockchainAddressDecoder { + XmrAddressDecodeResult decode(String addr, + {List? netVerBytes, List? paymentId}) { + return _XmrAddrUtils.decodeAddress(addr, + netVerBytes: netVerBytes, paymentIdBytes: paymentId); + } + /// Decodes a Monero (XMR) address. /// /// Given an XMR address and optional decoding parameters specified in [kwargs], @@ -187,14 +279,24 @@ class XmrAddrDecoder implements BlockchainAddressDecoder { /// A List containing the decoded address data. @override List decodeAddr(String addr, [Map kwargs = const {}]) { - AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); - final List netVerBytes = kwargs["net_ver"]; - return _XmrAddrUtils.decodeAddr(addr, netVerBytes); + final List netVerBytes = + AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); + final decodeAddr = decode(addr, netVerBytes: netVerBytes); + return decodeAddr.keyBytes; } } /// Implementation of the [BlockchainAddressEncoder] for Monero (XMR) blockchain addresses. class XmrAddrEncoder extends BlockchainAddressEncoder { + String encode( + {required List pubSpendKey, + required List pubViewKey, + required List netVarBytes, + List? paymentId}) { + return _XmrAddrUtils.encodeKey(pubSpendKey, pubViewKey, netVarBytes, + paymentIdBytes: paymentId); + } + /// Encodes a Monero (XMR) public key and view key as an XMR address. /// /// Given a public key, view key, and optional encoding parameters specified in [kwargs], @@ -211,11 +313,12 @@ class XmrAddrEncoder extends BlockchainAddressEncoder { /// A string representing the encoded XMR address. @override String encodeKey(List pubKey, [Map kwargs = const {}]) { - AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); - AddrKeyValidator.validateAddressArgs>(kwargs, "pub_vkey"); - final List netVerBytes = kwargs["net_ver"]; - final List pubVKey = kwargs["pub_vkey"]; - return _XmrAddrUtils.encodeKey(pubKey, pubVKey, netVerBytes); + final List netVerBytes = + AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); + final List pubVKey = + AddrKeyValidator.validateAddressArgs>(kwargs, "pub_vkey"); + return encode( + pubSpendKey: pubKey, pubViewKey: pubVKey, netVarBytes: netVerBytes); } } @@ -237,12 +340,13 @@ class XmrIntegratedAddrDecoder extends BlockchainAddressDecoder { /// A List representing the decoded public key and view key components. @override List decodeAddr(String addr, [Map kwargs = const {}]) { - AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); - AddrKeyValidator.validateAddressArgs>(kwargs, "payment_id"); - final List netVerBytes = kwargs["net_ver"]; - final List paymentId = kwargs["payment_id"]; - return _XmrAddrUtils.decodeAddr(addr, netVerBytes, - paymentIdBytes: paymentId); + final List netVerBytes = + AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); + final List paymentId = + AddrKeyValidator.validateAddressArgs>(kwargs, "payment_id"); + final decodeAddr = XmrAddrDecoder() + .decode(addr, netVerBytes: netVerBytes, paymentId: paymentId); + return decodeAddr.keyBytes; } } @@ -264,13 +368,16 @@ class XmrIntegratedAddrEncoder implements BlockchainAddressEncoder { /// A string representing the encoded XMR integrated address. @override String encodeKey(List pubKey, [Map kwargs = const {}]) { - AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); - AddrKeyValidator.validateAddressArgs>(kwargs, "payment_id"); - AddrKeyValidator.validateAddressArgs>(kwargs, "pub_vkey"); - final List netVerBytes = kwargs["net_ver"]; - final List paymentId = kwargs["payment_id"]; - final List pubVKey = kwargs["pub_vkey"]; - return _XmrAddrUtils.encodeKey(pubKey, pubVKey, netVerBytes, - paymentIdBytes: paymentId); + final List netVerBytes = + AddrKeyValidator.validateAddressArgs>(kwargs, "net_ver"); + final List paymentId = + AddrKeyValidator.validateAddressArgs>(kwargs, "payment_id"); + final List pubVKey = + AddrKeyValidator.validateAddressArgs>(kwargs, "pub_vkey"); + return XmrAddrEncoder().encode( + pubSpendKey: pubKey, + pubViewKey: pubVKey, + netVarBytes: netVerBytes, + paymentId: paymentId); } } diff --git a/lib/bip/bip/bip32/bip32_keys.dart b/lib/bip/bip/bip32/bip32_keys.dart index 194f2a4..c572468 100644 --- a/lib/bip/bip/bip32/bip32_keys.dart +++ b/lib/bip/bip/bip32/bip32_keys.dart @@ -108,7 +108,7 @@ class Bip32PrivateKey extends Bip32KeyBase { this.privKey, Bip32KeyData keyData, Bip32KeyNetVersions keyNetVer, - ) : super(keyData, keyNetVer, privKey.curveType); + ) : super(keyData, keyNetVer, privKey.curve); /// Gets the underlying private key object. IPrivateKey keyObject() { diff --git a/lib/bip/ecc/keys/ed25519_blake2b_keys.dart b/lib/bip/ecc/keys/ed25519_blake2b_keys.dart index 3b9e908..e84e75c 100644 --- a/lib/bip/ecc/keys/ed25519_blake2b_keys.dart +++ b/lib/bip/ecc/keys/ed25519_blake2b_keys.dart @@ -52,16 +52,16 @@ OF THE POSSIBILITY OF SUCH DAMAGE. */ -import 'package:blockchain_utils/utils/utils.dart'; import 'package:blockchain_utils/bip/ecc/keys/ed25519_keys.dart'; import 'package:blockchain_utils/bip/ecc/keys/i_keys.dart'; import 'package:blockchain_utils/bip/ecc/curve/elliptic_curve_types.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/privatekey.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/publickey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/privatekey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/publickey.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/crypto/crypto/hash/hash.dart'; import 'package:blockchain_utils/exception/exception.dart'; +import 'package:blockchain_utils/utils/utils.dart'; /// Represents an Ed25519 public key with Blake2b hashing, implementing the IPublicKey interface. class Ed25519Blake2bPublicKey implements IPublicKey { @@ -144,11 +144,12 @@ class Ed25519Blake2bPublicKey implements IPublicKey { @override operator ==(other) { if (other is! Ed25519Blake2bPublicKey) return false; + if (identical(this, other)) return true; return _publicKey == other._publicKey && curve == other.curve; } @override - int get hashCode => _publicKey.hashCode ^ curve.hashCode; + int get hashCode => HashCodeGenerator.generateHashCode([_publicKey, curve]); } /// Represents an Ed25519 private key with Blake2b hashing, implementing the IPrivateKey interface. @@ -173,7 +174,7 @@ class Ed25519Blake2bPrivateKey implements IPrivateKey { /// curve type @override - EllipticCurveTypes get curveType { + EllipticCurveTypes get curve { return EllipticCurveTypes.ed25519Blake2b; } @@ -213,9 +214,11 @@ class Ed25519Blake2bPrivateKey implements IPrivateKey { @override operator ==(other) { if (other is! Ed25519Blake2bPrivateKey) return false; - return _privateKey == other._privateKey && curveType == other.curveType; + if (identical(this, other)) return true; + return _privateKey == other._privateKey && curve == other.curve; } @override - int get hashCode => _privateKey.hashCode ^ curveType.hashCode; + int get hashCode => + HashCodeGenerator.generateHashCode([_privateKey, curve]); } diff --git a/lib/bip/ecc/keys/ed25519_keys.dart b/lib/bip/ecc/keys/ed25519_keys.dart index c4725ce..ee9d4f1 100644 --- a/lib/bip/ecc/keys/ed25519_keys.dart +++ b/lib/bip/ecc/keys/ed25519_keys.dart @@ -1,8 +1,8 @@ import 'package:blockchain_utils/utils/utils.dart'; import 'package:blockchain_utils/bip/ecc/curve/elliptic_curve_types.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/privatekey.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/publickey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/privatekey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/publickey.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/crypto/crypto/hash/hash.dart'; import 'package:blockchain_utils/exception/exception.dart'; @@ -108,11 +108,12 @@ class Ed25519PublicKey implements IPublicKey { @override operator ==(other) { if (other is! Ed25519PublicKey) return false; + if (identical(this, other)) return true; return _publicKey == other._publicKey && curve == other.curve; } @override - int get hashCode => _publicKey.hashCode ^ curve.hashCode; + int get hashCode => HashCodeGenerator.generateHashCode([_publicKey, curve]); } /// A class representing an Ed25519 private key that implements the IPrivateKey interface. @@ -136,7 +137,7 @@ class Ed25519PrivateKey implements IPrivateKey { /// curve type @override - EllipticCurveTypes get curveType { + EllipticCurveTypes get curve { return EllipticCurveTypes.ed25519; } @@ -177,9 +178,11 @@ class Ed25519PrivateKey implements IPrivateKey { @override operator ==(other) { if (other is! Ed25519PrivateKey) return false; - return _privateKey == other._privateKey && curveType == other.curveType; + if (identical(this, other)) return true; + return _privateKey == other._privateKey && curve == other.curve; } @override - int get hashCode => _privateKey.hashCode ^ curveType.hashCode; + int get hashCode => + HashCodeGenerator.generateHashCode([_privateKey, curve]); } diff --git a/lib/bip/ecc/keys/ed25519_kholaw_keys.dart b/lib/bip/ecc/keys/ed25519_kholaw_keys.dart index 2115249..ec9ed6d 100644 --- a/lib/bip/ecc/keys/ed25519_kholaw_keys.dart +++ b/lib/bip/ecc/keys/ed25519_kholaw_keys.dart @@ -3,8 +3,8 @@ import 'package:blockchain_utils/bip/ecc/keys/i_keys.dart'; import 'package:blockchain_utils/bip/ecc/curve/elliptic_curve_types.dart'; import 'package:blockchain_utils/bip/ecc/keys/ed25519_keys.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/privatekey.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/publickey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/privatekey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/publickey.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/exception/exception.dart'; @@ -96,11 +96,12 @@ class Ed25519KholawPublicKey implements IPublicKey { @override operator ==(other) { if (other is! Ed25519KholawPublicKey) return false; + if (identical(this, other)) return true; return _publicKey == other._publicKey && curve == other.curve; } @override - int get hashCode => _publicKey.hashCode ^ curve.hashCode; + int get hashCode => HashCodeGenerator.generateHashCode([_publicKey, curve]); } /// A class representing an Ed25519-Kholaw private key that implements the IPrivateKey interface. @@ -138,7 +139,7 @@ class Ed25519KholawPrivateKey implements IPrivateKey { /// curve type @override - EllipticCurveTypes get curveType { + EllipticCurveTypes get curve { return EllipticCurveTypes.ed25519Kholaw; } @@ -168,9 +169,11 @@ class Ed25519KholawPrivateKey implements IPrivateKey { @override operator ==(other) { if (other is! Ed25519KholawPrivateKey) return false; - return _privateKey == other._privateKey && curveType == other.curveType; + if (identical(other, this)) return true; + return _privateKey == other._privateKey && curve == other.curve; } @override - int get hashCode => _privateKey.hashCode ^ curveType.hashCode; + int get hashCode => + HashCodeGenerator.generateHashCode([_privateKey, curve]); } diff --git a/lib/bip/ecc/keys/ed25519_monero_keys.dart b/lib/bip/ecc/keys/ed25519_monero_keys.dart index 8b461f3..85b3922 100644 --- a/lib/bip/ecc/keys/ed25519_monero_keys.dart +++ b/lib/bip/ecc/keys/ed25519_monero_keys.dart @@ -52,35 +52,44 @@ OF THE POSSIBILITY OF SUCH DAMAGE. */ -import 'package:blockchain_utils/utils/utils.dart'; import 'package:blockchain_utils/bip/ecc/keys/i_keys.dart'; import 'package:blockchain_utils/bip/ecc/curve/elliptic_curve_types.dart'; import 'package:blockchain_utils/bip/ecc/keys/ed25519_keys.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/privatekey.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/publickey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/privatekey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/publickey.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/exception/exception.dart'; +import 'package:blockchain_utils/utils/utils.dart'; /// A class representing an Ed25519 Monero-compatible public key that implements the IPublicKey interface. -class Ed25519MoneroPublicKey implements IPublicKey { - final EDDSAPublicKey _publicKey; +class MoneroPublicKey implements IPublicKey { + final EDDSAPublicKey publicKey; - /// Private constructor for creating an Ed25519MoneroPublicKey instance from an EDDSAPublicKey. - Ed25519MoneroPublicKey._(this._publicKey); + /// Private constructor for creating an MoneroPublicKey instance from an EDDSAPublicKey. + MoneroPublicKey._(this.publicKey); - /// Factory method for creating an Ed25519MoneroPublicKey from a byte array. - factory Ed25519MoneroPublicKey.fromBytes(List keyBytes) { - return Ed25519MoneroPublicKey._( - EDDSAPublicKey(Curves.generatorED25519, keyBytes)); + /// Factory method for creating an MoneroPublicKey from a byte array. + factory MoneroPublicKey.fromBytes(List keyBytes) { + if (keyBytes.length == + Ed25519KeysConst.pubKeyByteLen + Ed25519KeysConst.pubKeyPrefix.length) { + keyBytes = keyBytes.sublist(Ed25519KeysConst.pubKeyPrefix.length); + } + return MoneroPublicKey._(EDDSAPublicKey(Curves.generatorED25519, keyBytes)); } - /// Factory method for creating an Ed25519MoneroPublicKey from an EDPoint. - factory Ed25519MoneroPublicKey.fromPoint(EDPoint point) { - return Ed25519MoneroPublicKey._( - EDDSAPublicKey.fromPoint(Curves.generatorED25519, point)); + /// Factory method for creating an MoneroPublicKey from a hex. + factory MoneroPublicKey.fromHex(String keyHex) { + return MoneroPublicKey.fromBytes(BytesUtils.fromHexString(keyHex)); } + /// Factory method for creating an MoneroPublicKey from an EDPoint. + MoneroPublicKey.fromPoint(EDPoint point) + : publicKey = EDDSAPublicKey.fromPoint(Curves.generatorED25519, point); + + /// immutable key + List get key => publicKey.key; + /// curve type @override EllipticCurveTypes get curve { @@ -101,20 +110,19 @@ class Ed25519MoneroPublicKey implements IPublicKey { /// check if bytes is valid for this key static bool isValidBytes(List keyBytes) { - return Ed25519MoneroPrivateKey.isValidBytes(keyBytes); + return MoneroPrivateKey.isValidBytes(keyBytes); } /// accsess to public key point @override EDPoint get point { - return _publicKey.point; + return publicKey.point; } /// public key compressed bytes @override List get compressed { - return List.from( - [...Ed25519KeysConst.pubKeyPrefix, ..._publicKey.point.toBytes()]); + return publicKey.point.toBytes(); } /// public key uncompressed bytes @@ -126,7 +134,7 @@ class Ed25519MoneroPublicKey implements IPublicKey { @override String toHex( {bool withPrefix = true, bool lowerCase = true, String? prefix = ""}) { - List key = _publicKey.point.toBytes(); + List key = publicKey.point.toBytes(); if (withPrefix) { key = compressed; } @@ -135,43 +143,52 @@ class Ed25519MoneroPublicKey implements IPublicKey { @override operator ==(other) { - if (other is! Ed25519MoneroPublicKey) return false; - return _publicKey == other._publicKey && curve == other.curve; + if (other is! MoneroPublicKey) return false; + if (identical(this, other)) return true; + return publicKey == other.publicKey && curve == other.curve; } @override - int get hashCode => _publicKey.hashCode ^ curve.hashCode; + int get hashCode => HashCodeGenerator.generateHashCode([publicKey, curve]); } /// A class representing an Ed25519 Monero-compatible private key that implements the IPrivateKey interface. -class Ed25519MoneroPrivateKey implements IPrivateKey { - final EDDSAPrivateKey _privateKey; +class MoneroPrivateKey implements IPrivateKey { + final EDDSAPrivateKey privateKey; - /// Private constructor for creating an Ed25519MoneroPrivateKey instance from an EDDSAPrivateKey. - Ed25519MoneroPrivateKey._(this._privateKey); + /// Private constructor for creating an MoneroPrivateKey instance from an EDDSAPrivateKey. + MoneroPrivateKey._(this.privateKey); - /// Factory method for creating an Ed25519MoneroPrivateKey from a byte array. + /// Factory method for creating an MoneroPrivateKey from a byte array. /// It checks the length of the provided keyBytes to ensure it matches the expected length. /// Then, it initializes an EdDSA private key using the Ed25519 generator and the specified keyBytes. - factory Ed25519MoneroPrivateKey.fromBytes(List keyBytes) { + factory MoneroPrivateKey.fromBytes(List keyBytes) { if (keyBytes.length != Ed25519KeysConst.privKeyByteLen) { throw const ArgumentException("invalid private key length"); } final gn = Curves.generatorED25519; final prv = EDDSAPrivateKey.fromKhalow(gn, keyBytes); - return Ed25519MoneroPrivateKey._(prv); + return MoneroPrivateKey._(prv); } + /// Factory method for creating an MoneroPrivateKey from a hex. + factory MoneroPrivateKey.fromHex(String keyHex) { + return MoneroPrivateKey.fromBytes(BytesUtils.fromHexString(keyHex)); + } + + /// imutable key + List get key => privateKey.key; + /// curve type @override - EllipticCurveTypes get curveType { + EllipticCurveTypes get curve { return EllipticCurveTypes.ed25519Monero; } /// check if bytes is valid for this key static bool isValidBytes(List keyBytes) { try { - Ed25519MoneroPrivateKey.fromBytes(keyBytes); + MoneroPrivateKey.fromBytes(keyBytes); return true; // ignore: empty_catches @@ -187,14 +204,14 @@ class Ed25519MoneroPrivateKey implements IPrivateKey { /// accsess to public key @override - IPublicKey get publicKey { - return Ed25519MoneroPublicKey._(_privateKey.publicKey); + MoneroPublicKey get publicKey { + return MoneroPublicKey._(privateKey.publicKey); } /// private key raw bytes @override List get raw { - return _privateKey.privateKey; + return privateKey.privateKey; } @override @@ -204,10 +221,11 @@ class Ed25519MoneroPrivateKey implements IPrivateKey { @override operator ==(other) { - if (other is! Ed25519MoneroPrivateKey) return false; - return _privateKey == other._privateKey && curveType == other.curveType; + if (other is! MoneroPrivateKey) return false; + if (identical(this, other)) return true; + return privateKey == other.privateKey && curve == other.curve; } @override - int get hashCode => _privateKey.hashCode ^ curveType.hashCode; + int get hashCode => HashCodeGenerator.generateHashCode([privateKey, curve]); } diff --git a/lib/bip/ecc/keys/i_keys.dart b/lib/bip/ecc/keys/i_keys.dart index 1cf29ec..77d9bc6 100644 --- a/lib/bip/ecc/keys/i_keys.dart +++ b/lib/bip/ecc/keys/i_keys.dart @@ -1,10 +1,10 @@ import 'package:blockchain_utils/bip/ecc/keys/ed25519_keys.dart'; import 'package:blockchain_utils/bip/ecc/keys/ed25519_blake2b_keys.dart'; import 'package:blockchain_utils/bip/ecc/keys/ed25519_kholaw_keys.dart'; +import 'package:blockchain_utils/bip/ecc/keys/ed25519_monero_keys.dart'; import 'package:blockchain_utils/bip/ecc/keys/nist256p1_keys.dart'; import 'package:blockchain_utils/bip/ecc/keys/secp256k1_keys_ecdsa.dart'; import 'package:blockchain_utils/bip/ecc/keys/sr25519_keys.dart'; -import 'package:blockchain_utils/bip/monero/monero_keys.dart'; import 'package:blockchain_utils/bip/ecc/curve/elliptic_curve_types.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/base.dart'; import 'package:blockchain_utils/utils/binary/utils.dart'; @@ -79,7 +79,7 @@ abstract class IPublicKey { /// An abstract class representing a generic private key interface for different elliptic curve types. abstract class IPrivateKey { /// Get the elliptic curve type associated with the private key. - EllipticCurveTypes get curveType; + EllipticCurveTypes get curve; /// Factory method for creating an IPrivateKey instance from a byte array and an elliptic curve type. factory IPrivateKey.fromBytes(List keyBytes, EllipticCurveTypes type) { @@ -92,8 +92,11 @@ abstract class IPrivateKey { return Ed25519KholawPrivateKey.fromBytes(keyBytes); case EllipticCurveTypes.ed25519Blake2b: return Ed25519Blake2bPrivateKey.fromBytes(keyBytes); + case EllipticCurveTypes.ed25519Monero: + return MoneroPrivateKey.fromBytes(keyBytes); case EllipticCurveTypes.sr25519: return Sr25519PrivateKey.fromBytes(keyBytes); + default: } return Secp256k1PrivateKeyEcdsa.fromBytes(keyBytes); @@ -123,6 +126,8 @@ abstract class IPrivateKey { return Ed25519KholawPrivateKey.isValidBytes(keyBytes); case EllipticCurveTypes.ed25519Blake2b: return Ed25519Blake2bPrivateKey.isValidBytes(keyBytes); + case EllipticCurveTypes.ed25519Monero: + return MoneroPrivateKey.isValidBytes(keyBytes); case EllipticCurveTypes.sr25519: return Sr25519PrivateKey.isValidBytes(keyBytes); default: diff --git a/lib/bip/ecc/keys/nist256p1_keys.dart b/lib/bip/ecc/keys/nist256p1_keys.dart index 839a180..edff52c 100644 --- a/lib/bip/ecc/keys/nist256p1_keys.dart +++ b/lib/bip/ecc/keys/nist256p1_keys.dart @@ -154,7 +154,7 @@ class Nist256p1PrivateKey implements IPrivateKey { /// curve type. @override - EllipticCurveTypes get curveType { + EllipticCurveTypes get curve { return EllipticCurveTypes.nist256p1; } @@ -194,9 +194,9 @@ class Nist256p1PrivateKey implements IPrivateKey { @override operator ==(other) { if (other is! Nist256p1PrivateKey) return false; - return privateKey == other.privateKey && curveType == other.curveType; + return privateKey == other.privateKey && curve == other.curve; } @override - int get hashCode => privateKey.hashCode ^ curveType.hashCode; + int get hashCode => privateKey.hashCode ^ curve.hashCode; } diff --git a/lib/bip/ecc/keys/secp256k1_keys_ecdsa.dart b/lib/bip/ecc/keys/secp256k1_keys_ecdsa.dart index 7317630..f4ef1a4 100644 --- a/lib/bip/ecc/keys/secp256k1_keys_ecdsa.dart +++ b/lib/bip/ecc/keys/secp256k1_keys_ecdsa.dart @@ -101,7 +101,7 @@ class Secp256k1PrivateKeyEcdsa implements IPrivateKey { /// curve type @override - EllipticCurveTypes get curveType { + EllipticCurveTypes get curve { return EllipticCurveTypes.secp256k1; } @@ -141,9 +141,9 @@ class Secp256k1PrivateKeyEcdsa implements IPrivateKey { @override operator ==(other) { if (other is! Secp256k1PrivateKeyEcdsa) return false; - return privateKey == other.privateKey && curveType == other.curveType; + return privateKey == other.privateKey && curve == other.curve; } @override - int get hashCode => privateKey.hashCode ^ curveType.hashCode; + int get hashCode => privateKey.hashCode ^ curve.hashCode; } diff --git a/lib/bip/ecc/keys/sr25519_keys.dart b/lib/bip/ecc/keys/sr25519_keys.dart index 3e18ebb..bfd7d4b 100644 --- a/lib/bip/ecc/keys/sr25519_keys.dart +++ b/lib/bip/ecc/keys/sr25519_keys.dart @@ -102,7 +102,7 @@ class Sr25519PrivateKey implements IPrivateKey { /// curve type. @override - EllipticCurveTypes get curveType { + EllipticCurveTypes get curve { return EllipticCurveTypes.sr25519; } @@ -142,9 +142,9 @@ class Sr25519PrivateKey implements IPrivateKey { @override operator ==(other) { if (other is! Sr25519PrivateKey) return false; - return secretKey == other.secretKey && curveType == other.curveType; + return secretKey == other.secretKey && curve == other.curve; } @override - int get hashCode => secretKey.hashCode ^ curveType.hashCode; + int get hashCode => secretKey.hashCode ^ curve.hashCode; } diff --git a/lib/bip/monero/monero.dart b/lib/bip/monero/monero.dart index e278891..217d003 100644 --- a/lib/bip/monero/monero.dart +++ b/lib/bip/monero/monero.dart @@ -20,8 +20,5 @@ export 'mnemonic/words_list/languages.dart'; /// Export statement for Monero base components, including address generation. export 'monero_base.dart'; -/// Export statement for Monero key management components. -export 'monero_keys.dart'; - /// Export statement for Monero subaddress components. export 'monero_subaddr.dart'; diff --git a/lib/bip/monero/monero_base.dart b/lib/bip/monero/monero_base.dart index 0a088b8..f87b563 100644 --- a/lib/bip/monero/monero_base.dart +++ b/lib/bip/monero/monero_base.dart @@ -1,15 +1,15 @@ import 'package:blockchain_utils/bip/address/xmr_addr.dart'; import 'package:blockchain_utils/bip/ecc/keys/ed25519_keys.dart'; +import 'package:blockchain_utils/bip/ecc/keys/ed25519_monero_keys.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/utils/ed25519_utils.dart'; import 'package:blockchain_utils/bip/monero/conf/monero_coin_conf.dart'; import 'package:blockchain_utils/bip/monero/conf/monero_coins.dart'; import 'package:blockchain_utils/bip/monero/monero_exc.dart'; -import 'package:blockchain_utils/bip/monero/monero_keys.dart'; import 'package:blockchain_utils/bip/monero/monero_subaddr.dart'; import 'package:blockchain_utils/crypto/quick_crypto.dart'; /// A class representing Monero cryptocurrency and its associated keys and configurations. -class Monero { +class MoneroAccount { /// Private spend key (optional) final MoneroPrivateKey? privSkey; @@ -29,7 +29,7 @@ class Monero { final MoneroSubaddress scubaddr; /// Private constructor for creating a Monero instance. - Monero.__( + MoneroAccount.__( {required this.coinConf, required this.privSkey, required this.privVkey, @@ -49,7 +49,7 @@ class Monero { /// If no public key is provided (pubKey is null), it generates the public keys from the private keys. /// /// Returns a Monero instance configured with the provided keys and coin type. - factory Monero._({ + factory MoneroAccount._({ required List privKey, List? pubKey, MoneroCoins coinType = MoneroCoins.moneroMainnet, @@ -59,7 +59,7 @@ class Monero { final mPrivVkey = _viewFromSpendKey(mPrivSkey); final mPubSkey = mPrivSkey.publicKey; final mPubVkey = mPrivVkey.publicKey; - return Monero.__( + return MoneroAccount.__( coinConf: coinType.conf, privSkey: mPrivSkey, privVkey: mPrivVkey, @@ -70,7 +70,7 @@ class Monero { final mPrivVkey = MoneroPrivateKey.fromBytes(privKey); final mPubSkey = MoneroPublicKey.fromBytes(pubKey); final mPubVkey = mPrivVkey.publicKey; - return Monero.__( + return MoneroAccount.__( coinConf: coinType.conf, privSkey: null, privVkey: mPrivVkey, @@ -79,17 +79,32 @@ class Monero { scubaddr: MoneroSubaddress(mPrivVkey, mPubSkey, mPubVkey)); } + factory MoneroAccount.multisig( + {required MoneroPrivateKey privVkey, + required MoneroPublicKey pubSkey, + required MoneroPrivateKey privSkey, + MoneroCoins coinType = MoneroCoins.moneroMainnet}) { + final mPubVkey = privVkey.publicKey; + return MoneroAccount.__( + coinConf: coinType.conf, + privSkey: privSkey, + privVkey: privVkey, + pubSkey: pubSkey, + pubVkey: mPubVkey, + scubaddr: MoneroSubaddress(privVkey, pubSkey, mPubVkey)); + } + /// Factory method to create a Monero instance from a seed. /// /// Given a [seedBytes] and an optional [coinType], this method constructs a Monero instance /// with the associated keys and configurations. - factory Monero.fromSeed(List seedBytes, + factory MoneroAccount.fromSeed(List seedBytes, {MoneroCoins coinType = MoneroCoins.moneroMainnet}) { List privSkeyBytes = seedBytes.length == Ed25519KeysConst.privKeyByteLen ? seedBytes : QuickCrypto.keccack256Hash(seedBytes); - return Monero.fromPrivateSpendKey(Ed25519Utils.scalarReduce(privSkeyBytes), + return MoneroAccount.fromPrivateSpendKey(Ed25519Utils.scalarReduce(privSkeyBytes), coinType: coinType); } @@ -97,9 +112,9 @@ class Monero { /// /// Given a [privKey] and an optional [coinType], this method constructs a Monero instance /// with the associated keys and configurations. - factory Monero.fromBip44PrivateKey(List privKey, + factory MoneroAccount.fromBip44PrivateKey(List privKey, {MoneroCoins coinType = MoneroCoins.moneroMainnet}) { - return Monero.fromPrivateSpendKey( + return MoneroAccount.fromPrivateSpendKey( Ed25519Utils.scalarReduce(QuickCrypto.keccack256Hash(privKey)), coinType: coinType); } @@ -108,18 +123,18 @@ class Monero { /// /// Given a [privSkey] and an optional [coinType], this method constructs a Monero instance /// with the associated keys and configurations. - factory Monero.fromPrivateSpendKey(List privSkey, + factory MoneroAccount.fromPrivateSpendKey(List privSkey, {MoneroCoins coinType = MoneroCoins.moneroMainnet}) { - return Monero._(privKey: privSkey, coinType: coinType); + return MoneroAccount._(privKey: privSkey, coinType: coinType); } /// Factory method to create a Monero instance from watch-only keys. /// /// Given a [privVkey], [pubSkey], and an optional [coinType], this method constructs a /// Monero instance with the associated keys and configurations. - factory Monero.fromWatchOnly(List privVkey, List pubSkey, + factory MoneroAccount.fromWatchOnly(List privVkey, List pubSkey, {MoneroCoins coinType = MoneroCoins.moneroMainnet}) { - return Monero._(privKey: privVkey, pubKey: pubSkey, coinType: coinType); + return MoneroAccount._(privKey: privVkey, pubKey: pubSkey, coinType: coinType); } /// Check if the Monero instance is watch-only (has no private spend key). @@ -175,7 +190,8 @@ class Monero { } /// Calculate and return the private view key from the private spend key. - static MoneroPrivateKey _viewFromSpendKey(MoneroPrivateKey privSkey) { + static MoneroPrivateKey _viewFromSpendKey( + MoneroPrivateKey privSkey) { List privVkeyBytes = Ed25519Utils.scalarReduce(QuickCrypto.keccack256Hash(privSkey.raw)); return MoneroPrivateKey.fromBytes(privVkeyBytes); diff --git a/lib/bip/monero/monero_keys.dart b/lib/bip/monero/monero_keys.dart deleted file mode 100644 index 98a31d5..0000000 --- a/lib/bip/monero/monero_keys.dart +++ /dev/null @@ -1,195 +0,0 @@ -import 'package:blockchain_utils/utils/utils.dart'; -import 'package:blockchain_utils/bip/ecc/keys/i_keys.dart'; -import 'package:blockchain_utils/bip/ecc/curve/elliptic_curve_types.dart'; -import 'package:blockchain_utils/bip/ecc/keys/ed25519_keys.dart'; -import 'package:blockchain_utils/bip/ecc/keys/ed25519_monero_keys.dart'; -import 'package:blockchain_utils/bip/monero/monero_exc.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/point/base.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; - -/// A class representing a Monero public key that implements the IPublicKey interface. -/// -/// This class is used to represent Monero public keys and provides methods for creating -/// them from byte data or Edwards points and validating their byte representation. -class MoneroPublicKey implements IPublicKey { - final IPublicKey pubKey; - - /// Private constructor for MoneroPublicKey. - /// - /// This constructor is used internally to create a MoneroPublicKey instance - /// from a given public key `pubKey`. - MoneroPublicKey._(this.pubKey); - - /// Factory method to create a MoneroPublicKey from its byte representation. - /// - /// Given a [List] `pubKey`, this method creates a new [MoneroPublicKey] instance - /// by invoking the private constructor [_keyFromBytes] with the provided byte data. - factory MoneroPublicKey.fromBytes(List pubKey) { - return MoneroPublicKey._(_keyFromBytes(pubKey)); - } - - /// Factory method to create a MoneroPublicKey from an Edwards point. - /// - /// This method creates a new [MoneroPublicKey] instance from an [EDPoint] - /// `point` by calling the private constructor [_keyFromPoint] with the given point. - factory MoneroPublicKey.fromPoint(EDPoint point) { - return MoneroPublicKey._(_keyFromPoint(point)); - } - - /// Static method to validate the byte representation of a Monero public key. - /// - /// This method checks the validity of a Monero public key's byte representation - /// by invoking the [isValidBytes] method from the [Ed25519MoneroPublicKey] class. - /// It returns `true` if the key bytes are valid and `false` otherwise. - static bool isValidBytes(List keyBytes) { - return Ed25519MoneroPublicKey.isValidBytes(keyBytes); - } - - /// public key compressed bytes. - @override - List get compressed { - return pubKey.point.toBytes(); - } - - /// public key uncompressed bytes. - @override - List get uncompressed { - return pubKey.uncompressed; - } - - /// Create a Monero public key from its byte representation. - /// - /// This method attempts to create a Monero public key from a byte representation - /// `keyBytes` by invoking the `fromBytes` method of [Ed25519MoneroPublicKey]. - /// If the byte representation is invalid, it throws a [MoneroKeyError] exception. - /// - /// Returns an implementation of the [IPublicKey] interface. - static IPublicKey _keyFromBytes(List keyBytes) { - try { - return Ed25519MoneroPublicKey.fromBytes(keyBytes); - } catch (ex) { - throw const MoneroKeyError('Invalid public key'); - } - } - - /// Create a Monero public key from an Edwards point. - /// - /// This method attempts to create a Monero public key from an [EDPoint] - /// `keyPoint` by invoking the `fromPoint` method of [Ed25519MoneroPublicKey]. - /// If the conversion is unsuccessful, it throws a [MoneroKeyError] exception. - /// - /// Returns an implementation of the [IPublicKey] interface. - static IPublicKey _keyFromPoint(EDPoint keyPoint) { - try { - return Ed25519MoneroPublicKey.fromPoint(keyPoint); - } catch (ex) { - throw const MoneroKeyError('Invalid key point'); - } - } - - /// public key compressed bytes length. - @override - int get length { - return Ed25519KeysConst.pubKeyByteLen; - } - - /// curve type. - @override - EllipticCurveTypes get curve { - return EllipticCurveTypes.ed25519Monero; - } - - /// public key uncompressed bytes length. - @override - int get uncompressedLength { - return length; - } - - /// public key point. - @override - AbstractPoint get point { - return pubKey.point; - } - - @override - String toHex( - {bool withPrefix = true, bool lowerCase = true, String? prefix = ""}) { - return BytesUtils.toHexString(compressed, - prefix: prefix, lowerCase: lowerCase); - } -} - -/// A class representing a Monero private key that implements the IPrivateKey interface. -/// -/// This class serves as a wrapper for a private key, implementing the [IPrivateKey] interface. -class MoneroPrivateKey implements IPrivateKey { - final IPrivateKey privKey; - - /// Private constructor for MoneroPrivateKey. - /// - /// This constructor is used internally to create a MoneroPrivateKey instance - /// from an existing private key `privKey`. - MoneroPrivateKey._(this.privKey); - - /// Factory method to create a MoneroPrivateKey from its byte representation. - /// - /// Given a [List] `keyBytes`, this method creates a new [MoneroPrivateKey] instance - /// by invoking the private constructor [_keyFromBytes] with the provided byte data - factory MoneroPrivateKey.fromBytes(List keyBytes) { - return MoneroPrivateKey._(_keyFromBytes(keyBytes)); - } - - /// Static method to validate the byte representation of a Monero public key. - /// - /// This method checks the validity of a Monero public key's byte representation - /// by invoking the [isValidBytes] method from the [Ed25519MoneroPublicKey] class. - /// It returns `true` if the key bytes are valid and `false` otherwise. - static bool isValidBytes(List keyBytes) { - return Ed25519MoneroPublicKey.isValidBytes(keyBytes); - } - - /// private key raw bytes. - @override - List get raw { - return privKey.raw; - } - - /// accsess to public key. - @override - MoneroPublicKey get publicKey { - return MoneroPublicKey._(privKey.publicKey); - } - - /// Create a Monero private key from its byte representation. - /// - /// This method attempts to create a Monero private key from a byte representation - /// `keyBytes` by invoking the `fromBytes` method of [Ed25519MoneroPrivateKey]. - /// If the byte representation is invalid or the conversion fails, it throws a - /// [MoneroKeyError] exception with the message 'Invalid private key.' - /// - /// Returns an implementation of the [IPrivateKey] interface. - static IPrivateKey _keyFromBytes(List keyBytes) { - try { - return Ed25519MoneroPrivateKey.fromBytes(keyBytes); - } catch (ex) { - throw const MoneroKeyError('Invalid private key'); - } - } - - /// curve type. - @override - EllipticCurveTypes get curveType { - return EllipticCurveTypes.ed25519Monero; - } - - /// private key bytes length. - @override - int get length { - return privKey.length; - } - - @override - String toHex({bool lowerCase = true, String? prefix = ""}) { - return BytesUtils.toHexString(raw, lowerCase: lowerCase, prefix: prefix); - } -} diff --git a/lib/bip/monero/monero_subaddr.dart b/lib/bip/monero/monero_subaddr.dart index 3e77692..c36bc80 100644 --- a/lib/bip/monero/monero_subaddr.dart +++ b/lib/bip/monero/monero_subaddr.dart @@ -1,12 +1,11 @@ import 'dart:typed_data'; +import 'package:blockchain_utils/bip/ecc/keys/ed25519_monero_keys.dart'; import 'package:blockchain_utils/exception/exception.dart'; import 'package:blockchain_utils/utils/utils.dart'; import 'package:blockchain_utils/bip/address/xmr_addr.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/utils/ed25519_utils.dart'; -import 'package:blockchain_utils/bip/monero/monero_keys.dart'; import 'package:blockchain_utils/crypto/quick_crypto.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; /// A class containing constants related to Monero subaddresses. class MoneroSubaddressConst { @@ -27,6 +26,20 @@ class MoneroSubaddressConst { static const subaddrIdxByteLen = 4; } +class MoneroComputeKey { + /// Public spend key + final MoneroPublicKey pubSKey; + + /// Public view key + final MoneroPublicKey pubVKey; + + /// private key + final MoneroPrivateKey privateKey; + + const MoneroComputeKey( + {required this.pubSKey, required this.pubVKey, required this.privateKey}); +} + /// A class representing a Monero subaddress, which consists of private and public keys. class MoneroSubaddress { /// Private view key @@ -42,7 +55,8 @@ class MoneroSubaddress { /// /// The constructor takes a private view key [privVKey] and a public spend key [pubSKey]. /// Optionally, it can also accept a public view key [publicVkey] (defaulting to `null`). - MoneroSubaddress(this.privVKey, this.pubSKey, [MoneroPublicKey? publicVkey]) + MoneroSubaddress(this.privVKey, this.pubSKey, + [MoneroPublicKey? publicVkey]) : pubVKey = publicVkey ?? privVKey.publicKey; /// Compute the subaddress keys based on minor and major indexes. @@ -50,8 +64,7 @@ class MoneroSubaddress { /// This method calculates Monero subaddress keys using the provided [minorIndex] and [majorIdx]. /// If the indexes are out of valid range, it throws an `ArgumentException`. /// It returns a tuple of subaddress public spend key and subaddress public view key. - Tuple computeKeys( - int minorIndex, int majorIndex) { + MoneroComputeKey computeKeys(int minorIndex, int majorIndex) { if (minorIndex < 0 || minorIndex > MoneroSubaddressConst.subaddrMaxIdx) { throw ArgumentException('Invalid minor index ($minorIndex)'); } @@ -60,7 +73,8 @@ class MoneroSubaddress { } if (minorIndex == 0 && majorIndex == 0) { - return Tuple(pubSKey, pubVKey); + return MoneroComputeKey( + pubSKey: pubSKey, pubVKey: pubVKey, privateKey: privVKey); } List majorIdxBytes = IntUtils.toBytes(majorIndex, @@ -78,18 +92,19 @@ class MoneroSubaddress { ...majorIdxBytes, ...minorIdxBytes ])); - BigInt mInt = BigintUtils.fromBytes(Ed25519Utils.scalarReduce(mBytes), - byteOrder: Endian.little); - final newPoint = - pubSKey.pubKey.point + (Curves.generatorED25519 * mInt) as EDPoint; + List secretKey = Ed25519Utils.scalarReduce(mBytes); + BigInt mInt = BigintUtils.fromBytes(secretKey, byteOrder: Endian.little); + final newPoint = pubSKey.point + (Curves.generatorED25519 * mInt); - MoneroPublicKey subaddrPubSKey = MoneroPublicKey.fromPoint(newPoint); + MoneroPublicKey subaddrPubSKey = + MoneroPublicKey.fromPoint(newPoint); MoneroPublicKey subaddrPubVKey = MoneroPublicKey.fromPoint( - (subaddrPubSKey.pubKey.point * - BigintUtils.fromBytes(privVKey.raw, byteOrder: Endian.little)) - as EDPoint); + (subaddrPubSKey.point * + BigintUtils.fromBytes(privVKey.raw, byteOrder: Endian.little))); + final sKey = MoneroPrivateKey.fromBytes(secretKey); - return Tuple(subaddrPubSKey, subaddrPubVKey); + return MoneroComputeKey( + pubSKey: subaddrPubSKey, pubVKey: subaddrPubVKey, privateKey: sKey); } /// Compute and encode Monero subaddress keys into a string representation. @@ -103,7 +118,7 @@ class MoneroSubaddress { int minorIndex, int majorIndex, List netVer) { final keys = computeKeys(minorIndex, majorIndex); - return XmrAddrEncoder().encodeKey(keys.item1.compressed, - {"pub_vkey": keys.item2.compressed, "net_ver": netVer}); + return XmrAddrEncoder().encodeKey(keys.pubSKey.compressed, + {"pub_vkey": keys.pubVKey.compressed, "net_ver": netVer}); } } diff --git a/lib/cbor/types/bytes.dart b/lib/cbor/types/bytes.dart index 2e8a0d1..f7e070e 100644 --- a/lib/cbor/types/bytes.dart +++ b/lib/cbor/types/bytes.dart @@ -10,6 +10,7 @@ class CborBytesValue implements CborObject { /// It accepts the bytes value. CborBytesValue(List value) : value = value.asImmutableBytes; + @override final List value; /// Encode the value into CBOR bytes diff --git a/lib/crypto/crypto/cdsa/cdsa.dart b/lib/crypto/crypto/cdsa/cdsa.dart index 21168ba..dd9842d 100644 --- a/lib/crypto/crypto/cdsa/cdsa.dart +++ b/lib/crypto/crypto/cdsa/cdsa.dart @@ -13,8 +13,7 @@ export 'ecdsa/signature.dart'; /// Export statement for EDDSA (Edwards-curve Digital Signature Algorithm) private and /// public key components. -export 'eddsa/privatekey.dart'; -export 'eddsa/publickey.dart'; +export 'eddsa/keys.dart'; /// Export statements for elliptic curve point representations, including Edwards /// and projective points. @@ -25,3 +24,5 @@ export 'point/ec_projective_point.dart'; /// Export statement for RFC 6979, which provides deterministic ECDSA signatures, /// allowing for secure signature generation. export 'rfc6979/rfc6979.dart'; + +export 'crypto_ops/crypto_ops.dart'; \ No newline at end of file diff --git a/lib/crypto/crypto/cdsa/crypto_ops/const/const.dart b/lib/crypto/crypto/cdsa/crypto_ops/const/const.dart new file mode 100644 index 0000000..3b9e935 --- /dev/null +++ b/lib/crypto/crypto/cdsa/crypto_ops/const/const.dart @@ -0,0 +1,10029 @@ +import 'package:blockchain_utils/crypto/crypto/cdsa/crypto_ops/models/models.dart'; + +class CryptoOpsConst { + static const List scMinusOne = [ + 236, + 211, + 245, + 92, + 26, + 99, + 18, + 88, + 214, + 156, + 247, + 162, + 222, + 249, + 222, + 20, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16 + ]; + static const List zero = [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 + ]; + static const List infinity = [ + 1, + 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 + ]; + static const ma2 = + FieldElement.uncheck([-12721188, -3529, 0, 0, 0, 0, 0, 0, 0, 0]); + static const ma = FieldElement.uncheck([-486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + static const fffb1 = FieldElement.uncheck([ + -31702527, + -2466483, + -26106795, + -12203692, + -12169197, + -321052, + 14850977, + -10296299, + -16929438, + -407568 + ]); /* sqrt(-2 * A * (A + 2)) */ + static const fffb2 = FieldElement.uncheck([ + 8166131, + -6741800, + -17040804, + 3154616, + 21461005, + 1466302, + -30876704, + -6368709, + 10503587, + -13363080 + ]); /* sqrt(2 * A * (A + 2)) */ + static const fffb3 = FieldElement.uncheck([ + -13620103, + 14639558, + 4532995, + 7679154, + 16815101, + -15883539, + -22863840, + -14813421, + 13716513, + -6477756 + ]); + static FieldElement fffb4 = const FieldElement.uncheck([ + -21786234, + -12173074, + 21573800, + 4524538, + -4645904, + 16204591, + 8012863, + -8444712, + 3212926, + 6885324 + ]); + static const FieldElement d2 = FieldElement.uncheck([ + -21827239, + -5839606, + -30745221, + 13898782, + 229458, + 15978800, + -12551817, + -6495438, + 29715968, + 9444199 + ]); + static const FieldElement d = FieldElement.uncheck([ + -10913610, + 13857413, + -15372611, + 6949391, + 114729, + -8787816, + -6275908, + -3247719, + -18696448, + -12055116 + ]); + static const List> geBase = [ + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 25967493, + -14356035, + 29566456, + 3660896, + -12694345, + 4014787, + 27544626, + -11754271, + -6079156, + 2047605 + ]), + yminusx: FieldElement.uncheck([ + -12545711, + 934262, + -2722910, + 3049990, + -727428, + 9406986, + 12720692, + 5043384, + 19500929, + -15469378 + ]), + xy2d: FieldElement.uncheck([ + -8738181, + 4489570, + 9688441, + -14785194, + 10184609, + -12363380, + 29287919, + 11864899, + -24514362, + -4438546 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -12815894, + -12976347, + -21581243, + 11784320, + -25355658, + -2750717, + -11717903, + -3814571, + -358445, + -10211303 + ]), + yminusx: FieldElement.uncheck([ + -21703237, + 6903825, + 27185491, + 6451973, + -29577724, + -9554005, + -15616551, + 11189268, + -26829678, + -5319081 + ]), + xy2d: FieldElement.uncheck([ + 26966642, + 11152617, + 32442495, + 15396054, + 14353839, + -12752335, + -3128826, + -9541118, + -15472047, + -4166697 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15636291, + -9688557, + 24204773, + -7912398, + 616977, + -16685262, + 27787600, + -14772189, + 28944400, + -1550024 + ]), + yminusx: FieldElement.uncheck([ + 16568933, + 4717097, + -11556148, + -1102322, + 15682896, + -11807043, + 16354577, + -11775962, + 7689662, + 11199574 + ]), + xy2d: FieldElement.uncheck([ + 30464156, + -5976125, + -11779434, + -15670865, + 23220365, + 15915852, + 7512774, + 10017326, + -17749093, + -9920357 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -17036878, + 13921892, + 10945806, + -6033431, + 27105052, + -16084379, + -28926210, + 15006023, + 3284568, + -6276540 + ]), + yminusx: FieldElement.uncheck([ + 23599295, + -8306047, + -11193664, + -7687416, + 13236774, + 10506355, + 7464579, + 9656445, + 13059162, + 10374397 + ]), + xy2d: FieldElement.uncheck([ + 7798556, + 16710257, + 3033922, + 2874086, + 28997861, + 2835604, + 32406664, + -3839045, + -641708, + -101325 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 10861363, + 11473154, + 27284546, + 1981175, + -30064349, + 12577861, + 32867885, + 14515107, + -15438304, + 10819380 + ]), + yminusx: FieldElement.uncheck([ + 4708026, + 6336745, + 20377586, + 9066809, + -11272109, + 6594696, + -25653668, + 12483688, + -12668491, + 5581306 + ]), + xy2d: FieldElement.uncheck([ + 19563160, + 16186464, + -29386857, + 4097519, + 10237984, + -4348115, + 28542350, + 13850243, + -23678021, + -15815942 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -15371964, + -12862754, + 32573250, + 4720197, + -26436522, + 5875511, + -19188627, + -15224819, + -9818940, + -12085777 + ]), + yminusx: FieldElement.uncheck([ + -8549212, + 109983, + 15149363, + 2178705, + 22900618, + 4543417, + 3044240, + -15689887, + 1762328, + 14866737 + ]), + xy2d: FieldElement.uncheck([ + -18199695, + -15951423, + -10473290, + 1707278, + -17185920, + 3916101, + -28236412, + 3959421, + 27914454, + 4383652 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 5153746, + 9909285, + 1723747, + -2777874, + 30523605, + 5516873, + 19480852, + 5230134, + -23952439, + -15175766 + ]), + yminusx: FieldElement.uncheck([ + -30269007, + -3463509, + 7665486, + 10083793, + 28475525, + 1649722, + 20654025, + 16520125, + 30598449, + 7715701 + ]), + xy2d: FieldElement.uncheck([ + 28881845, + 14381568, + 9657904, + 3680757, + -20181635, + 7843316, + -31400660, + 1370708, + 29794553, + -1409300 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 14499471, + -2729599, + -33191113, + -4254652, + 28494862, + 14271267, + 30290735, + 10876454, + -33154098, + 2381726 + ]), + yminusx: FieldElement.uncheck([ + -7195431, + -2655363, + -14730155, + 462251, + -27724326, + 3941372, + -6236617, + 3696005, + -32300832, + 15351955 + ]), + xy2d: FieldElement.uncheck([ + 27431194, + 8222322, + 16448760, + -3907995, + -18707002, + 11938355, + -32961401, + -2970515, + 29551813, + 10109425 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -13657040, + -13155431, + -31283750, + 11777098, + 21447386, + 6519384, + -2378284, + -1627556, + 10092783, + -4764171 + ]), + yminusx: FieldElement.uncheck([ + 27939166, + 14210322, + 4677035, + 16277044, + -22964462, + -12398139, + -32508754, + 12005538, + -17810127, + 12803510 + ]), + xy2d: FieldElement.uncheck([ + 17228999, + -15661624, + -1233527, + 300140, + -1224870, + -11714777, + 30364213, + -9038194, + 18016357, + 4397660 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -10958843, + -7690207, + 4776341, + -14954238, + 27850028, + -15602212, + -26619106, + 14544525, + -17477504, + 982639 + ]), + yminusx: FieldElement.uncheck([ + 29253598, + 15796703, + -2863982, + -9908884, + 10057023, + 3163536, + 7332899, + -4120128, + -21047696, + 9934963 + ]), + xy2d: FieldElement.uncheck([ + 5793303, + 16271923, + -24131614, + -10116404, + 29188560, + 1206517, + -14747930, + 4559895, + -30123922, + -10897950 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -27643952, + -11493006, + 16282657, + -11036493, + 28414021, + -15012264, + 24191034, + 4541697, + -13338309, + 5500568 + ]), + yminusx: FieldElement.uncheck([ + 12650548, + -1497113, + 9052871, + 11355358, + -17680037, + -8400164, + -17430592, + 12264343, + 10874051, + 13524335 + ]), + xy2d: FieldElement.uncheck([ + 25556948, + -3045990, + 714651, + 2510400, + 23394682, + -10415330, + 33119038, + 5080568, + -22528059, + 5376628 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -26088264, + -4011052, + -17013699, + -3537628, + -6726793, + 1920897, + -22321305, + -9447443, + 4535768, + 1569007 + ]), + yminusx: FieldElement.uncheck([ + -2255422, + 14606630, + -21692440, + -8039818, + 28430649, + 8775819, + -30494562, + 3044290, + 31848280, + 12543772 + ]), + xy2d: FieldElement.uncheck([ + -22028579, + 2943893, + -31857513, + 6777306, + 13784462, + -4292203, + -27377195, + -2062731, + 7718482, + 14474653 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 2385315, + 2454213, + -22631320, + 46603, + -4437935, + -15680415, + 656965, + -7236665, + 24316168, + -5253567 + ]), + yminusx: FieldElement.uncheck([ + 13741529, + 10911568, + -33233417, + -8603737, + -20177830, + -1033297, + 33040651, + -13424532, + -20729456, + 8321686 + ]), + xy2d: FieldElement.uncheck([ + 21060490, + -2212744, + 15712757, + -4336099, + 1639040, + 10656336, + 23845965, + -11874838, + -9984458, + 608372 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -13672732, + -15087586, + -10889693, + -7557059, + -6036909, + 11305547, + 1123968, + -6780577, + 27229399, + 23887 + ]), + yminusx: FieldElement.uncheck([ + -23244140, + -294205, + -11744728, + 14712571, + -29465699, + -2029617, + 12797024, + -6440308, + -1633405, + 16678954 + ]), + xy2d: FieldElement.uncheck([ + -29500620, + 4770662, + -16054387, + 14001338, + 7830047, + 9564805, + -1508144, + -4795045, + -17169265, + 4904953 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 24059557, + 14617003, + 19037157, + -15039908, + 19766093, + -14906429, + 5169211, + 16191880, + 2128236, + -4326833 + ]), + yminusx: FieldElement.uncheck([ + -16981152, + 4124966, + -8540610, + -10653797, + 30336522, + -14105247, + -29806336, + 916033, + -6882542, + -2986532 + ]), + xy2d: FieldElement.uncheck([ + -22630907, + 12419372, + -7134229, + -7473371, + -16478904, + 16739175, + 285431, + 2763829, + 15736322, + 4143876 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 2379352, + 11839345, + -4110402, + -5988665, + 11274298, + 794957, + 212801, + -14594663, + 23527084, + -16458268 + ]), + yminusx: FieldElement.uncheck([ + 33431127, + -11130478, + -17838966, + -15626900, + 8909499, + 8376530, + -32625340, + 4087881, + -15188911, + -14416214 + ]), + xy2d: FieldElement.uncheck([ + 1767683, + 7197987, + -13205226, + -2022635, + -13091350, + 448826, + 5799055, + 4357868, + -4774191, + -16323038 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 6721966, + 13833823, + -23523388, + -1551314, + 26354293, + -11863321, + 23365147, + -3949732, + 7390890, + 2759800 + ]), + yminusx: FieldElement.uncheck([ + 4409041, + 2052381, + 23373853, + 10530217, + 7676779, + -12885954, + 21302353, + -4264057, + 1244380, + -12919645 + ]), + xy2d: FieldElement.uncheck([ + -4421239, + 7169619, + 4982368, + -2957590, + 30256825, + -2777540, + 14086413, + 9208236, + 15886429, + 16489664 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 1996075, + 10375649, + 14346367, + 13311202, + -6874135, + -16438411, + -13693198, + 398369, + -30606455, + -712933 + ]), + yminusx: FieldElement.uncheck([ + -25307465, + 9795880, + -2777414, + 14878809, + -33531835, + 14780363, + 13348553, + 12076947, + -30836462, + 5113182 + ]), + xy2d: FieldElement.uncheck([ + -17770784, + 11797796, + 31950843, + 13929123, + -25888302, + 12288344, + -30341101, + -7336386, + 13847711, + 5387222 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -18582163, + -3416217, + 17824843, + -2340966, + 22744343, + -10442611, + 8763061, + 3617786, + -19600662, + 10370991 + ]), + yminusx: FieldElement.uncheck([ + 20246567, + -14369378, + 22358229, + -543712, + 18507283, + -10413996, + 14554437, + -8746092, + 32232924, + 16763880 + ]), + xy2d: FieldElement.uncheck([ + 9648505, + 10094563, + 26416693, + 14745928, + -30374318, + -6472621, + 11094161, + 15689506, + 3140038, + -16510092 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -16160072, + 5472695, + 31895588, + 4744994, + 8823515, + 10365685, + -27224800, + 9448613, + -28774454, + 366295 + ]), + yminusx: FieldElement.uncheck([ + 19153450, + 11523972, + -11096490, + -6503142, + -24647631, + 5420647, + 28344573, + 8041113, + 719605, + 11671788 + ]), + xy2d: FieldElement.uncheck([ + 8678025, + 2694440, + -6808014, + 2517372, + 4964326, + 11152271, + -15432916, + -15266516, + 27000813, + -10195553 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -15157904, + 7134312, + 8639287, + -2814877, + -7235688, + 10421742, + 564065, + 5336097, + 6750977, + -14521026 + ]), + yminusx: FieldElement.uncheck([ + 11836410, + -3979488, + 26297894, + 16080799, + 23455045, + 15735944, + 1695823, + -8819122, + 8169720, + 16220347 + ]), + xy2d: FieldElement.uncheck([ + -18115838, + 8653647, + 17578566, + -6092619, + -8025777, + -16012763, + -11144307, + -2627664, + -5990708, + -14166033 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -23308498, + -10968312, + 15213228, + -10081214, + -30853605, + -11050004, + 27884329, + 2847284, + 2655861, + 1738395 + ]), + yminusx: FieldElement.uncheck([ + -27537433, + -14253021, + -25336301, + -8002780, + -9370762, + 8129821, + 21651608, + -3239336, + -19087449, + -11005278 + ]), + xy2d: FieldElement.uncheck([ + 1533110, + 3437855, + 23735889, + 459276, + 29970501, + 11335377, + 26030092, + 5821408, + 10478196, + 8544890 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 32173121, + -16129311, + 24896207, + 3921497, + 22579056, + -3410854, + 19270449, + 12217473, + 17789017, + -3395995 + ]), + yminusx: FieldElement.uncheck([ + -30552961, + -2228401, + -15578829, + -10147201, + 13243889, + 517024, + 15479401, + -3853233, + 30460520, + 1052596 + ]), + xy2d: FieldElement.uncheck([ + -11614875, + 13323618, + 32618793, + 8175907, + -15230173, + 12596687, + 27491595, + -4612359, + 3179268, + -9478891 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 31947069, + -14366651, + -4640583, + -15339921, + -15125977, + -6039709, + -14756777, + -16411740, + 19072640, + -9511060 + ]), + yminusx: FieldElement.uncheck([ + 11685058, + 11822410, + 3158003, + -13952594, + 33402194, + -4165066, + 5977896, + -5215017, + 473099, + 5040608 + ]), + xy2d: FieldElement.uncheck([ + -20290863, + 8198642, + -27410132, + 11602123, + 1290375, + -2799760, + 28326862, + 1721092, + -19558642, + -3131606 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 7881532, + 10687937, + 7578723, + 7738378, + -18951012, + -2553952, + 21820786, + 8076149, + -27868496, + 11538389 + ]), + yminusx: FieldElement.uncheck([ + -19935666, + 3899861, + 18283497, + -6801568, + -15728660, + -11249211, + 8754525, + 7446702, + -5676054, + 5797016 + ]), + xy2d: FieldElement.uncheck([ + -11295600, + -3793569, + -15782110, + -7964573, + 12708869, + -8456199, + 2014099, + -9050574, + -2369172, + -5877341 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -22472376, + -11568741, + -27682020, + 1146375, + 18956691, + 16640559, + 1192730, + -3714199, + 15123619, + 10811505 + ]), + yminusx: FieldElement.uncheck([ + 14352098, + -3419715, + -18942044, + 10822655, + 32750596, + 4699007, + -70363, + 15776356, + -28886779, + -11974553 + ]), + xy2d: FieldElement.uncheck([ + -28241164, + -8072475, + -4978962, + -5315317, + 29416931, + 1847569, + -20654173, + -16484855, + 4714547, + -9600655 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15200332, + 8368572, + 19679101, + 15970074, + -31872674, + 1959451, + 24611599, + -4543832, + -11745876, + 12340220 + ]), + yminusx: FieldElement.uncheck([ + 12876937, + -10480056, + 33134381, + 6590940, + -6307776, + 14872440, + 9613953, + 8241152, + 15370987, + 9608631 + ]), + xy2d: FieldElement.uncheck([ + -4143277, + -12014408, + 8446281, + -391603, + 4407738, + 13629032, + -7724868, + 15866074, + -28210621, + -8814099 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 26660628, + -15677655, + 8393734, + 358047, + -7401291, + 992988, + -23904233, + 858697, + 20571223, + 8420556 + ]), + yminusx: FieldElement.uncheck([ + 14620715, + 13067227, + -15447274, + 8264467, + 14106269, + 15080814, + 33531827, + 12516406, + -21574435, + -12476749 + ]), + xy2d: FieldElement.uncheck([ + 236881, + 10476226, + 57258, + -14677024, + 6472998, + 2466984, + 17258519, + 7256740, + 8791136, + 15069930 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 1276410, + -9371918, + 22949635, + -16322807, + -23493039, + -5702186, + 14711875, + 4874229, + -30663140, + -2331391 + ]), + yminusx: FieldElement.uncheck([ + 5855666, + 4990204, + -13711848, + 7294284, + -7804282, + 1924647, + -1423175, + -7912378, + -33069337, + 9234253 + ]), + xy2d: FieldElement.uncheck([ + 20590503, + -9018988, + 31529744, + -7352666, + -2706834, + 10650548, + 31559055, + -11609587, + 18979186, + 13396066 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 24474287, + 4968103, + 22267082, + 4407354, + 24063882, + -8325180, + -18816887, + 13594782, + 33514650, + 7021958 + ]), + yminusx: FieldElement.uncheck([ + -11566906, + -6565505, + -21365085, + 15928892, + -26158305, + 4315421, + -25948728, + -3916677, + -21480480, + 12868082 + ]), + xy2d: FieldElement.uncheck([ + -28635013, + 13504661, + 19988037, + -2132761, + 21078225, + 6443208, + -21446107, + 2244500, + -12455797, + -8089383 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -30595528, + 13793479, + -5852820, + 319136, + -25723172, + -6263899, + 33086546, + 8957937, + -15233648, + 5540521 + ]), + yminusx: FieldElement.uncheck([ + -11630176, + -11503902, + -8119500, + -7643073, + 2620056, + 1022908, + -23710744, + -1568984, + -16128528, + -14962807 + ]), + xy2d: FieldElement.uncheck([ + 23152971, + 775386, + 27395463, + 14006635, + -9701118, + 4649512, + 1689819, + 892185, + -11513277, + -15205948 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 9770129, + 9586738, + 26496094, + 4324120, + 1556511, + -3550024, + 27453819, + 4763127, + -19179614, + 5867134 + ]), + yminusx: FieldElement.uncheck([ + -32765025, + 1927590, + 31726409, + -4753295, + 23962434, + -16019500, + 27846559, + 5931263, + -29749703, + -16108455 + ]), + xy2d: FieldElement.uncheck([ + 27461885, + -2977536, + 22380810, + 1815854, + -23033753, + -3031938, + 7283490, + -15148073, + -19526700, + 7734629 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -8010264, + -9590817, + -11120403, + 6196038, + 29344158, + -13430885, + 7585295, + -3176626, + 18549497, + 15302069 + ]), + yminusx: FieldElement.uncheck([ + -32658337, + -6171222, + -7672793, + -11051681, + 6258878, + 13504381, + 10458790, + -6418461, + -8872242, + 8424746 + ]), + xy2d: FieldElement.uncheck([ + 24687205, + 8613276, + -30667046, + -3233545, + 1863892, + -1830544, + 19206234, + 7134917, + -11284482, + -828919 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 11334899, + -9218022, + 8025293, + 12707519, + 17523892, + -10476071, + 10243738, + -14685461, + -5066034, + 16498837 + ]), + yminusx: FieldElement.uncheck([ + 8911542, + 6887158, + -9584260, + -6958590, + 11145641, + -9543680, + 17303925, + -14124238, + 6536641, + 10543906 + ]), + xy2d: FieldElement.uncheck([ + -28946384, + 15479763, + -17466835, + 568876, + -1497683, + 11223454, + -2669190, + -16625574, + -27235709, + 8876771 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25742899, + -12566864, + -15649966, + -846607, + -33026686, + -796288, + -33481822, + 15824474, + -604426, + -9039817 + ]), + yminusx: FieldElement.uncheck([ + 10330056, + 70051, + 7957388, + -9002667, + 9764902, + 15609756, + 27698697, + -4890037, + 1657394, + 3084098 + ]), + xy2d: FieldElement.uncheck([ + 10477963, + -7470260, + 12119566, + -13250805, + 29016247, + -5365589, + 31280319, + 14396151, + -30233575, + 15272409 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -12288309, + 3169463, + 28813183, + 16658753, + 25116432, + -5630466, + -25173957, + -12636138, + -25014757, + 1950504 + ]), + yminusx: FieldElement.uncheck([ + -26180358, + 9489187, + 11053416, + -14746161, + -31053720, + 5825630, + -8384306, + -8767532, + 15341279, + 8373727 + ]), + xy2d: FieldElement.uncheck([ + 28685821, + 7759505, + -14378516, + -12002860, + -31971820, + 4079242, + 298136, + -10232602, + -2878207, + 15190420 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -32932876, + 13806336, + -14337485, + -15794431, + -24004620, + 10940928, + 8669718, + 2742393, + -26033313, + -6875003 + ]), + yminusx: FieldElement.uncheck([ + -1580388, + -11729417, + -25979658, + -11445023, + -17411874, + -10912854, + 9291594, + -16247779, + -12154742, + 6048605 + ]), + xy2d: FieldElement.uncheck([ + -30305315, + 14843444, + 1539301, + 11864366, + 20201677, + 1900163, + 13934231, + 5128323, + 11213262, + 9168384 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -26280513, + 11007847, + 19408960, + -940758, + -18592965, + -4328580, + -5088060, + -11105150, + 20470157, + -16398701 + ]), + yminusx: FieldElement.uncheck([ + -23136053, + 9282192, + 14855179, + -15390078, + -7362815, + -14408560, + -22783952, + 14461608, + 14042978, + 5230683 + ]), + xy2d: FieldElement.uncheck([ + 29969567, + -2741594, + -16711867, + -8552442, + 9175486, + -2468974, + 21556951, + 3506042, + -5933891, + -12449708 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -3144746, + 8744661, + 19704003, + 4581278, + -20430686, + 6830683, + -21284170, + 8971513, + -28539189, + 15326563 + ]), + yminusx: FieldElement.uncheck([ + -19464629, + 10110288, + -17262528, + -3503892, + -23500387, + 1355669, + -15523050, + 15300988, + -20514118, + 9168260 + ]), + xy2d: FieldElement.uncheck([ + -5353335, + 4488613, + -23803248, + 16314347, + 7780487, + -15638939, + -28948358, + 9601605, + 33087103, + -9011387 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -19443170, + -15512900, + -20797467, + -12445323, + -29824447, + 10229461, + -27444329, + -15000531, + -5996870, + 15664672 + ]), + yminusx: FieldElement.uncheck([ + 23294591, + -16632613, + -22650781, + -8470978, + 27844204, + 11461195, + 13099750, + -2460356, + 18151676, + 13417686 + ]), + xy2d: FieldElement.uncheck([ + -24722913, + -4176517, + -31150679, + 5988919, + -26858785, + 6685065, + 1661597, + -12551441, + 15271676, + -15452665 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 11433042, + -13228665, + 8239631, + -5279517, + -1985436, + -725718, + -18698764, + 2167544, + -6921301, + -13440182 + ]), + yminusx: FieldElement.uncheck([ + -31436171, + 15575146, + 30436815, + 12192228, + -22463353, + 9395379, + -9917708, + -8638997, + 12215110, + 12028277 + ]), + xy2d: FieldElement.uncheck([ + 14098400, + 6555944, + 23007258, + 5757252, + -15427832, + -12950502, + 30123440, + 4617780, + -16900089, + -655628 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -4026201, + -15240835, + 11893168, + 13718664, + -14809462, + 1847385, + -15819999, + 10154009, + 23973261, + -12684474 + ]), + yminusx: FieldElement.uncheck([ + -26531820, + -3695990, + -1908898, + 2534301, + -31870557, + -16550355, + 18341390, + -11419951, + 32013174, + -10103539 + ]), + xy2d: FieldElement.uncheck([ + -25479301, + 10876443, + -11771086, + -14625140, + -12369567, + 1838104, + 21911214, + 6354752, + 4425632, + -837822 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -10433389, + -14612966, + 22229858, + -3091047, + -13191166, + 776729, + -17415375, + -12020462, + 4725005, + 14044970 + ]), + yminusx: FieldElement.uncheck([ + 19268650, + -7304421, + 1555349, + 8692754, + -21474059, + -9910664, + 6347390, + -1411784, + -19522291, + -16109756 + ]), + xy2d: FieldElement.uncheck([ + -24864089, + 12986008, + -10898878, + -5558584, + -11312371, + -148526, + 19541418, + 8180106, + 9282262, + 10282508 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -26205082, + 4428547, + -8661196, + -13194263, + 4098402, + -14165257, + 15522535, + 8372215, + 5542595, + -10702683 + ]), + yminusx: FieldElement.uncheck([ + -10562541, + 14895633, + 26814552, + -16673850, + -17480754, + -2489360, + -2781891, + 6993761, + -18093885, + 10114655 + ]), + xy2d: FieldElement.uncheck([ + -20107055, + -929418, + 31422704, + 10427861, + -7110749, + 6150669, + -29091755, + -11529146, + 25953725, + -106158 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -4234397, + -8039292, + -9119125, + 3046000, + 2101609, + -12607294, + 19390020, + 6094296, + -3315279, + 12831125 + ]), + yminusx: FieldElement.uncheck([ + -15998678, + 7578152, + 5310217, + 14408357, + -33548620, + -224739, + 31575954, + 6326196, + 7381791, + -2421839 + ]), + xy2d: FieldElement.uncheck([ + -20902779, + 3296811, + 24736065, + -16328389, + 18374254, + 7318640, + 6295303, + 8082724, + -15362489, + 12339664 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 27724736, + 2291157, + 6088201, + -14184798, + 1792727, + 5857634, + 13848414, + 15768922, + 25091167, + 14856294 + ]), + yminusx: FieldElement.uncheck([ + -18866652, + 8331043, + 24373479, + 8541013, + -701998, + -9269457, + 12927300, + -12695493, + -22182473, + -9012899 + ]), + xy2d: FieldElement.uncheck([ + -11423429, + -5421590, + 11632845, + 3405020, + 30536730, + -11674039, + -27260765, + 13866390, + 30146206, + 9142070 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 3924129, + -15307516, + -13817122, + -10054960, + 12291820, + -668366, + -27702774, + 9326384, + -8237858, + 4171294 + ]), + yminusx: FieldElement.uncheck([ + -15921940, + 16037937, + 6713787, + 16606682, + -21612135, + 2790944, + 26396185, + 3731949, + 345228, + -5462949 + ]), + xy2d: FieldElement.uncheck([ + -21327538, + 13448259, + 25284571, + 1143661, + 20614966, + -8849387, + 2031539, + -12391231, + -16253183, + -13582083 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 31016211, + -16722429, + 26371392, + -14451233, + -5027349, + 14854137, + 17477601, + 3842657, + 28012650, + -16405420 + ]), + yminusx: FieldElement.uncheck([ + -5075835, + 9368966, + -8562079, + -4600902, + -15249953, + 6970560, + -9189873, + 16292057, + -8867157, + 3507940 + ]), + xy2d: FieldElement.uncheck([ + 29439664, + 3537914, + 23333589, + 6997794, + -17555561, + -11018068, + -15209202, + -15051267, + -9164929, + 6580396 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -12185861, + -7679788, + 16438269, + 10826160, + -8696817, + -6235611, + 17860444, + -9273846, + -2095802, + 9304567 + ]), + yminusx: FieldElement.uncheck([ + 20714564, + -4336911, + 29088195, + 7406487, + 11426967, + -5095705, + 14792667, + -14608617, + 5289421, + -477127 + ]), + xy2d: FieldElement.uncheck([ + -16665533, + -10650790, + -6160345, + -13305760, + 9192020, + -1802462, + 17271490, + 12349094, + 26939669, + -3752294 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -12889898, + 9373458, + 31595848, + 16374215, + 21471720, + 13221525, + -27283495, + -12348559, + -3698806, + 117887 + ]), + yminusx: FieldElement.uncheck([ + 22263325, + -6560050, + 3984570, + -11174646, + -15114008, + -566785, + 28311253, + 5358056, + -23319780, + 541964 + ]), + xy2d: FieldElement.uncheck([ + 16259219, + 3261970, + 2309254, + -15534474, + -16885711, + -4581916, + 24134070, + -16705829, + -13337066, + -13552195 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 9378160, + -13140186, + -22845982, + -12745264, + 28198281, + -7244098, + -2399684, + -717351, + 690426, + 14876244 + ]), + yminusx: FieldElement.uncheck([ + 24977353, + -314384, + -8223969, + -13465086, + 28432343, + -1176353, + -13068804, + -12297348, + -22380984, + 6618999 + ]), + xy2d: FieldElement.uncheck([ + -1538174, + 11685646, + 12944378, + 13682314, + -24389511, + -14413193, + 8044829, + -13817328, + 32239829, + -5652762 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -18603066, + 4762990, + -926250, + 8885304, + -28412480, + -3187315, + 9781647, + -10350059, + 32779359, + 5095274 + ]), + yminusx: FieldElement.uncheck([ + -33008130, + -5214506, + -32264887, + -3685216, + 9460461, + -9327423, + -24601656, + 14506724, + 21639561, + -2630236 + ]), + xy2d: FieldElement.uncheck([ + -16400943, + -13112215, + 25239338, + 15531969, + 3987758, + -4499318, + -1289502, + -6863535, + 17874574, + 558605 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -13600129, + 10240081, + 9171883, + 16131053, + -20869254, + 9599700, + 33499487, + 5080151, + 2085892, + 5119761 + ]), + yminusx: FieldElement.uncheck([ + -22205145, + -2519528, + -16381601, + 414691, + -25019550, + 2170430, + 30634760, + -8363614, + -31999993, + -5759884 + ]), + xy2d: FieldElement.uncheck([ + -6845704, + 15791202, + 8550074, + -1312654, + 29928809, + -12092256, + 27534430, + -7192145, + -22351378, + 12961482 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -24492060, + -9570771, + 10368194, + 11582341, + -23397293, + -2245287, + 16533930, + 8206996, + -30194652, + -5159638 + ]), + yminusx: FieldElement.uncheck([ + -11121496, + -3382234, + 2307366, + 6362031, + -135455, + 8868177, + -16835630, + 7031275, + 7589640, + 8945490 + ]), + xy2d: FieldElement.uncheck([ + -32152748, + 8917967, + 6661220, + -11677616, + -1192060, + -15793393, + 7251489, + -11182180, + 24099109, + -14456170 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 5019558, + -7907470, + 4244127, + -14714356, + -26933272, + 6453165, + -19118182, + -13289025, + -6231896, + -10280736 + ]), + yminusx: FieldElement.uncheck([ + 10853594, + 10721687, + 26480089, + 5861829, + -22995819, + 1972175, + -1866647, + -10557898, + -3363451, + -6441124 + ]), + xy2d: FieldElement.uncheck([ + -17002408, + 5906790, + 221599, + -6563147, + 7828208, + -13248918, + 24362661, + -2008168, + -13866408, + 7421392 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 8139927, + -6546497, + 32257646, + -5890546, + 30375719, + 1886181, + -21175108, + 15441252, + 28826358, + -4123029 + ]), + yminusx: FieldElement.uncheck([ + 6267086, + 9695052, + 7709135, + -16603597, + -32869068, + -1886135, + 14795160, + -7840124, + 13746021, + -1742048 + ]), + xy2d: FieldElement.uncheck([ + 28584902, + 7787108, + -6732942, + -15050729, + 22846041, + -7571236, + -3181936, + -363524, + 4771362, + -8419958 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 24949256, + 6376279, + -27466481, + -8174608, + -18646154, + -9930606, + 33543569, + -12141695, + 3569627, + 11342593 + ]), + yminusx: FieldElement.uncheck([ + 26514989, + 4740088, + 27912651, + 3697550, + 19331575, + -11472339, + 6809886, + 4608608, + 7325975, + -14801071 + ]), + xy2d: FieldElement.uncheck([ + -11618399, + -14554430, + -24321212, + 7655128, + -1369274, + 5214312, + -27400540, + 10258390, + -17646694, + -8186692 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 11431204, + 15823007, + 26570245, + 14329124, + 18029990, + 4796082, + -31446179, + 15580664, + 9280358, + -3973687 + ]), + yminusx: FieldElement.uncheck([ + -160783, + -10326257, + -22855316, + -4304997, + -20861367, + -13621002, + -32810901, + -11181622, + -15545091, + 4387441 + ]), + xy2d: FieldElement.uncheck([ + -20799378, + 12194512, + 3937617, + -5805892, + -27154820, + 9340370, + -24513992, + 8548137, + 20617071, + -7482001 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -938825, + -3930586, + -8714311, + 16124718, + 24603125, + -6225393, + -13775352, + -11875822, + 24345683, + 10325460 + ]), + yminusx: FieldElement.uncheck([ + -19855277, + -1568885, + -22202708, + 8714034, + 14007766, + 6928528, + 16318175, + -1010689, + 4766743, + 3552007 + ]), + xy2d: FieldElement.uncheck([ + -21751364, + -16730916, + 1351763, + -803421, + -4009670, + 3950935, + 3217514, + 14481909, + 10988822, + -3994762 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15564307, + -14311570, + 3101243, + 5684148, + 30446780, + -8051356, + 12677127, + -6505343, + -8295852, + 13296005 + ]), + yminusx: FieldElement.uncheck([ + -9442290, + 6624296, + -30298964, + -11913677, + -4670981, + -2057379, + 31521204, + 9614054, + -30000824, + 12074674 + ]), + xy2d: FieldElement.uncheck([ + 4771191, + -135239, + 14290749, + -13089852, + 27992298, + 14998318, + -1413936, + -1556716, + 29832613, + -16391035 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 7064884, + -7541174, + -19161962, + -5067537, + -18891269, + -2912736, + 25825242, + 5293297, + -27122660, + 13101590 + ]), + yminusx: FieldElement.uncheck([ + -2298563, + 2439670, + -7466610, + 1719965, + -27267541, + -16328445, + 32512469, + -5317593, + -30356070, + -4190957 + ]), + xy2d: FieldElement.uncheck([ + -30006540, + 10162316, + -33180176, + 3981723, + -16482138, + -13070044, + 14413974, + 9515896, + 19568978, + 9628812 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 33053803, + 199357, + 15894591, + 1583059, + 27380243, + -4580435, + -17838894, + -6106839, + -6291786, + 3437740 + ]), + yminusx: FieldElement.uncheck([ + -18978877, + 3884493, + 19469877, + 12726490, + 15913552, + 13614290, + -22961733, + 70104, + 7463304, + 4176122 + ]), + xy2d: FieldElement.uncheck([ + -27124001, + 10659917, + 11482427, + -16070381, + 12771467, + -6635117, + -32719404, + -5322751, + 24216882, + 5944158 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 8894125, + 7450974, + -2664149, + -9765752, + -28080517, + -12389115, + 19345746, + 14680796, + 11632993, + 5847885 + ]), + yminusx: FieldElement.uncheck([ + 26942781, + -2315317, + 9129564, + -4906607, + 26024105, + 11769399, + -11518837, + 6367194, + -9727230, + 4782140 + ]), + xy2d: FieldElement.uncheck([ + 19916461, + -4828410, + -22910704, + -11414391, + 25606324, + -5972441, + 33253853, + 8220911, + 6358847, + -1873857 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 801428, + -2081702, + 16569428, + 11065167, + 29875704, + 96627, + 7908388, + -4480480, + -13538503, + 1387155 + ]), + yminusx: FieldElement.uncheck([ + 19646058, + 5720633, + -11416706, + 12814209, + 11607948, + 12749789, + 14147075, + 15156355, + -21866831, + 11835260 + ]), + xy2d: FieldElement.uncheck([ + 19299512, + 1155910, + 28703737, + 14890794, + 2925026, + 7269399, + 26121523, + 15467869, + -26560550, + 5052483 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -3017432, + 10058206, + 1980837, + 3964243, + 22160966, + 12322533, + -6431123, + -12618185, + 12228557, + -7003677 + ]), + yminusx: FieldElement.uncheck([ + 32944382, + 14922211, + -22844894, + 5188528, + 21913450, + -8719943, + 4001465, + 13238564, + -6114803, + 8653815 + ]), + xy2d: FieldElement.uncheck([ + 22865569, + -4652735, + 27603668, + -12545395, + 14348958, + 8234005, + 24808405, + 5719875, + 28483275, + 2841751 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -16420968, + -1113305, + -327719, + -12107856, + 21886282, + -15552774, + -1887966, + -315658, + 19932058, + -12739203 + ]), + yminusx: FieldElement.uncheck([ + -11656086, + 10087521, + -8864888, + -5536143, + -19278573, + -3055912, + 3999228, + 13239134, + -4777469, + -13910208 + ]), + xy2d: FieldElement.uncheck([ + 1382174, + -11694719, + 17266790, + 9194690, + -13324356, + 9720081, + 20403944, + 11284705, + -14013818, + 3093230 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 16650921, + -11037932, + -1064178, + 1570629, + -8329746, + 7352753, + -302424, + 16271225, + -24049421, + -6691850 + ]), + yminusx: FieldElement.uncheck([ + -21911077, + -5927941, + -4611316, + -5560156, + -31744103, + -10785293, + 24123614, + 15193618, + -21652117, + -16739389 + ]), + xy2d: FieldElement.uncheck([ + -9935934, + -4289447, + -25279823, + 4372842, + 2087473, + 10399484, + 31870908, + 14690798, + 17361620, + 11864968 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -11307610, + 6210372, + 13206574, + 5806320, + -29017692, + -13967200, + -12331205, + -7486601, + -25578460, + -16240689 + ]), + yminusx: FieldElement.uncheck([ + 14668462, + -12270235, + 26039039, + 15305210, + 25515617, + 4542480, + 10453892, + 6577524, + 9145645, + -6443880 + ]), + xy2d: FieldElement.uncheck([ + 5974874, + 3053895, + -9433049, + -10385191, + -31865124, + 3225009, + -7972642, + 3936128, + -5652273, + -3050304 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30625386, + -4729400, + -25555961, + -12792866, + -20484575, + 7695099, + 17097188, + -16303496, + -27999779, + 1803632 + ]), + yminusx: FieldElement.uncheck([ + -3553091, + 9865099, + -5228566, + 4272701, + -5673832, + -16689700, + 14911344, + 12196514, + -21405489, + 7047412 + ]), + xy2d: FieldElement.uncheck([ + 20093277, + 9920966, + -11138194, + -5343857, + 13161587, + 12044805, + -32856851, + 4124601, + -32343828, + -10257566 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -20788824, + 14084654, + -13531713, + 7842147, + 19119038, + -13822605, + 4752377, + -8714640, + -21679658, + 2288038 + ]), + yminusx: FieldElement.uncheck([ + -26819236, + -3283715, + 29965059, + 3039786, + -14473765, + 2540457, + 29457502, + 14625692, + -24819617, + 12570232 + ]), + xy2d: FieldElement.uncheck([ + -1063558, + -11551823, + 16920318, + 12494842, + 1278292, + -5869109, + -21159943, + -3498680, + -11974704, + 4724943 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 17960970, + -11775534, + -4140968, + -9702530, + -8876562, + -1410617, + -12907383, + -8659932, + -29576300, + 1903856 + ]), + yminusx: FieldElement.uncheck([ + 23134274, + -14279132, + -10681997, + -1611936, + 20684485, + 15770816, + -12989750, + 3190296, + 26955097, + 14109738 + ]), + xy2d: FieldElement.uncheck([ + 15308788, + 5320727, + -30113809, + -14318877, + 22902008, + 7767164, + 29425325, + -11277562, + 31960942, + 11934971 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -27395711, + 8435796, + 4109644, + 12222639, + -24627868, + 14818669, + 20638173, + 4875028, + 10491392, + 1379718 + ]), + yminusx: FieldElement.uncheck([ + -13159415, + 9197841, + 3875503, + -8936108, + -1383712, + -5879801, + 33518459, + 16176658, + 21432314, + 12180697 + ]), + xy2d: FieldElement.uncheck([ + -11787308, + 11500838, + 13787581, + -13832590, + -22430679, + 10140205, + 1465425, + 12689540, + -10301319, + -13872883 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 5414091, + -15386041, + -21007664, + 9643570, + 12834970, + 1186149, + -2622916, + -1342231, + 26128231, + 6032912 + ]), + yminusx: FieldElement.uncheck([ + -26337395, + -13766162, + 32496025, + -13653919, + 17847801, + -12669156, + 3604025, + 8316894, + -25875034, + -10437358 + ]), + xy2d: FieldElement.uncheck([ + 3296484, + 6223048, + 24680646, + -12246460, + -23052020, + 5903205, + -8862297, + -4639164, + 12376617, + 3188849 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 29190488, + -14659046, + 27549113, + -1183516, + 3520066, + -10697301, + 32049515, + -7309113, + -16109234, + -9852307 + ]), + yminusx: FieldElement.uncheck([ + -14744486, + -9309156, + 735818, + -598978, + -20407687, + -5057904, + 25246078, + -15795669, + 18640741, + -960977 + ]), + xy2d: FieldElement.uncheck([ + -6928835, + -16430795, + 10361374, + 5642961, + 4910474, + 12345252, + -31638386, + -494430, + 10530747, + 1053335 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -29265967, + -14186805, + -13538216, + -12117373, + -19457059, + -10655384, + -31462369, + -2948985, + 24018831, + 15026644 + ]), + yminusx: FieldElement.uncheck([ + -22592535, + -3145277, + -2289276, + 5953843, + -13440189, + 9425631, + 25310643, + 13003497, + -2314791, + -15145616 + ]), + xy2d: FieldElement.uncheck([ + -27419985, + -603321, + -8043984, + -1669117, + -26092265, + 13987819, + -27297622, + 187899, + -23166419, + -2531735 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -21744398, + -13810475, + 1844840, + 5021428, + -10434399, + -15911473, + 9716667, + 16266922, + -5070217, + 726099 + ]), + yminusx: FieldElement.uncheck([ + 29370922, + -6053998, + 7334071, + -15342259, + 9385287, + 2247707, + -13661962, + -4839461, + 30007388, + -15823341 + ]), + xy2d: FieldElement.uncheck([ + -936379, + 16086691, + 23751945, + -543318, + -1167538, + -5189036, + 9137109, + 730663, + 9835848, + 4555336 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -23376435, + 1410446, + -22253753, + -12899614, + 30867635, + 15826977, + 17693930, + 544696, + -11985298, + 12422646 + ]), + yminusx: FieldElement.uncheck([ + 31117226, + -12215734, + -13502838, + 6561947, + -9876867, + -12757670, + -5118685, + -4096706, + 29120153, + 13924425 + ]), + xy2d: FieldElement.uncheck([ + -17400879, + -14233209, + 19675799, + -2734756, + -11006962, + -5858820, + -9383939, + -11317700, + 7240931, + -237388 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -31361739, + -11346780, + -15007447, + -5856218, + -22453340, + -12152771, + 1222336, + 4389483, + 3293637, + -15551743 + ]), + yminusx: FieldElement.uncheck([ + -16684801, + -14444245, + 11038544, + 11054958, + -13801175, + -3338533, + -24319580, + 7733547, + 12796905, + -6335822 + ]), + xy2d: FieldElement.uncheck([ + -8759414, + -10817836, + -25418864, + 10783769, + -30615557, + -9746811, + -28253339, + 3647836, + 3222231, + -11160462 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 18606113, + 1693100, + -25448386, + -15170272, + 4112353, + 10045021, + 23603893, + -2048234, + -7550776, + 2484985 + ]), + yminusx: FieldElement.uncheck([ + 9255317, + -3131197, + -12156162, + -1004256, + 13098013, + -9214866, + 16377220, + -2102812, + -19802075, + -3034702 + ]), + xy2d: FieldElement.uncheck([ + -22729289, + 7496160, + -5742199, + 11329249, + 19991973, + -3347502, + -31718148, + 9936966, + -30097688, + -10618797 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 21878590, + -5001297, + 4338336, + 13643897, + -3036865, + 13160960, + 19708896, + 5415497, + -7360503, + -4109293 + ]), + yminusx: FieldElement.uncheck([ + 27736861, + 10103576, + 12500508, + 8502413, + -3413016, + -9633558, + 10436918, + -1550276, + -23659143, + -8132100 + ]), + xy2d: FieldElement.uncheck([ + 19492550, + -12104365, + -29681976, + -852630, + -3208171, + 12403437, + 30066266, + 8367329, + 13243957, + 8709688 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 12015105, + 2801261, + 28198131, + 10151021, + 24818120, + -4743133, + -11194191, + -5645734, + 5150968, + 7274186 + ]), + yminusx: FieldElement.uncheck([ + 2831366, + -12492146, + 1478975, + 6122054, + 23825128, + -12733586, + 31097299, + 6083058, + 31021603, + -9793610 + ]), + xy2d: FieldElement.uncheck([ + -2529932, + -2229646, + 445613, + 10720828, + -13849527, + -11505937, + -23507731, + 16354465, + 15067285, + -14147707 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 7840942, + 14037873, + -33364863, + 15934016, + -728213, + -3642706, + 21403988, + 1057586, + -19379462, + -12403220 + ]), + yminusx: FieldElement.uncheck([ + 915865, + -16469274, + 15608285, + -8789130, + -24357026, + 6060030, + -17371319, + 8410997, + -7220461, + 16527025 + ]), + xy2d: FieldElement.uncheck([ + 32922597, + -556987, + 20336074, + -16184568, + 10903705, + -5384487, + 16957574, + 52992, + 23834301, + 6588044 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 32752030, + 11232950, + 3381995, + -8714866, + 22652988, + -10744103, + 17159699, + 16689107, + -20314580, + -1305992 + ]), + yminusx: FieldElement.uncheck([ + -4689649, + 9166776, + -25710296, + -10847306, + 11576752, + 12733943, + 7924251, + -2752281, + 1976123, + -7249027 + ]), + xy2d: FieldElement.uncheck([ + 21251222, + 16309901, + -2983015, + -6783122, + 30810597, + 12967303, + 156041, + -3371252, + 12331345, + -8237197 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 8651614, + -4477032, + -16085636, + -4996994, + 13002507, + 2950805, + 29054427, + -5106970, + 10008136, + -4667901 + ]), + yminusx: FieldElement.uncheck([ + 31486080, + 15114593, + -14261250, + 12951354, + 14369431, + -7387845, + 16347321, + -13662089, + 8684155, + -10532952 + ]), + xy2d: FieldElement.uncheck([ + 19443825, + 11385320, + 24468943, + -9659068, + -23919258, + 2187569, + -26263207, + -6086921, + 31316348, + 14219878 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -28594490, + 1193785, + 32245219, + 11392485, + 31092169, + 15722801, + 27146014, + 6992409, + 29126555, + 9207390 + ]), + yminusx: FieldElement.uncheck([ + 32382935, + 1110093, + 18477781, + 11028262, + -27411763, + -7548111, + -4980517, + 10843782, + -7957600, + -14435730 + ]), + xy2d: FieldElement.uncheck([ + 2814918, + 7836403, + 27519878, + -7868156, + -20894015, + -11553689, + -21494559, + 8550130, + 28346258, + 1994730 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -19578299, + 8085545, + -14000519, + -3948622, + 2785838, + -16231307, + -19516951, + 7174894, + 22628102, + 8115180 + ]), + yminusx: FieldElement.uncheck([ + -30405132, + 955511, + -11133838, + -15078069, + -32447087, + -13278079, + -25651578, + 3317160, + -9943017, + 930272 + ]), + xy2d: FieldElement.uncheck([ + -15303681, + -6833769, + 28856490, + 1357446, + 23421993, + 1057177, + 24091212, + -1388970, + -22765376, + -10650715 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -22751231, + -5303997, + -12907607, + -12768866, + -15811511, + -7797053, + -14839018, + -16554220, + -1867018, + 8398970 + ]), + yminusx: FieldElement.uncheck([ + -31969310, + 2106403, + -4736360, + 1362501, + 12813763, + 16200670, + 22981545, + -6291273, + 18009408, + -15772772 + ]), + xy2d: FieldElement.uncheck([ + -17220923, + -9545221, + -27784654, + 14166835, + 29815394, + 7444469, + 29551787, + -3727419, + 19288549, + 1325865 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15100157, + -15835752, + -23923978, + -1005098, + -26450192, + 15509408, + 12376730, + -3479146, + 33166107, + -8042750 + ]), + yminusx: FieldElement.uncheck([ + 20909231, + 13023121, + -9209752, + 16251778, + -5778415, + -8094914, + 12412151, + 10018715, + 2213263, + -13878373 + ]), + xy2d: FieldElement.uncheck([ + 32529814, + -11074689, + 30361439, + -16689753, + -9135940, + 1513226, + 22922121, + 6382134, + -5766928, + 8371348 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 9923462, + 11271500, + 12616794, + 3544722, + -29998368, + -1721626, + 12891687, + -8193132, + -26442943, + 10486144 + ]), + yminusx: FieldElement.uncheck([ + -22597207, + -7012665, + 8587003, + -8257861, + 4084309, + -12970062, + 361726, + 2610596, + -23921530, + -11455195 + ]), + xy2d: FieldElement.uncheck([ + 5408411, + -1136691, + -4969122, + 10561668, + 24145918, + 14240566, + 31319731, + -4235541, + 19985175, + -3436086 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -13994457, + 16616821, + 14549246, + 3341099, + 32155958, + 13648976, + -17577068, + 8849297, + 65030, + 8370684 + ]), + yminusx: FieldElement.uncheck([ + -8320926, + -12049626, + 31204563, + 5839400, + -20627288, + -1057277, + -19442942, + 6922164, + 12743482, + -9800518 + ]), + xy2d: FieldElement.uncheck([ + -2361371, + 12678785, + 28815050, + 4759974, + -23893047, + 4884717, + 23783145, + 11038569, + 18800704, + 255233 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -5269658, + -1773886, + 13957886, + 7990715, + 23132995, + 728773, + 13393847, + 9066957, + 19258688, + -14753793 + ]), + yminusx: FieldElement.uncheck([ + -2936654, + -10827535, + -10432089, + 14516793, + -3640786, + 4372541, + -31934921, + 2209390, + -1524053, + 2055794 + ]), + xy2d: FieldElement.uncheck([ + 580882, + 16705327, + 5468415, + -2683018, + -30926419, + -14696000, + -7203346, + -8994389, + -30021019, + 7394435 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 23838809, + 1822728, + -15738443, + 15242727, + 8318092, + -3733104, + -21672180, + -3492205, + -4821741, + 14799921 + ]), + yminusx: FieldElement.uncheck([ + 13345610, + 9759151, + 3371034, + -16137791, + 16353039, + 8577942, + 31129804, + 13496856, + -9056018, + 7402518 + ]), + xy2d: FieldElement.uncheck([ + 2286874, + -4435931, + -20042458, + -2008336, + -13696227, + 5038122, + 11006906, + -15760352, + 8205061, + 1607563 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 14414086, + -8002132, + 3331830, + -3208217, + 22249151, + -5594188, + 18364661, + -2906958, + 30019587, + -9029278 + ]), + yminusx: FieldElement.uncheck([ + -27688051, + 1585953, + -10775053, + 931069, + -29120221, + -11002319, + -14410829, + 12029093, + 9944378, + 8024 + ]), + xy2d: FieldElement.uncheck([ + 4368715, + -3709630, + 29874200, + -15022983, + -20230386, + -11410704, + -16114594, + -999085, + -8142388, + 5640030 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 10299610, + 13746483, + 11661824, + 16234854, + 7630238, + 5998374, + 9809887, + -16694564, + 15219798, + -14327783 + ]), + yminusx: FieldElement.uncheck([ + 27425505, + -5719081, + 3055006, + 10660664, + 23458024, + 595578, + -15398605, + -1173195, + -18342183, + 9742717 + ]), + xy2d: FieldElement.uncheck([ + 6744077, + 2427284, + 26042789, + 2720740, + -847906, + 1118974, + 32324614, + 7406442, + 12420155, + 1994844 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 14012521, + -5024720, + -18384453, + -9578469, + -26485342, + -3936439, + -13033478, + -10909803, + 24319929, + -6446333 + ]), + yminusx: FieldElement.uncheck([ + 16412690, + -4507367, + 10772641, + 15929391, + -17068788, + -4658621, + 10555945, + -10484049, + -30102368, + -4739048 + ]), + xy2d: FieldElement.uncheck([ + 22397382, + -7767684, + -9293161, + -12792868, + 17166287, + -9755136, + -27333065, + 6199366, + 21880021, + -12250760 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -4283307, + 5368523, + -31117018, + 8163389, + -30323063, + 3209128, + 16557151, + 8890729, + 8840445, + 4957760 + ]), + yminusx: FieldElement.uncheck([ + -15447727, + 709327, + -6919446, + -10870178, + -29777922, + 6522332, + -21720181, + 12130072, + -14796503, + 5005757 + ]), + xy2d: FieldElement.uncheck([ + -2114751, + -14308128, + 23019042, + 15765735, + -25269683, + 6002752, + 10183197, + -13239326, + -16395286, + -2176112 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -19025756, + 1632005, + 13466291, + -7995100, + -23640451, + 16573537, + -32013908, + -3057104, + 22208662, + 2000468 + ]), + yminusx: FieldElement.uncheck([ + 3065073, + -1412761, + -25598674, + -361432, + -17683065, + -5703415, + -8164212, + 11248527, + -3691214, + -7414184 + ]), + xy2d: FieldElement.uncheck([ + 10379208, + -6045554, + 8877319, + 1473647, + -29291284, + -12507580, + 16690915, + 2553332, + -3132688, + 16400289 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15716668, + 1254266, + -18472690, + 7446274, + -8448918, + 6344164, + -22097271, + -7285580, + 26894937, + 9132066 + ]), + yminusx: FieldElement.uncheck([ + 24158887, + 12938817, + 11085297, + -8177598, + -28063478, + -4457083, + -30576463, + 64452, + -6817084, + -2692882 + ]), + xy2d: FieldElement.uncheck([ + 13488534, + 7794716, + 22236231, + 5989356, + 25426474, + -12578208, + 2350710, + -3418511, + -4688006, + 2364226 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 16335052, + 9132434, + 25640582, + 6678888, + 1725628, + 8517937, + -11807024, + -11697457, + 15445875, + -7798101 + ]), + yminusx: FieldElement.uncheck([ + 29004207, + -7867081, + 28661402, + -640412, + -12794003, + -7943086, + 31863255, + -4135540, + -278050, + -15759279 + ]), + xy2d: FieldElement.uncheck([ + -6122061, + -14866665, + -28614905, + 14569919, + -10857999, + -3591829, + 10343412, + -6976290, + -29828287, + -10815811 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 27081650, + 3463984, + 14099042, + -4517604, + 1616303, + -6205604, + 29542636, + 15372179, + 17293797, + 960709 + ]), + yminusx: FieldElement.uncheck([ + 20263915, + 11434237, + -5765435, + 11236810, + 13505955, + -10857102, + -16111345, + 6493122, + -19384511, + 7639714 + ]), + xy2d: FieldElement.uncheck([ + -2830798, + -14839232, + 25403038, + -8215196, + -8317012, + -16173699, + 18006287, + -16043750, + 29994677, + -15808121 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 9769828, + 5202651, + -24157398, + -13631392, + -28051003, + -11561624, + -24613141, + -13860782, + -31184575, + 709464 + ]), + yminusx: FieldElement.uncheck([ + 12286395, + 13076066, + -21775189, + -1176622, + -25003198, + 4057652, + -32018128, + -8890874, + 16102007, + 13205847 + ]), + xy2d: FieldElement.uncheck([ + 13733362, + 5599946, + 10557076, + 3195751, + -5557991, + 8536970, + -25540170, + 8525972, + 10151379, + 10394400 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 4024660, + -16137551, + 22436262, + 12276534, + -9099015, + -2686099, + 19698229, + 11743039, + -33302334, + 8934414 + ]), + yminusx: FieldElement.uncheck([ + -15879800, + -4525240, + -8580747, + -2934061, + 14634845, + -698278, + -9449077, + 3137094, + -11536886, + 11721158 + ]), + xy2d: FieldElement.uncheck([ + 17555939, + -5013938, + 8268606, + 2331751, + -22738815, + 9761013, + 9319229, + 8835153, + -9205489, + -1280045 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -461409, + -7830014, + 20614118, + 16688288, + -7514766, + -4807119, + 22300304, + 505429, + 6108462, + -6183415 + ]), + yminusx: FieldElement.uncheck([ + -5070281, + 12367917, + -30663534, + 3234473, + 32617080, + -8422642, + 29880583, + -13483331, + -26898490, + -7867459 + ]), + xy2d: FieldElement.uncheck([ + -31975283, + 5726539, + 26934134, + 10237677, + -3173717, + -605053, + 24199304, + 3795095, + 7592688, + -14992079 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 21594432, + -14964228, + 17466408, + -4077222, + 32537084, + 2739898, + 6407723, + 12018833, + -28256052, + 4298412 + ]), + yminusx: FieldElement.uncheck([ + -20650503, + -11961496, + -27236275, + 570498, + 3767144, + -1717540, + 13891942, + -1569194, + 13717174, + 10805743 + ]), + xy2d: FieldElement.uncheck([ + -14676630, + -15644296, + 15287174, + 11927123, + 24177847, + -8175568, + -796431, + 14860609, + -26938930, + -5863836 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 12962541, + 5311799, + -10060768, + 11658280, + 18855286, + -7954201, + 13286263, + -12808704, + -4381056, + 9882022 + ]), + yminusx: FieldElement.uncheck([ + 18512079, + 11319350, + -20123124, + 15090309, + 18818594, + 5271736, + -22727904, + 3666879, + -23967430, + -3299429 + ]), + xy2d: FieldElement.uncheck([ + -6789020, + -3146043, + 16192429, + 13241070, + 15898607, + -14206114, + -10084880, + -6661110, + -2403099, + 5276065 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30169808, + -5317648, + 26306206, + -11750859, + 27814964, + 7069267, + 7152851, + 3684982, + 1449224, + 13082861 + ]), + yminusx: FieldElement.uncheck([ + 10342826, + 3098505, + 2119311, + 193222, + 25702612, + 12233820, + 23697382, + 15056736, + -21016438, + -8202000 + ]), + xy2d: FieldElement.uncheck([ + -33150110, + 3261608, + 22745853, + 7948688, + 19370557, + -15177665, + -26171976, + 6482814, + -10300080, + -11060101 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 32869458, + -5408545, + 25609743, + 15678670, + -10687769, + -15471071, + 26112421, + 2521008, + -22664288, + 6904815 + ]), + yminusx: FieldElement.uncheck([ + 29506923, + 4457497, + 3377935, + -9796444, + -30510046, + 12935080, + 1561737, + 3841096, + -29003639, + -6657642 + ]), + xy2d: FieldElement.uncheck([ + 10340844, + -6630377, + -18656632, + -2278430, + 12621151, + -13339055, + 30878497, + -11824370, + -25584551, + 5181966 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 25940115, + -12658025, + 17324188, + -10307374, + -8671468, + 15029094, + 24396252, + -16450922, + -2322852, + -12388574 + ]), + yminusx: FieldElement.uncheck([ + -21765684, + 9916823, + -1300409, + 4079498, + -1028346, + 11909559, + 1782390, + 12641087, + 20603771, + -6561742 + ]), + xy2d: FieldElement.uncheck([ + -18882287, + -11673380, + 24849422, + 11501709, + 13161720, + -4768874, + 1925523, + 11914390, + 4662781, + 7820689 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 12241050, + -425982, + 8132691, + 9393934, + 32846760, + -1599620, + 29749456, + 12172924, + 16136752, + 15264020 + ]), + yminusx: FieldElement.uncheck([ + -10349955, + -14680563, + -8211979, + 2330220, + -17662549, + -14545780, + 10658213, + 6671822, + 19012087, + 3772772 + ]), + xy2d: FieldElement.uncheck([ + 3753511, + -3421066, + 10617074, + 2028709, + 14841030, + -6721664, + 28718732, + -15762884, + 20527771, + 12988982 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -14822485, + -5797269, + -3707987, + 12689773, + -898983, + -10914866, + -24183046, + -10564943, + 3299665, + -12424953 + ]), + yminusx: FieldElement.uncheck([ + -16777703, + -15253301, + -9642417, + 4978983, + 3308785, + 8755439, + 6943197, + 6461331, + -25583147, + 8991218 + ]), + xy2d: FieldElement.uncheck([ + -17226263, + 1816362, + -1673288, + -6086439, + 31783888, + -8175991, + -32948145, + 7417950, + -30242287, + 1507265 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 29692663, + 6829891, + -10498800, + 4334896, + 20945975, + -11906496, + -28887608, + 8209391, + 14606362, + -10647073 + ]), + yminusx: FieldElement.uncheck([ + -3481570, + 8707081, + 32188102, + 5672294, + 22096700, + 1711240, + -33020695, + 9761487, + 4170404, + -2085325 + ]), + xy2d: FieldElement.uncheck([ + -11587470, + 14855945, + -4127778, + -1531857, + -26649089, + 15084046, + 22186522, + 16002000, + -14276837, + -8400798 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -4811456, + 13761029, + -31703877, + -2483919, + -3312471, + 7869047, + -7113572, + -9620092, + 13240845, + 10965870 + ]), + yminusx: FieldElement.uncheck([ + -7742563, + -8256762, + -14768334, + -13656260, + -23232383, + 12387166, + 4498947, + 14147411, + 29514390, + 4302863 + ]), + xy2d: FieldElement.uncheck([ + -13413405, + -12407859, + 20757302, + -13801832, + 14785143, + 8976368, + -5061276, + -2144373, + 17846988, + -13971927 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -2244452, + -754728, + -4597030, + -1066309, + -6247172, + 1455299, + -21647728, + -9214789, + -5222701, + 12650267 + ]), + yminusx: FieldElement.uncheck([ + -9906797, + -16070310, + 21134160, + 12198166, + -27064575, + 708126, + 387813, + 13770293, + -19134326, + 10958663 + ]), + xy2d: FieldElement.uncheck([ + 22470984, + 12369526, + 23446014, + -5441109, + -21520802, + -9698723, + -11772496, + -11574455, + -25083830, + 4271862 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25169565, + -10053642, + -19909332, + 15361595, + -5984358, + 2159192, + 75375, + -4278529, + -32526221, + 8469673 + ]), + yminusx: FieldElement.uncheck([ + 15854970, + 4148314, + -8893890, + 7259002, + 11666551, + 13824734, + -30531198, + 2697372, + 24154791, + -9460943 + ]), + xy2d: FieldElement.uncheck([ + 15446137, + -15806644, + 29759747, + 14019369, + 30811221, + -9610191, + -31582008, + 12840104, + 24913809, + 9815020 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -4709286, + -5614269, + -31841498, + -12288893, + -14443537, + 10799414, + -9103676, + 13438769, + 18735128, + 9466238 + ]), + yminusx: FieldElement.uncheck([ + 11933045, + 9281483, + 5081055, + -5183824, + -2628162, + -4905629, + -7727821, + -10896103, + -22728655, + 16199064 + ]), + xy2d: FieldElement.uncheck([ + 14576810, + 379472, + -26786533, + -8317236, + -29426508, + -10812974, + -102766, + 1876699, + 30801119, + 2164795 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15995086, + 3199873, + 13672555, + 13712240, + -19378835, + -4647646, + -13081610, + -15496269, + -13492807, + 1268052 + ]), + yminusx: FieldElement.uncheck([ + -10290614, + -3659039, + -3286592, + 10948818, + 23037027, + 3794475, + -3470338, + -12600221, + -17055369, + 3565904 + ]), + xy2d: FieldElement.uncheck([ + 29210088, + -9419337, + -5919792, + -4952785, + 10834811, + -13327726, + -16512102, + -10820713, + -27162222, + -14030531 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -13161890, + 15508588, + 16663704, + -8156150, + -28349942, + 9019123, + -29183421, + -3769423, + 2244111, + -14001979 + ]), + yminusx: FieldElement.uncheck([ + -5152875, + -3800936, + -9306475, + -6071583, + 16243069, + 14684434, + -25673088, + -16180800, + 13491506, + 4641841 + ]), + xy2d: FieldElement.uncheck([ + 10813417, + 643330, + -19188515, + -728916, + 30292062, + -16600078, + 27548447, + -7721242, + 14476989, + -12767431 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 10292079, + 9984945, + 6481436, + 8279905, + -7251514, + 7032743, + 27282937, + -1644259, + -27912810, + 12651324 + ]), + yminusx: FieldElement.uncheck([ + -31185513, + -813383, + 22271204, + 11835308, + 10201545, + 15351028, + 17099662, + 3988035, + 21721536, + -3148940 + ]), + xy2d: FieldElement.uncheck([ + 10202177, + -6545839, + -31373232, + -9574638, + -32150642, + -8119683, + -12906320, + 3852694, + 13216206, + 14842320 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -15815640, + -10601066, + -6538952, + -7258995, + -6984659, + -6581778, + -31500847, + 13765824, + -27434397, + 9900184 + ]), + yminusx: FieldElement.uncheck([ + 14465505, + -13833331, + -32133984, + -14738873, + -27443187, + 12990492, + 33046193, + 15796406, + -7051866, + -8040114 + ]), + xy2d: FieldElement.uncheck([ + 30924417, + -8279620, + 6359016, + -12816335, + 16508377, + 9071735, + -25488601, + 15413635, + 9524356, + -7018878 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 12274201, + -13175547, + 32627641, + -1785326, + 6736625, + 13267305, + 5237659, + -5109483, + 15663516, + 4035784 + ]), + yminusx: FieldElement.uncheck([ + -2951309, + 8903985, + 17349946, + 601635, + -16432815, + -4612556, + -13732739, + -15889334, + -22258478, + 4659091 + ]), + xy2d: FieldElement.uncheck([ + -16916263, + -4952973, + -30393711, + -15158821, + 20774812, + 15897498, + 5736189, + 15026997, + -2178256, + -13455585 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -8858980, + -2219056, + 28571666, + -10155518, + -474467, + -10105698, + -3801496, + 278095, + 23440562, + -290208 + ]), + yminusx: FieldElement.uncheck([ + 10226241, + -5928702, + 15139956, + 120818, + -14867693, + 5218603, + 32937275, + 11551483, + -16571960, + -7442864 + ]), + xy2d: FieldElement.uncheck([ + 17932739, + -12437276, + -24039557, + 10749060, + 11316803, + 7535897, + 22503767, + 5561594, + -3646624, + 3898661 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 7749907, + -969567, + -16339731, + -16464, + -25018111, + 15122143, + -1573531, + 7152530, + 21831162, + 1245233 + ]), + yminusx: FieldElement.uncheck([ + 26958459, + -14658026, + 4314586, + 8346991, + -5677764, + 11960072, + -32589295, + -620035, + -30402091, + -16716212 + ]), + xy2d: FieldElement.uncheck([ + -12165896, + 9166947, + 33491384, + 13673479, + 29787085, + 13096535, + 6280834, + 14587357, + -22338025, + 13987525 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -24349909, + 7778775, + 21116000, + 15572597, + -4833266, + -5357778, + -4300898, + -5124639, + -7469781, + -2858068 + ]), + yminusx: FieldElement.uncheck([ + 9681908, + -6737123, + -31951644, + 13591838, + -6883821, + 386950, + 31622781, + 6439245, + -14581012, + 4091397 + ]), + xy2d: FieldElement.uncheck([ + -8426427, + 1470727, + -28109679, + -1596990, + 3978627, + -5123623, + -19622683, + 12092163, + 29077877, + -14741988 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 5269168, + -6859726, + -13230211, + -8020715, + 25932563, + 1763552, + -5606110, + -5505881, + -20017847, + 2357889 + ]), + yminusx: FieldElement.uncheck([ + 32264008, + -15407652, + -5387735, + -1160093, + -2091322, + -3946900, + 23104804, + -12869908, + 5727338, + 189038 + ]), + xy2d: FieldElement.uncheck([ + 14609123, + -8954470, + -6000566, + -16622781, + -14577387, + -7743898, + -26745169, + 10942115, + -25888931, + -14884697 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 20513500, + 5557931, + -15604613, + 7829531, + 26413943, + -2019404, + -21378968, + 7471781, + 13913677, + -5137875 + ]), + yminusx: FieldElement.uncheck([ + -25574376, + 11967826, + 29233242, + 12948236, + -6754465, + 4713227, + -8940970, + 14059180, + 12878652, + 8511905 + ]), + xy2d: FieldElement.uncheck([ + -25656801, + 3393631, + -2955415, + -7075526, + -2250709, + 9366908, + -30223418, + 6812974, + 5568676, + -3127656 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 11630004, + 12144454, + 2116339, + 13606037, + 27378885, + 15676917, + -17408753, + -13504373, + -14395196, + 8070818 + ]), + yminusx: FieldElement.uncheck([ + 27117696, + -10007378, + -31282771, + -5570088, + 1127282, + 12772488, + -29845906, + 10483306, + -11552749, + -1028714 + ]), + xy2d: FieldElement.uncheck([ + 10637467, + -5688064, + 5674781, + 1072708, + -26343588, + -6982302, + -1683975, + 9177853, + -27493162, + 15431203 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 20525145, + 10892566, + -12742472, + 12779443, + -29493034, + 16150075, + -28240519, + 14943142, + -15056790, + -7935931 + ]), + yminusx: FieldElement.uncheck([ + -30024462, + 5626926, + -551567, + -9981087, + 753598, + 11981191, + 25244767, + -3239766, + -3356550, + 9594024 + ]), + xy2d: FieldElement.uncheck([ + -23752644, + 2636870, + -5163910, + -10103818, + 585134, + 7877383, + 11345683, + -6492290, + 13352335, + -10977084 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -1931799, + -5407458, + 3304649, + -12884869, + 17015806, + -4877091, + -29783850, + -7752482, + -13215537, + -319204 + ]), + yminusx: FieldElement.uncheck([ + 20239939, + 6607058, + 6203985, + 3483793, + -18386976, + -779229, + -20723742, + 15077870, + -22750759, + 14523817 + ]), + xy2d: FieldElement.uncheck([ + 27406042, + -6041657, + 27423596, + -4497394, + 4996214, + 10002360, + -28842031, + -4545494, + -30172742, + -4805667 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 11374242, + 12660715, + 17861383, + -12540833, + 10935568, + 1099227, + -13886076, + -9091740, + -27727044, + 11358504 + ]), + yminusx: FieldElement.uncheck([ + -12730809, + 10311867, + 1510375, + 10778093, + -2119455, + -9145702, + 32676003, + 11149336, + -26123651, + 4985768 + ]), + xy2d: FieldElement.uncheck([ + -19096303, + 341147, + -6197485, + -239033, + 15756973, + -8796662, + -983043, + 13794114, + -19414307, + -15621255 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 6490081, + 11940286, + 25495923, + -7726360, + 8668373, + -8751316, + 3367603, + 6970005, + -1691065, + -9004790 + ]), + yminusx: FieldElement.uncheck([ + 1656497, + 13457317, + 15370807, + 6364910, + 13605745, + 8362338, + -19174622, + -5475723, + -16796596, + -5031438 + ]), + xy2d: FieldElement.uncheck([ + -22273315, + -13524424, + -64685, + -4334223, + -18605636, + -10921968, + -20571065, + -7007978, + -99853, + -10237333 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 17747465, + 10039260, + 19368299, + -4050591, + -20630635, + -16041286, + 31992683, + -15857976, + -29260363, + -5511971 + ]), + yminusx: FieldElement.uncheck([ + 31932027, + -4986141, + -19612382, + 16366580, + 22023614, + 88450, + 11371999, + -3744247, + 4882242, + -10626905 + ]), + xy2d: FieldElement.uncheck([ + 29796507, + 37186, + 19818052, + 10115756, + -11829032, + 3352736, + 18551198, + 3272828, + -5190932, + -4162409 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 12501286, + 4044383, + -8612957, + -13392385, + -32430052, + 5136599, + -19230378, + -3529697, + 330070, + -3659409 + ]), + yminusx: FieldElement.uncheck([ + 6384877, + 2899513, + 17807477, + 7663917, + -2358888, + 12363165, + 25366522, + -8573892, + -271295, + 12071499 + ]), + xy2d: FieldElement.uncheck([ + -8365515, + -4042521, + 25133448, + -4517355, + -6211027, + 2265927, + -32769618, + 1936675, + -5159697, + 3829363 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 28425966, + -5835433, + -577090, + -4697198, + -14217555, + 6870930, + 7921550, + -6567787, + 26333140, + 14267664 + ]), + yminusx: FieldElement.uncheck([ + -11067219, + 11871231, + 27385719, + -10559544, + -4585914, + -11189312, + 10004786, + -8709488, + -21761224, + 8930324 + ]), + xy2d: FieldElement.uncheck([ + -21197785, + -16396035, + 25654216, + -1725397, + 12282012, + 11008919, + 1541940, + 4757911, + -26491501, + -16408940 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 13537262, + -7759490, + -20604840, + 10961927, + -5922820, + -13218065, + -13156584, + 6217254, + -15943699, + 13814990 + ]), + yminusx: FieldElement.uncheck([ + -17422573, + 15157790, + 18705543, + 29619, + 24409717, + -260476, + 27361681, + 9257833, + -1956526, + -1776914 + ]), + xy2d: FieldElement.uncheck([ + -25045300, + -10191966, + 15366585, + 15166509, + -13105086, + 8423556, + -29171540, + 12361135, + -18685978, + 4578290 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 24579768, + 3711570, + 1342322, + -11180126, + -27005135, + 14124956, + -22544529, + 14074919, + 21964432, + 8235257 + ]), + yminusx: FieldElement.uncheck([ + -6528613, + -2411497, + 9442966, + -5925588, + 12025640, + -1487420, + -2981514, + -1669206, + 13006806, + 2355433 + ]), + xy2d: FieldElement.uncheck([ + -16304899, + -13605259, + -6632427, + -5142349, + 16974359, + -10911083, + 27202044, + 1719366, + 1141648, + -12796236 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -12863944, + -13219986, + -8318266, + -11018091, + -6810145, + -4843894, + 13475066, + -3133972, + 32674895, + 13715045 + ]), + yminusx: FieldElement.uncheck([ + 11423335, + -5468059, + 32344216, + 8962751, + 24989809, + 9241752, + -13265253, + 16086212, + -28740881, + -15642093 + ]), + xy2d: FieldElement.uncheck([ + -1409668, + 12530728, + -6368726, + 10847387, + 19531186, + -14132160, + -11709148, + 7791794, + -27245943, + 4383347 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -28970898, + 5271447, + -1266009, + -9736989, + -12455236, + 16732599, + -4862407, + -4906449, + 27193557, + 6245191 + ]), + yminusx: FieldElement.uncheck([ + -15193956, + 5362278, + -1783893, + 2695834, + 4960227, + 12840725, + 23061898, + 3260492, + 22510453, + 8577507 + ]), + xy2d: FieldElement.uncheck([ + -12632451, + 11257346, + -32692994, + 13548177, + -721004, + 10879011, + 31168030, + 13952092, + -29571492, + -3635906 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 3877321, + -9572739, + 32416692, + 5405324, + -11004407, + -13656635, + 3759769, + 11935320, + 5611860, + 8164018 + ]), + yminusx: FieldElement.uncheck([ + -16275802, + 14667797, + 15906460, + 12155291, + -22111149, + -9039718, + 32003002, + -8832289, + 5773085, + -8422109 + ]), + xy2d: FieldElement.uncheck([ + -23788118, + -8254300, + 1950875, + 8937633, + 18686727, + 16459170, + -905725, + 12376320, + 31632953, + 190926 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -24593607, + -16138885, + -8423991, + 13378746, + 14162407, + 6901328, + -8288749, + 4508564, + -25341555, + -3627528 + ]), + yminusx: FieldElement.uncheck([ + 8884438, + -5884009, + 6023974, + 10104341, + -6881569, + -4941533, + 18722941, + -14786005, + -1672488, + 827625 + ]), + xy2d: FieldElement.uncheck([ + -32720583, + -16289296, + -32503547, + 7101210, + 13354605, + 2659080, + -1800575, + -14108036, + -24878478, + 1541286 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 2901347, + -1117687, + 3880376, + -10059388, + -17620940, + -3612781, + -21802117, + -3567481, + 20456845, + -1885033 + ]), + yminusx: FieldElement.uncheck([ + 27019610, + 12299467, + -13658288, + -1603234, + -12861660, + -4861471, + -19540150, + -5016058, + 29439641, + 15138866 + ]), + xy2d: FieldElement.uncheck([ + 21536104, + -6626420, + -32447818, + -10690208, + -22408077, + 5175814, + -5420040, + -16361163, + 7779328, + 109896 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30279744, + 14648750, + -8044871, + 6425558, + 13639621, + -743509, + 28698390, + 12180118, + 23177719, + -554075 + ]), + yminusx: FieldElement.uncheck([ + 26572847, + 3405927, + -31701700, + 12890905, + -19265668, + 5335866, + -6493768, + 2378492, + 4439158, + -13279347 + ]), + xy2d: FieldElement.uncheck([ + -22716706, + 3489070, + -9225266, + -332753, + 18875722, + -1140095, + 14819434, + -12731527, + -17717757, + -5461437 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -5056483, + 16566551, + 15953661, + 3767752, + -10436499, + 15627060, + -820954, + 2177225, + 8550082, + -15114165 + ]), + yminusx: FieldElement.uncheck([ + -18473302, + 16596775, + -381660, + 15663611, + 22860960, + 15585581, + -27844109, + -3582739, + -23260460, + -8428588 + ]), + xy2d: FieldElement.uncheck([ + -32480551, + 15707275, + -8205912, + -5652081, + 29464558, + 2713815, + -22725137, + 15860482, + -21902570, + 1494193 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -19562091, + -14087393, + -25583872, + -9299552, + 13127842, + 759709, + 21923482, + 16529112, + 8742704, + 12967017 + ]), + yminusx: FieldElement.uncheck([ + -28464899, + 1553205, + 32536856, + -10473729, + -24691605, + -406174, + -8914625, + -2933896, + -29903758, + 15553883 + ]), + xy2d: FieldElement.uncheck([ + 21877909, + 3230008, + 9881174, + 10539357, + -4797115, + 2841332, + 11543572, + 14513274, + 19375923, + -12647961 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 8832269, + -14495485, + 13253511, + 5137575, + 5037871, + 4078777, + 24880818, + -6222716, + 2862653, + 9455043 + ]), + yminusx: FieldElement.uncheck([ + 29306751, + 5123106, + 20245049, + -14149889, + 9592566, + 8447059, + -2077124, + -2990080, + 15511449, + 4789663 + ]), + xy2d: FieldElement.uncheck([ + -20679756, + 7004547, + 8824831, + -9434977, + -4045704, + -3750736, + -5754762, + 108893, + 23513200, + 16652362 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -33256173, + 4144782, + -4476029, + -6579123, + 10770039, + -7155542, + -6650416, + -12936300, + -18319198, + 10212860 + ]), + yminusx: FieldElement.uncheck([ + 2756081, + 8598110, + 7383731, + -6859892, + 22312759, + -1105012, + 21179801, + 2600940, + -9988298, + -12506466 + ]), + xy2d: FieldElement.uncheck([ + -24645692, + 13317462, + -30449259, + -15653928, + 21365574, + -10869657, + 11344424, + 864440, + -2499677, + -16710063 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -26432803, + 6148329, + -17184412, + -14474154, + 18782929, + -275997, + -22561534, + 211300, + 2719757, + 4940997 + ]), + yminusx: FieldElement.uncheck([ + -1323882, + 3911313, + -6948744, + 14759765, + -30027150, + 7851207, + 21690126, + 8518463, + 26699843, + 5276295 + ]), + xy2d: FieldElement.uncheck([ + -13149873, + -6429067, + 9396249, + 365013, + 24703301, + -10488939, + 1321586, + 149635, + -15452774, + 7159369 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 9987780, + -3404759, + 17507962, + 9505530, + 9731535, + -2165514, + 22356009, + 8312176, + 22477218, + -8403385 + ]), + yminusx: FieldElement.uncheck([ + 18155857, + -16504990, + 19744716, + 9006923, + 15154154, + -10538976, + 24256460, + -4864995, + -22548173, + 9334109 + ]), + xy2d: FieldElement.uncheck([ + 2986088, + -4911893, + 10776628, + -3473844, + 10620590, + -7083203, + -21413845, + 14253545, + -22587149, + 536906 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 4377756, + 8115836, + 24567078, + 15495314, + 11625074, + 13064599, + 7390551, + 10589625, + 10838060, + -15420424 + ]), + yminusx: FieldElement.uncheck([ + -19342404, + 867880, + 9277171, + -3218459, + -14431572, + -1986443, + 19295826, + -15796950, + 6378260, + 699185 + ]), + xy2d: FieldElement.uncheck([ + 7895026, + 4057113, + -7081772, + -13077756, + -17886831, + -323126, + -716039, + 15693155, + -5045064, + -13373962 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -7737563, + -5869402, + -14566319, + -7406919, + 11385654, + 13201616, + 31730678, + -10962840, + -3918636, + -9669325 + ]), + yminusx: FieldElement.uncheck([ + 10188286, + -15770834, + -7336361, + 13427543, + 22223443, + 14896287, + 30743455, + 7116568, + -21786507, + 5427593 + ]), + xy2d: FieldElement.uncheck([ + 696102, + 13206899, + 27047647, + -10632082, + 15285305, + -9853179, + 10798490, + -4578720, + 19236243, + 12477404 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -11229439, + 11243796, + -17054270, + -8040865, + -788228, + -8167967, + -3897669, + 11180504, + -23169516, + 7733644 + ]), + yminusx: FieldElement.uncheck([ + 17800790, + -14036179, + -27000429, + -11766671, + 23887827, + 3149671, + 23466177, + -10538171, + 10322027, + 15313801 + ]), + xy2d: FieldElement.uncheck([ + 26246234, + 11968874, + 32263343, + -5468728, + 6830755, + -13323031, + -15794704, + -101982, + -24449242, + 10890804 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -31365647, + 10271363, + -12660625, + -6267268, + 16690207, + -13062544, + -14982212, + 16484931, + 25180797, + -5334884 + ]), + yminusx: FieldElement.uncheck([ + -586574, + 10376444, + -32586414, + -11286356, + 19801893, + 10997610, + 2276632, + 9482883, + 316878, + 13820577 + ]), + xy2d: FieldElement.uncheck([ + -9882808, + -4510367, + -2115506, + 16457136, + -11100081, + 11674996, + 30756178, + -7515054, + 30696930, + -3712849 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 32988917, + -9603412, + 12499366, + 7910787, + -10617257, + -11931514, + -7342816, + -9985397, + -32349517, + 7392473 + ]), + yminusx: FieldElement.uncheck([ + -8855661, + 15927861, + 9866406, + -3649411, + -2396914, + -16655781, + -30409476, + -9134995, + 25112947, + -2926644 + ]), + xy2d: FieldElement.uncheck([ + -2504044, + -436966, + 25621774, + -5678772, + 15085042, + -5479877, + -24884878, + -13526194, + 5537438, + -13914319 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -11225584, + 2320285, + -9584280, + 10149187, + -33444663, + 5808648, + -14876251, + -1729667, + 31234590, + 6090599 + ]), + yminusx: FieldElement.uncheck([ + -9633316, + 116426, + 26083934, + 2897444, + -6364437, + -2688086, + 609721, + 15878753, + -6970405, + -9034768 + ]), + xy2d: FieldElement.uncheck([ + -27757857, + 247744, + -15194774, + -9002551, + 23288161, + -10011936, + -23869595, + 6503646, + 20650474, + 1804084 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -27589786, + 15456424, + 8972517, + 8469608, + 15640622, + 4439847, + 3121995, + -10329713, + 27842616, + -202328 + ]), + yminusx: FieldElement.uncheck([ + -15306973, + 2839644, + 22530074, + 10026331, + 4602058, + 5048462, + 28248656, + 5031932, + -11375082, + 12714369 + ]), + xy2d: FieldElement.uncheck([ + 20807691, + -7270825, + 29286141, + 11421711, + -27876523, + -13868230, + -21227475, + 1035546, + -19733229, + 12796920 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 12076899, + -14301286, + -8785001, + -11848922, + -25012791, + 16400684, + -17591495, + -12899438, + 3480665, + -15182815 + ]), + yminusx: FieldElement.uncheck([ + -32361549, + 5457597, + 28548107, + 7833186, + 7303070, + -11953545, + -24363064, + -15921875, + -33374054, + 2771025 + ]), + xy2d: FieldElement.uncheck([ + -21389266, + 421932, + 26597266, + 6860826, + 22486084, + -6737172, + -17137485, + -4210226, + -24552282, + 15673397 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -20184622, + 2338216, + 19788685, + -9620956, + -4001265, + -8740893, + -20271184, + 4733254, + 3727144, + -12934448 + ]), + yminusx: FieldElement.uncheck([ + 6120119, + 814863, + -11794402, + -622716, + 6812205, + -15747771, + 2019594, + 7975683, + 31123697, + -10958981 + ]), + xy2d: FieldElement.uncheck([ + 30069250, + -11435332, + 30434654, + 2958439, + 18399564, + -976289, + 12296869, + 9204260, + -16432438, + 9648165 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 32705432, + -1550977, + 30705658, + 7451065, + -11805606, + 9631813, + 3305266, + 5248604, + -26008332, + -11377501 + ]), + yminusx: FieldElement.uncheck([ + 17219865, + 2375039, + -31570947, + -5575615, + -19459679, + 9219903, + 294711, + 15298639, + 2662509, + -16297073 + ]), + xy2d: FieldElement.uncheck([ + -1172927, + -7558695, + -4366770, + -4287744, + -21346413, + -8434326, + 32087529, + -1222777, + 32247248, + -14389861 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 14312628, + 1221556, + 17395390, + -8700143, + -4945741, + -8684635, + -28197744, + -9637817, + -16027623, + -13378845 + ]), + yminusx: FieldElement.uncheck([ + -1428825, + -9678990, + -9235681, + 6549687, + -7383069, + -468664, + 23046502, + 9803137, + 17597934, + 2346211 + ]), + xy2d: FieldElement.uncheck([ + 18510800, + 15337574, + 26171504, + 981392, + -22241552, + 7827556, + -23491134, + -11323352, + 3059833, + -11782870 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 10141598, + 6082907, + 17829293, + -1947643, + 9830092, + 13613136, + -25556636, + -5544586, + -33502212, + 3592096 + ]), + yminusx: FieldElement.uncheck([ + 33114168, + -15889352, + -26525686, + -13343397, + 33076705, + 8716171, + 1151462, + 1521897, + -982665, + -6837803 + ]), + xy2d: FieldElement.uncheck([ + -32939165, + -4255815, + 23947181, + -324178, + -33072974, + -12305637, + -16637686, + 3891704, + 26353178, + 693168 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30374239, + 1595580, + -16884039, + 13186931, + 4600344, + 406904, + 9585294, + -400668, + 31375464, + 14369965 + ]), + yminusx: FieldElement.uncheck([ + -14370654, + -7772529, + 1510301, + 6434173, + -18784789, + -6262728, + 32732230, + -13108839, + 17901441, + 16011505 + ]), + xy2d: FieldElement.uncheck([ + 18171223, + -11934626, + -12500402, + 15197122, + -11038147, + -15230035, + -19172240, + -16046376, + 8764035, + 12309598 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 5975908, + -5243188, + -19459362, + -9681747, + -11541277, + 14015782, + -23665757, + 1228319, + 17544096, + -10593782 + ]), + yminusx: FieldElement.uncheck([ + 5811932, + -1715293, + 3442887, + -2269310, + -18367348, + -8359541, + -18044043, + -15410127, + -5565381, + 12348900 + ]), + xy2d: FieldElement.uncheck([ + -31399660, + 11407555, + 25755363, + 6891399, + -3256938, + 14872274, + -24849353, + 8141295, + -10632534, + -585479 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -12675304, + 694026, + -5076145, + 13300344, + 14015258, + -14451394, + -9698672, + -11329050, + 30944593, + 1130208 + ]), + yminusx: FieldElement.uncheck([ + 8247766, + -6710942, + -26562381, + -7709309, + -14401939, + -14648910, + 4652152, + 2488540, + 23550156, + -271232 + ]), + xy2d: FieldElement.uncheck([ + 17294316, + -3788438, + 7026748, + 15626851, + 22990044, + 113481, + 2267737, + -5908146, + -408818, + -137719 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 16091085, + -16253926, + 18599252, + 7340678, + 2137637, + -1221657, + -3364161, + 14550936, + 3260525, + -7166271 + ]), + yminusx: FieldElement.uncheck([ + -4910104, + -13332887, + 18550887, + 10864893, + -16459325, + -7291596, + -23028869, + -13204905, + -12748722, + 2701326 + ]), + xy2d: FieldElement.uncheck([ + -8574695, + 16099415, + 4629974, + -16340524, + -20786213, + -6005432, + -10018363, + 9276971, + 11329923, + 1862132 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 14763076, + -15903608, + -30918270, + 3689867, + 3511892, + 10313526, + -21951088, + 12219231, + -9037963, + -940300 + ]), + yminusx: FieldElement.uncheck([ + 8894987, + -3446094, + 6150753, + 3013931, + 301220, + 15693451, + -31981216, + -2909717, + -15438168, + 11595570 + ]), + xy2d: FieldElement.uncheck([ + 15214962, + 3537601, + -26238722, + -14058872, + 4418657, + -15230761, + 13947276, + 10730794, + -13489462, + -4363670 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -2538306, + 7682793, + 32759013, + 263109, + -29984731, + -7955452, + -22332124, + -10188635, + 977108, + 699994 + ]), + yminusx: FieldElement.uncheck([ + -12466472, + 4195084, + -9211532, + 550904, + -15565337, + 12917920, + 19118110, + -439841, + -30534533, + -14337913 + ]), + xy2d: FieldElement.uncheck([ + 31788461, + -14507657, + 4799989, + 7372237, + 8808585, + -14747943, + 9408237, + -10051775, + 12493932, + -5409317 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25680606, + 5260744, + -19235809, + -6284470, + -3695942, + 16566087, + 27218280, + 2607121, + 29375955, + 6024730 + ]), + yminusx: FieldElement.uncheck([ + 842132, + -2794693, + -4763381, + -8722815, + 26332018, + -12405641, + 11831880, + 6985184, + -9940361, + 2854096 + ]), + xy2d: FieldElement.uncheck([ + -4847262, + -7969331, + 2516242, + -5847713, + 9695691, + -7221186, + 16512645, + 960770, + 12121869, + 16648078 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -15218652, + 14667096, + -13336229, + 2013717, + 30598287, + -464137, + -31504922, + -7882064, + 20237806, + 2838411 + ]), + yminusx: FieldElement.uncheck([ + -19288047, + 4453152, + 15298546, + -16178388, + 22115043, + -15972604, + 12544294, + -13470457, + 1068881, + -12499905 + ]), + xy2d: FieldElement.uncheck([ + -9558883, + -16518835, + 33238498, + 13506958, + 30505848, + -1114596, + -8486907, + -2630053, + 12521378, + 4845654 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -28198521, + 10744108, + -2958380, + 10199664, + 7759311, + -13088600, + 3409348, + -873400, + -6482306, + -12885870 + ]), + yminusx: FieldElement.uncheck([ + -23561822, + 6230156, + -20382013, + 10655314, + -24040585, + -11621172, + 10477734, + -1240216, + -3113227, + 13974498 + ]), + xy2d: FieldElement.uncheck([ + 12966261, + 15550616, + -32038948, + -1615346, + 21025980, + -629444, + 5642325, + 7188737, + 18895762, + 12629579 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 14741879, + -14946887, + 22177208, + -11721237, + 1279741, + 8058600, + 11758140, + 789443, + 32195181, + 3895677 + ]), + yminusx: FieldElement.uncheck([ + 10758205, + 15755439, + -4509950, + 9243698, + -4879422, + 6879879, + -2204575, + -3566119, + -8982069, + 4429647 + ]), + xy2d: FieldElement.uncheck([ + -2453894, + 15725973, + -20436342, + -10410672, + -5803908, + -11040220, + -7135870, + -11642895, + 18047436, + -15281743 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25173001, + -11307165, + 29759956, + 11776784, + -22262383, + -15820455, + 10993114, + -12850837, + -17620701, + -9408468 + ]), + yminusx: FieldElement.uncheck([ + 21987233, + 700364, + -24505048, + 14972008, + -7774265, + -5718395, + 32155026, + 2581431, + -29958985, + 8773375 + ]), + xy2d: FieldElement.uncheck([ + -25568350, + 454463, + -13211935, + 16126715, + 25240068, + 8594567, + 20656846, + 12017935, + -7874389, + -13920155 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 6028182, + 6263078, + -31011806, + -11301710, + -818919, + 2461772, + -31841174, + -5468042, + -1721788, + -2776725 + ]), + yminusx: FieldElement.uncheck([ + -12278994, + 16624277, + 987579, + -5922598, + 32908203, + 1248608, + 7719845, + -4166698, + 28408820, + 6816612 + ]), + xy2d: FieldElement.uncheck([ + -10358094, + -8237829, + 19549651, + -12169222, + 22082623, + 16147817, + 20613181, + 13982702, + -10339570, + 5067943 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -30505967, + -3821767, + 12074681, + 13582412, + -19877972, + 2443951, + -19719286, + 12746132, + 5331210, + -10105944 + ]), + yminusx: FieldElement.uncheck([ + 30528811, + 3601899, + -1957090, + 4619785, + -27361822, + -15436388, + 24180793, + -12570394, + 27679908, + -1648928 + ]), + xy2d: FieldElement.uncheck([ + 9402404, + -13957065, + 32834043, + 10838634, + -26580150, + -13237195, + 26653274, + -8685565, + 22611444, + -12715406 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 22190590, + 1118029, + 22736441, + 15130463, + -30460692, + -5991321, + 19189625, + -4648942, + 4854859, + 6622139 + ]), + yminusx: FieldElement.uncheck([ + -8310738, + -2953450, + -8262579, + -3388049, + -10401731, + -271929, + 13424426, + -3567227, + 26404409, + 13001963 + ]), + xy2d: FieldElement.uncheck([ + -31241838, + -15415700, + -2994250, + 8939346, + 11562230, + -12840670, + -26064365, + -11621720, + -15405155, + 11020693 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 1866042, + -7949489, + -7898649, + -10301010, + 12483315, + 13477547, + 3175636, + -12424163, + 28761762, + 1406734 + ]), + yminusx: FieldElement.uncheck([ + -448555, + -1777666, + 13018551, + 3194501, + -9580420, + -11161737, + 24760585, + -4347088, + 25577411, + -13378680 + ]), + xy2d: FieldElement.uncheck([ + -24290378, + 4759345, + -690653, + -1852816, + 2066747, + 10693769, + -29595790, + 9884936, + -9368926, + 4745410 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -9141284, + 6049714, + -19531061, + -4341411, + -31260798, + 9944276, + -15462008, + -11311852, + 10931924, + -11931931 + ]), + yminusx: FieldElement.uncheck([ + -16561513, + 14112680, + -8012645, + 4817318, + -8040464, + -11414606, + -22853429, + 10856641, + -20470770, + 13434654 + ]), + xy2d: FieldElement.uncheck([ + 22759489, + -10073434, + -16766264, + -1871422, + 13637442, + -10168091, + 1765144, + -12654326, + 28445307, + -5364710 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 29875063, + 12493613, + 2795536, + -3786330, + 1710620, + 15181182, + -10195717, + -8788675, + 9074234, + 1167180 + ]), + yminusx: FieldElement.uncheck([ + -26205683, + 11014233, + -9842651, + -2635485, + -26908120, + 7532294, + -18716888, + -9535498, + 3843903, + 9367684 + ]), + xy2d: FieldElement.uncheck([ + -10969595, + -6403711, + 9591134, + 9582310, + 11349256, + 108879, + 16235123, + 8601684, + -139197, + 4242895 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 22092954, + -13191123, + -2042793, + -11968512, + 32186753, + -11517388, + -6574341, + 2470660, + -27417366, + 16625501 + ]), + yminusx: FieldElement.uncheck([ + -11057722, + 3042016, + 13770083, + -9257922, + 584236, + -544855, + -7770857, + 2602725, + -27351616, + 14247413 + ]), + xy2d: FieldElement.uncheck([ + 6314175, + -10264892, + -32772502, + 15957557, + -10157730, + 168750, + -8618807, + 14290061, + 27108877, + -1180880 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -8586597, + -7170966, + 13241782, + 10960156, + -32991015, + -13794596, + 33547976, + -11058889, + -27148451, + 981874 + ]), + yminusx: FieldElement.uncheck([ + 22833440, + 9293594, + -32649448, + -13618667, + -9136966, + 14756819, + -22928859, + -13970780, + -10479804, + -16197962 + ]), + xy2d: FieldElement.uncheck([ + -7768587, + 3326786, + -28111797, + 10783824, + 19178761, + 14905060, + 22680049, + 13906969, + -15933690, + 3797899 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 21721356, + -4212746, + -12206123, + 9310182, + -3882239, + -13653110, + 23740224, + -2709232, + 20491983, + -8042152 + ]), + yminusx: FieldElement.uncheck([ + 9209270, + -15135055, + -13256557, + -6167798, + -731016, + 15289673, + 25947805, + 15286587, + 30997318, + -6703063 + ]), + xy2d: FieldElement.uncheck([ + 7392032, + 16618386, + 23946583, + -8039892, + -13265164, + -1533858, + -14197445, + -2321576, + 17649998, + -250080 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -9301088, + -14193827, + 30609526, + -3049543, + -25175069, + -1283752, + -15241566, + -9525724, + -2233253, + 7662146 + ]), + yminusx: FieldElement.uncheck([ + -17558673, + 1763594, + -33114336, + 15908610, + -30040870, + -12174295, + 7335080, + -8472199, + -3174674, + 3440183 + ]), + xy2d: FieldElement.uncheck([ + -19889700, + -5977008, + -24111293, + -9688870, + 10799743, + -16571957, + 40450, + -4431835, + 4862400, + 1133 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -32856209, + -7873957, + -5422389, + 14860950, + -16319031, + 7956142, + 7258061, + 311861, + -30594991, + -7379421 + ]), + yminusx: FieldElement.uncheck([ + -3773428, + -1565936, + 28985340, + 7499440, + 24445838, + 9325937, + 29727763, + 16527196, + 18278453, + 15405622 + ]), + xy2d: FieldElement.uncheck([ + -4381906, + 8508652, + -19898366, + -3674424, + -5984453, + 15149970, + -13313598, + 843523, + -21875062, + 13626197 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 2281448, + -13487055, + -10915418, + -2609910, + 1879358, + 16164207, + -10783882, + 3953792, + 13340839, + 15928663 + ]), + yminusx: FieldElement.uncheck([ + 31727126, + -7179855, + -18437503, + -8283652, + 2875793, + -16390330, + -25269894, + -7014826, + -23452306, + 5964753 + ]), + xy2d: FieldElement.uncheck([ + 4100420, + -5959452, + -17179337, + 6017714, + -18705837, + 12227141, + -26684835, + 11344144, + 2538215, + -7570755 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -9433605, + 6123113, + 11159803, + -2156608, + 30016280, + 14966241, + -20474983, + 1485421, + -629256, + -15958862 + ]), + yminusx: FieldElement.uncheck([ + -26804558, + 4260919, + 11851389, + 9658551, + -32017107, + 16367492, + -20205425, + -13191288, + 11659922, + -11115118 + ]), + xy2d: FieldElement.uncheck([ + 26180396, + 10015009, + -30844224, + -8581293, + 5418197, + 9480663, + 2231568, + -10170080, + 33100372, + -1306171 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15121113, + -5201871, + -10389905, + 15427821, + -27509937, + -15992507, + 21670947, + 4486675, + -5931810, + -14466380 + ]), + yminusx: FieldElement.uncheck([ + 16166486, + -9483733, + -11104130, + 6023908, + -31926798, + -1364923, + 2340060, + -16254968, + -10735770, + -10039824 + ]), + xy2d: FieldElement.uncheck([ + 28042865, + -3557089, + -12126526, + 12259706, + -3717498, + -6945899, + 6766453, + -8689599, + 18036436, + 5803270 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -817581, + 6763912, + 11803561, + 1585585, + 10958447, + -2671165, + 23855391, + 4598332, + -6159431, + -14117438 + ]), + yminusx: FieldElement.uncheck([ + -31031306, + -14256194, + 17332029, + -2383520, + 31312682, + -5967183, + 696309, + 50292, + -20095739, + 11763584 + ]), + xy2d: FieldElement.uncheck([ + -594563, + -2514283, + -32234153, + 12643980, + 12650761, + 14811489, + 665117, + -12613632, + -19773211, + -10713562 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30464590, + -11262872, + -4127476, + -12734478, + 19835327, + -7105613, + -24396175, + 2075773, + -17020157, + 992471 + ]), + yminusx: FieldElement.uncheck([ + 18357185, + -6994433, + 7766382, + 16342475, + -29324918, + 411174, + 14578841, + 8080033, + -11574335, + -10601610 + ]), + xy2d: FieldElement.uncheck([ + 19598397, + 10334610, + 12555054, + 2555664, + 18821899, + -10339780, + 21873263, + 16014234, + 26224780, + 16452269 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -30223925, + 5145196, + 5944548, + 16385966, + 3976735, + 2009897, + -11377804, + -7618186, + -20533829, + 3698650 + ]), + yminusx: FieldElement.uncheck([ + 14187449, + 3448569, + -10636236, + -10810935, + -22663880, + -3433596, + 7268410, + -10890444, + 27394301, + 12015369 + ]), + xy2d: FieldElement.uncheck([ + 19695761, + 16087646, + 28032085, + 12999827, + 6817792, + 11427614, + 20244189, + -1312777, + -13259127, + -3402461 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30860103, + 12735208, + -1888245, + -4699734, + -16974906, + 2256940, + -8166013, + 12298312, + -8550524, + -10393462 + ]), + yminusx: FieldElement.uncheck([ + -5719826, + -11245325, + -1910649, + 15569035, + 26642876, + -7587760, + -5789354, + -15118654, + -4976164, + 12651793 + ]), + xy2d: FieldElement.uncheck([ + -2848395, + 9953421, + 11531313, + -5282879, + 26895123, + -12697089, + -13118820, + -16517902, + 9768698, + -2533218 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -24719459, + 1894651, + -287698, + -4704085, + 15348719, + -8156530, + 32767513, + 12765450, + 4940095, + 10678226 + ]), + yminusx: FieldElement.uncheck([ + 18860224, + 15980149, + -18987240, + -1562570, + -26233012, + -11071856, + -7843882, + 13944024, + -24372348, + 16582019 + ]), + xy2d: FieldElement.uncheck([ + -15504260, + 4970268, + -29893044, + 4175593, + -20993212, + -2199756, + -11704054, + 15444560, + -11003761, + 7989037 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 31490452, + 5568061, + -2412803, + 2182383, + -32336847, + 4531686, + -32078269, + 6200206, + -19686113, + -14800171 + ]), + yminusx: FieldElement.uncheck([ + -17308668, + -15879940, + -31522777, + -2831, + -32887382, + 16375549, + 8680158, + -16371713, + 28550068, + -6857132 + ]), + xy2d: FieldElement.uncheck([ + -28126887, + -5688091, + 16837845, + -1820458, + -6850681, + 12700016, + -30039981, + 4364038, + 1155602, + 5988841 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 21890435, + -13272907, + -12624011, + 12154349, + -7831873, + 15300496, + 23148983, + -4470481, + 24618407, + 8283181 + ]), + yminusx: FieldElement.uncheck([ + -33136107, + -10512751, + 9975416, + 6841041, + -31559793, + 16356536, + 3070187, + -7025928, + 1466169, + 10740210 + ]), + xy2d: FieldElement.uncheck([ + -1509399, + -15488185, + -13503385, + -10655916, + 32799044, + 909394, + -13938903, + -5779719, + -32164649, + -15327040 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 3960823, + -14267803, + -28026090, + -15918051, + -19404858, + 13146868, + 15567327, + 951507, + -3260321, + -573935 + ]), + yminusx: FieldElement.uncheck([ + 24740841, + 5052253, + -30094131, + 8961361, + 25877428, + 6165135, + -24368180, + 14397372, + -7380369, + -6144105 + ]), + xy2d: FieldElement.uncheck([ + -28888365, + 3510803, + -28103278, + -1158478, + -11238128, + -10631454, + -15441463, + -14453128, + -1625486, + -6494814 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 793299, + -9230478, + 8836302, + -6235707, + -27360908, + -2369593, + 33152843, + -4885251, + -9906200, + -621852 + ]), + yminusx: FieldElement.uncheck([ + 5666233, + 525582, + 20782575, + -8038419, + -24538499, + 14657740, + 16099374, + 1468826, + -6171428, + -15186581 + ]), + xy2d: FieldElement.uncheck([ + -4859255, + -3779343, + -2917758, + -6748019, + 7778750, + 11688288, + -30404353, + -9871238, + -1558923, + -9863646 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 10896332, + -7719704, + 824275, + 472601, + -19460308, + 3009587, + 25248958, + 14783338, + -30581476, + -15757844 + ]), + yminusx: FieldElement.uncheck([ + 10566929, + 12612572, + -31944212, + 11118703, + -12633376, + 12362879, + 21752402, + 8822496, + 24003793, + 14264025 + ]), + xy2d: FieldElement.uncheck([ + 27713862, + -7355973, + -11008240, + 9227530, + 27050101, + 2504721, + 23886875, + -13117525, + 13958495, + -5732453 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -23481610, + 4867226, + -27247128, + 3900521, + 29838369, + -8212291, + -31889399, + -10041781, + 7340521, + -15410068 + ]), + yminusx: FieldElement.uncheck([ + 4646514, + -8011124, + -22766023, + -11532654, + 23184553, + 8566613, + 31366726, + -1381061, + -15066784, + -10375192 + ]), + xy2d: FieldElement.uncheck([ + -17270517, + 12723032, + -16993061, + 14878794, + 21619651, + -6197576, + 27584817, + 3093888, + -8843694, + 3849921 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -9064912, + 2103172, + 25561640, + -15125738, + -5239824, + 9582958, + 32477045, + -9017955, + 5002294, + -15550259 + ]), + yminusx: FieldElement.uncheck([ + -12057553, + -11177906, + 21115585, + -13365155, + 8808712, + -12030708, + 16489530, + 13378448, + -25845716, + 12741426 + ]), + xy2d: FieldElement.uncheck([ + -5946367, + 10645103, + -30911586, + 15390284, + -3286982, + -7118677, + 24306472, + 15852464, + 28834118, + -7646072 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -17335748, + -9107057, + -24531279, + 9434953, + -8472084, + -583362, + -13090771, + 455841, + 20461858, + 5491305 + ]), + yminusx: FieldElement.uncheck([ + 13669248, + -16095482, + -12481974, + -10203039, + -14569770, + -11893198, + -24995986, + 11293807, + -28588204, + -9421832 + ]), + xy2d: FieldElement.uncheck([ + 28497928, + 6272777, + -33022994, + 14470570, + 8906179, + -1225630, + 18504674, + -14165166, + 29867745, + -8795943 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -16207023, + 13517196, + -27799630, + -13697798, + 24009064, + -6373891, + -6367600, + -13175392, + 22853429, + -4012011 + ]), + yminusx: FieldElement.uncheck([ + 24191378, + 16712145, + -13931797, + 15217831, + 14542237, + 1646131, + 18603514, + -11037887, + 12876623, + -2112447 + ]), + xy2d: FieldElement.uncheck([ + 17902668, + 4518229, + -411702, + -2829247, + 26878217, + 5258055, + -12860753, + 608397, + 16031844, + 3723494 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -28632773, + 12763728, + -20446446, + 7577504, + 33001348, + -13017745, + 17558842, + -7872890, + 23896954, + -4314245 + ]), + yminusx: FieldElement.uncheck([ + -20005381, + -12011952, + 31520464, + 605201, + 2543521, + 5991821, + -2945064, + 7229064, + -9919646, + -8826859 + ]), + xy2d: FieldElement.uncheck([ + 28816045, + 298879, + -28165016, + -15920938, + 19000928, + -1665890, + -12680833, + -2949325, + -18051778, + -2082915 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 16000882, + -344896, + 3493092, + -11447198, + -29504595, + -13159789, + 12577740, + 16041268, + -19715240, + 7847707 + ]), + yminusx: FieldElement.uncheck([ + 10151868, + 10572098, + 27312476, + 7922682, + 14825339, + 4723128, + -32855931, + -6519018, + -10020567, + 3852848 + ]), + xy2d: FieldElement.uncheck([ + -11430470, + 15697596, + -21121557, + -4420647, + 5386314, + 15063598, + 16514493, + -15932110, + 29330899, + -15076224 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25499735, + -4378794, + -15222908, + -6901211, + 16615731, + 2051784, + 3303702, + 15490, + -27548796, + 12314391 + ]), + yminusx: FieldElement.uncheck([ + 15683520, + -6003043, + 18109120, + -9980648, + 15337968, + -5997823, + -16717435, + 15921866, + 16103996, + -3731215 + ]), + xy2d: FieldElement.uncheck([ + -23169824, + -10781249, + 13588192, + -1628807, + -3798557, + -1074929, + -19273607, + 5402699, + -29815713, + -9841101 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 23190676, + 2384583, + -32714340, + 3462154, + -29903655, + -1529132, + -11266856, + 8911517, + -25205859, + 2739713 + ]), + yminusx: FieldElement.uncheck([ + 21374101, + -3554250, + -33524649, + 9874411, + 15377179, + 11831242, + -33529904, + 6134907, + 4931255, + 11987849 + ]), + xy2d: FieldElement.uncheck([ + -7732, + -2978858, + -16223486, + 7277597, + 105524, + -322051, + -31480539, + 13861388, + -30076310, + 10117930 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -29501170, + -10744872, + -26163768, + 13051539, + -25625564, + 5089643, + -6325503, + 6704079, + 12890019, + 15728940 + ]), + yminusx: FieldElement.uncheck([ + -21972360, + -11771379, + -951059, + -4418840, + 14704840, + 2695116, + 903376, + -10428139, + 12885167, + 8311031 + ]), + xy2d: FieldElement.uncheck([ + -17516482, + 5352194, + 10384213, + -13811658, + 7506451, + 13453191, + 26423267, + 4384730, + 1888765, + -5435404 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25817338, + -3107312, + -13494599, + -3182506, + 30896459, + -13921729, + -32251644, + -12707869, + -19464434, + -3340243 + ]), + yminusx: FieldElement.uncheck([ + -23607977, + -2665774, + -526091, + 4651136, + 5765089, + 4618330, + 6092245, + 14845197, + 17151279, + -9854116 + ]), + xy2d: FieldElement.uncheck([ + -24830458, + -12733720, + -15165978, + 10367250, + -29530908, + -265356, + 22825805, + -7087279, + -16866484, + 16176525 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -23583256, + 6564961, + 20063689, + 3798228, + -4740178, + 7359225, + 2006182, + -10363426, + -28746253, + -10197509 + ]), + yminusx: FieldElement.uncheck([ + -10626600, + -4486402, + -13320562, + -5125317, + 3432136, + -6393229, + 23632037, + -1940610, + 32808310, + 1099883 + ]), + xy2d: FieldElement.uncheck([ + 15030977, + 5768825, + -27451236, + -2887299, + -6427378, + -15361371, + -15277896, + -6809350, + 2051441, + -15225865 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -3362323, + -7239372, + 7517890, + 9824992, + 23555850, + 295369, + 5148398, + -14154188, + -22686354, + 16633660 + ]), + yminusx: FieldElement.uncheck([ + 4577086, + -16752288, + 13249841, + -15304328, + 19958763, + -14537274, + 18559670, + -10759549, + 8402478, + -9864273 + ]), + xy2d: FieldElement.uncheck([ + -28406330, + -1051581, + -26790155, + -907698, + -17212414, + -11030789, + 9453451, + -14980072, + 17983010, + 9967138 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25762494, + 6524722, + 26585488, + 9969270, + 24709298, + 1220360, + -1677990, + 7806337, + 17507396, + 3651560 + ]), + yminusx: FieldElement.uncheck([ + -10420457, + -4118111, + 14584639, + 15971087, + -15768321, + 8861010, + 26556809, + -5574557, + -18553322, + -11357135 + ]), + xy2d: FieldElement.uncheck([ + 2839101, + 14284142, + 4029895, + 3472686, + 14402957, + 12689363, + -26642121, + 8459447, + -5605463, + -7621941 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -4839289, + -3535444, + 9744961, + 2871048, + 25113978, + 3187018, + -25110813, + -849066, + 17258084, + -7977739 + ]), + yminusx: FieldElement.uncheck([ + 18164541, + -10595176, + -17154882, + -1542417, + 19237078, + -9745295, + 23357533, + -15217008, + 26908270, + 12150756 + ]), + xy2d: FieldElement.uncheck([ + -30264870, + -7647865, + 5112249, + -7036672, + -1499807, + -6974257, + 43168, + -5537701, + -32302074, + 16215819 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -6898905, + 9824394, + -12304779, + -4401089, + -31397141, + -6276835, + 32574489, + 12532905, + -7503072, + -8675347 + ]), + yminusx: FieldElement.uncheck([ + -27343522, + -16515468, + -27151524, + -10722951, + 946346, + 16291093, + 254968, + 7168080, + 21676107, + -1943028 + ]), + xy2d: FieldElement.uncheck([ + 21260961, + -8424752, + -16831886, + -11920822, + -23677961, + 3968121, + -3651949, + -6215466, + -3556191, + -7913075 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 16544754, + 13250366, + -16804428, + 15546242, + -4583003, + 12757258, + -2462308, + -8680336, + -18907032, + -9662799 + ]), + yminusx: FieldElement.uncheck([ + -2415239, + -15577728, + 18312303, + 4964443, + -15272530, + -12653564, + 26820651, + 16690659, + 25459437, + -4564609 + ]), + xy2d: FieldElement.uncheck([ + -25144690, + 11425020, + 28423002, + -11020557, + -6144921, + -15826224, + 9142795, + -2391602, + -6432418, + -1644817 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -23104652, + 6253476, + 16964147, + -3768872, + -25113972, + -12296437, + -27457225, + -16344658, + 6335692, + 7249989 + ]), + yminusx: FieldElement.uncheck([ + -30333227, + 13979675, + 7503222, + -12368314, + -11956721, + -4621693, + -30272269, + 2682242, + 25993170, + -12478523 + ]), + xy2d: FieldElement.uncheck([ + 4364628, + 5930691, + 32304656, + -10044554, + -8054781, + 15091131, + 22857016, + -10598955, + 31820368, + 15075278 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 31879134, + -8918693, + 17258761, + 90626, + -8041836, + -4917709, + 24162788, + -9650886, + -17970238, + 12833045 + ]), + yminusx: FieldElement.uncheck([ + 19073683, + 14851414, + -24403169, + -11860168, + 7625278, + 11091125, + -19619190, + 2074449, + -9413939, + 14905377 + ]), + xy2d: FieldElement.uncheck([ + 24483667, + -11935567, + -2518866, + -11547418, + -1553130, + 15355506, + -25282080, + 9253129, + 27628530, + -7555480 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 17597607, + 8340603, + 19355617, + 552187, + 26198470, + -3176583, + 4593324, + -9157582, + -14110875, + 15297016 + ]), + yminusx: FieldElement.uncheck([ + 510886, + 14337390, + -31785257, + 16638632, + 6328095, + 2713355, + -20217417, + -11864220, + 8683221, + 2921426 + ]), + xy2d: FieldElement.uncheck([ + 18606791, + 11874196, + 27155355, + -5281482, + -24031742, + 6265446, + -25178240, + -1278924, + 4674690, + 13890525 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 13609624, + 13069022, + -27372361, + -13055908, + 24360586, + 9592974, + 14977157, + 9835105, + 4389687, + 288396 + ]), + yminusx: FieldElement.uncheck([ + 9922506, + -519394, + 13613107, + 5883594, + -18758345, + -434263, + -12304062, + 8317628, + 23388070, + 16052080 + ]), + xy2d: FieldElement.uncheck([ + 12720016, + 11937594, + -31970060, + -5028689, + 26900120, + 8561328, + -20155687, + -11632979, + -14754271, + -10812892 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15961858, + 14150409, + 26716931, + -665832, + -22794328, + 13603569, + 11829573, + 7467844, + -28822128, + 929275 + ]), + yminusx: FieldElement.uncheck([ + 11038231, + -11582396, + -27310482, + -7316562, + -10498527, + -16307831, + -23479533, + -9371869, + -21393143, + 2465074 + ]), + xy2d: FieldElement.uncheck([ + 20017163, + -4323226, + 27915242, + 1529148, + 12396362, + 15675764, + 13817261, + -9658066, + 2463391, + -4622140 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -16358878, + -12663911, + -12065183, + 4996454, + -1256422, + 1073572, + 9583558, + 12851107, + 4003896, + 12673717 + ]), + yminusx: FieldElement.uncheck([ + -1731589, + -15155870, + -3262930, + 16143082, + 19294135, + 13385325, + 14741514, + -9103726, + 7903886, + 2348101 + ]), + xy2d: FieldElement.uncheck([ + 24536016, + -16515207, + 12715592, + -3862155, + 1511293, + 10047386, + -3842346, + -7129159, + -28377538, + 10048127 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -12622226, + -6204820, + 30718825, + 2591312, + -10617028, + 12192840, + 18873298, + -7297090, + -32297756, + 15221632 + ]), + yminusx: FieldElement.uncheck([ + -26478122, + -11103864, + 11546244, + -1852483, + 9180880, + 7656409, + -21343950, + 2095755, + 29769758, + 6593415 + ]), + xy2d: FieldElement.uncheck([ + -31994208, + -2907461, + 4176912, + 3264766, + 12538965, + -868111, + 26312345, + -6118678, + 30958054, + 8292160 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 31429822, + -13959116, + 29173532, + 15632448, + 12174511, + -2760094, + 32808831, + 3977186, + 26143136, + -3148876 + ]), + yminusx: FieldElement.uncheck([ + 22648901, + 1402143, + -22799984, + 13746059, + 7936347, + 365344, + -8668633, + -1674433, + -3758243, + -2304625 + ]), + xy2d: FieldElement.uncheck([ + -15491917, + 8012313, + -2514730, + -12702462, + -23965846, + -10254029, + -1612713, + -1535569, + -16664475, + 8194478 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 27338066, + -7507420, + -7414224, + 10140405, + -19026427, + -6589889, + 27277191, + 8855376, + 28572286, + 3005164 + ]), + yminusx: FieldElement.uncheck([ + 26287124, + 4821776, + 25476601, + -4145903, + -3764513, + -15788984, + -18008582, + 1182479, + -26094821, + -13079595 + ]), + xy2d: FieldElement.uncheck([ + -7171154, + 3178080, + 23970071, + 6201893, + -17195577, + -4489192, + -21876275, + -13982627, + 32208683, + -1198248 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -16657702, + 2817643, + -10286362, + 14811298, + 6024667, + 13349505, + -27315504, + -10497842, + -27672585, + -11539858 + ]), + yminusx: FieldElement.uncheck([ + 15941029, + -9405932, + -21367050, + 8062055, + 31876073, + -238629, + -15278393, + -1444429, + 15397331, + -4130193 + ]), + xy2d: FieldElement.uncheck([ + 8934485, + -13485467, + -23286397, + -13423241, + -32446090, + 14047986, + 31170398, + -1441021, + -27505566, + 15087184 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -18357243, + -2156491, + 24524913, + -16677868, + 15520427, + -6360776, + -15502406, + 11461896, + 16788528, + -5868942 + ]), + yminusx: FieldElement.uncheck([ + -1947386, + 16013773, + 21750665, + 3714552, + -17401782, + -16055433, + -3770287, + -10323320, + 31322514, + -11615635 + ]), + xy2d: FieldElement.uncheck([ + 21426655, + -5650218, + -13648287, + -5347537, + -28812189, + -4920970, + -18275391, + -14621414, + 13040862, + -12112948 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 11293895, + 12478086, + -27136401, + 15083750, + -29307421, + 14748872, + 14555558, + -13417103, + 1613711, + 4896935 + ]), + yminusx: FieldElement.uncheck([ + -25894883, + 15323294, + -8489791, + -8057900, + 25967126, + -13425460, + 2825960, + -4897045, + -23971776, + -11267415 + ]), + xy2d: FieldElement.uncheck([ + -15924766, + -5229880, + -17443532, + 6410664, + 3622847, + 10243618, + 20615400, + 12405433, + -23753030, + -8436416 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -7091295, + 12556208, + -20191352, + 9025187, + -17072479, + 4333801, + 4378436, + 2432030, + 23097949, + -566018 + ]), + yminusx: FieldElement.uncheck([ + 4565804, + -16025654, + 20084412, + -7842817, + 1724999, + 189254, + 24767264, + 10103221, + -18512313, + 2424778 + ]), + xy2d: FieldElement.uncheck([ + 366633, + -11976806, + 8173090, + -6890119, + 30788634, + 5745705, + -7168678, + 1344109, + -3642553, + 12412659 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -24001791, + 7690286, + 14929416, + -168257, + -32210835, + -13412986, + 24162697, + -15326504, + -3141501, + 11179385 + ]), + yminusx: FieldElement.uncheck([ + 18289522, + -14724954, + 8056945, + 16430056, + -21729724, + 7842514, + -6001441, + -1486897, + -18684645, + -11443503 + ]), + xy2d: FieldElement.uncheck([ + 476239, + 6601091, + -6152790, + -9723375, + 17503545, + -4863900, + 27672959, + 13403813, + 11052904, + 5219329 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 20678546, + -8375738, + -32671898, + 8849123, + -5009758, + 14574752, + 31186971, + -3973730, + 9014762, + -8579056 + ]), + yminusx: FieldElement.uncheck([ + -13644050, + -10350239, + -15962508, + 5075808, + -1514661, + -11534600, + -33102500, + 9160280, + 8473550, + -3256838 + ]), + xy2d: FieldElement.uncheck([ + 24900749, + 14435722, + 17209120, + -15292541, + -22592275, + 9878983, + -7689309, + -16335821, + -24568481, + 11788948 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -3118155, + -11395194, + -13802089, + 14797441, + 9652448, + -6845904, + -20037437, + 10410733, + -24568470, + -1458691 + ]), + yminusx: FieldElement.uncheck([ + -15659161, + 16736706, + -22467150, + 10215878, + -9097177, + 7563911, + 11871841, + -12505194, + -18513325, + 8464118 + ]), + xy2d: FieldElement.uncheck([ + -23400612, + 8348507, + -14585951, + -861714, + -3950205, + -6373419, + 14325289, + 8628612, + 33313881, + -8370517 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -20186973, + -4967935, + 22367356, + 5271547, + -1097117, + -4788838, + -24805667, + -10236854, + -8940735, + -5818269 + ]), + yminusx: FieldElement.uncheck([ + -6948785, + -1795212, + -32625683, + -16021179, + 32635414, + -7374245, + 15989197, + -12838188, + 28358192, + -4253904 + ]), + xy2d: FieldElement.uncheck([ + -23561781, + -2799059, + -32351682, + -1661963, + -9147719, + 10429267, + -16637684, + 4072016, + -5351664, + 5596589 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -28236598, + -3390048, + 12312896, + 6213178, + 3117142, + 16078565, + 29266239, + 2557221, + 1768301, + 15373193 + ]), + yminusx: FieldElement.uncheck([ + -7243358, + -3246960, + -4593467, + -7553353, + -127927, + -912245, + -1090902, + -4504991, + -24660491, + 3442910 + ]), + xy2d: FieldElement.uncheck([ + -30210571, + 5124043, + 14181784, + 8197961, + 18964734, + -11939093, + 22597931, + 7176455, + -18585478, + 13365930 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -7877390, + -1499958, + 8324673, + 4690079, + 6261860, + 890446, + 24538107, + -8570186, + -9689599, + -3031667 + ]), + yminusx: FieldElement.uncheck([ + 25008904, + -10771599, + -4305031, + -9638010, + 16265036, + 15721635, + 683793, + -11823784, + 15723479, + -15163481 + ]), + xy2d: FieldElement.uncheck([ + -9660625, + 12374379, + -27006999, + -7026148, + -7724114, + -12314514, + 11879682, + 5400171, + 519526, + -1235876 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 22258397, + -16332233, + -7869817, + 14613016, + -22520255, + -2950923, + -20353881, + 7315967, + 16648397, + 7605640 + ]), + yminusx: FieldElement.uncheck([ + -8081308, + -8464597, + -8223311, + 9719710, + 19259459, + -15348212, + 23994942, + -5281555, + -9468848, + 4763278 + ]), + xy2d: FieldElement.uncheck([ + -21699244, + 9220969, + -15730624, + 1084137, + -25476107, + -2852390, + 31088447, + -7764523, + -11356529, + 728112 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 26047220, + -11751471, + -6900323, + -16521798, + 24092068, + 9158119, + -4273545, + -12555558, + -29365436, + -5498272 + ]), + yminusx: FieldElement.uncheck([ + 17510331, + -322857, + 5854289, + 8403524, + 17133918, + -3112612, + -28111007, + 12327945, + 10750447, + 10014012 + ]), + xy2d: FieldElement.uncheck([ + -10312768, + 3936952, + 9156313, + -8897683, + 16498692, + -994647, + -27481051, + -666732, + 3424691, + 7540221 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30322361, + -6964110, + 11361005, + -4143317, + 7433304, + 4989748, + -7071422, + -16317219, + -9244265, + 15258046 + ]), + yminusx: FieldElement.uncheck([ + 13054562, + -2779497, + 19155474, + 469045, + -12482797, + 4566042, + 5631406, + 2711395, + 1062915, + -5136345 + ]), + xy2d: FieldElement.uncheck([ + -19240248, + -11254599, + -29509029, + -7499965, + -5835763, + 13005411, + -6066489, + 12194497, + 32960380, + 1459310 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 19852034, + 7027924, + 23669353, + 10020366, + 8586503, + -6657907, + 394197, + -6101885, + 18638003, + -11174937 + ]), + yminusx: FieldElement.uncheck([ + 31395534, + 15098109, + 26581030, + 8030562, + -16527914, + -5007134, + 9012486, + -7584354, + -6643087, + -5442636 + ]), + xy2d: FieldElement.uncheck([ + -9192165, + -2347377, + -1997099, + 4529534, + 25766844, + 607986, + -13222, + 9677543, + -32294889, + -6456008 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -2444496, + -149937, + 29348902, + 8186665, + 1873760, + 12489863, + -30934579, + -7839692, + -7852844, + -8138429 + ]), + yminusx: FieldElement.uncheck([ + -15236356, + -15433509, + 7766470, + 746860, + 26346930, + -10221762, + -27333451, + 10754588, + -9431476, + 5203576 + ]), + xy2d: FieldElement.uncheck([ + 31834314, + 14135496, + -770007, + 5159118, + 20917671, + -16768096, + -7467973, + -7337524, + 31809243, + 7347066 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -9606723, + -11874240, + 20414459, + 13033986, + 13716524, + -11691881, + 19797970, + -12211255, + 15192876, + -2087490 + ]), + yminusx: FieldElement.uncheck([ + -12663563, + -2181719, + 1168162, + -3804809, + 26747877, + -14138091, + 10609330, + 12694420, + 33473243, + -13382104 + ]), + xy2d: FieldElement.uncheck([ + 33184999, + 11180355, + 15832085, + -11385430, + -1633671, + 225884, + 15089336, + -11023903, + -6135662, + 14480053 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 31308717, + -5619998, + 31030840, + -1897099, + 15674547, + -6582883, + 5496208, + 13685227, + 27595050, + 8737275 + ]), + yminusx: FieldElement.uncheck([ + -20318852, + -15150239, + 10933843, + -16178022, + 8335352, + -7546022, + -31008351, + -12610604, + 26498114, + 66511 + ]), + xy2d: FieldElement.uncheck([ + 22644454, + -8761729, + -16671776, + 4884562, + -3105614, + -13559366, + 30540766, + -4286747, + -13327787, + -7515095 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -28017847, + 9834845, + 18617207, + -2681312, + -3401956, + -13307506, + 8205540, + 13585437, + -17127465, + 15115439 + ]), + yminusx: FieldElement.uncheck([ + 23711543, + -672915, + 31206561, + -8362711, + 6164647, + -9709987, + -33535882, + -1426096, + 8236921, + 16492939 + ]), + xy2d: FieldElement.uncheck([ + -23910559, + -13515526, + -26299483, + -4503841, + 25005590, + -7687270, + 19574902, + 10071562, + 6708380, + -6222424 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 2101391, + -4930054, + 19702731, + 2367575, + -15427167, + 1047675, + 5301017, + 9328700, + 29955601, + -11678310 + ]), + yminusx: FieldElement.uncheck([ + 3096359, + 9271816, + -21620864, + -15521844, + -14847996, + -7592937, + -25892142, + -12635595, + -9917575, + 6216608 + ]), + xy2d: FieldElement.uncheck([ + -32615849, + 338663, + -25195611, + 2510422, + -29213566, + -13820213, + 24822830, + -6146567, + -26767480, + 7525079 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -23066649, + -13985623, + 16133487, + -7896178, + -3389565, + 778788, + -910336, + -2782495, + -19386633, + 11994101 + ]), + yminusx: FieldElement.uncheck([ + 21691500, + -13624626, + -641331, + -14367021, + 3285881, + -3483596, + -25064666, + 9718258, + -7477437, + 13381418 + ]), + xy2d: FieldElement.uncheck([ + 18445390, + -4202236, + 14979846, + 11622458, + -1727110, + -3582980, + 23111648, + -6375247, + 28535282, + 15779576 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30098053, + 3089662, + -9234387, + 16662135, + -21306940, + 11308411, + -14068454, + 12021730, + 9955285, + -16303356 + ]), + yminusx: FieldElement.uncheck([ + 9734894, + -14576830, + -7473633, + -9138735, + 2060392, + 11313496, + -18426029, + 9924399, + 20194861, + 13380996 + ]), + xy2d: FieldElement.uncheck([ + -26378102, + -7965207, + -22167821, + 15789297, + -18055342, + -6168792, + -1984914, + 15707771, + 26342023, + 10146099 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -26016874, + -219943, + 21339191, + -41388, + 19745256, + -2878700, + -29637280, + 2227040, + 21612326, + -545728 + ]), + yminusx: FieldElement.uncheck([ + -13077387, + 1184228, + 23562814, + -5970442, + -20351244, + -6348714, + 25764461, + 12243797, + -20856566, + 11649658 + ]), + xy2d: FieldElement.uncheck([ + -10031494, + 11262626, + 27384172, + 2271902, + 26947504, + -15997771, + 39944, + 6114064, + 33514190, + 2333242 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -21433588, + -12421821, + 8119782, + 7219913, + -21830522, + -9016134, + -6679750, + -12670638, + 24350578, + -13450001 + ]), + yminusx: FieldElement.uncheck([ + -4116307, + -11271533, + -23886186, + 4843615, + -30088339, + 690623, + -31536088, + -10406836, + 8317860, + 12352766 + ]), + xy2d: FieldElement.uncheck([ + 18200138, + -14475911, + -33087759, + -2696619, + -23702521, + -9102511, + -23552096, + -2287550, + 20712163, + 6719373 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 26656208, + 6075253, + -7858556, + 1886072, + -28344043, + 4262326, + 11117530, + -3763210, + 26224235, + -3297458 + ]), + yminusx: FieldElement.uncheck([ + -17168938, + -14854097, + -3395676, + -16369877, + -19954045, + 14050420, + 21728352, + 9493610, + 18620611, + -16428628 + ]), + xy2d: FieldElement.uncheck([ + -13323321, + 13325349, + 11432106, + 5964811, + 18609221, + 6062965, + -5269471, + -9725556, + -30701573, + -16479657 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -23860538, + -11233159, + 26961357, + 1640861, + -32413112, + -16737940, + 12248509, + -5240639, + 13735342, + 1934062 + ]), + yminusx: FieldElement.uncheck([ + 25089769, + 6742589, + 17081145, + -13406266, + 21909293, + -16067981, + -15136294, + -3765346, + -21277997, + 5473616 + ]), + xy2d: FieldElement.uncheck([ + 31883677, + -7961101, + 1083432, + -11572403, + 22828471, + 13290673, + -7125085, + 12469656, + 29111212, + -5451014 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 24244947, + -15050407, + -26262976, + 2791540, + -14997599, + 16666678, + 24367466, + 6388839, + -10295587, + 452383 + ]), + yminusx: FieldElement.uncheck([ + -25640782, + -3417841, + 5217916, + 16224624, + 19987036, + -4082269, + -24236251, + -5915248, + 15766062, + 8407814 + ]), + xy2d: FieldElement.uncheck([ + -20406999, + 13990231, + 15495425, + 16395525, + 5377168, + 15166495, + -8917023, + -4388953, + -8067909, + 2276718 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 30157918, + 12924066, + -17712050, + 9245753, + 19895028, + 3368142, + -23827587, + 5096219, + 22740376, + -7303417 + ]), + yminusx: FieldElement.uncheck([ + 2041139, + -14256350, + 7783687, + 13876377, + -25946985, + -13352459, + 24051124, + 13742383, + -15637599, + 13295222 + ]), + xy2d: FieldElement.uncheck([ + 33338237, + -8505733, + 12532113, + 7977527, + 9106186, + -1715251, + -17720195, + -4612972, + -4451357, + -14669444 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -20045281, + 5454097, + -14346548, + 6447146, + 28862071, + 1883651, + -2469266, + -4141880, + 7770569, + 9620597 + ]), + yminusx: FieldElement.uncheck([ + 23208068, + 7979712, + 33071466, + 8149229, + 1758231, + -10834995, + 30945528, + -1694323, + -33502340, + -14767970 + ]), + xy2d: FieldElement.uncheck([ + 1439958, + -16270480, + -1079989, + -793782, + 4625402, + 10647766, + -5043801, + 1220118, + 30494170, + -11440799 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -5037580, + -13028295, + -2970559, + -3061767, + 15640974, + -6701666, + -26739026, + 926050, + -1684339, + -13333647 + ]), + yminusx: FieldElement.uncheck([ + 13908495, + -3549272, + 30919928, + -6273825, + -21521863, + 7989039, + 9021034, + 9078865, + 3353509, + 4033511 + ]), + xy2d: FieldElement.uncheck([ + -29663431, + -15113610, + 32259991, + -344482, + 24295849, + -12912123, + 23161163, + 8839127, + 27485041, + 7356032 + ])) + ], + [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 9661027, + 705443, + 11980065, + -5370154, + -1628543, + 14661173, + -6346142, + 2625015, + 28431036, + -16771834 + ]), + yminusx: FieldElement.uncheck([ + -23839233, + -8311415, + -25945511, + 7480958, + -17681669, + -8354183, + -22545972, + 14150565, + 15970762, + 4099461 + ]), + xy2d: FieldElement.uncheck([ + 29262576, + 16756590, + 26350592, + -8793563, + 8529671, + -11208050, + 13617293, + -9937143, + 11465739, + 8317062 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25493081, + -6962928, + 32500200, + -9419051, + -23038724, + -2302222, + 14898637, + 3848455, + 20969334, + -5157516 + ]), + yminusx: FieldElement.uncheck([ + -20384450, + -14347713, + -18336405, + 13884722, + -33039454, + 2842114, + -21610826, + -3649888, + 11177095, + 14989547 + ]), + xy2d: FieldElement.uncheck([ + -24496721, + -11716016, + 16959896, + 2278463, + 12066309, + 10137771, + 13515641, + 2581286, + -28487508, + 9930240 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -17751622, + -2097826, + 16544300, + -13009300, + -15914807, + -14949081, + 18345767, + -13403753, + 16291481, + -5314038 + ]), + yminusx: FieldElement.uncheck([ + -33229194, + 2553288, + 32678213, + 9875984, + 8534129, + 6889387, + -9676774, + 6957617, + 4368891, + 9788741 + ]), + xy2d: FieldElement.uncheck([ + 16660756, + 7281060, + -10830758, + 12911820, + 20108584, + -8101676, + -21722536, + -8613148, + 16250552, + -11111103 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -19765507, + 2390526, + -16551031, + 14161980, + 1905286, + 6414907, + 4689584, + 10604807, + -30190403, + 4782747 + ]), + yminusx: FieldElement.uncheck([ + -1354539, + 14736941, + -7367442, + -13292886, + 7710542, + -14155590, + -9981571, + 4383045, + 22546403, + 437323 + ]), + xy2d: FieldElement.uncheck([ + 31665577, + -12180464, + -16186830, + 1491339, + -18368625, + 3294682, + 27343084, + 2786261, + -30633590, + -14097016 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -14467279, + -683715, + -33374107, + 7448552, + 19294360, + 14334329, + -19690631, + 2355319, + -19284671, + -6114373 + ]), + yminusx: FieldElement.uncheck([ + 15121312, + -15796162, + 6377020, + -6031361, + -10798111, + -12957845, + 18952177, + 15496498, + -29380133, + 11754228 + ]), + xy2d: FieldElement.uncheck([ + -2637277, + -13483075, + 8488727, + -14303896, + 12728761, + -1622493, + 7141596, + 11724556, + 22761615, + -10134141 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 16918416, + 11729663, + -18083579, + 3022987, + -31015732, + -13339659, + -28741185, + -12227393, + 32851222, + 11717399 + ]), + yminusx: FieldElement.uncheck([ + 11166634, + 7338049, + -6722523, + 4531520, + -29468672, + -7302055, + 31474879, + 3483633, + -1193175, + -4030831 + ]), + xy2d: FieldElement.uncheck([ + -185635, + 9921305, + 31456609, + -13536438, + -12013818, + 13348923, + 33142652, + 6546660, + -19985279, + -3948376 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -32460596, + 11266712, + -11197107, + -7899103, + 31703694, + 3855903, + -8537131, + -12833048, + -30772034, + -15486313 + ]), + yminusx: FieldElement.uncheck([ + -18006477, + 12709068, + 3991746, + -6479188, + -21491523, + -10550425, + -31135347, + -16049879, + 10928917, + 3011958 + ]), + xy2d: FieldElement.uncheck([ + -6957757, + -15594337, + 31696059, + 334240, + 29576716, + 14796075, + -30831056, + -12805180, + 18008031, + 10258577 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -22448644, + 15655569, + 7018479, + -4410003, + -30314266, + -1201591, + -1853465, + 1367120, + 25127874, + 6671743 + ]), + yminusx: FieldElement.uncheck([ + 29701166, + -14373934, + -10878120, + 9279288, + -17568, + 13127210, + 21382910, + 11042292, + 25838796, + 4642684 + ]), + xy2d: FieldElement.uncheck([ + -20430234, + 14955537, + -24126347, + 8124619, + -5369288, + -5990470, + 30468147, + -13900640, + 18423289, + 4177476 + ])) + ] + ]; + static const List geBi = [ + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 25967493, + -14356035, + 29566456, + 3660896, + -12694345, + 4014787, + 27544626, + -11754271, + -6079156, + 2047605 + ]), + yminusx: FieldElement.uncheck([ + -12545711, + 934262, + -2722910, + 3049990, + -727428, + 9406986, + 12720692, + 5043384, + 19500929, + -15469378 + ]), + xy2d: FieldElement.uncheck([ + -8738181, + 4489570, + 9688441, + -14785194, + 10184609, + -12363380, + 29287919, + 11864899, + -24514362, + -4438546 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 15636291, + -9688557, + 24204773, + -7912398, + 616977, + -16685262, + 27787600, + -14772189, + 28944400, + -1550024 + ]), + yminusx: FieldElement.uncheck([ + 16568933, + 4717097, + -11556148, + -1102322, + 15682896, + -11807043, + 16354577, + -11775962, + 7689662, + 11199574 + ]), + xy2d: FieldElement.uncheck([ + 30464156, + -5976125, + -11779434, + -15670865, + 23220365, + 15915852, + 7512774, + 10017326, + -17749093, + -9920357 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 10861363, + 11473154, + 27284546, + 1981175, + -30064349, + 12577861, + 32867885, + 14515107, + -15438304, + 10819380 + ]), + yminusx: FieldElement.uncheck([ + 4708026, + 6336745, + 20377586, + 9066809, + -11272109, + 6594696, + -25653668, + 12483688, + -12668491, + 5581306 + ]), + xy2d: FieldElement.uncheck([ + 19563160, + 16186464, + -29386857, + 4097519, + 10237984, + -4348115, + 28542350, + 13850243, + -23678021, + -15815942 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + 5153746, + 9909285, + 1723747, + -2777874, + 30523605, + 5516873, + 19480852, + 5230134, + -23952439, + -15175766 + ]), + yminusx: FieldElement.uncheck([ + -30269007, + -3463509, + 7665486, + 10083793, + 28475525, + 1649722, + 20654025, + 16520125, + 30598449, + 7715701 + ]), + xy2d: FieldElement.uncheck([ + 28881845, + 14381568, + 9657904, + 3680757, + -20181635, + 7843316, + -31400660, + 1370708, + 29794553, + -1409300 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -22518993, + -6692182, + 14201702, + -8745502, + -23510406, + 8844726, + 18474211, + -1361450, + -13062696, + 13821877 + ]), + yminusx: FieldElement.uncheck([ + -6455177, + -7839871, + 3374702, + -4740862, + -27098617, + -10571707, + 31655028, + -7212327, + 18853322, + -14220951 + ]), + xy2d: FieldElement.uncheck([ + 4566830, + -12963868, + -28974889, + -12240689, + -7602672, + -2830569, + -8514358, + -10431137, + 2207753, + -3209784 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -25154831, + -4185821, + 29681144, + 7868801, + -6854661, + -9423865, + -12437364, + -663000, + -31111463, + -16132436 + ]), + yminusx: FieldElement.uncheck([ + 25576264, + -2703214, + 7349804, + -11814844, + 16472782, + 9300885, + 3844789, + 15725684, + 171356, + 6466918 + ]), + xy2d: FieldElement.uncheck([ + 23103977, + 13316479, + 9739013, + -16149481, + 817875, + -15038942, + 8965339, + -14088058, + -30714912, + 16193877 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -33521811, + 3180713, + -2394130, + 14003687, + -16903474, + -16270840, + 17238398, + 4729455, + -18074513, + 9256800 + ]), + yminusx: FieldElement.uncheck([ + -25182317, + -4174131, + 32336398, + 5036987, + -21236817, + 11360617, + 22616405, + 9761698, + -19827198, + 630305 + ]), + xy2d: FieldElement.uncheck([ + -13720693, + 2639453, + -24237460, + -7406481, + 9494427, + -5774029, + -6554551, + -15960994, + -2449256, + -14291300 + ])), + GroupElementPrecomp.uncheck( + yplusx: FieldElement.uncheck([ + -3151181, + -5046075, + 9282714, + 6866145, + -31907062, + -863023, + -18940575, + 15033784, + 25105118, + -7894876 + ]), + yminusx: FieldElement.uncheck([ + -24326370, + 15950226, + -31801215, + -14592823, + -11662737, + -5090925, + 1573892, + -2625887, + 2198790, + -15804619 + ]), + xy2d: FieldElement.uncheck([ + -3099351, + 10324967, + -2241613, + 7453183, + -5446979, + -2735503, + -13812022, + -16236442, + -32461234, + -12290683 + ])) + ]; + static const FieldElement feSqrtm1 = FieldElement.uncheck([ + -32595792, + -7943725, + 9377950, + 3500415, + 12389472, + -272473, + -25146209, + -2005654, + 326686, + 11406482 + ]); /* sqrt(-1) */ +} diff --git a/lib/crypto/crypto/cdsa/crypto_ops/crypto_ops.dart b/lib/crypto/crypto/cdsa/crypto_ops/crypto_ops.dart new file mode 100644 index 0000000..b69a213 --- /dev/null +++ b/lib/crypto/crypto/cdsa/crypto_ops/crypto_ops.dart @@ -0,0 +1,4 @@ +export 'const/const.dart'; +export 'exception/exception.dart'; +export 'models/models.dart'; +export 'operations/ops.dart'; diff --git a/lib/crypto/crypto/cdsa/crypto_ops/exception/exception.dart b/lib/crypto/crypto/cdsa/crypto_ops/exception/exception.dart new file mode 100644 index 0000000..2d1dd02 --- /dev/null +++ b/lib/crypto/crypto/cdsa/crypto_ops/exception/exception.dart @@ -0,0 +1,6 @@ +import 'package:blockchain_utils/exception/exception.dart'; + +class CryptoOpsException extends BlockchainUtilsException { + const CryptoOpsException(String message, {Map? details}) + : super(message, details: details); +} diff --git a/lib/crypto/crypto/cdsa/crypto_ops/models/models.dart b/lib/crypto/crypto/cdsa/crypto_ops/models/models.dart new file mode 100644 index 0000000..a8a6e69 --- /dev/null +++ b/lib/crypto/crypto/cdsa/crypto_ops/models/models.dart @@ -0,0 +1,209 @@ +import 'package:blockchain_utils/helper/helper.dart'; + +class FieldElement { + final List h; + const FieldElement.uncheck(this.h); + factory FieldElement() => FieldElement.uncheck(List.filled(10, 0)); + FieldElement clone({bool immutable = false}) { + return FieldElement.uncheck(h.clone(immutable: immutable)); + } + + factory FieldElement.fromJson(Map json) { + return FieldElement.uncheck(json["h"]); + } + + Map toJson() { + return {"h": h}; + } + + void fillZero() { + for (int i = 0; i < 10; i++) { + h[i] = 0; + } + } + + void fillOne() { + h[0] = 1; + for (int i = 1; i < 10; i++) { + h[i] = 0; + } + } + + void fill(List other) { + assert(other.length >= 10); + for (int i = 0; i < 10; i++) { + h[i] = other[i]; + } + } +} + +class GroupElementP2 { + final FieldElement x; + final FieldElement y; + final FieldElement z; + const GroupElementP2.uncheck( + {required this.x, required this.y, required this.z}); + factory GroupElementP2() => GroupElementP2.uncheck( + x: FieldElement(), y: FieldElement(), z: FieldElement()); + + Map toJson() { + return { + "x": x.toJson(), + "y": y.toJson(), + "z": z.toJson(), + }; + } + + @override + String toString() { + String m = ""; + for (final i in toJson().entries) { + final ln = List.from(i.value["h"]); + final sm = ln.fold(0, (c, p) => c + p); + m += "${i.key}:${i.value["h"]} sum: $sm \n"; + } + return m; + } +} + +class GroupElementP1P1 { + final FieldElement x; + final FieldElement y; + final FieldElement z; + final FieldElement t; + const GroupElementP1P1.uncheck( + {required this.x, required this.y, required this.z, required this.t}); + factory GroupElementP1P1() => GroupElementP1P1.uncheck( + x: FieldElement(), + y: FieldElement(), + z: FieldElement(), + t: FieldElement()); + Map toJson() { + return {"x": x.toJson(), "y": y.toJson(), "z": z.toJson(), "t": t.toJson()}; + } + + @override + String toString() { + String m = ""; + for (final i in toJson().entries) { + final ln = List.from(i.value["h"]); + final sm = ln.fold(0, (c, p) => c + p); + m += "${i.key}:${i.value["h"]} sum: $sm \n"; + } + return m; + } +} + +class GroupElementP3 { + final FieldElement x; + final FieldElement y; + final FieldElement z; + final FieldElement t; + const GroupElementP3.uncheck( + {required this.x, required this.y, required this.z, required this.t}); + factory GroupElementP3() => GroupElementP3.uncheck( + x: FieldElement(), + y: FieldElement(), + z: FieldElement(), + t: FieldElement()); + GroupElementP3 clone({bool immutable = false}) { + return GroupElementP3.uncheck( + x: x.clone(immutable: immutable), + y: y.clone(immutable: immutable), + z: z.clone(immutable: immutable), + t: t.clone(immutable: immutable), + ); + } + + Map toJson() { + return {"x": x.toJson(), "y": y.toJson(), "z": z.toJson(), "t": t.toJson()}; + } + + factory GroupElementP3.fromJson(Map json) { + return GroupElementP3.uncheck( + x: FieldElement.fromJson(json["x"]), + y: FieldElement.fromJson(json["y"]), + z: FieldElement.fromJson(json["z"]), + t: FieldElement.fromJson(json["t"])); + } + @override + String toString() { + String m = ""; + for (final i in toJson().entries) { + final ln = List.from(i.value["h"]); + final sm = ln.fold(0, (c, p) => c + p); + m += "${i.key}:${i.value["h"]} sum: $sm \n"; + } + return m; + } +} + +class GroupElementCached { + final FieldElement yPlusX; + final FieldElement yMinusX; + final FieldElement z; + final FieldElement t2d; + const GroupElementCached.uncheck( + {required this.yPlusX, + required this.yMinusX, + required this.z, + required this.t2d}); + + factory GroupElementCached() => GroupElementCached.uncheck( + yPlusX: FieldElement(), + yMinusX: FieldElement(), + z: FieldElement(), + t2d: FieldElement()); + + static List get dsmp { + return List.generate(8, (_) => GroupElementCached()).immutable; + } + + Map toJson() { + return { + "yPlusX": yPlusX.toJson(), + "yMinusX": yMinusX.toJson(), + "z": z.toJson(), + "t2d": t2d.toJson(), + }; + } + + @override + String toString() { + String m = ""; + for (final i in toJson().entries) { + final ln = List.from(i.value["h"]); + final sm = ln.fold(0, (c, p) => c + p); + m += "${i.key}:${i.value["h"]} sum: $sm \n"; + } + return m; + } +} + +class GroupElementPrecomp { + final FieldElement yplusx; + final FieldElement yminusx; + final FieldElement xy2d; + const GroupElementPrecomp.uncheck( + {required this.yplusx, required this.yminusx, required this.xy2d}); + factory GroupElementPrecomp() => GroupElementPrecomp.uncheck( + yplusx: FieldElement(), yminusx: FieldElement(), xy2d: FieldElement()); + Map toJson() { + return { + "yplusx": yplusx.toJson(), + "yminusx": yminusx.toJson(), + "xy2d": xy2d.toJson() + }; + } + + @override + String toString() { + String m = ""; + for (final i in toJson().entries) { + m += "${i.key}:${i.value}\n"; + } + return m; + } +} + +typedef GroupElementDsmp = List; diff --git a/lib/crypto/crypto/cdsa/crypto_ops/operations/ops.dart b/lib/crypto/crypto/cdsa/crypto_ops/operations/ops.dart new file mode 100644 index 0000000..def5af4 --- /dev/null +++ b/lib/crypto/crypto/cdsa/crypto_ops/operations/ops.dart @@ -0,0 +1,4735 @@ +// Copyright (c) 2014-2024, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +// Note: This code has been adapted from its original c version to Dart. +// The 3-Clause BSD License +// Copyright (c) 2023 Mohsen Haydari (MRTNETWORK) +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions, and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this +// list of conditions, and the following disclaimer in the documentation and/or +// other materials provided with the distribution. +// 3. Neither the name of the [organization] nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +import 'package:blockchain_utils/crypto/crypto/cdsa/crypto_ops/const/const.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/crypto_ops/exception/exception.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/crypto_ops/models/models.dart'; + +class CryptoOps { + static final BigInt _bitMaskFor25 = BigInt.one << 25; + static final BigInt _bitMaskFor24 = BigInt.one << 24; + static final BigInt _bitMaskFor20 = BigInt.one << 20; + + static int scIsNonZero(List s) { + s.asMin32("scIsNonZero"); + for (int i = 0; i < 32; i++) { + final byte = s[i]; + if (byte != 0) { + return 1; + } + } + return 0; + } + + static final _b2097151 = BigInt.from(2097151); + + static BigInt signum(BigInt a) { + if (a > BigInt.zero) { + return BigInt.one; + } + if (a < BigInt.zero) { + return BigInt.from(-1); + } + return BigInt.zero; + } + + static int scCheck(List s) { + s.asMin32("scCheck"); + BigInt s0 = _load4(s, 0); + BigInt s1 = _load4(s, 4); + BigInt s2 = _load4(s, 8); + BigInt s3 = _load4(s, 12); + BigInt s4 = _load4(s, 16); + BigInt s5 = _load4(s, 20); + BigInt s6 = _load4(s, 24); + BigInt s7 = _load4(s, 28); + final r = (signum(1559614444.toBig - s0) + + (signum(1477600026.toBig - s1) << 1) + + (signum(2734136534.toBig - s2) << 2) + + (signum(350157278.toBig - s3) << 3) + + (signum(-s4) << 4) + + (signum(-s5) << 5) + + (signum(-s6) << 6) + + (signum(268435456.toBig - s7) << 7)) >> + 8; + return r.toInt(); + } + + static void scReduce32Copy(List scopy, List s) { + s.asMin32("scReduce32Copy"); + scopy.asMin32("scReduce32Copy"); + BigInt s0 = _b2097151 & _load3(s, 0); + BigInt s1 = _b2097151 & (_load4(s, 2) >> 5); + BigInt s2 = _b2097151 & (_load3(s, 5) >> 2); + BigInt s3 = _b2097151 & (_load4(s, 7) >> 7); + BigInt s4 = _b2097151 & (_load4(s, 10) >> 4); + BigInt s5 = _b2097151 & (_load3(s, 13) >> 1); + BigInt s6 = _b2097151 & (_load4(s, 15) >> 6); + BigInt s7 = _b2097151 & (_load3(s, 18) >> 3); + BigInt s8 = _b2097151 & _load3(s, 21); + BigInt s9 = _b2097151 & (_load4(s, 23) >> 5); + BigInt s10 = _b2097151 & (_load3(s, 26) >> 2); + BigInt s11 = (_load4(s, 28) >> 7); + BigInt s12 = BigInt.zero; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + BigInt carry10; + BigInt carry11; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = 0.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + final List sBig = List.filled(32, BigInt.zero); + sBig[0] = s0 >> 0; + sBig[1] = s0 >> 8; + sBig[2] = (s0 >> 16) | (s1 << 5); + sBig[3] = s1 >> 3; + sBig[4] = s1 >> 11; + sBig[5] = (s1 >> 19) | (s2 << 2); + sBig[6] = s2 >> 6; + sBig[7] = (s2 >> 14) | (s3 << 7); + sBig[8] = s3 >> 1; + sBig[9] = s3 >> 9; + sBig[10] = (s3 >> 17) | (s4 << 4); + sBig[11] = s4 >> 4; + sBig[12] = s4 >> 12; + sBig[13] = (s4 >> 20) | (s5 << 1); + sBig[14] = s5 >> 7; + sBig[15] = (s5 >> 15) | (s6 << 6); + sBig[16] = s6 >> 2; + sBig[17] = s6 >> 10; + sBig[18] = (s6 >> 18) | (s7 << 3); + sBig[19] = s7 >> 5; + sBig[20] = s7 >> 13; + sBig[21] = s8 >> 0; + sBig[22] = s8 >> 8; + sBig[23] = (s8 >> 16) | (s9 << 5); + sBig[24] = s9 >> 3; + sBig[25] = s9 >> 11; + sBig[26] = (s9 >> 19) | (s10 << 2); + sBig[27] = s10 >> 6; + sBig[28] = (s10 >> 14) | (s11 << 7); + sBig[29] = s11 >> 1; + sBig[30] = s11 >> 9; + sBig[31] = s11 >> 17; + for (int i = 0; i < sBig.length; i++) { + scopy[i] = sBig[i].toUnsigned8; + } + } + + static void fe0(FieldElement h) { + h.fillZero(); + } + + static void fe1(FieldElement h) { + h.fillOne(); + } + + static void feAdd(FieldElement h, FieldElement f, FieldElement g) { + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + int g0 = g.h[0]; + int g1 = g.h[1]; + int g2 = g.h[2]; + int g3 = g.h[3]; + int g4 = g.h[4]; + int g5 = g.h[5]; + int g6 = g.h[6]; + int g7 = g.h[7]; + int g8 = g.h[8]; + int g9 = g.h[9]; + int h0 = f0 + g0; + int h1 = f1 + g1; + int h2 = f2 + g2; + int h3 = f3 + g3; + int h4 = f4 + g4; + int h5 = f5 + g5; + int h6 = f6 + g6; + int h7 = f7 + g7; + int h8 = f8 + g8; + int h9 = f9 + g9; + h.h[0] = h0; + h.h[1] = h1; + h.h[2] = h2; + h.h[3] = h3; + h.h[4] = h4; + h.h[5] = h5; + h.h[6] = h6; + h.h[7] = h7; + h.h[8] = h8; + h.h[9] = h9; + } + + static void pr(String name, dynamic v) {} + + static int _xor32(int a, int b) { + return (a ^ b).toInt32; + } + + static void feCmov(FieldElement f, FieldElement g, int b) { + assert(b == 0 || b == 1, "b should be either 0 or 1."); + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + int g0 = g.h[0]; + int g1 = g.h[1]; + int g2 = g.h[2]; + int g3 = g.h[3]; + int g4 = g.h[4]; + int g5 = g.h[5]; + int g6 = g.h[6]; + int g7 = g.h[7]; + int g8 = g.h[8]; + int g9 = g.h[9]; + int x0 = f0 ^ g0; + int x1 = f1 ^ g1; + int x2 = f2 ^ g2; + int x3 = f3 ^ g3; + int x4 = f4 ^ g4; + int x5 = f5 ^ g5; + int x6 = f6 ^ g6; + int x7 = f7 ^ g7; + int x8 = f8 ^ g8; + int x9 = f9 ^ g9; + b = -b; + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + f.h[0] = _xor32(f0, x0); + f.h[1] = _xor32(f1, x1); + f.h[2] = _xor32(f2, x2); + f.h[3] = _xor32(f3, x3); + f.h[4] = _xor32(f4, x4); + f.h[5] = _xor32(f5, x5); + f.h[6] = _xor32(f6, x6); + f.h[7] = _xor32(f7, x7); + f.h[8] = _xor32(f8, x8); + f.h[9] = _xor32(f9, x9); + } + + static void feCopy(FieldElement h, FieldElement f) { + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + h.h[0] = f0; + h.h[1] = f1; + h.h[2] = f2; + h.h[3] = f3; + h.h[4] = f4; + h.h[5] = f5; + h.h[6] = f6; + h.h[7] = f7; + h.h[8] = f8; + h.h[9] = f9; + } + + static void feSq(FieldElement h, FieldElement f) { + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + int f0_2 = (2 * f0).toInt32; + int f1_2 = (2 * f1).toInt32; + int f2_2 = (2 * f2).toInt32; + int f3_2 = (2 * f3).toInt32; + int f4_2 = (2 * f4).toInt32; + int f5_2 = (2 * f5).toInt32; + int f6_2 = (2 * f6).toInt32; + int f7_2 = (2 * f7).toInt32; + int f5_38 = (38 * f5).toInt32; /* 1.959375*2^30 */ + int f6_19 = (19 * f6).toInt32; /* 1.959375*2^30 */ + int f7_38 = (38 * f7).toInt32; /* 1.959375*2^30 */ + int f8_19 = (19 * f8).toInt32; /* 1.959375*2^30 */ + int f9_38 = (38 * f9).toInt32; /* 1.959375*2^30 */ + + BigInt f0f0 = f0.toBig * f0.toBig; + BigInt f0f1_2 = f0_2.toBig * f1.toBig; + BigInt f0f2_2 = f0_2.toBig * f2.toBig; + BigInt f0f3_2 = f0_2.toBig * f3.toBig; + BigInt f0f4_2 = f0_2.toBig * f4.toBig; + BigInt f0f5_2 = f0_2.toBig * f5.toBig; + BigInt f0f6_2 = f0_2.toBig * f6.toBig; + BigInt f0f7_2 = f0_2.toBig * f7.toBig; + BigInt f0f8_2 = f0_2.toBig * f8.toBig; + BigInt f0f9_2 = f0_2.toBig * f9.toBig; + BigInt f1f1_2 = f1_2.toBig * f1.toBig; + BigInt f1f2_2 = f1_2.toBig * f2.toBig; + BigInt f1f3_4 = f1_2.toBig * f3_2.toBig; + BigInt f1f4_2 = f1_2.toBig * f4.toBig; + BigInt f1f5_4 = f1_2.toBig * f5_2.toBig; + BigInt f1f6_2 = f1_2.toBig * f6.toBig; + BigInt f1f7_4 = f1_2.toBig * f7_2.toBig; + BigInt f1f8_2 = f1_2.toBig * f8.toBig; + BigInt f1f9_76 = f1_2.toBig * f9_38.toBig; + BigInt f2f2 = f2.toBig * f2.toBig; + BigInt f2f3_2 = f2_2.toBig * f3.toBig; + BigInt f2f4_2 = f2_2.toBig * f4.toBig; + BigInt f2f5_2 = f2_2.toBig * f5.toBig; + BigInt f2f6_2 = f2_2.toBig * f6.toBig; + BigInt f2f7_2 = f2_2.toBig * f7.toBig; + BigInt f2f8_38 = f2_2.toBig * f8_19.toBig; + BigInt f2f9_38 = f2.toBig * f9_38.toBig; + BigInt f3f3_2 = f3_2.toBig * f3.toBig; + BigInt f3f4_2 = f3_2.toBig * f4.toBig; + BigInt f3f5_4 = f3_2.toBig * f5_2.toBig; + BigInt f3f6_2 = f3_2.toBig * f6.toBig; + BigInt f3f7_76 = f3_2.toBig * f7_38.toBig; + BigInt f3f8_38 = f3_2.toBig * f8_19.toBig; + BigInt f3f9_76 = f3_2.toBig * f9_38.toBig; + BigInt f4f4 = f4.toBig * f4.toBig; + BigInt f4f5_2 = f4_2.toBig * f5.toBig; + BigInt f4f6_38 = f4_2.toBig * f6_19.toBig; + BigInt f4f7_38 = f4.toBig * f7_38.toBig; + BigInt f4f8_38 = f4_2.toBig * f8_19.toBig; + BigInt f4f9_38 = f4.toBig * f9_38.toBig; + BigInt f5f5_38 = f5.toBig * f5_38.toBig; + BigInt f5f6_38 = f5_2.toBig * f6_19.toBig; + BigInt f5f7_76 = f5_2.toBig * f7_38.toBig; + BigInt f5f8_38 = f5_2.toBig * f8_19.toBig; + BigInt f5f9_76 = f5_2.toBig * f9_38.toBig; + BigInt f6f6_19 = f6.toBig * f6_19.toBig; + BigInt f6f7_38 = f6.toBig * f7_38.toBig; + BigInt f6f8_38 = f6_2.toBig * f8_19.toBig; + BigInt f6f9_38 = f6.toBig * f9_38.toBig; + BigInt f7f7_38 = f7.toBig * f7_38.toBig; + BigInt f7f8_38 = f7_2.toBig * f8_19.toBig; + BigInt f7f9_76 = f7_2.toBig * f9_38.toBig; + BigInt f8f8_19 = f8.toBig * f8_19.toBig; + BigInt f8f9_38 = f8.toBig * f9_38.toBig; + BigInt f9f9_38 = f9.toBig * f9_38.toBig; + BigInt h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + BigInt h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + BigInt h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + BigInt h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + BigInt h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + BigInt h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + BigInt h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + BigInt h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + BigInt h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + BigInt h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + + carry1 = (h1 + _bitMaskFor24) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry5 = (h5 + _bitMaskFor24) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + + carry2 = (h2 + _bitMaskFor25) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry6 = (h6 + _bitMaskFor25) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + + carry3 = (h3 + _bitMaskFor24) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry7 = (h7 + _bitMaskFor24) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry8 = (h8 + _bitMaskFor25) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + + carry9 = (h9 + _bitMaskFor24) >> 25; + h0 += carry9 * 19.toBig; + h9 -= carry9 << 25; + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + + h.h[0] = h0.toInt32; + h.h[1] = h1.toInt32; + h.h[2] = h2.toInt32; + h.h[3] = h3.toInt32; + h.h[4] = h4.toInt32; + h.h[5] = h5.toInt32; + h.h[6] = h6.toInt32; + h.h[7] = h7.toInt32; + h.h[8] = h8.toInt32; + h.h[9] = h9.toInt32; + } + + static void feSq2(FieldElement h, FieldElement f) { + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + int f0_2 = (2 * f0).toInt32; + int f1_2 = (2 * f1).toInt32; + int f2_2 = (2 * f2).toInt32; + int f3_2 = (2 * f3).toInt32; + int f4_2 = (2 * f4).toInt32; + int f5_2 = (2 * f5).toInt32; + int f6_2 = (2 * f6).toInt32; + int f7_2 = (2 * f7).toInt32; + int f5_38 = (38 * f5).toInt32; /* 1.959375*2^30 */ + int f6_19 = (19 * f6).toInt32; /* 1.959375*2^30 */ + int f7_38 = (38 * f7).toInt32; /* 1.959375*2^30 */ + int f8_19 = (19 * f8).toInt32; /* 1.959375*2^30 */ + int f9_38 = (38 * f9).toInt32; /* 1.959375*2^30 */ + BigInt f0f0 = f0.toBig * f0.toBig; + + BigInt f0f1_2 = f0_2.toBig * f1.toBig; + BigInt f0f2_2 = f0_2.toBig * f2.toBig; + BigInt f0f3_2 = f0_2.toBig * f3.toBig; + BigInt f0f4_2 = f0_2.toBig * f4.toBig; + BigInt f0f5_2 = f0_2.toBig * f5.toBig; + BigInt f0f6_2 = f0_2.toBig * f6.toBig; + BigInt f0f7_2 = f0_2.toBig * f7.toBig; + BigInt f0f8_2 = f0_2.toBig * f8.toBig; + BigInt f0f9_2 = f0_2.toBig * f9.toBig; + BigInt f1f1_2 = f1_2.toBig * f1.toBig; + BigInt f1f2_2 = f1_2.toBig * f2.toBig; + BigInt f1f3_4 = f1_2.toBig * f3_2.toBig; + BigInt f1f4_2 = f1_2.toBig * f4.toBig; + BigInt f1f5_4 = f1_2.toBig * f5_2.toBig; + BigInt f1f6_2 = f1_2.toBig * f6.toBig; + BigInt f1f7_4 = f1_2.toBig * f7_2.toBig; + BigInt f1f8_2 = f1_2.toBig * f8.toBig; + BigInt f1f9_76 = f1_2.toBig * f9_38.toBig; + BigInt f2f2 = f2.toBig * f2.toBig; + BigInt f2f3_2 = f2_2.toBig * f3.toBig; + BigInt f2f4_2 = f2_2.toBig * f4.toBig; + BigInt f2f5_2 = f2_2.toBig * f5.toBig; + BigInt f2f6_2 = f2_2.toBig * f6.toBig; + BigInt f2f7_2 = f2_2.toBig * f7.toBig; + BigInt f2f8_38 = f2_2.toBig * f8_19.toBig; + BigInt f2f9_38 = f2.toBig * f9_38.toBig; + BigInt f3f3_2 = f3_2.toBig * f3.toBig; + BigInt f3f4_2 = f3_2.toBig * f4.toBig; + BigInt f3f5_4 = f3_2.toBig * f5_2.toBig; + BigInt f3f6_2 = f3_2.toBig * f6.toBig; + BigInt f3f7_76 = f3_2.toBig * f7_38.toBig; + BigInt f3f8_38 = f3_2.toBig * f8_19.toBig; + BigInt f3f9_76 = f3_2.toBig * f9_38.toBig; + BigInt f4f4 = f4.toBig * f4.toBig; + BigInt f4f5_2 = f4_2.toBig * f5.toBig; + BigInt f4f6_38 = f4_2.toBig * f6_19.toBig; + BigInt f4f7_38 = f4.toBig * f7_38.toBig; + BigInt f4f8_38 = f4_2.toBig * f8_19.toBig; + BigInt f4f9_38 = f4.toBig * f9_38.toBig; + BigInt f5f5_38 = f5.toBig * f5_38.toBig; + BigInt f5f6_38 = f5_2.toBig * f6_19.toBig; + BigInt f5f7_76 = f5_2.toBig * f7_38.toBig; + BigInt f5f8_38 = f5_2.toBig * f8_19.toBig; + BigInt f5f9_76 = f5_2.toBig * f9_38.toBig; + BigInt f6f6_19 = f6.toBig * f6_19.toBig; + BigInt f6f7_38 = f6.toBig * f7_38.toBig; + BigInt f6f8_38 = f6_2.toBig * f8_19.toBig; + BigInt f6f9_38 = f6.toBig * f9_38.toBig; + BigInt f7f7_38 = f7.toBig * f7_38.toBig; + BigInt f7f8_38 = f7_2.toBig * f8_19.toBig; + BigInt f7f9_76 = f7_2.toBig * f9_38.toBig; + BigInt f8f8_19 = f8.toBig * f8_19.toBig; + BigInt f8f9_38 = f8.toBig * f9_38.toBig; + BigInt f9f9_38 = f9.toBig * f9_38.toBig; + BigInt h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + BigInt h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + BigInt h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + BigInt h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + BigInt h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + BigInt h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + BigInt h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + BigInt h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + BigInt h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + BigInt h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + + carry1 = (h1 + _bitMaskFor24) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry5 = (h5 + _bitMaskFor24) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + + carry2 = (h2 + _bitMaskFor25) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry6 = (h6 + _bitMaskFor25) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + + carry3 = (h3 + _bitMaskFor24) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry7 = (h7 + _bitMaskFor24) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry8 = (h8 + _bitMaskFor25) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + + carry9 = (h9 + _bitMaskFor24) >> 25; + h0 += carry9 * BigInt.from(19); + h9 -= carry9 << 25; + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + + h.h[0] = h0.toInt32; + h.h[1] = h1.toInt32; + h.h[2] = h2.toInt32; + h.h[3] = h3.toInt32; + h.h[4] = h4.toInt32; + h.h[5] = h5.toInt32; + h.h[6] = h6.toInt32; + h.h[7] = h7.toInt32; + h.h[8] = h8.toInt32; + h.h[9] = h9.toInt32; + } + + static void feSub(FieldElement h, FieldElement f, FieldElement g) { + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + int g0 = g.h[0]; + int g1 = g.h[1]; + int g2 = g.h[2]; + int g3 = g.h[3]; + int g4 = g.h[4]; + int g5 = g.h[5]; + int g6 = g.h[6]; + int g7 = g.h[7]; + int g8 = g.h[8]; + int g9 = g.h[9]; + int h0 = f0 - g0; + int h1 = f1 - g1; + int h2 = f2 - g2; + int h3 = f3 - g3; + int h4 = f4 - g4; + int h5 = f5 - g5; + int h6 = f6 - g6; + int h7 = f7 - g7; + int h8 = f8 - g8; + int h9 = f9 - g9; + h.h[0] = h0; + h.h[1] = h1; + h.h[2] = h2; + h.h[3] = h3; + h.h[4] = h4; + h.h[5] = h5; + h.h[6] = h6; + h.h[7] = h7; + h.h[8] = h8; + h.h[9] = h9; + } + + static void feTobytes(List s, FieldElement h) { + s.asMin32("feTobytes"); + BigInt h0 = h.h[0].toBig; + BigInt h1 = h.h[1].toBig; + BigInt h2 = h.h[2].toBig; + BigInt h3 = h.h[3].toBig; + BigInt h4 = h.h[4].toBig; + BigInt h5 = h.h[5].toBig; + BigInt h6 = h.h[6].toBig; + BigInt h7 = h.h[7].toBig; + BigInt h8 = h.h[8].toBig; + BigInt h9 = h.h[9].toBig; + BigInt q; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + + q = (BigInt.from(19) * h9 + ((1) << 24).toBig) >> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += BigInt.from(19) * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = (h0 >> 26); + h1 += carry0; + h0 -= carry0 << 26; + carry1 = h1 >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry2 = h2 >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry3 = h3 >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry4 = h4 >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry5 = h5 >> 25; + h6 += carry5; + h5 -= carry5 << 25; + carry6 = h6 >> 26; + h7 += carry6; + h6 -= carry6 << 26; + carry7 = h7 >> 25; + h8 += carry7; + h7 -= carry7 << 25; + carry8 = h8 >> 26; + h9 += carry8; + h8 -= carry8 << 26; + carry9 = h9 >> 25; + h9 -= carry9 << 25; + /* h10 = carry9 */ + + /* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + Goal: Output h0+...+2^230 h9. + */ + List sBig = List.filled(32, BigInt.zero); + sBig[0] = h0 >> 0; + sBig[1] = h0 >> 8; + sBig[2] = h0 >> 16; + sBig[3] = (h0 >> 24) | (h1 << 2); + sBig[4] = h1 >> 6; + sBig[5] = h1 >> 14; + sBig[6] = (h1 >> 22) | (h2 << 3); + sBig[7] = h2 >> 5; + sBig[8] = h2 >> 13; + sBig[9] = (h2 >> 21) | (h3 << 5); + sBig[10] = h3 >> 3; + sBig[11] = h3 >> 11; + sBig[12] = (h3 >> 19) | (h4 << 6); + sBig[13] = h4 >> 2; + sBig[14] = h4 >> 10; + sBig[15] = h4 >> 18; + sBig[16] = h5 >> 0; + sBig[17] = h5 >> 8; + sBig[18] = h5 >> 16; + sBig[19] = (h5 >> 24) | (h6 << 1); + sBig[20] = h6 >> 7; + sBig[21] = h6 >> 15; + sBig[22] = (h6 >> 23) | (h7 << 3); + sBig[23] = h7 >> 5; + sBig[24] = h7 >> 13; + sBig[25] = (h7 >> 21) | (h8 << 4); + sBig[26] = h8 >> 4; + sBig[27] = h8 >> 12; + sBig[28] = (h8 >> 20) | (h9 << 6); + sBig[29] = h9 >> 2; + sBig[30] = h9 >> 10; + sBig[31] = h9 >> 18; + for (int i = 0; i < s.length; i++) { + s[i] = sBig[i].toUnsigned8; + } + } + + static void feMul(FieldElement h, FieldElement f, FieldElement g) { + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + int g0 = g.h[0]; + int g1 = g.h[1]; + int g2 = g.h[2]; + int g3 = g.h[3]; + int g4 = g.h[4]; + int g5 = g.h[5]; + int g6 = g.h[6]; + int g7 = g.h[7]; + int g8 = g.h[8]; + int g9 = g.h[9]; + int g1_19 = (19 * g1).toInt32; /* 1.959375*2^29 */ + int g2_19 = (19 * g2).toInt32; /* 1.959375*2^30; still ok */ + int g3_19 = (19 * g3).toInt32; + int g4_19 = (19 * g4).toInt32; + int g5_19 = (19 * g5).toInt32; + int g6_19 = (19 * g6).toInt32; + int g7_19 = (19 * g7).toInt32; + int g8_19 = (19 * g8).toInt32; + int g9_19 = (19 * g9).toInt32; + int f1_2 = (2 * f1).toInt32; + int f3_2 = (2 * f3).toInt32; + int f5_2 = (2 * f5).toInt32; + int f7_2 = (2 * f7).toInt32; + int f9_2 = (2 * f9).toInt32; + + BigInt f0g0 = f0.toBig * g0.toBig; + BigInt f0g1 = f0.toBig * g1.toBig; + BigInt f0g2 = f0.toBig * g2.toBig; + BigInt f0g3 = f0.toBig * g3.toBig; + BigInt f0g4 = f0.toBig * g4.toBig; + BigInt f0g5 = f0.toBig * g5.toBig; + BigInt f0g6 = f0.toBig * g6.toBig; + BigInt f0g7 = f0.toBig * g7.toBig; + BigInt f0g8 = f0.toBig * g8.toBig; + BigInt f0g9 = f0.toBig * g9.toBig; + BigInt f1g0 = f1.toBig * g0.toBig; + BigInt f1g1_2 = f1_2.toBig * g1.toBig; + BigInt f1g2 = f1.toBig * g2.toBig; + BigInt f1g3_2 = f1_2.toBig * g3.toBig; + BigInt f1g4 = f1.toBig * g4.toBig; + BigInt f1g5_2 = f1_2.toBig * g5.toBig; + BigInt f1g6 = f1.toBig * g6.toBig; + BigInt f1g7_2 = f1_2.toBig * g7.toBig; + BigInt f1g8 = f1.toBig * g8.toBig; + BigInt f1g9_38 = f1_2.toBig * g9_19.toBig; + BigInt f2g0 = f2.toBig * g0.toBig; + BigInt f2g1 = f2.toBig * g1.toBig; + BigInt f2g2 = f2.toBig * g2.toBig; + BigInt f2g3 = f2.toBig * g3.toBig; + BigInt f2g4 = f2.toBig * g4.toBig; + BigInt f2g5 = f2.toBig * g5.toBig; + BigInt f2g6 = f2.toBig * g6.toBig; + BigInt f2g7 = f2.toBig * g7.toBig; + BigInt f2g8_19 = f2.toBig * g8_19.toBig; + BigInt f2g9_19 = f2.toBig * g9_19.toBig; + BigInt f3g0 = f3.toBig * g0.toBig; + BigInt f3g1_2 = f3_2.toBig * g1.toBig; + BigInt f3g2 = f3.toBig * g2.toBig; + BigInt f3g3_2 = f3_2.toBig * g3.toBig; + BigInt f3g4 = f3.toBig * g4.toBig; + BigInt f3g5_2 = f3_2.toBig * g5.toBig; + BigInt f3g6 = f3.toBig * g6.toBig; + BigInt f3g7_38 = f3_2.toBig * g7_19.toBig; + BigInt f3g8_19 = f3.toBig * g8_19.toBig; + BigInt f3g9_38 = f3_2.toBig * g9_19.toBig; + BigInt f4g0 = f4.toBig * g0.toBig; + BigInt f4g1 = f4.toBig * g1.toBig; + BigInt f4g2 = f4.toBig * g2.toBig; + BigInt f4g3 = f4.toBig * g3.toBig; + BigInt f4g4 = f4.toBig * g4.toBig; + BigInt f4g5 = f4.toBig * g5.toBig; + BigInt f4g6_19 = f4.toBig * g6_19.toBig; + BigInt f4g7_19 = f4.toBig * g7_19.toBig; + BigInt f4g8_19 = f4.toBig * g8_19.toBig; + BigInt f4g9_19 = f4.toBig * g9_19.toBig; + BigInt f5g0 = f5.toBig * g0.toBig; + BigInt f5g1_2 = f5_2.toBig * g1.toBig; + BigInt f5g2 = f5.toBig * g2.toBig; + BigInt f5g3_2 = f5_2.toBig * g3.toBig; + BigInt f5g4 = f5.toBig * g4.toBig; + BigInt f5g5_38 = f5_2.toBig * g5_19.toBig; + BigInt f5g6_19 = f5.toBig * g6_19.toBig; + BigInt f5g7_38 = f5_2.toBig * g7_19.toBig; + BigInt f5g8_19 = f5.toBig * g8_19.toBig; + BigInt f5g9_38 = f5_2.toBig * g9_19.toBig; + BigInt f6g0 = f6.toBig * g0.toBig; + BigInt f6g1 = f6.toBig * g1.toBig; + BigInt f6g2 = f6.toBig * g2.toBig; + BigInt f6g3 = f6.toBig * g3.toBig; + BigInt f6g4_19 = f6.toBig * g4_19.toBig; + BigInt f6g5_19 = f6.toBig * g5_19.toBig; + BigInt f6g6_19 = f6.toBig * g6_19.toBig; + BigInt f6g7_19 = f6.toBig * g7_19.toBig; + BigInt f6g8_19 = f6.toBig * g8_19.toBig; + BigInt f6g9_19 = f6.toBig * g9_19.toBig; + BigInt f7g0 = f7.toBig * g0.toBig; + BigInt f7g1_2 = f7_2.toBig * g1.toBig; + BigInt f7g2 = f7.toBig * g2.toBig; + BigInt f7g3_38 = f7_2.toBig * g3_19.toBig; + BigInt f7g4_19 = f7.toBig * g4_19.toBig; + BigInt f7g5_38 = f7_2.toBig * g5_19.toBig; + BigInt f7g6_19 = f7.toBig * g6_19.toBig; + BigInt f7g7_38 = f7_2.toBig * g7_19.toBig; + BigInt f7g8_19 = f7.toBig * g8_19.toBig; + BigInt f7g9_38 = f7_2.toBig * g9_19.toBig; + BigInt f8g0 = f8.toBig * g0.toBig; + BigInt f8g1 = f8.toBig * g1.toBig; + BigInt f8g2_19 = f8.toBig * g2_19.toBig; + BigInt f8g3_19 = f8.toBig * g3_19.toBig; + BigInt f8g4_19 = f8.toBig * g4_19.toBig; + BigInt f8g5_19 = f8.toBig * g5_19.toBig; + BigInt f8g6_19 = f8.toBig * g6_19.toBig; + BigInt f8g7_19 = f8.toBig * g7_19.toBig; + BigInt f8g8_19 = f8.toBig * g8_19.toBig; + BigInt f8g9_19 = f8.toBig * g9_19.toBig; + BigInt f9g0 = f9.toBig * g0.toBig; + BigInt f9g1_38 = f9_2.toBig * g1_19.toBig; + BigInt f9g2_19 = f9.toBig * g2_19.toBig; + BigInt f9g3_38 = f9_2.toBig * g3_19.toBig; + BigInt f9g4_19 = f9.toBig * g4_19.toBig; + BigInt f9g5_38 = f9_2.toBig * g5_19.toBig; + BigInt f9g6_19 = f9.toBig * g6_19.toBig; + BigInt f9g7_38 = f9_2.toBig * g7_19.toBig; + BigInt f9g8_19 = f9.toBig * g8_19.toBig; + BigInt f9g9_38 = f9_2.toBig * g9_19.toBig; + BigInt h0 = f0g0 + + f1g9_38 + + f2g8_19 + + f3g7_38 + + f4g6_19 + + f5g5_38 + + f6g4_19 + + f7g3_38 + + f8g2_19 + + f9g1_38; + BigInt h1 = f0g1 + + f1g0 + + f2g9_19 + + f3g8_19 + + f4g7_19 + + f5g6_19 + + f6g5_19 + + f7g4_19 + + f8g3_19 + + f9g2_19; + BigInt h2 = f0g2 + + f1g1_2 + + f2g0 + + f3g9_38 + + f4g8_19 + + f5g7_38 + + f6g6_19 + + f7g5_38 + + f8g4_19 + + f9g3_38; + BigInt h3 = f0g3 + + f1g2 + + f2g1 + + f3g0 + + f4g9_19 + + f5g8_19 + + f6g7_19 + + f7g6_19 + + f8g5_19 + + f9g4_19; + BigInt h4 = f0g4 + + f1g3_2 + + f2g2 + + f3g1_2 + + f4g0 + + f5g9_38 + + f6g8_19 + + f7g7_38 + + f8g6_19 + + f9g5_38; + BigInt h5 = f0g5 + + f1g4 + + f2g3 + + f3g2 + + f4g1 + + f5g0 + + f6g9_19 + + f7g8_19 + + f8g7_19 + + f9g6_19; + BigInt h6 = f0g6 + + f1g5_2 + + f2g4 + + f3g3_2 + + f4g2 + + f5g1_2 + + f6g0 + + f7g9_38 + + f8g8_19 + + f9g7_38; + BigInt h7 = f0g7 + + f1g6 + + f2g5 + + f3g4 + + f4g3 + + f5g2 + + f6g1 + + f7g0 + + f8g9_19 + + f9g8_19; + BigInt h8 = f0g8 + + f1g7_2 + + f2g6 + + f3g5_2 + + f4g4 + + f5g3_2 + + f6g2 + + f7g1_2 + + f8g0 + + f9g9_38; + BigInt h9 = + f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + + /* + |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 + */ + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = (h1 + _bitMaskFor24) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry5 = (h5 + _bitMaskFor24) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = (h2 + _bitMaskFor25) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry6 = (h6 + _bitMaskFor25) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = (h3 + _bitMaskFor24) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry7 = (h7 + _bitMaskFor24) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry8 = (h8 + _bitMaskFor25) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = (h9 + _bitMaskFor24) >> 25; + h0 += carry9 * BigInt.from(19); + h9 -= carry9 << 25; + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h.h[0] = h0.toInt32; + h.h[1] = h1.toInt32; + h.h[2] = h2.toInt32; + h.h[3] = h3.toInt32; + h.h[4] = h4.toInt32; + h.h[5] = h5.toInt32; + h.h[6] = h6.toInt32; + h.h[7] = h7.toInt32; + h.h[8] = h8.toInt32; + h.h[9] = h9.toInt32; + } + + static void feDivpowm1(FieldElement r, FieldElement u, FieldElement v) { + FieldElement v3 = FieldElement(), + uv7 = FieldElement(), + t0 = FieldElement(), + t1 = FieldElement(), + t2 = FieldElement(); + int i; + + feSq(v3, v); + feMul(v3, v3, v); /* v3 = v^3 */ + feSq(uv7, v3); + feMul(uv7, uv7, v); + feMul(uv7, uv7, u); /* uv7 = uv^7 */ + + /*fe_pow22523(uv7, uv7);*/ + + /* From fe_pow22523.c */ + + feSq(t0, uv7); + feSq(t1, t0); + feSq(t1, t1); + feMul(t1, uv7, t1); + feMul(t0, t0, t1); + feSq(t0, t0); + feMul(t0, t1, t0); + feSq(t1, t0); + for (i = 0; i < 4; ++i) { + feSq(t1, t1); + } + feMul(t0, t1, t0); + feSq(t1, t0); + for (i = 0; i < 9; ++i) { + feSq(t1, t1); + } + feMul(t1, t1, t0); + feSq(t2, t1); + for (i = 0; i < 19; ++i) { + feSq(t2, t2); + } + feMul(t1, t2, t1); + for (i = 0; i < 10; ++i) { + feSq(t1, t1); + } + feMul(t0, t1, t0); + feSq(t1, t0); + for (i = 0; i < 49; ++i) { + feSq(t1, t1); + } + feMul(t1, t1, t0); + feSq(t2, t1); + for (i = 0; i < 99; ++i) { + feSq(t2, t2); + } + feMul(t1, t2, t1); + for (i = 0; i < 50; ++i) { + feSq(t1, t1); + } + feMul(t0, t1, t0); + feSq(t0, t0); + feSq(t0, t0); + feMul(t0, t0, uv7); + + /* End fe_pow22523.c */ + /* t0 = (uv^7)^((q-5)/8) */ + feMul(t0, t0, v3); + feMul(r, t0, u); /* u^(m+1)v^(-(m+1)) */ + } + + static int feIsnonzero(FieldElement f) { + final List s = List.filled(32, 0); + feTobytes(s, f); + for (int byte in s) { + if (byte != 0) { + return 1; // Found a non-zero byte + } + } + return 0; + } + + static void feInvert(FieldElement out, FieldElement z) { + FieldElement t0 = FieldElement(); + FieldElement t1 = FieldElement(); + FieldElement t2 = FieldElement(); + FieldElement t3 = FieldElement(); + int i; + + feSq(t0, z); + feSq(t1, t0); + feSq(t1, t1); + feMul(t1, z, t1); + feMul(t0, t0, t1); + feSq(t2, t0); + feMul(t1, t1, t2); + feSq(t2, t1); + for (i = 0; i < 4; ++i) { + feSq(t2, t2); + } + feMul(t1, t2, t1); + feSq(t2, t1); + for (i = 0; i < 9; ++i) { + feSq(t2, t2); + } + feMul(t2, t2, t1); + feSq(t3, t2); + for (i = 0; i < 19; ++i) { + feSq(t3, t3); + } + feMul(t2, t3, t2); + feSq(t2, t2); + for (i = 0; i < 9; ++i) { + feSq(t2, t2); + } + feMul(t1, t2, t1); + feSq(t2, t1); + for (i = 0; i < 49; ++i) { + feSq(t2, t2); + } + feMul(t2, t2, t1); + feSq(t3, t2); + for (i = 0; i < 99; ++i) { + feSq(t3, t3); + } + feMul(t2, t3, t2); + feSq(t2, t2); + for (i = 0; i < 49; ++i) { + feSq(t2, t2); + } + feMul(t1, t2, t1); + feSq(t1, t1); + for (i = 0; i < 4; ++i) { + feSq(t1, t1); + } + feMul(out, t1, t0); + + return; + } + + static List geTobytes_(GroupElementP2 h) { + final s = List.filled(32, 0); + geToBytes(s, h); + return s; + } + + static void geToBytes(List s, GroupElementP2 h) { + FieldElement recip = FieldElement(); + FieldElement x = FieldElement(); + FieldElement y = FieldElement(); + feInvert(recip, h.z); + feMul(x, h.x, recip); + feMul(y, h.y, recip); + feTobytes(s, y); + s[31] ^= (feIsnegative(x) << 7) & 0xFF; + } + + static void geSub( + GroupElementP1P1 r, GroupElementP3 p, GroupElementCached q) { + FieldElement t0 = FieldElement(); + feAdd(r.x, p.y, p.x); + feSub(r.y, p.y, p.x); + feMul(r.z, r.x, q.yMinusX); + feMul(r.y, r.y, q.yPlusX); + feMul(r.t, q.t2d, p.t); + feMul(r.x, p.z, q.z); + feAdd(t0, r.x, r.x); + feSub(r.x, r.z, r.y); + feAdd(r.y, r.z, r.y); + feSub(r.z, t0, r.t); + feAdd(r.t, t0, r.t); + } + + static void scMul(List s, List a, List b) { + s.asMin32("scMul"); + a.asMin32("scMul"); + b.asMin32("scMul"); + BigInt a0 = _b2097151 & _load3(a, 0); + BigInt a1 = _b2097151 & (_load4(a, 2) >> 5); + BigInt a2 = _b2097151 & (_load3(a, 5) >> 2); + BigInt a3 = _b2097151 & (_load4(a, 7) >> 7); + BigInt a4 = _b2097151 & (_load4(a, 10) >> 4); + BigInt a5 = _b2097151 & (_load3(a, 13) >> 1); + BigInt a6 = _b2097151 & (_load4(a, 15) >> 6); + BigInt a7 = _b2097151 & (_load3(a, 18) >> 3); + BigInt a8 = _b2097151 & _load3(a, 21); + BigInt a9 = _b2097151 & (_load4(a, 23) >> 5); + BigInt a10 = _b2097151 & (_load3(a, 26) >> 2); + BigInt a11 = (_load4(a, 28) >> 7); + BigInt b0 = _b2097151 & _load3(b, 0); + BigInt b1 = _b2097151 & (_load4(b, 2) >> 5); + BigInt b2 = _b2097151 & (_load3(b, 5) >> 2); + BigInt b3 = _b2097151 & (_load4(b, 7) >> 7); + BigInt b4 = _b2097151 & (_load4(b, 10) >> 4); + BigInt b5 = _b2097151 & (_load3(b, 13) >> 1); + BigInt b6 = _b2097151 & (_load4(b, 15) >> 6); + BigInt b7 = _b2097151 & (_load3(b, 18) >> 3); + BigInt b8 = _b2097151 & _load3(b, 21); + BigInt b9 = _b2097151 & (_load4(b, 23) >> 5); + BigInt b10 = _b2097151 & (_load3(b, 26) >> 2); + BigInt b11 = (_load4(b, 28) >> 7); + BigInt s0; + BigInt s1; + BigInt s2; + BigInt s3; + BigInt s4; + BigInt s5; + BigInt s6; + BigInt s7; + BigInt s8; + BigInt s9; + BigInt s10; + BigInt s11; + BigInt s12; + BigInt s13; + BigInt s14; + BigInt s15; + BigInt s16; + BigInt s17; + BigInt s18; + BigInt s19; + BigInt s20; + BigInt s21; + BigInt s22; + BigInt s23; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + BigInt carry10; + BigInt carry11; + BigInt carry12; + BigInt carry13; + BigInt carry14; + BigInt carry15; + BigInt carry16; + BigInt carry17; + BigInt carry18; + BigInt carry19; + BigInt carry20; + BigInt carry21; + BigInt carry22; + + s0 = a0 * b0; + s1 = (a0 * b1 + a1 * b0); + s2 = (a0 * b2 + a1 * b1 + a2 * b0); + s3 = (a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0); + s4 = (a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0); + s5 = (a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0); + s6 = (a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0); + s7 = (a0 * b7 + + a1 * b6 + + a2 * b5 + + a3 * b4 + + a4 * b3 + + a5 * b2 + + a6 * b1 + + a7 * b0); + s8 = (a0 * b8 + + a1 * b7 + + a2 * b6 + + a3 * b5 + + a4 * b4 + + a5 * b3 + + a6 * b2 + + a7 * b1 + + a8 * b0); + s9 = (a0 * b9 + + a1 * b8 + + a2 * b7 + + a3 * b6 + + a4 * b5 + + a5 * b4 + + a6 * b3 + + a7 * b2 + + a8 * b1 + + a9 * b0); + s10 = (a0 * b10 + + a1 * b9 + + a2 * b8 + + a3 * b7 + + a4 * b6 + + a5 * b5 + + a6 * b4 + + a7 * b3 + + a8 * b2 + + a9 * b1 + + a10 * b0); + s11 = (a0 * b11 + + a1 * b10 + + a2 * b9 + + a3 * b8 + + a4 * b7 + + a5 * b6 + + a6 * b5 + + a7 * b4 + + a8 * b3 + + a9 * b2 + + a10 * b1 + + a11 * b0); + s12 = (a1 * b11 + + a2 * b10 + + a3 * b9 + + a4 * b8 + + a5 * b7 + + a6 * b6 + + a7 * b5 + + a8 * b4 + + a9 * b3 + + a10 * b2 + + a11 * b1); + s13 = (a2 * b11 + + a3 * b10 + + a4 * b9 + + a5 * b8 + + a6 * b7 + + a7 * b6 + + a8 * b5 + + a9 * b4 + + a10 * b3 + + a11 * b2); + s14 = (a3 * b11 + + a4 * b10 + + a5 * b9 + + a6 * b8 + + a7 * b7 + + a8 * b6 + + a9 * b5 + + a10 * b4 + + a11 * b3); + s15 = (a4 * b11 + + a5 * b10 + + a6 * b9 + + a7 * b8 + + a8 * b7 + + a9 * b6 + + a10 * b5 + + a11 * b4); + s16 = (a5 * b11 + + a6 * b10 + + a7 * b9 + + a8 * b8 + + a9 * b7 + + a10 * b6 + + a11 * b5); + s17 = (a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6); + s18 = (a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7); + s19 = (a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8); + s20 = (a9 * b11 + a10 * b10 + a11 * b9); + s21 = (a10 * b11 + a11 * b10); + s22 = a11 * b11; + s23 = BigInt.zero; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + _bitMaskFor20) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + _bitMaskFor20) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + _bitMaskFor20) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + _bitMaskFor20) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + _bitMaskFor20) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + _bitMaskFor20) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + _bitMaskFor20) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + _bitMaskFor20) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + _bitMaskFor20) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + _bitMaskFor20) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + _bitMaskFor20) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643.toBig; + s12 += s23 * 470296.toBig; + s13 += s23 * 654183.toBig; + s14 -= s23 * 997805.toBig; + s15 += s23 * 136657.toBig; + s16 -= s23 * 683901.toBig; + + s10 += s22 * 666643.toBig; + s11 += s22 * 470296.toBig; + s12 += s22 * 654183.toBig; + s13 -= s22 * 997805.toBig; + s14 += s22 * 136657.toBig; + s15 -= s22 * 683901.toBig; + + s9 += s21 * 666643.toBig; + s10 += s21 * 470296.toBig; + s11 += s21 * 654183.toBig; + s12 -= s21 * 997805.toBig; + s13 += s21 * 136657.toBig; + s14 -= s21 * 683901.toBig; + + s8 += s20 * 666643.toBig; + s9 += s20 * 470296.toBig; + s10 += s20 * 654183.toBig; + s11 -= s20 * 997805.toBig; + s12 += s20 * 136657.toBig; + s13 -= s20 * 683901.toBig; + + s7 += s19 * 666643.toBig; + s8 += s19 * 470296.toBig; + s9 += s19 * 654183.toBig; + s10 -= s19 * 997805.toBig; + s11 += s19 * 136657.toBig; + s12 -= s19 * 683901.toBig; + + s6 += s18 * 666643.toBig; + s7 += s18 * 470296.toBig; + s8 += s18 * 654183.toBig; + s9 -= s18 * 997805.toBig; + s10 += s18 * 136657.toBig; + s11 -= s18 * 683901.toBig; + + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + _bitMaskFor20) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + _bitMaskFor20) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + _bitMaskFor20) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + _bitMaskFor20) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + _bitMaskFor20) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643.toBig; + s6 += s17 * 470296.toBig; + s7 += s17 * 654183.toBig; + s8 -= s17 * 997805.toBig; + s9 += s17 * 136657.toBig; + s10 -= s17 * 683901.toBig; + + s4 += s16 * 666643.toBig; + s5 += s16 * 470296.toBig; + s6 += s16 * 654183.toBig; + s7 -= s16 * 997805.toBig; + s8 += s16 * 136657.toBig; + s9 -= s16 * 683901.toBig; + + s3 += s15 * 666643.toBig; + s4 += s15 * 470296.toBig; + s5 += s15 * 654183.toBig; + s6 -= s15 * 997805.toBig; + s7 += s15 * 136657.toBig; + s8 -= s15 * 683901.toBig; + + s2 += s14 * 666643.toBig; + s3 += s14 * 470296.toBig; + s4 += s14 * 654183.toBig; + s5 -= s14 * 997805.toBig; + s6 += s14 * 136657.toBig; + s7 -= s14 * 683901.toBig; + + s1 += s13 * 666643.toBig; + s2 += s13 * 470296.toBig; + s3 += s13 * 654183.toBig; + s4 -= s13 * 997805.toBig; + s5 += s13 * 136657.toBig; + s6 -= s13 * 683901.toBig; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + List sBig = List.filled(32, BigInt.zero); + sBig[0] = s0 >> 0; + sBig[1] = s0 >> 8; + sBig[2] = (s0 >> 16) | (s1 << 5); + sBig[3] = s1 >> 3; + sBig[4] = s1 >> 11; + sBig[5] = (s1 >> 19) | (s2 << 2); + sBig[6] = s2 >> 6; + sBig[7] = (s2 >> 14) | (s3 << 7); + sBig[8] = s3 >> 1; + sBig[9] = s3 >> 9; + sBig[10] = (s3 >> 17) | (s4 << 4); + sBig[11] = s4 >> 4; + sBig[12] = s4 >> 12; + sBig[13] = (s4 >> 20) | (s5 << 1); + sBig[14] = s5 >> 7; + sBig[15] = (s5 >> 15) | (s6 << 6); + sBig[16] = s6 >> 2; + sBig[17] = s6 >> 10; + sBig[18] = (s6 >> 18) | (s7 << 3); + sBig[19] = s7 >> 5; + sBig[20] = s7 >> 13; + sBig[21] = s8 >> 0; + sBig[22] = s8 >> 8; + sBig[23] = (s8 >> 16) | (s9 << 5); + sBig[24] = s9 >> 3; + sBig[25] = s9 >> 11; + sBig[26] = (s9 >> 19) | (s10 << 2); + sBig[27] = s10 >> 6; + sBig[28] = (s10 >> 14) | (s11 << 7); + sBig[29] = s11 >> 1; + sBig[30] = s11 >> 9; + sBig[31] = s11 >> 17; + for (int i = 0; i < sBig.length; i++) { + s[i] = sBig[i].toUnsigned8; + } + } + + static void geP3ToCached(GroupElementCached r, GroupElementP3 p) { + feAdd(r.yPlusX, p.y, p.x); + feSub(r.yMinusX, p.y, p.x); + feCopy(r.z, p.z); + feMul(r.t2d, p.t, CryptoOpsConst.d2); + } + + static void scMulAdd(List s, List a, List b, List c) { + s.asMin32("scMulAdd"); + a.asMin32("scMulAdd"); + b.asMin32("scMulAdd"); + c.asMin32("scMulAdd"); + BigInt a0 = _b2097151 & _load3(a, 0); + BigInt a1 = _b2097151 & (_load4(a, 2) >> 5); + BigInt a2 = _b2097151 & (_load3(a, 5) >> 2); + BigInt a3 = _b2097151 & (_load4(a, 7) >> 7); + BigInt a4 = _b2097151 & (_load4(a, 10) >> 4); + BigInt a5 = _b2097151 & (_load3(a, 13) >> 1); + BigInt a6 = _b2097151 & (_load4(a, 15) >> 6); + BigInt a7 = _b2097151 & (_load3(a, 18) >> 3); + BigInt a8 = _b2097151 & _load3(a, 21); + BigInt a9 = _b2097151 & (_load4(a, 23) >> 5); + BigInt a10 = _b2097151 & (_load3(a, 26) >> 2); + BigInt a11 = (_load4(a, 28) >> 7); + BigInt b0 = _b2097151 & _load3(b, 0); + BigInt b1 = _b2097151 & (_load4(b, 2) >> 5); + BigInt b2 = _b2097151 & (_load3(b, 5) >> 2); + BigInt b3 = _b2097151 & (_load4(b, 7) >> 7); + BigInt b4 = _b2097151 & (_load4(b, 10) >> 4); + BigInt b5 = _b2097151 & (_load3(b, 13) >> 1); + BigInt b6 = _b2097151 & (_load4(b, 15) >> 6); + BigInt b7 = _b2097151 & (_load3(b, 18) >> 3); + BigInt b8 = _b2097151 & _load3(b, 21); + BigInt b9 = _b2097151 & (_load4(b, 23) >> 5); + BigInt b10 = _b2097151 & (_load3(b, 26) >> 2); + BigInt b11 = (_load4(b, 28) >> 7); + BigInt c0 = _b2097151 & _load3(c, 0); + BigInt c1 = _b2097151 & (_load4(c, 2) >> 5); + BigInt c2 = _b2097151 & (_load3(c, 5) >> 2); + BigInt c3 = _b2097151 & (_load4(c, 7) >> 7); + BigInt c4 = _b2097151 & (_load4(c, 10) >> 4); + BigInt c5 = _b2097151 & (_load3(c, 13) >> 1); + BigInt c6 = _b2097151 & (_load4(c, 15) >> 6); + BigInt c7 = _b2097151 & (_load3(c, 18) >> 3); + BigInt c8 = _b2097151 & _load3(c, 21); + BigInt c9 = _b2097151 & (_load4(c, 23) >> 5); + BigInt c10 = _b2097151 & (_load3(c, 26) >> 2); + BigInt c11 = (_load4(c, 28) >> 7); + BigInt s0; + BigInt s1; + BigInt s2; + BigInt s3; + BigInt s4; + BigInt s5; + BigInt s6; + BigInt s7; + BigInt s8; + BigInt s9; + BigInt s10; + BigInt s11; + BigInt s12; + BigInt s13; + BigInt s14; + BigInt s15; + BigInt s16; + BigInt s17; + BigInt s18; + BigInt s19; + BigInt s20; + BigInt s21; + BigInt s22; + BigInt s23; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + BigInt carry10; + BigInt carry11; + BigInt carry12; + BigInt carry13; + BigInt carry14; + BigInt carry15; + BigInt carry16; + BigInt carry17; + BigInt carry18; + BigInt carry19; + BigInt carry20; + BigInt carry21; + BigInt carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + (a0 * b1 + a1 * b0); + s2 = c2 + (a0 * b2 + a1 * b1 + a2 * b0); + s3 = c3 + (a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0); + s4 = c4 + (a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0); + s5 = c5 + (a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0); + s6 = c6 + + (a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0); + s7 = c7 + + (a0 * b7 + + a1 * b6 + + a2 * b5 + + a3 * b4 + + a4 * b3 + + a5 * b2 + + a6 * b1 + + a7 * b0); + s8 = c8 + + (a0 * b8 + + a1 * b7 + + a2 * b6 + + a3 * b5 + + a4 * b4 + + a5 * b3 + + a6 * b2 + + a7 * b1 + + a8 * b0); + s9 = c9 + + (a0 * b9 + + a1 * b8 + + a2 * b7 + + a3 * b6 + + a4 * b5 + + a5 * b4 + + a6 * b3 + + a7 * b2 + + a8 * b1 + + a9 * b0); + s10 = c10 + + (a0 * b10 + + a1 * b9 + + a2 * b8 + + a3 * b7 + + a4 * b6 + + a5 * b5 + + a6 * b4 + + a7 * b3 + + a8 * b2 + + a9 * b1 + + a10 * b0); + s11 = c11 + + (a0 * b11 + + a1 * b10 + + a2 * b9 + + a3 * b8 + + a4 * b7 + + a5 * b6 + + a6 * b5 + + a7 * b4 + + a8 * b3 + + a9 * b2 + + a10 * b1 + + a11 * b0); + s12 = (a1 * b11 + + a2 * b10 + + a3 * b9 + + a4 * b8 + + a5 * b7 + + a6 * b6 + + a7 * b5 + + a8 * b4 + + a9 * b3 + + a10 * b2 + + a11 * b1); + s13 = (a2 * b11 + + a3 * b10 + + a4 * b9 + + a5 * b8 + + a6 * b7 + + a7 * b6 + + a8 * b5 + + a9 * b4 + + a10 * b3 + + a11 * b2); + s14 = (a3 * b11 + + a4 * b10 + + a5 * b9 + + a6 * b8 + + a7 * b7 + + a8 * b6 + + a9 * b5 + + a10 * b4 + + a11 * b3); + s15 = (a4 * b11 + + a5 * b10 + + a6 * b9 + + a7 * b8 + + a8 * b7 + + a9 * b6 + + a10 * b5 + + a11 * b4); + s16 = (a5 * b11 + + a6 * b10 + + a7 * b9 + + a8 * b8 + + a9 * b7 + + a10 * b6 + + a11 * b5); + s17 = (a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6); + s18 = (a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7); + s19 = (a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8); + s20 = (a9 * b11 + a10 * b10 + a11 * b9); + s21 = (a10 * b11 + a11 * b10); + s22 = a11 * b11; + s23 = BigInt.zero; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + _bitMaskFor20) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + _bitMaskFor20) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + _bitMaskFor20) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + _bitMaskFor20) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + _bitMaskFor20) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + _bitMaskFor20) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + _bitMaskFor20) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + _bitMaskFor20) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + _bitMaskFor20) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + _bitMaskFor20) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + _bitMaskFor20) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643.toBig; + s12 += s23 * 470296.toBig; + s13 += s23 * 654183.toBig; + s14 -= s23 * 997805.toBig; + s15 += s23 * 136657.toBig; + s16 -= s23 * 683901.toBig; + + s10 += s22 * 666643.toBig; + s11 += s22 * 470296.toBig; + s12 += s22 * 654183.toBig; + s13 -= s22 * 997805.toBig; + s14 += s22 * 136657.toBig; + s15 -= s22 * 683901.toBig; + + s9 += s21 * 666643.toBig; + s10 += s21 * 470296.toBig; + s11 += s21 * 654183.toBig; + s12 -= s21 * 997805.toBig; + s13 += s21 * 136657.toBig; + s14 -= s21 * 683901.toBig; + + s8 += s20 * 666643.toBig; + s9 += s20 * 470296.toBig; + s10 += s20 * 654183.toBig; + s11 -= s20 * 997805.toBig; + s12 += s20 * 136657.toBig; + s13 -= s20 * 683901.toBig; + + s7 += s19 * 666643.toBig; + s8 += s19 * 470296.toBig; + s9 += s19 * 654183.toBig; + s10 -= s19 * 997805.toBig; + s11 += s19 * 136657.toBig; + s12 -= s19 * 683901.toBig; + + s6 += s18 * 666643.toBig; + s7 += s18 * 470296.toBig; + s8 += s18 * 654183.toBig; + s9 -= s18 * 997805.toBig; + s10 += s18 * 136657.toBig; + s11 -= s18 * 683901.toBig; + + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + _bitMaskFor20) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + _bitMaskFor20) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + _bitMaskFor20) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + _bitMaskFor20) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + _bitMaskFor20) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643.toBig; + s6 += s17 * 470296.toBig; + s7 += s17 * 654183.toBig; + s8 -= s17 * 997805.toBig; + s9 += s17 * 136657.toBig; + s10 -= s17 * 683901.toBig; + + s4 += s16 * 666643.toBig; + s5 += s16 * 470296.toBig; + s6 += s16 * 654183.toBig; + s7 -= s16 * 997805.toBig; + s8 += s16 * 136657.toBig; + s9 -= s16 * 683901.toBig; + + s3 += s15 * 666643.toBig; + s4 += s15 * 470296.toBig; + s5 += s15 * 654183.toBig; + s6 -= s15 * 997805.toBig; + s7 += s15 * 136657.toBig; + s8 -= s15 * 683901.toBig; + + s2 += s14 * 666643.toBig; + s3 += s14 * 470296.toBig; + s4 += s14 * 654183.toBig; + s5 -= s14 * 997805.toBig; + s6 += s14 * 136657.toBig; + s7 -= s14 * 683901.toBig; + + s1 += s13 * 666643.toBig; + s2 += s13 * 470296.toBig; + s3 += s13 * 654183.toBig; + s4 -= s13 * 997805.toBig; + s5 += s13 * 136657.toBig; + s6 -= s13 * 683901.toBig; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = 0.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + List sBig = List.filled(32, BigInt.zero); + sBig[0] = s0 >> 0; + sBig[1] = s0 >> 8; + sBig[2] = (s0 >> 16) | (s1 << 5); + sBig[3] = s1 >> 3; + sBig[4] = s1 >> 11; + sBig[5] = (s1 >> 19) | (s2 << 2); + sBig[6] = s2 >> 6; + sBig[7] = (s2 >> 14) | (s3 << 7); + sBig[8] = s3 >> 1; + sBig[9] = s3 >> 9; + sBig[10] = (s3 >> 17) | (s4 << 4); + sBig[11] = s4 >> 4; + sBig[12] = s4 >> 12; + sBig[13] = (s4 >> 20) | (s5 << 1); + sBig[14] = s5 >> 7; + sBig[15] = (s5 >> 15) | (s6 << 6); + sBig[16] = s6 >> 2; + sBig[17] = s6 >> 10; + sBig[18] = (s6 >> 18) | (s7 << 3); + sBig[19] = s7 >> 5; + sBig[20] = s7 >> 13; + sBig[21] = s8 >> 0; + sBig[22] = s8 >> 8; + sBig[23] = (s8 >> 16) | (s9 << 5); + sBig[24] = s9 >> 3; + sBig[25] = s9 >> 11; + sBig[26] = (s9 >> 19) | (s10 << 2); + sBig[27] = s10 >> 6; + sBig[28] = (s10 >> 14) | (s11 << 7); + sBig[29] = s11 >> 1; + sBig[30] = s11 >> 9; + sBig[31] = s11 >> 17; + for (int i = 0; i < sBig.length; i++) { + s[i] = sBig[i].toUnsigned8; + } + } + + static void geDsmPrecomp(List r, GroupElementP3 s) { + GroupElementP1P1 t = GroupElementP1P1(); + GroupElementP3 s2 = GroupElementP3(); + GroupElementP3 u = GroupElementP3(); + geP3ToCached(r[0], s); + + geP3Dbl(t, s); + geP1P1ToP3(s2, t); + geAdd(t, s2, r[0]); + + geP1P1ToP3(u, t); + + geP3ToCached(r[1], u); + geAdd(t, s2, r[1]); + geP1P1ToP3(u, t); + geP3ToCached(r[2], u); + geAdd(t, s2, r[2]); + geP1P1ToP3(u, t); + geP3ToCached(r[3], u); + geAdd(t, s2, r[3]); + geP1P1ToP3(u, t); + geP3ToCached(r[4], u); + geAdd(t, s2, r[4]); + geP1P1ToP3(u, t); + geP3ToCached(r[5], u); + geAdd(t, s2, r[5]); + geP1P1ToP3(u, t); + geP3ToCached(r[6], u); + geAdd(t, s2, r[6]); + geP1P1ToP3(u, t); + geP3ToCached(r[7], u); + } + + static void slide(List r, List a) { + int i, b, k; + + // First loop: Initialize r[i] based on a[i >> 3] and bitwise operations. + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + // Second loop: Update r based on the specified conditions. + for (i = 0; i < 256; ++i) { + if (r[i] != 0) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b] != 0) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 256; ++k) { + if (r[k] == 0) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else { + break; + } + } + } + } + } + } + + static void geMsub( + GroupElementP1P1 r, GroupElementP3 p, GroupElementPrecomp q) { + FieldElement t0 = FieldElement(); + feAdd(r.x, p.y, p.x); + feSub(r.y, p.y, p.x); + feMul(r.z, r.x, q.yminusx); + feMul(r.y, r.y, q.yplusx); + feMul(r.t, q.xy2d, p.t); + feAdd(t0, p.z, p.z); + feSub(r.x, r.z, r.y); + feAdd(r.y, r.z, r.y); + feSub(r.z, t0, r.t); + feAdd(r.t, t0, r.t); + } + + static void geDoubleScalarMultBaseVartimeP3( + GroupElementP3 r3, List a, GroupElementP3 gA, List b) { + b.asMin32("geDoubleScalarMultBaseVartimeP3"); + final List aslide = List.filled(256, 0); + final List bslide = List.filled(256, 0); + List aI = GroupElementCached.dsmp; + GroupElementP1P1 t = GroupElementP1P1(); + GroupElementP3 u = GroupElementP3(); + GroupElementP2 r = GroupElementP2(); + int i; + + slide(aslide, a); + slide(bslide, b); + geDsmPrecomp(aI, gA); + + geP2Zero(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] != 0 || bslide[i] != 0) { + break; + } + } + + for (; i >= 0; --i) { + geP2Dbl(t, r); + + if (aslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, aI[aslide[i] ~/ 2]); + } else if (aslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, aI[(-aslide[i]) ~/ 2]); + } + + if (bslide[i] > 0) { + geP1P1ToP3(u, t); + geMadd(t, u, CryptoOpsConst.geBi[bslide[i] ~/ 2]); + } else if (bslide[i] < 0) { + geP1P1ToP3(u, t); + geMsub(t, u, CryptoOpsConst.geBi[(-bslide[i]) ~/ 2]); + } + + if (i == 0) { + geP1P1ToP3(r3, t); + } else { + geP1P1ToP2(r, t); + } + } + } + + static void geDoubleScalarMultBaseVartime( + GroupElementP2 r, List a, GroupElementP3 gA, List b) { + b.asMin32("geDoubleScalarMultBaseVartime"); + final List aslide = List.filled(256, 0); + final List bslide = List.filled(256, 0); + List aI = GroupElementCached.dsmp; + final GroupElementP1P1 t = GroupElementP1P1(); + final GroupElementP3 u = GroupElementP3(); + int i; + + slide(aslide, a); + slide(bslide, b); + + geDsmPrecomp(aI, gA); + geP2Zero(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] != 0 || bslide[i] != 0) { + break; + } + } + for (; i >= 0; --i) { + geP2Dbl(t, r); + + if (aslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, aI[aslide[i] ~/ 2]); + } else if (aslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, aI[(-aslide[i]) ~/ 2]); + } + + if (bslide[i] > 0) { + geP1P1ToP3(u, t); + geMadd(t, u, CryptoOpsConst.geBi[bslide[i] ~/ 2]); + } else if (bslide[i] < 0) { + geP1P1ToP3(u, t); + geMsub(t, u, CryptoOpsConst.geBi[(-bslide[i]) ~/ 2]); + } + + geP1P1ToP2(r, t); + } + } + + static void geFromfeFrombytesVartime(GroupElementP2 r, List s) { + s.asMin32("geFromfeFrombytesVartime"); + FieldElement u = FieldElement(), + v = FieldElement(), + w = FieldElement(), + x = FieldElement(), + y = FieldElement(), + z = FieldElement(); + + /* From fe_frombytes.c */ + + BigInt h0 = _load4(s, 0); + BigInt h1 = _load3(s, 4) << 6; + BigInt h2 = _load3(s, 7) << 5; + BigInt h3 = _load3(s, 10) << 3; + BigInt h4 = _load3(s, 13) << 2; + BigInt h5 = _load4(s, 16); + BigInt h6 = _load3(s, 20) << 7; + BigInt h7 = _load3(s, 23) << 5; + BigInt h8 = _load3(s, 26) << 4; + BigInt h9 = _load3(s, 29) << 2; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + + carry9 = (h9 + _bitMaskFor24) >> 25; + h0 += carry9 * BigInt.from(19); + h9 -= carry9 << 25; + carry1 = (h1 + _bitMaskFor24) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry3 = (h3 + _bitMaskFor24) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry5 = (h5 + _bitMaskFor24) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + carry7 = (h7 + _bitMaskFor24) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry2 = (h2 + _bitMaskFor25) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry6 = (h6 + _bitMaskFor25) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + carry8 = (h8 + _bitMaskFor25) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + + u.h[0] = h0.toInt32; + u.h[1] = h1.toInt32; + u.h[2] = h2.toInt32; + u.h[3] = h3.toInt32; + u.h[4] = h4.toInt32; + u.h[5] = h5.toInt32; + u.h[6] = h6.toInt32; + u.h[7] = h7.toInt32; + u.h[8] = h8.toInt32; + u.h[9] = h9.toInt32; + + /* End fe_frombytes.c */ + + feSq2(v, u); /* 2 * u^2 */ + fe1(w); + feAdd(w, v, w); /* w = 2 * u^2 + 1 */ + feSq(x, w); /* w^2 */ + feMul(y, CryptoOpsConst.ma2, v); /* -2 * A^2 * u^2 */ + feAdd(x, x, y); /* x = w^2 - 2 * A^2 * u^2 */ + feDivpowm1(r.x, w, x); /* (w / x)^(m + 1) */ + feSq(y, r.x); + feMul(x, y, x); + feSub(y, w, x); + feCopy(z, CryptoOpsConst.ma); + if (feIsnonzero(y) != 0) { + feAdd(y, w, x); + if (feIsnonzero(y) != 0) { + return _negative(x: x, r: r, y: y, w: w, z: z); + } else { + feMul(r.x, r.x, CryptoOpsConst.fffb1); + } + } else { + feMul(r.x, r.x, CryptoOpsConst.fffb2); + } + feMul(r.x, r.x, u); /* u * sqrt(2 * A * (A + 2) * w / x) */ + feMul(z, z, v); /* -2 * A * u^2 */ + _setSign(r: r, sign: 0, z: z, w: w); + } + + static void _negative( + {required FieldElement x, + required GroupElementP2 r, + required FieldElement y, + required FieldElement w, + required FieldElement z}) { + feMul(x, x, CryptoOpsConst.feSqrtm1); + feSub(y, w, x); + if (feIsnonzero(y) != 0) { + // assert((feAdd(y, w, x), feIsnonzero(y)==0)); + feMul(r.x, r.x, CryptoOpsConst.fffb3); + } else { + feMul(r.x, r.x, CryptoOpsConst.fffb4); + } + _setSign(r: r, sign: 1, z: z, w: w); + } + + static void geP1P1ToP3(GroupElementP3 r, GroupElementP1P1 p) { + feMul(r.x, p.x, p.t); + feMul(r.y, p.y, p.z); + feMul(r.z, p.z, p.t); + feMul(r.t, p.x, p.y); + } + + static List geP3Tobytes_(GroupElementP3 h) { + final List s = List.filled(32, 0); + FieldElement recip = FieldElement(); + FieldElement x = FieldElement(); + FieldElement y = FieldElement(); + + feInvert(recip, h.z); + feMul(x, h.x, recip); + feMul(y, h.y, recip); + feTobytes(s, y); + s[31] ^= feIsnegative(x) << 7; + return s; + } + + static void geP3Tobytes(List s, GroupElementP3 h) { + FieldElement recip = FieldElement(); + FieldElement x = FieldElement(); + FieldElement y = FieldElement(); + + feInvert(recip, h.z); + feMul(x, h.x, recip); + feMul(y, h.y, recip); + feTobytes(s, y); + s[31] ^= feIsnegative(x) << 7; + } + + static void geAdd( + GroupElementP1P1 r, GroupElementP3 p, GroupElementCached q) { + FieldElement t0 = FieldElement(); + feAdd(r.x, p.y, p.x); + feSub(r.y, p.y, p.x); + feMul(r.z, r.x, q.yPlusX); + feMul(r.y, r.y, q.yMinusX); + feMul(r.t, q.t2d, p.t); + feMul(r.x, p.z, q.z); + feAdd(t0, r.x, r.x); + feSub(r.x, r.z, r.y); + feAdd(r.y, r.z, r.y); + feAdd(r.z, t0, r.t); + feSub(r.t, t0, r.t); + } + + static void geCached0(GroupElementCached r) { + fe1(r.yPlusX); + fe1(r.yMinusX); + fe1(r.z); + fe0(r.t2d); + } + + static int negative(int b) { + BigInt x = b.toBig; + x >>= 63; + return (x & BigInt.one).toInt(); + } + + static int equal(int b, int c) { + int ub = b & 0xFF; + int uc = c & 0xFF; + int x = ub ^ uc; + BigInt y = BigInt.from(x) & BigInt.from(0xFFFFFFFF); + y = y - BigInt.one; + y = y >> 31; + return (y & BigInt.one).toInt(); + } + + static void geP2Zero(GroupElementP2 h) { + fe0(h.x); + fe1(h.y); + fe1(h.z); + } + + static void geP3Zero(GroupElementP3 h) { + fe0(h.x); + fe1(h.y); + fe1(h.z); + fe0(h.t); + } + + static void geMadd( + GroupElementP1P1 r, GroupElementP3 p, GroupElementPrecomp q) { + FieldElement t0 = FieldElement(); + feAdd(r.x, p.y, p.x); + feSub(r.y, p.y, p.x); + feMul(r.z, r.x, q.yplusx); + feMul(r.y, r.y, q.yminusx); + feMul(r.t, q.xy2d, p.t); + feAdd(t0, p.z, p.z); + feSub(r.x, r.z, r.y); + feAdd(r.y, r.z, r.y); + feAdd(r.z, t0, r.t); + feSub(r.t, t0, r.t); + } + + static void geP3Dbl(GroupElementP1P1 r, GroupElementP3 p) { + GroupElementP2 q = GroupElementP2(); + geP3ToP2(q, p); + geP2Dbl(r, q); + } + + static void geP3ToP2(GroupElementP2 r, GroupElementP3 p) { + feCopy(r.x, p.x); + feCopy(r.y, p.y); + feCopy(r.z, p.z); + } + + static void gePrecompCmov( + GroupElementPrecomp t, GroupElementPrecomp u, int b) { + feCmov(t.yplusx, u.yplusx, b); + feCmov(t.yminusx, u.yminusx, b); + feCmov(t.xy2d, u.xy2d, b); + } + + static void gePrecompZero(GroupElementPrecomp h) { + fe1(h.yplusx); + fe1(h.yminusx); + fe0(h.xy2d); + } + + static void select(GroupElementPrecomp t, int pos, int b) { + GroupElementPrecomp minust = GroupElementPrecomp(); + int bnegative = negative(b); + int babs = b - (((-bnegative) & b) << 1); + gePrecompZero(t); + gePrecompCmov(t, CryptoOpsConst.geBase[pos][0], equal(babs, 1)); + + gePrecompCmov(t, CryptoOpsConst.geBase[pos][1], equal(babs, 2)); + + gePrecompCmov(t, CryptoOpsConst.geBase[pos][2], equal(babs, 3)); + + gePrecompCmov(t, CryptoOpsConst.geBase[pos][3], equal(babs, 4)); + + gePrecompCmov(t, CryptoOpsConst.geBase[pos][4], equal(babs, 5)); + + gePrecompCmov(t, CryptoOpsConst.geBase[pos][5], equal(babs, 6)); + + gePrecompCmov(t, CryptoOpsConst.geBase[pos][6], equal(babs, 7)); + gePrecompCmov(t, CryptoOpsConst.geBase[pos][7], equal(babs, 8)); + + feCopy(minust.yplusx, t.yminusx); + feCopy(minust.yminusx, t.yplusx); + feNeg(minust.xy2d, t.xy2d); + gePrecompCmov(t, minust, bnegative); + } + + static void geScalarMultBase(GroupElementP3 h, List a) { + a.asMin32("geScalarMultBase"); + List e = List.filled(64, 0); + int carry; + GroupElementP1P1 r = GroupElementP1P1(); + GroupElementP2 s = GroupElementP2(); + GroupElementPrecomp t = GroupElementPrecomp(); + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + geP3Zero(h); + for (i = 1; i < 64; i += 2) { + select(t, i ~/ 2, e[i]); + geMadd(r, h, t); + geP1P1ToP3(h, r); + } + + geP3Dbl(r, h); + geP1P1ToP2(s, r); + geP2Dbl(r, s); + geP1P1ToP2(s, r); + geP2Dbl(r, s); + geP1P1ToP2(s, r); + geP2Dbl(r, s); + geP1P1ToP3(h, r); + for (i = 0; i < 64; i += 2) { + select(t, i ~/ 2, e[i]); + geMadd(r, h, t); + geP1P1ToP3(h, r); + } + } + + static void geScalarMult(GroupElementP2 r, List a, GroupElementP3 gA) { + a.asMin32("geScalarMultBase"); + List e = List.filled(64, 0); + int carry, carry2, i; + List aI = + GroupElementCached.dsmp; /* 1 * A, 2 * A, ..., 8 * A */ + GroupElementP1P1 t = GroupElementP1P1(); + GroupElementP3 u = GroupElementP3(); + + carry = 0; /* 0..1 */ + for (i = 0; i < 31; i++) { + carry += a[i]; /* 0..256 */ + carry2 = (carry + 8) >> 4; /* 0..16 */ + e[2 * i] = carry - (carry2 << 4); /* -8..7 */ + carry = (carry2 + 8) >> 4; /* 0..1 */ + e[2 * i + 1] = carry2 - (carry << 4); /* -8..7 */ + } + carry += a[31]; /* 0..128 */ + carry2 = (carry + 8) >> 4; /* 0..8 */ + e[62] = carry - (carry2 << 4); /* -8..7 */ + e[63] = carry2; /* 0..8 */ + + geP3ToCached(aI[0], gA); + for (i = 0; i < 7; i++) { + geAdd(t, gA, aI[i]); + geP1P1ToP3(u, t); + geP3ToCached(aI[i + 1], u); + } + + geP2Zero(r); + for (i = 63; i >= 0; i--) { + int b = e[i]; + int bnegative = negative(b); + int babs = b - (((-bnegative) & b) << 1); + GroupElementCached cur = GroupElementCached(), + minuscur = GroupElementCached(); + geP2Dbl(t, r); + geP1P1ToP2(r, t); + geP2Dbl(t, r); + geP1P1ToP2(r, t); + geP2Dbl(t, r); + geP1P1ToP2(r, t); + geP2Dbl(t, r); + geP1P1ToP3(u, t); + geCached0(cur); + geCachedCmov(cur, aI[0], equal(babs, 1)); + geCachedCmov(cur, aI[1], equal(babs, 2)); + geCachedCmov(cur, aI[2], equal(babs, 3)); + geCachedCmov(cur, aI[3], equal(babs, 4)); + geCachedCmov(cur, aI[4], equal(babs, 5)); + geCachedCmov(cur, aI[5], equal(babs, 6)); + geCachedCmov(cur, aI[6], equal(babs, 7)); + geCachedCmov(cur, aI[7], equal(babs, 8)); + feCopy(minuscur.yPlusX, cur.yMinusX); + feCopy(minuscur.yMinusX, cur.yPlusX); + feCopy(minuscur.z, cur.z); + feNeg(minuscur.t2d, cur.t2d); + geCachedCmov(cur, minuscur, bnegative); + geAdd(t, u, cur); + geP1P1ToP2(r, t); + } + } + + static void _setSign( + {required GroupElementP2 r, + required int sign, + required FieldElement z, + required FieldElement w}) { + if (feIsnegative(r.x) != sign) { + feNeg(r.x, r.x); + } + feAdd(r.z, z, w); + feSub(r.y, z, w); + feMul(r.x, r.x, r.z); + } + + static int feIsnegative(FieldElement f) { + List s = List.filled(32, 0); + feTobytes(s, f); + return s[0] & 1; + } + + static void feNeg(FieldElement h, FieldElement f) { + int f0 = f.h[0]; + int f1 = f.h[1]; + int f2 = f.h[2]; + int f3 = f.h[3]; + int f4 = f.h[4]; + int f5 = f.h[5]; + int f6 = f.h[6]; + int f7 = f.h[7]; + int f8 = f.h[8]; + int f9 = f.h[9]; + int h0 = -f0; + int h1 = -f1; + int h2 = -f2; + int h3 = -f3; + int h4 = -f4; + int h5 = -f5; + int h6 = -f6; + int h7 = -f7; + int h8 = -f8; + int h9 = -f9; + h.h[0] = h0; + h.h[1] = h1; + h.h[2] = h2; + h.h[3] = h3; + h.h[4] = h4; + h.h[5] = h5; + h.h[6] = h6; + h.h[7] = h7; + h.h[8] = h8; + h.h[9] = h9; + } + + static void scMulSub(List s, List a, List b, List c) { + s.asMin32("scMulSub"); + a.asMin32("scMulSub"); + b.asMin32("scMulSub"); + c.asMin32("scMulSub"); + BigInt a0 = _b2097151 & _load3(a, 0); + BigInt a1 = _b2097151 & (_load4(a, 2) >> 5); + BigInt a2 = _b2097151 & (_load3(a, 5) >> 2); + BigInt a3 = _b2097151 & (_load4(a, 7) >> 7); + BigInt a4 = _b2097151 & (_load4(a, 10) >> 4); + BigInt a5 = _b2097151 & (_load3(a, 13) >> 1); + BigInt a6 = _b2097151 & (_load4(a, 15) >> 6); + BigInt a7 = _b2097151 & (_load3(a, 18) >> 3); + BigInt a8 = _b2097151 & _load3(a, 21); + BigInt a9 = _b2097151 & (_load4(a, 23) >> 5); + BigInt a10 = _b2097151 & (_load3(a, 26) >> 2); + BigInt a11 = (_load4(a, 28) >> 7); + BigInt b0 = _b2097151 & _load3(b, 0); + BigInt b1 = _b2097151 & (_load4(b, 2) >> 5); + BigInt b2 = _b2097151 & (_load3(b, 5) >> 2); + BigInt b3 = _b2097151 & (_load4(b, 7) >> 7); + BigInt b4 = _b2097151 & (_load4(b, 10) >> 4); + BigInt b5 = _b2097151 & (_load3(b, 13) >> 1); + BigInt b6 = _b2097151 & (_load4(b, 15) >> 6); + BigInt b7 = _b2097151 & (_load3(b, 18) >> 3); + BigInt b8 = _b2097151 & _load3(b, 21); + BigInt b9 = _b2097151 & (_load4(b, 23) >> 5); + BigInt b10 = _b2097151 & (_load3(b, 26) >> 2); + BigInt b11 = (_load4(b, 28) >> 7); + BigInt c0 = _b2097151 & _load3(c, 0); + BigInt c1 = _b2097151 & (_load4(c, 2) >> 5); + BigInt c2 = _b2097151 & (_load3(c, 5) >> 2); + BigInt c3 = _b2097151 & (_load4(c, 7) >> 7); + BigInt c4 = _b2097151 & (_load4(c, 10) >> 4); + BigInt c5 = _b2097151 & (_load3(c, 13) >> 1); + BigInt c6 = _b2097151 & (_load4(c, 15) >> 6); + BigInt c7 = _b2097151 & (_load3(c, 18) >> 3); + BigInt c8 = _b2097151 & _load3(c, 21); + BigInt c9 = _b2097151 & (_load4(c, 23) >> 5); + BigInt c10 = _b2097151 & (_load3(c, 26) >> 2); + BigInt c11 = (_load4(c, 28) >> 7); + BigInt s0; + BigInt s1; + BigInt s2; + BigInt s3; + BigInt s4; + BigInt s5; + BigInt s6; + BigInt s7; + BigInt s8; + BigInt s9; + BigInt s10; + BigInt s11; + BigInt s12; + BigInt s13; + BigInt s14; + BigInt s15; + BigInt s16; + BigInt s17; + BigInt s18; + BigInt s19; + BigInt s20; + BigInt s21; + BigInt s22; + BigInt s23; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + BigInt carry10; + BigInt carry11; + BigInt carry12; + BigInt carry13; + BigInt carry14; + BigInt carry15; + BigInt carry16; + BigInt carry17; + BigInt carry18; + BigInt carry19; + BigInt carry20; + BigInt carry21; + BigInt carry22; + + s0 = c0 - a0 * b0; + s1 = c1 - (a0 * b1 + a1 * b0); + s2 = c2 - (a0 * b2 + a1 * b1 + a2 * b0); + s3 = c3 - (a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0); + s4 = c4 - (a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0); + s5 = c5 - (a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0); + s6 = c6 - + (a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0); + s7 = c7 - + (a0 * b7 + + a1 * b6 + + a2 * b5 + + a3 * b4 + + a4 * b3 + + a5 * b2 + + a6 * b1 + + a7 * b0); + s8 = c8 - + (a0 * b8 + + a1 * b7 + + a2 * b6 + + a3 * b5 + + a4 * b4 + + a5 * b3 + + a6 * b2 + + a7 * b1 + + a8 * b0); + s9 = c9 - + (a0 * b9 + + a1 * b8 + + a2 * b7 + + a3 * b6 + + a4 * b5 + + a5 * b4 + + a6 * b3 + + a7 * b2 + + a8 * b1 + + a9 * b0); + s10 = c10 - + (a0 * b10 + + a1 * b9 + + a2 * b8 + + a3 * b7 + + a4 * b6 + + a5 * b5 + + a6 * b4 + + a7 * b3 + + a8 * b2 + + a9 * b1 + + a10 * b0); + s11 = c11 - + (a0 * b11 + + a1 * b10 + + a2 * b9 + + a3 * b8 + + a4 * b7 + + a5 * b6 + + a6 * b5 + + a7 * b4 + + a8 * b3 + + a9 * b2 + + a10 * b1 + + a11 * b0); + s12 = -(a1 * b11 + + a2 * b10 + + a3 * b9 + + a4 * b8 + + a5 * b7 + + a6 * b6 + + a7 * b5 + + a8 * b4 + + a9 * b3 + + a10 * b2 + + a11 * b1); + s13 = -(a2 * b11 + + a3 * b10 + + a4 * b9 + + a5 * b8 + + a6 * b7 + + a7 * b6 + + a8 * b5 + + a9 * b4 + + a10 * b3 + + a11 * b2); + s14 = -(a3 * b11 + + a4 * b10 + + a5 * b9 + + a6 * b8 + + a7 * b7 + + a8 * b6 + + a9 * b5 + + a10 * b4 + + a11 * b3); + s15 = -(a4 * b11 + + a5 * b10 + + a6 * b9 + + a7 * b8 + + a8 * b7 + + a9 * b6 + + a10 * b5 + + a11 * b4); + s16 = -(a5 * b11 + + a6 * b10 + + a7 * b9 + + a8 * b8 + + a9 * b7 + + a10 * b6 + + a11 * b5); + s17 = -(a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6); + s18 = -(a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7); + s19 = -(a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8); + s20 = -(a9 * b11 + a10 * b10 + a11 * b9); + s21 = -(a10 * b11 + a11 * b10); + s22 = -a11 * b11; + s23 = BigInt.zero; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + _bitMaskFor20) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + _bitMaskFor20) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + _bitMaskFor20) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + _bitMaskFor20) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + _bitMaskFor20) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + _bitMaskFor20) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + _bitMaskFor20) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + _bitMaskFor20) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + _bitMaskFor20) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + _bitMaskFor20) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + _bitMaskFor20) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643.toBig; + s12 += s23 * 470296.toBig; + s13 += s23 * 654183.toBig; + s14 -= s23 * 997805.toBig; + s15 += s23 * 136657.toBig; + s16 -= s23 * 683901.toBig; + + s10 += s22 * 666643.toBig; + s11 += s22 * 470296.toBig; + s12 += s22 * 654183.toBig; + s13 -= s22 * 997805.toBig; + s14 += s22 * 136657.toBig; + s15 -= s22 * 683901.toBig; + + s9 += s21 * 666643.toBig; + s10 += s21 * 470296.toBig; + s11 += s21 * 654183.toBig; + s12 -= s21 * 997805.toBig; + s13 += s21 * 136657.toBig; + s14 -= s21 * 683901.toBig; + + s8 += s20 * 666643.toBig; + s9 += s20 * 470296.toBig; + s10 += s20 * 654183.toBig; + s11 -= s20 * 997805.toBig; + s12 += s20 * 136657.toBig; + s13 -= s20 * 683901.toBig; + + s7 += s19 * 666643.toBig; + s8 += s19 * 470296.toBig; + s9 += s19 * 654183.toBig; + s10 -= s19 * 997805.toBig; + s11 += s19 * 136657.toBig; + s12 -= s19 * 683901.toBig; + + s6 += s18 * 666643.toBig; + s7 += s18 * 470296.toBig; + s8 += s18 * 654183.toBig; + s9 -= s18 * 997805.toBig; + s10 += s18 * 136657.toBig; + s11 -= s18 * 683901.toBig; + + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + _bitMaskFor20) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + _bitMaskFor20) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + _bitMaskFor20) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + _bitMaskFor20) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + _bitMaskFor20) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643.toBig; + s6 += s17 * 470296.toBig; + s7 += s17 * 654183.toBig; + s8 -= s17 * 997805.toBig; + s9 += s17 * 136657.toBig; + s10 -= s17 * 683901.toBig; + + s4 += s16 * 666643.toBig; + s5 += s16 * 470296.toBig; + s6 += s16 * 654183.toBig; + s7 -= s16 * 997805.toBig; + s8 += s16 * 136657.toBig; + s9 -= s16 * 683901.toBig; + + s3 += s15 * 666643.toBig; + s4 += s15 * 470296.toBig; + s5 += s15 * 654183.toBig; + s6 -= s15 * 997805.toBig; + s7 += s15 * 136657.toBig; + s8 -= s15 * 683901.toBig; + + s2 += s14 * 666643.toBig; + s3 += s14 * 470296.toBig; + s4 += s14 * 654183.toBig; + s5 -= s14 * 997805.toBig; + s6 += s14 * 136657.toBig; + s7 -= s14 * 683901.toBig; + + s1 += s13 * 666643.toBig; + s2 += s13 * 470296.toBig; + s3 += s13 * 654183.toBig; + s4 -= s13 * 997805.toBig; + s5 += s13 * 136657.toBig; + s6 -= s13 * 683901.toBig; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + List sBig = List.filled(32, BigInt.zero); + sBig[0] = s0 >> 0; + sBig[1] = s0 >> 8; + sBig[2] = (s0 >> 16) | (s1 << 5); + sBig[3] = s1 >> 3; + sBig[4] = s1 >> 11; + sBig[5] = (s1 >> 19) | (s2 << 2); + sBig[6] = s2 >> 6; + sBig[7] = (s2 >> 14) | (s3 << 7); + sBig[8] = s3 >> 1; + sBig[9] = s3 >> 9; + sBig[10] = (s3 >> 17) | (s4 << 4); + sBig[11] = s4 >> 4; + sBig[12] = s4 >> 12; + sBig[13] = (s4 >> 20) | (s5 << 1); + sBig[14] = s5 >> 7; + sBig[15] = (s5 >> 15) | (s6 << 6); + sBig[16] = s6 >> 2; + sBig[17] = s6 >> 10; + sBig[18] = (s6 >> 18) | (s7 << 3); + sBig[19] = s7 >> 5; + sBig[20] = s7 >> 13; + sBig[21] = s8 >> 0; + sBig[22] = s8 >> 8; + sBig[23] = (s8 >> 16) | (s9 << 5); + sBig[24] = s9 >> 3; + sBig[25] = s9 >> 11; + sBig[26] = (s9 >> 19) | (s10 << 2); + sBig[27] = s10 >> 6; + sBig[28] = (s10 >> 14) | (s11 << 7); + sBig[29] = s11 >> 1; + sBig[30] = s11 >> 9; + sBig[31] = s11 >> 17; + for (int i = 0; i < sBig.length; i++) { + s[i] = sBig[i].toUnsigned8; + } + } + + static void scSub(List s, List a, List b) { + s.asMin32("scSub"); + a.asMin32("scSub"); + b.asMin32("scSub"); + BigInt a0 = _b2097151 & _load3(a, 0); + BigInt a1 = _b2097151 & (_load4(a, 2) >> 5); + BigInt a2 = _b2097151 & (_load3(a, 5) >> 2); + BigInt a3 = _b2097151 & (_load4(a, 7) >> 7); + BigInt a4 = _b2097151 & (_load4(a, 10) >> 4); + BigInt a5 = _b2097151 & (_load3(a, 13) >> 1); + BigInt a6 = _b2097151 & (_load4(a, 15) >> 6); + BigInt a7 = _b2097151 & (_load3(a, 18) >> 3); + BigInt a8 = _b2097151 & _load3(a, 21); + BigInt a9 = _b2097151 & (_load4(a, 23) >> 5); + BigInt a10 = _b2097151 & (_load3(a, 26) >> 2); + BigInt a11 = (_load4(a, 28) >> 7); + BigInt b0 = _b2097151 & _load3(b, 0); + BigInt b1 = _b2097151 & (_load4(b, 2) >> 5); + BigInt b2 = _b2097151 & (_load3(b, 5) >> 2); + BigInt b3 = _b2097151 & (_load4(b, 7) >> 7); + BigInt b4 = _b2097151 & (_load4(b, 10) >> 4); + BigInt b5 = _b2097151 & (_load3(b, 13) >> 1); + BigInt b6 = _b2097151 & (_load4(b, 15) >> 6); + BigInt b7 = _b2097151 & (_load3(b, 18) >> 3); + BigInt b8 = _b2097151 & _load3(b, 21); + BigInt b9 = _b2097151 & (_load4(b, 23) >> 5); + BigInt b10 = _b2097151 & (_load3(b, 26) >> 2); + BigInt b11 = (_load4(b, 28) >> 7); + BigInt s0 = a0 - b0; + BigInt s1 = a1 - b1; + BigInt s2 = a2 - b2; + BigInt s3 = a3 - b3; + BigInt s4 = a4 - b4; + BigInt s5 = a5 - b5; + BigInt s6 = a6 - b6; + BigInt s7 = a7 - b7; + BigInt s8 = a8 - b8; + BigInt s9 = a9 - b9; + BigInt s10 = a10 - b10; + BigInt s11 = a11 - b11; + BigInt s12 = BigInt.zero; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + BigInt carry10; + BigInt carry11; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + List sBig = List.filled(32, BigInt.zero); + sBig[0] = s0 >> 0; + sBig[1] = s0 >> 8; + sBig[2] = (s0 >> 16) | (s1 << 5); + sBig[3] = s1 >> 3; + sBig[4] = s1 >> 11; + sBig[5] = (s1 >> 19) | (s2 << 2); + sBig[6] = s2 >> 6; + sBig[7] = (s2 >> 14) | (s3 << 7); + sBig[8] = s3 >> 1; + sBig[9] = s3 >> 9; + sBig[10] = (s3 >> 17) | (s4 << 4); + sBig[11] = s4 >> 4; + sBig[12] = s4 >> 12; + sBig[13] = (s4 >> 20) | (s5 << 1); + sBig[14] = s5 >> 7; + sBig[15] = (s5 >> 15) | (s6 << 6); + sBig[16] = s6 >> 2; + sBig[17] = s6 >> 10; + sBig[18] = (s6 >> 18) | (s7 << 3); + sBig[19] = s7 >> 5; + sBig[20] = s7 >> 13; + sBig[21] = s8 >> 0; + sBig[22] = s8 >> 8; + sBig[23] = (s8 >> 16) | (s9 << 5); + sBig[24] = s9 >> 3; + sBig[25] = s9 >> 11; + sBig[26] = (s9 >> 19) | (s10 << 2); + sBig[27] = s10 >> 6; + sBig[28] = (s10 >> 14) | (s11 << 7); + sBig[29] = s11 >> 1; + sBig[30] = s11 >> 9; + sBig[31] = s11 >> 17; + for (int i = 0; i < sBig.length; i++) { + s[i] = sBig[i].toUnsigned8; + } + } + + static void scZero(List s) { + s.asMin32("scZero"); + int i; + for (i = 0; i < 32; i++) { + s[i] = 0; + } + } + + static void scFill(List s, List a) { + s.asMin32("scFill"); + a.asMin32("scFill"); + int i; + for (i = 0; i < 32; i++) { + s[i] = a[i]; + } + } + + static void geP1P1ToP2(GroupElementP2 r, GroupElementP1P1 p) { + feMul(r.x, p.x, p.t); + feMul(r.y, p.y, p.z); + feMul(r.z, p.z, p.t); + } + + static void geP2Dbl(GroupElementP1P1 r, GroupElementP2 p) { + FieldElement t0 = FieldElement(); + feSq(r.x, p.x); + feSq(r.z, p.y); + feSq2(r.t, p.z); + feAdd(r.y, p.x, p.y); + feSq(t0, r.y); + feAdd(r.y, r.z, r.x); + feSub(r.z, r.z, r.x); + feSub(r.x, t0, r.y); + feSub(r.t, r.t, r.z); + } + + static void geMul8(GroupElementP1P1 r, GroupElementP2 t) { + GroupElementP2 u = GroupElementP2(); + geP2Dbl(r, t); + geP1P1ToP2(u, r); + geP2Dbl(r, u); + geP1P1ToP2(u, r); + geP2Dbl(r, u); + } + + static void geCachedCmov(GroupElementCached t, GroupElementCached u, int b) { + feCmov(t.yPlusX, u.yPlusX, b); + feCmov(t.yMinusX, u.yMinusX, b); + feCmov(t.z, u.z, b); + feCmov(t.t2d, u.t2d, b); + } + + static void scAdd(List s, List a, List b) { + s.asMin32("scAdd"); + a.asMin32("scAdd"); + b.asMin32("scAdd"); + BigInt a0 = _b2097151 & _load3(a, 0); + BigInt a1 = _b2097151 & (_load4(a, 2) >> 5); + BigInt a2 = _b2097151 & (_load3(a, 5) >> 2); + BigInt a3 = _b2097151 & (_load4(a, 7) >> 7); + BigInt a4 = _b2097151 & (_load4(a, 10) >> 4); + BigInt a5 = _b2097151 & (_load3(a, 13) >> 1); + BigInt a6 = _b2097151 & (_load4(a, 15) >> 6); + BigInt a7 = _b2097151 & (_load3(a, 18) >> 3); + BigInt a8 = _b2097151 & _load3(a, 21); + BigInt a9 = _b2097151 & (_load4(a, 23) >> 5); + BigInt a10 = _b2097151 & (_load3(a, 26) >> 2); + BigInt a11 = (_load4(a, 28) >> 7); + BigInt b0 = _b2097151 & _load3(b, 0); + BigInt b1 = _b2097151 & (_load4(b, 2) >> 5); + BigInt b2 = _b2097151 & (_load3(b, 5) >> 2); + BigInt b3 = _b2097151 & (_load4(b, 7) >> 7); + BigInt b4 = _b2097151 & (_load4(b, 10) >> 4); + BigInt b5 = _b2097151 & (_load3(b, 13) >> 1); + BigInt b6 = _b2097151 & (_load4(b, 15) >> 6); + BigInt b7 = _b2097151 & (_load3(b, 18) >> 3); + BigInt b8 = _b2097151 & _load3(b, 21); + BigInt b9 = _b2097151 & (_load4(b, 23) >> 5); + BigInt b10 = _b2097151 & (_load3(b, 26) >> 2); + BigInt b11 = (_load4(b, 28) >> 7); + BigInt s0 = a0 + b0; + BigInt s1 = a1 + b1; + BigInt s2 = a2 + b2; + BigInt s3 = a3 + b3; + BigInt s4 = a4 + b4; + BigInt s5 = a5 + b5; + BigInt s6 = a6 + b6; + BigInt s7 = a7 + b7; + BigInt s8 = a8 + b8; + BigInt s9 = a9 + b9; + BigInt s10 = a10 + b10; + BigInt s11 = a11 + b11; + BigInt s12 = BigInt.zero; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + BigInt carry10; + BigInt carry11; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + List sBig = List.filled(32, BigInt.zero); + sBig[0] = s0 >> 0; + sBig[1] = s0 >> 8; + sBig[2] = (s0 >> 16) | (s1 << 5); + sBig[3] = s1 >> 3; + sBig[4] = s1 >> 11; + sBig[5] = (s1 >> 19) | (s2 << 2); + sBig[6] = s2 >> 6; + sBig[7] = (s2 >> 14) | (s3 << 7); + sBig[8] = s3 >> 1; + sBig[9] = s3 >> 9; + sBig[10] = (s3 >> 17) | (s4 << 4); + sBig[11] = s4 >> 4; + sBig[12] = s4 >> 12; + sBig[13] = (s4 >> 20) | (s5 << 1); + sBig[14] = s5 >> 7; + sBig[15] = (s5 >> 15) | (s6 << 6); + sBig[16] = s6 >> 2; + sBig[17] = s6 >> 10; + sBig[18] = (s6 >> 18) | (s7 << 3); + sBig[19] = s7 >> 5; + sBig[20] = s7 >> 13; + sBig[21] = s8 >> 0; + sBig[22] = s8 >> 8; + sBig[23] = (s8 >> 16) | (s9 << 5); + sBig[24] = s9 >> 3; + sBig[25] = s9 >> 11; + sBig[26] = (s9 >> 19) | (s10 << 2); + sBig[27] = s10 >> 6; + sBig[28] = (s10 >> 14) | (s11 << 7); + sBig[29] = s11 >> 1; + sBig[30] = s11 >> 9; + sBig[31] = s11 >> 17; + for (int i = 0; i < sBig.length; i++) { + s[i] = sBig[i].toUnsigned8; + } + } + + static void scReduce32(List s) { + s.asMin32("scReduce32"); + BigInt s0 = _b2097151 & _load3(s, 0); + BigInt s1 = _b2097151 & (_load4(s, 2) >> 5); + BigInt s2 = _b2097151 & (_load3(s, 5) >> 2); + BigInt s3 = _b2097151 & (_load4(s, 7) >> 7); + BigInt s4 = _b2097151 & (_load4(s, 10) >> 4); + BigInt s5 = _b2097151 & (_load3(s, 13) >> 1); + BigInt s6 = _b2097151 & (_load4(s, 15) >> 6); + BigInt s7 = _b2097151 & (_load3(s, 18) >> 3); + BigInt s8 = _b2097151 & _load3(s, 21); + BigInt s9 = _b2097151 & (_load4(s, 23) >> 5); + BigInt s10 = _b2097151 & (_load3(s, 26) >> 2); + BigInt s11 = (_load4(s, 28) >> 7); + BigInt s12 = BigInt.zero; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + BigInt carry10; + BigInt carry11; + + carry0 = (s0 + _bitMaskFor20) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + _bitMaskFor20) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + _bitMaskFor20) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + _bitMaskFor20) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + _bitMaskFor20) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + _bitMaskFor20) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + _bitMaskFor20) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + _bitMaskFor20) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + _bitMaskFor20) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + _bitMaskFor20) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + _bitMaskFor20) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + _bitMaskFor20) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + s12 = BigInt.zero; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643.toBig; + s1 += s12 * 470296.toBig; + s2 += s12 * 654183.toBig; + s3 -= s12 * 997805.toBig; + s4 += s12 * 136657.toBig; + s5 -= s12 * 683901.toBig; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + List sBig = List.filled(32, BigInt.zero); + sBig[0] = s0 >> 0; + sBig[1] = s0 >> 8; + sBig[2] = (s0 >> 16) | (s1 << 5); + sBig[3] = s1 >> 3; + sBig[4] = s1 >> 11; + sBig[5] = (s1 >> 19) | (s2 << 2); + sBig[6] = s2 >> 6; + sBig[7] = (s2 >> 14) | (s3 << 7); + sBig[8] = s3 >> 1; + sBig[9] = s3 >> 9; + sBig[10] = (s3 >> 17) | (s4 << 4); + sBig[11] = s4 >> 4; + sBig[12] = s4 >> 12; + sBig[13] = (s4 >> 20) | (s5 << 1); + sBig[14] = s5 >> 7; + sBig[15] = (s5 >> 15) | (s6 << 6); + sBig[16] = s6 >> 2; + sBig[17] = s6 >> 10; + sBig[18] = (s6 >> 18) | (s7 << 3); + sBig[19] = s7 >> 5; + sBig[20] = s7 >> 13; + sBig[21] = s8 >> 0; + sBig[22] = s8 >> 8; + sBig[23] = (s8 >> 16) | (s9 << 5); + sBig[24] = s9 >> 3; + sBig[25] = s9 >> 11; + sBig[26] = (s9 >> 19) | (s10 << 2); + sBig[27] = s10 >> 6; + sBig[28] = (s10 >> 14) | (s11 << 7); + sBig[29] = s11 >> 1; + sBig[30] = s11 >> 9; + sBig[31] = s11 >> 17; + for (int i = 0; i < sBig.length; i++) { + s[i] = sBig[i].toUnsigned8; + } + } + + static BigInt _load4(List data, int offset) { + int r = data[offset]; + r |= data[offset + 1] << 8; + r |= data[offset + 2] << 16; + r |= data[offset + 3] << 24; + return BigInt.from(r); + } + + static BigInt _load3(List data, int offset) { + int r = data[offset]; + r |= data[offset + 1] << 8; + r |= data[offset + 2] << 16; + return BigInt.from(r); + } + + static GroupElementP3 geFromBytesVartime(List s) { + s.asMin32("geFromBytesVartime"); + final p = GroupElementP3(); + if (geFromBytesVartime_(p, s) != 0) { + throw const CryptoOpsException("Invalid point bytes."); + } + return p; + } + + static int geFromBytesVartime_(GroupElementP3 h, List s) { + s.asMin32("geFromBytesVartime"); + FieldElement u = FieldElement(); + FieldElement v = FieldElement(); + FieldElement vxx = FieldElement(); + FieldElement check = FieldElement(); + + /* From fe_frombytes.c */ + + BigInt h0 = _load4(s, 0); + BigInt h1 = _load3(s, 4) << 6; + BigInt h2 = _load3(s, 7) << 5; + BigInt h3 = _load3(s, 10) << 3; + BigInt h4 = _load3(s, 13) << 2; + BigInt h5 = _load4(s, 16); + BigInt h6 = _load3(s, 20) << 7; + BigInt h7 = _load3(s, 23) << 5; + BigInt h8 = _load3(s, 26) << 4; + BigInt h9 = (_load3(s, 29) & BigInt.from(8388607)) << 2; + BigInt carry0; + BigInt carry1; + BigInt carry2; + BigInt carry3; + BigInt carry4; + BigInt carry5; + BigInt carry6; + BigInt carry7; + BigInt carry8; + BigInt carry9; + + /* Validate the number to be canonical */ + if (h9 == 33554428.toBig && + h8 == 268435440.toBig && + h7 == 536870880.toBig && + h6 == 2147483520.toBig && + h5 == 4294967295.toBig && + h4 == 67108860.toBig && + h3 == 134217720.toBig && + h2 == 536870880.toBig && + h1 == 1073741760.toBig && + h0 >= 4294967277.toBig) { + return -1; + } + + carry9 = (h9 + _bitMaskFor24) >> 25; + h0 += carry9 * BigInt.from(19); + h9 -= carry9 << 25; + carry1 = (h1 + _bitMaskFor24) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry3 = (h3 + _bitMaskFor24) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry5 = (h5 + _bitMaskFor24) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + carry7 = (h7 + _bitMaskFor24) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + + carry0 = (h0 + _bitMaskFor25) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry2 = (h2 + _bitMaskFor25) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry4 = (h4 + _bitMaskFor25) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry6 = (h6 + _bitMaskFor25) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + carry8 = (h8 + _bitMaskFor25) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + + h.y.h[0] = h0.toInt32; + h.y.h[1] = h1.toInt32; + h.y.h[2] = h2.toInt32; + h.y.h[3] = h3.toInt32; + h.y.h[4] = h4.toInt32; + h.y.h[5] = h5.toInt32; + h.y.h[6] = h6.toInt32; + h.y.h[7] = h7.toInt32; + h.y.h[8] = h8.toInt32; + h.y.h[9] = h9.toInt32; + + /* End fe_frombytes.c */ + + fe1(h.z); + feSq(u, h.y); + feMul(v, u, CryptoOpsConst.d); + feSub(u, u, h.z); /* u = y^2-1 */ + feAdd(v, v, h.z); /* v = dy^2+1 */ + + feDivpowm1(h.x, u, v); /* x = uv^3(uv^7)^((q-5)/8) */ + + feSq(vxx, h.x); + feMul(vxx, vxx, v); + feSub(check, vxx, u); /* vx^2-u */ + if (feIsnonzero(check) != 0) { + feAdd(check, vxx, u); /* vx^2+u */ + if (feIsnonzero(check) != 0) { + return -1; + } + feMul(h.x, h.x, CryptoOpsConst.feSqrtm1); + } + + if (feIsnegative(h.x) != (s[31] >> 7)) { + /* If x = 0, the sign must be positive */ + if (feIsnonzero(h.x) == 0) { + return -1; + } + feNeg(h.x, h.x); + } + + feMul(h.t, h.x, h.y); + return 0; + } + + static void geDoubleScalarMultPrecompVartime(GroupElementP2 r, List a, + GroupElementP3 A, List b, List bI) { + a.asMin32("geDoubleScalarMultPrecompVartime"); + b.asMin32("geDoubleScalarMultPrecompVartime"); + List aI = GroupElementCached.dsmp; + geDsmPrecomp(aI, A); + geDoubleScalarMultPrecompVartime2(r, a, aI, b, bI); + } + + static void geDoubleScalarMultPrecompVartime2(GroupElementP2 r, List a, + List aI, List b, List bI) { + a.asMin32("geDoubleScalarMultPrecompVartime2"); + b.asMin32("geDoubleScalarMultPrecompVartime2"); + List aslide = List.filled(256, 0); + List bslide = List.filled(256, 0); + + GroupElementP1P1 t = GroupElementP1P1(); + GroupElementP3 u = GroupElementP3(); + int i; + + slide(aslide, a); + slide(bslide, b); + + geP2Zero(r); + + for (i = 255; i >= 0; --i) { + if ((aslide[i] != 0) || (bslide[i] != 0)) break; + } + + for (; i >= 0; --i) { + geP2Dbl(t, r); + + if (aslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, aI[aslide[i] ~/ 2]); + } else if (aslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, aI[(-aslide[i]) ~/ 2]); + } + + if (bslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, bI[bslide[i] ~/ 2]); + } else if (bslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, bI[(-bslide[i]) ~/ 2]); + } + + geP1P1ToP2(r, t); + } + } + + static void geDoubleScalarMultPrecompVartime2P3( + GroupElementP3 r3, + List a, + List aI, + List b, + List bI) { + b.asMin32("geDoubleScalarMultPrecompVartime2P3"); + a.asMin32("geDoubleScalarMultPrecompVartime2P3"); + final List aslide = List.filled(256, 0); + final List bslide = List.filled(256, 0); + GroupElementP1P1 t = GroupElementP1P1(); + GroupElementP3 u = GroupElementP3(); + GroupElementP2 r = GroupElementP2(); + int i = 0; + + slide(aslide, a); + slide(bslide, b); + + geP2Zero(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] != 0 || bslide[i] != 0) { + break; + } + } + + for (; i >= 0; --i) { + geP2Dbl(t, r); + + if (aslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, aI[aslide[i] ~/ 2]); + } else if (aslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, aI[(-aslide[i]) ~/ 2]); + } + + if (bslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, bI[bslide[i] ~/ 2]); + } else if (bslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, bI[(-bslide[i]) ~/ 2]); + } + + if (i == 0) { + geP1P1ToP3(r3, t); + } else { + geP1P1ToP2(r, t); + } + } + } + + static void geTripleScalarMultBaseVartime(GroupElementP2 r, List a, + List b, GroupElementDsmp bI, List c, GroupElementDsmp cI) { + b.asMin32("geTripleScalarMultBaseVartime"); + a.asMin32("geTripleScalarMultBaseVartime"); + c.asMin32("geTripleScalarMultBaseVartime"); + final List aslide = List.filled(256, 0); + final List bslide = List.filled(256, 0); + final List cslide = List.filled(256, 0); + + GroupElementP1P1 t = GroupElementP1P1(); + GroupElementP3 u = GroupElementP3(); + int i; + + slide(aslide, a); + slide(bslide, b); + slide(cslide, c); + + geP2Zero(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] != 0 || bslide[i] != 0 || cslide[i] != 0) { + break; + } + } + + for (; i >= 0; --i) { + geP2Dbl(t, r); + + if (aslide[i] > 0) { + geP1P1ToP3(u, t); + geMadd(t, u, CryptoOpsConst.geBi[aslide[i] ~/ 2]); + } else if (aslide[i] < 0) { + geP1P1ToP3(u, t); + geMsub(t, u, CryptoOpsConst.geBi[(-aslide[i]) ~/ 2]); + } + + if (bslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, bI[bslide[i] ~/ 2]); + } else if (bslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, bI[(-bslide[i]) ~/ 2]); + } + + if (cslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, cI[cslide[i] ~/ 2]); + } else if (cslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, cI[(-cslide[i]) ~/ 2]); + } + + geP1P1ToP2(r, t); + } + } + + static void geTripleScalarMultBasePrecompVartime( + GroupElementP2 r, + List a, + GroupElementDsmp aI, + List b, + GroupElementDsmp bI, + List c, + GroupElementDsmp cI) { + b.asMin32("geTripleScalarMultBasePrecompVartime"); + a.asMin32("geTripleScalarMultBasePrecompVartime"); + c.asMin32("geTripleScalarMultBasePrecompVartime"); + final List aslide = List.filled(256, 0); + final List bslide = List.filled(256, 0); + final List cslide = List.filled(256, 0); + GroupElementP1P1 t = GroupElementP1P1(); + GroupElementP3 u = GroupElementP3(); + int i; + + slide(aslide, a); + slide(bslide, b); + slide(cslide, c); + + geP2Zero(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] != 0 || bslide[i] != 0 || cslide[i] != 0) { + break; + } + } + + for (; i >= 0; --i) { + geP2Dbl(t, r); + + if (aslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, aI[aslide[i] ~/ 2]); + } else if (aslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, aI[(-aslide[i]) ~/ 2]); + } + + if (bslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, bI[bslide[i] ~/ 2]); + } else if (bslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, bI[(-bslide[i]) ~/ 2]); + } + + if (cslide[i] > 0) { + geP1P1ToP3(u, t); + geAdd(t, u, cI[cslide[i] ~/ 2]); + } else if (cslide[i] < 0) { + geP1P1ToP3(u, t); + geSub(t, u, cI[(-cslide[i]) ~/ 2]); + } + + geP1P1ToP2(r, t); + } + } +} + +extension _NumericHelper on int { + int get toInt32 { + final n = toSigned(32); + return n; + } + + BigInt get toBig => BigInt.from(this); +} + +extension _BigNumericHelper on BigInt { + int get toInt32 => toSigned(32).toInt(); + int get toUnsigned8 => toUnsigned(8).toInt(); +} + +extension _BytesHelper on List { + void asMin32(String methodName) { + if (length < 32 || any((e) => e.isNegative || e > 0xFF)) { + throw CryptoOpsException( + "$methodName operation failed. invalid key provided."); + } + } +} diff --git a/lib/crypto/crypto/cdsa/curve/curve.dart b/lib/crypto/crypto/cdsa/curve/curve.dart index 5c1c08d..2ad219b 100644 --- a/lib/crypto/crypto/cdsa/curve/curve.dart +++ b/lib/crypto/crypto/cdsa/curve/curve.dart @@ -87,6 +87,7 @@ class CurveED extends Curve { @override operator ==(other) { if (other is CurveED) { + if (identical(this, other)) return true; return (p == other.p && a == other.a && d == other.d && h == other.h); } return false; diff --git a/lib/crypto/crypto/cdsa/ecdsa/private_key.dart b/lib/crypto/crypto/cdsa/ecdsa/private_key.dart index db2d65d..d6fe50a 100644 --- a/lib/crypto/crypto/cdsa/ecdsa/private_key.dart +++ b/lib/crypto/crypto/cdsa/ecdsa/private_key.dart @@ -29,15 +29,6 @@ class ECDSAPrivateKey { return ECDSAPrivateKey._(publicKey, secexp); } - @override - bool operator ==(other) { - if (other is ECDSAPrivateKey) { - return publicKey == other.publicKey && - secretMultiplier == other.secretMultiplier; - } - return false; - } - /// Signs a hash value using the private key. /// /// Parameters: @@ -87,5 +78,16 @@ class ECDSAPrivateKey { } @override - int get hashCode => secretMultiplier.hashCode ^ publicKey.hashCode; + bool operator ==(other) { + if (other is ECDSAPrivateKey) { + if (identical(this, other)) return true; + return publicKey == other.publicKey && + secretMultiplier == other.secretMultiplier; + } + return false; + } + + @override + int get hashCode => + HashCodeGenerator.generateHashCode([publicKey, secretMultiplier]); } diff --git a/lib/crypto/crypto/cdsa/ecdsa/public_key.dart b/lib/crypto/crypto/cdsa/ecdsa/public_key.dart index a2292e2..736c5a4 100644 --- a/lib/crypto/crypto/cdsa/ecdsa/public_key.dart +++ b/lib/crypto/crypto/cdsa/ecdsa/public_key.dart @@ -44,14 +44,6 @@ class ECDSAPublicKey { return ECDSAPublicKey._(generator, point); } - @override - bool operator ==(Object other) { - if (other is ECDSAPublicKey) { - return generator.curve == other.generator.curve && point == other.point; - } - return false; - } - /// Verifies an ECDSA signature against a hash value. /// /// Parameters: @@ -85,10 +77,20 @@ class ECDSAPublicKey { return v == r; } - @override - int get hashCode => generator.hashCode ^ point.hashCode; - List toBytes([EncodeType encodeType = EncodeType.comprossed]) { return point.toBytes(encodeType); } + + @override + bool operator ==(Object other) { + if (other is ECDSAPublicKey) { + if (identical(this, other)) return true; + return generator.curve == other.generator.curve && point == other.point; + } + return false; + } + + @override + int get hashCode => + HashCodeGenerator.generateHashCode([generator.curve, point]); } diff --git a/lib/crypto/crypto/cdsa/eddsa/keys.dart b/lib/crypto/crypto/cdsa/eddsa/keys.dart new file mode 100644 index 0000000..d9d834b --- /dev/null +++ b/lib/crypto/crypto/cdsa/eddsa/keys.dart @@ -0,0 +1,2 @@ +export 'keys/privatekey.dart'; +export 'keys/publickey.dart'; diff --git a/lib/crypto/crypto/cdsa/eddsa/privatekey.dart b/lib/crypto/crypto/cdsa/eddsa/keys/privatekey.dart similarity index 85% rename from lib/crypto/crypto/cdsa/eddsa/privatekey.dart rename to lib/crypto/crypto/cdsa/eddsa/keys/privatekey.dart index 8d31c19..0e77be5 100644 --- a/lib/crypto/crypto/cdsa/eddsa/privatekey.dart +++ b/lib/crypto/crypto/cdsa/eddsa/keys/privatekey.dart @@ -1,25 +1,33 @@ import 'dart:typed_data'; import 'package:blockchain_utils/helper/helper.dart'; -import 'package:blockchain_utils/utils/utils.dart'; +import 'package:blockchain_utils/utils/binary/utils.dart'; +import 'package:blockchain_utils/utils/compare/hash_code.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/publickey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/publickey.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/crypto/crypto/hash/hash.dart'; import 'package:blockchain_utils/exception/exception.dart'; +import 'package:blockchain_utils/utils/numbers/utils/bigint_utils.dart'; /// Represents an EdDSA private key and provides methods for key operations. class EDDSAPrivateKey { final EDPoint generator; final int baselen; - final List _privateKey; + + /// immutable key bytes + final List key; final List? _extendedKey; - final BigInt _secret; + final BigInt secret; final EDDSAPublicKey publicKey; + + /// Retrieves the private key bytes. + List get privateKey => List.from(key); + EDDSAPrivateKey._(this.generator, this.baselen, List privateKey, - this._secret, List? extendedKey) - : _privateKey = privateKey.asImmutableBytes, + this.secret, List? extendedKey) + : key = privateKey.asImmutableBytes, _extendedKey = extendedKey?.asImmutableBytes, - publicKey = EDDSAPublicKey(generator, (generator * _secret).toBytes()); + publicKey = EDDSAPublicKey(generator, (generator * secret).toBytes()); /// Creates an EdDSA private key from a random value using a provided hash method. /// @@ -78,18 +86,6 @@ class EDDSAPrivateKey { generator, baselen, privateKeyPart, secret, extendedKey); } - /// Retrieves the private key bytes. - List get privateKey => List.from(_privateKey); - - @override - bool operator ==(Object other) { - if (other is EDDSAPrivateKey) { - return generator.curve == other.generator.curve && - BytesUtils.bytesEqual(_privateKey, other._privateKey); - } - return false; - } - /// Prunes the key to achieve improved security. static List _keyPrune(List key, EDPoint generator) { final h = generator.curve.cofactor(); @@ -140,7 +136,7 @@ class EDDSAPrivateKey { byteOrder: Endian.little); k %= generator.order!; - final s = (r + k * _secret) % generator.order!; + final s = (r + k * secret) % generator.order!; return List.from([ ...R, ...BigintUtils.toBytes(s, length: baselen, order: Endian.little) @@ -148,5 +144,16 @@ class EDDSAPrivateKey { } @override - int get hashCode => _privateKey.hashCode ^ generator.hashCode; + bool operator ==(Object other) { + if (other is EDDSAPrivateKey) { + if (identical(this, other)) return true; + return generator.curve == other.generator.curve && + BytesUtils.bytesEqual(key, other.key); + } + return false; + } + + @override + int get hashCode => + HashCodeGenerator.generateBytesHashCode(key, [generator.curve]); } diff --git a/lib/crypto/crypto/cdsa/eddsa/publickey.dart b/lib/crypto/crypto/cdsa/eddsa/keys/publickey.dart similarity index 96% rename from lib/crypto/crypto/cdsa/eddsa/publickey.dart rename to lib/crypto/crypto/cdsa/eddsa/keys/publickey.dart index fbdb343..03b5802 100644 --- a/lib/crypto/crypto/cdsa/eddsa/publickey.dart +++ b/lib/crypto/crypto/cdsa/eddsa/keys/publickey.dart @@ -1,10 +1,10 @@ import 'dart:typed_data'; import 'package:blockchain_utils/helper/helper.dart'; -import 'package:blockchain_utils/utils/utils.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/crypto/crypto/hash/hash.dart'; import 'package:blockchain_utils/exception/exception.dart'; +import 'package:blockchain_utils/utils/utils.dart'; /// Represents an EdDSA public key in the Edwards curve format. class EDDSAPublicKey { @@ -20,6 +20,9 @@ class EDDSAPublicKey { /// The Edwards curve point derived from the encoded public key. final EDPoint _point; + /// immutable key + List get key => _encoded; + EDDSAPublicKey._( this.generator, List _encoded, this.baselen, this._point) : _encoded = _encoded.asImmutableBytes; @@ -95,8 +98,10 @@ class EDDSAPublicKey { @override bool operator ==(other) { if (other is EDDSAPublicKey) { - return generator.curve == other.generator.curve && + if (identical(this, other)) return true; + final equal = generator.curve == other.generator.curve && BytesUtils.bytesEqual(_encoded, other._encoded); + return equal; } return false; } @@ -174,5 +179,7 @@ class EDDSAPublicKey { } @override - int get hashCode => generator.curve.hashCode ^ _encoded.hashCode; + int get hashCode { + return HashCodeGenerator.generateBytesHashCode(_encoded, [generator.curve]); + } } diff --git a/lib/crypto/crypto/cdsa/point/edwards.dart b/lib/crypto/crypto/cdsa/point/edwards.dart index f52016f..446effe 100644 --- a/lib/crypto/crypto/cdsa/point/edwards.dart +++ b/lib/crypto/crypto/cdsa/point/edwards.dart @@ -58,7 +58,8 @@ class EDPoint extends AbstractPoint { /// Returns: /// - An instance of [EDPoint] representing the point at infinity. factory EDPoint.infinity({required CurveED curve}) { - return EDPoint._(curve, [BigInt.zero, BigInt.zero, BigInt.zero]); + return EDPoint._( + curve, [BigInt.zero, BigInt.zero, BigInt.zero, BigInt.zero]); } /// Private constructor for creating an [EDPoint] with specified curve, coordinates, and optional order. @@ -153,11 +154,7 @@ class EDPoint extends AbstractPoint { List coordsList = getCoords(); /// Create a temporary point for doubling. - EDPoint doubler = EDPoint._( - curve, - getCoords(), - order: newOrder, - ); + EDPoint doubler = EDPoint._(curve, getCoords(), order: newOrder); newOrder *= BigInt.from(4); @@ -246,8 +243,6 @@ class EDPoint extends AbstractPoint { /// Returns: /// - A reference to the scaled Edwards curve point. EDPoint scale() { - // List newCoords = _coords; - BigInt z1 = _coords[2]; /// If the z-coordinate is already 1, the point is already in projective form, and no scaling is required. @@ -564,8 +559,7 @@ class EDPoint extends AbstractPoint { BigInt t2 = _coords[3]; BigInt y2 = _coords[1]; BigInt z2 = _coords[2]; - - if (x2 == BigInt.zero || t2 == BigInt.zero || other == BigInt.zero) { + if (other == BigInt.zero) { return EDPoint.infinity(curve: curve); } @@ -608,10 +602,6 @@ class EDPoint extends AbstractPoint { } } - if (x3 == BigInt.zero || t3 == BigInt.zero) { - return EDPoint.infinity(curve: curve); - } - return EDPoint._(curve, [x3, y3, z3, t3], order: order); } @@ -633,5 +623,5 @@ class EDPoint extends AbstractPoint { @override bool get isInfinity => _coords.isEmpty || - (_coords[0] == BigInt.zero && _coords[1] == BigInt.zero); + (_coords[0] == BigInt.zero || _coords[3] == BigInt.zero); } diff --git a/lib/crypto/crypto/cdsa/utils/ed25519_utils.dart b/lib/crypto/crypto/cdsa/utils/ed25519_utils.dart index 9c1b25c..addb604 100644 --- a/lib/crypto/crypto/cdsa/utils/ed25519_utils.dart +++ b/lib/crypto/crypto/cdsa/utils/ed25519_utils.dart @@ -1,7 +1,8 @@ import 'dart:typed_data'; - +import 'package:blockchain_utils/crypto/crypto/cdsa/crypto_ops/crypto_ops.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/utils/exp.dart'; +import 'package:blockchain_utils/helper/helper.dart'; import 'package:blockchain_utils/utils/utils.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; /// Utility class for Ed25519-specific operations. class Ed25519Utils { @@ -22,11 +23,109 @@ class Ed25519Utils { /// operation, and converts the result back to a byte array. This ensures /// that the scalar remains within the valid range for Ed25519 operations. static List scalarReduce(List scalar) { - final toint = BigintUtils.fromBytes(scalar, byteOrder: Endian.little); - final reduce = toint % Curves.generatorED25519.order!; - final tobytes = BigintUtils.toBytes(reduce, - order: Endian.little, - length: BigintUtils.orderLen(Curves.generatorED25519.order!)); - return tobytes; + final sc = List.from(scalar); + CryptoOps.scReduce32(sc); + return sc; + } + + static BigInt asScalarInt(List scalar) { + if (CryptoOps.scCheck(scalar) == 0) { + return BigintUtils.fromBytes(scalar, byteOrder: Endian.little); + } + throw const SquareRootError( + "The provided scalar exceeds the allowed range."); + } + + /// Adds two scalar values represented as Lists and returns the result as a List. + /// + /// This method adds two scalar values, `scalar1` and `scalar2`, and stores the result in the `out` List. + /// The addition is performed according to Ristretto255 scalar operations. + /// + /// Parameters: + /// - scalar1: The first scalar value to add. + /// - scalar2: The second scalar value to add. + /// + /// Returns: + /// A List representing the result of the addition. + static List add(List scalar1, List scalar2) { + final out = List.filled(32, 0); + CryptoOps.scMulAdd(out, CryptoOpsConst.infinity, scalar1, scalar2); + return BytesUtils.toBytes(out); + } + + /// Subtracts one scalar value from another and returns the result as a List. + /// + /// This method subtracts `scalar2` from `scalar1` and stores the result in the `out` List. + /// The subtraction is performed according to Ristretto255 scalar operations. + /// + /// Parameters: + /// - scalar1: The scalar value to subtract from. + /// - scalar2: The scalar value to subtract. + /// + /// Returns: + /// A List representing the result of the subtraction. + static List sub(List scalar1, List scalar2) { + final out = List.filled(32, 0); + CryptoOps.scMulAdd(out, CryptoOpsConst.scMinusOne, scalar2, scalar1); + return BytesUtils.toBytes(out); + } + + /// Negates a scalar value and returns the result as a List. + /// + /// This method negates the given `scalar` and stores the result in the `out` List. + /// The negation is performed according to Ristretto255 scalar operations. + /// + /// Parameters: + /// - scalar: The scalar value to negate. + /// + /// Returns: + /// A List representing the negated scalar. + static List neg(List scalar) { + final out = List.filled(32, 0); + CryptoOps.scMulAdd( + out, CryptoOpsConst.scMinusOne, scalar, CryptoOpsConst.zero); + return BytesUtils.toBytes(out); + } + + /// Multiplies two scalar values represented as Lists and returns the result as a List. + /// + /// This method multiplies two scalar values, `scalar1` and `scalar2`, and stores the result in the `out` List. + /// The multiplication is performed according to Ristretto255 scalar operations. + /// + /// Parameters: + /// - scalar1: The first scalar value to multiply. + /// - scalar2: The second scalar value to multiply. + /// + /// Returns: + /// A List representing the result of the multiplication. + static List mul(List scalar1, List scalar2) { + final out = List.filled(32, 0); + CryptoOps.scMulAdd(out, scalar1, scalar2, CryptoOpsConst.zero); + return BytesUtils.toBytes(out); + } + + static bool isValidScalar(List bytes) { + return CryptoOps.scCheck(bytes) == 0; + } + + static bool isValidPoint(List bytes) { + GroupElementP3 p = GroupElementP3(); + return CryptoOps.geFromBytesVartime_(p, bytes) == 0; + } + + static List zero() { + return CryptoOpsConst.zero.clone(); + } + + static List secretKeyToPubKey({required List secretKey}) { + if (CryptoOps.scCheck(secretKey) != 0) { + throw const SquareRootError("The provided scalar exceeds the allowed range."); + } + final List pubKey = zero(); + final GroupElementP3 point = GroupElementP3(); + CryptoOps.geScalarMultBase(point, secretKey); + + CryptoOps.geP3Tobytes(pubKey, point); + return pubKey; } } diff --git a/lib/crypto/crypto/cdsa/utils/ristretto_utils.dart b/lib/crypto/crypto/cdsa/utils/ristretto_utils.dart index 9d8b176..255fb13 100644 --- a/lib/crypto/crypto/cdsa/utils/ristretto_utils.dart +++ b/lib/crypto/crypto/cdsa/utils/ristretto_utils.dart @@ -1,5 +1,4 @@ import 'package:blockchain_utils/utils/utils.dart'; - import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; /// Helper methods for Ristretto255 operations. @@ -83,6 +82,7 @@ BigInt _mExp(BigInt x, BigInt power, BigInt modulo) { /// - An intermediate value 'b2' used in the calculations. /// BigInt _pow252(BigInt x) { + // CryptoOps.geDoubleScalarMultBaseVartime(r, a, gA, b) final P = Curves.curveEd25519.p; final xSquared = (x * x) % P; final xCubed = (xSquared * x) % P; @@ -143,766 +143,3 @@ Tuple sqrtUV(BigInt u, BigInt v) { } return Tuple(useRoot1 || useRoot2, x); } - -/// Constants for scalar arithmetic operations -const scMinusOne = [ - 236, - 211, - 245, - 92, - 26, - 99, - 18, - 88, - 214, - 156, - 247, - 162, - 222, - 249, - 222, - 20, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16 -]; -const scOne = [ - 1, - 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 -]; -const scZero = [ - 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 -]; - -/// Loads a 3-byte integer from a list of integers and returns it as a BigInt. -/// -/// This method takes a list of integers and interprets the first 3 integers as -/// little-endian bytes to form a 3-byte integer. It then converts this integer to -/// a BigInt and returns it. -/// -/// Parameters: -/// - input: A list of integers representing the 3-byte integer. -/// -/// Returns: -/// A BigInt representation of the loaded 3-byte integer. -/// -BigInt _load3(List input) { - int r = input[0]; - r |= input[1] << 8; - r |= input[2] << 16; - return BigInt.from(r); -} - -/// Loads a 4-byte integer from a list of integers and returns it as a BigInt. -/// -/// This method takes a list of integers and interprets the first 4 integers as -/// little-endian bytes to form a 4-byte integer. It then converts this integer to -/// a BigInt and returns it. -/// -/// Parameters: -/// - input: A list of integers representing the 4-byte integer. -/// -/// Returns: -/// A BigInt representation of the loaded 4-byte integer. -/// -BigInt _load4(List input) { - int r = input[0]; - r |= input[1] << 8; - r |= input[2] << 16; - r |= input[3] << 24; - return BigInt.from(r); -} - -/// Adds two scalar values represented as Lists and returns the result as a List. -/// -/// This method adds two scalar values, `scalar1` and `scalar2`, and stores the result in the `out` List. -/// The addition is performed according to Ristretto255 scalar operations. -/// -/// Parameters: -/// - scalar1: The first scalar value to add. -/// - scalar2: The second scalar value to add. -/// -/// Returns: -/// A List representing the result of the addition. -List add(List scalar1, List scalar2) { - final out = List.filled(32, 0); - _mulAdd(out, scOne, scalar1, scalar2); - return BytesUtils.toBytes(out); -} - -/// Subtracts one scalar value from another and returns the result as a List. -/// -/// This method subtracts `scalar2` from `scalar1` and stores the result in the `out` List. -/// The subtraction is performed according to Ristretto255 scalar operations. -/// -/// Parameters: -/// - scalar1: The scalar value to subtract from. -/// - scalar2: The scalar value to subtract. -/// -/// Returns: -/// A List representing the result of the subtraction. -List sub(List scalar1, List scalar2) { - final out = List.filled(32, 0); - _mulAdd(out, scMinusOne, scalar2, scalar1); - return BytesUtils.toBytes(out); -} - -/// Negates a scalar value and returns the result as a List. -/// -/// This method negates the given `scalar` and stores the result in the `out` List. -/// The negation is performed according to Ristretto255 scalar operations. -/// -/// Parameters: -/// - scalar: The scalar value to negate. -/// -/// Returns: -/// A List representing the negated scalar. -List neg(List scalar) { - final out = List.filled(32, 0); - _mulAdd(out, scMinusOne, scalar, scZero); - return BytesUtils.toBytes(out); -} - -/// Multiplies two scalar values represented as Lists and returns the result as a List. -/// -/// This method multiplies two scalar values, `scalar1` and `scalar2`, and stores the result in the `out` List. -/// The multiplication is performed according to Ristretto255 scalar operations. -/// -/// Parameters: -/// - scalar1: The first scalar value to multiply. -/// - scalar2: The second scalar value to multiply. -/// -/// Returns: -/// A List representing the result of the multiplication. -List mul(List scalar1, List scalar2) { - final out = List.filled(32, 0); - _mulAdd(out, scalar1, scalar2, scZero); - - return BytesUtils.toBytes(out); -} - -/// A constant representing the value 2097151 as a BigInt. -/// -/// This constant is used in various scalar operations in the Ristretto255 library. -/// -final _b2097151 = BigInt.from(2097151); - -/// A constant representing the value 666643 as a BigInt. -/// -/// This constant is used in various scalar operations in the Ristretto255 library. -/// -final _b666643 = BigInt.from(666643); - -/// A constant representing the value 470296 as a BigInt. -/// -/// This constant is used in various scalar operations in the Ristretto255 library. -/// -final _b470296 = BigInt.from(470296); - -/// A constant representing the value 654183 as a BigInt. -/// -/// This constant is used in various scalar operations in the Ristretto255 library. -/// -final _b654183 = BigInt.from(654183); - -/// A constant representing the value 997805 as a BigInt. -/// -/// This constant is used in various scalar operations in the Ristretto255 library. -/// -final _b997805 = BigInt.from(997805); - -/// A constant representing the value 136657 as a BigInt. -/// -/// This constant is used in various scalar operations in the Ristretto255 library. -/// -final _b136657 = BigInt.from(136657); - -/// A constant representing the value 683901 as a BigInt. -/// -/// This constant is used in various scalar operations in the Ristretto255 library. -final _b683901 = BigInt.from(683901); - -void _mulAdd(List s, List a, List b, List c) { - BigInt a0 = _b2097151 & _load3(a.sublist(0)); - BigInt a1 = _b2097151 & (_load4(a.sublist(2)) >> 5); - BigInt a2 = _b2097151 & (_load3(a.sublist(5)) >> 2); - BigInt a3 = _b2097151 & (_load4(a.sublist(7)) >> 7); - BigInt a4 = _b2097151 & (_load4(a.sublist(10)) >> 4); - BigInt a5 = _b2097151 & (_load3(a.sublist(13)) >> 1); - BigInt a6 = _b2097151 & (_load4(a.sublist(15)) >> 6); - BigInt a7 = _b2097151 & (_load3(a.sublist(18)) >> 3); - BigInt a8 = _b2097151 & _load3(a.sublist(21)); - BigInt a9 = _b2097151 & (_load4(a.sublist(23)) >> 5); - BigInt a10 = _b2097151 & (_load3(a.sublist(26)) >> 2); - BigInt a11 = (_load4(a.sublist(28)) >> 7); - - BigInt b0 = _b2097151 & _load3(b.sublist(0)); - BigInt b1 = _b2097151 & (_load4(b.sublist(2)) >> 5); - BigInt b2 = _b2097151 & (_load3(b.sublist(5)) >> 2); - BigInt b3 = _b2097151 & (_load4(b.sublist(7)) >> 7); - BigInt b4 = _b2097151 & (_load4(b.sublist(10)) >> 4); - BigInt b5 = _b2097151 & (_load3(b.sublist(13)) >> 1); - BigInt b6 = _b2097151 & (_load4(b.sublist(15)) >> 6); - BigInt b7 = _b2097151 & (_load3(b.sublist(18)) >> 3); - BigInt b8 = _b2097151 & _load3(b.sublist(21)); - BigInt b9 = _b2097151 & (_load4(b.sublist(23)) >> 5); - BigInt b10 = _b2097151 & (_load3(b.sublist(26)) >> 2); - BigInt b11 = (_load4(b.sublist(28)) >> 7); - - BigInt c0 = _b2097151 & _load3(c.sublist(0)); - BigInt c1 = _b2097151 & (_load4(c.sublist(2)) >> 5); - BigInt c2 = _b2097151 & (_load3(c.sublist(5)) >> 2); - BigInt c3 = _b2097151 & (_load4(c.sublist(7)) >> 7); - BigInt c4 = _b2097151 & (_load4(c.sublist(10)) >> 4); - BigInt c5 = _b2097151 & (_load3(c.sublist(13)) >> 1); - BigInt c6 = _b2097151 & (_load4(c.sublist(15)) >> 6); - BigInt c7 = _b2097151 & (_load3(c.sublist(18)) >> 3); - BigInt c8 = _b2097151 & _load3(c.sublist(21)); - BigInt c9 = _b2097151 & (_load4(c.sublist(23)) >> 5); - BigInt c10 = _b2097151 & (_load3(c.sublist(26)) >> 2); - BigInt c11 = (_load4(c.sublist(28)) >> 7); - List carry = List.filled(23, BigInt.zero); - BigInt s0 = c0 + a0 * b0; - BigInt s1 = c1 + a0 * b1 + a1 * b0; - BigInt s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; - BigInt s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; - BigInt s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; - BigInt s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; - BigInt s6 = - c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; - BigInt s7 = c7 + - a0 * b7 + - a1 * b6 + - a2 * b5 + - a3 * b4 + - a4 * b3 + - a5 * b2 + - a6 * b1 + - a7 * b0; - BigInt s8 = c8 + - a0 * b8 + - a1 * b7 + - a2 * b6 + - a3 * b5 + - a4 * b4 + - a5 * b3 + - a6 * b2 + - a7 * b1 + - a8 * b0; - BigInt s9 = c9 + - a0 * b9 + - a1 * b8 + - a2 * b7 + - a3 * b6 + - a4 * b5 + - a5 * b4 + - a6 * b3 + - a7 * b2 + - a8 * b1 + - a9 * b0; - BigInt s10 = c10 + - a0 * b10 + - a1 * b9 + - a2 * b8 + - a3 * b7 + - a4 * b6 + - a5 * b5 + - a6 * b4 + - a7 * b3 + - a8 * b2 + - a9 * b1 + - a10 * b0; - BigInt s11 = c11 + - a0 * b11 + - a1 * b10 + - a2 * b9 + - a3 * b8 + - a4 * b7 + - a5 * b6 + - a6 * b5 + - a7 * b4 + - a8 * b3 + - a9 * b2 + - a10 * b1 + - a11 * b0; - BigInt s12 = a1 * b11 + - a2 * b10 + - a3 * b9 + - a4 * b8 + - a5 * b7 + - a6 * b6 + - a7 * b5 + - a8 * b4 + - a9 * b3 + - a10 * b2 + - a11 * b1; - BigInt s13 = a2 * b11 + - a3 * b10 + - a4 * b9 + - a5 * b8 + - a6 * b7 + - a7 * b6 + - a8 * b5 + - a9 * b4 + - a10 * b3 + - a11 * b2; - BigInt s14 = a3 * b11 + - a4 * b10 + - a5 * b9 + - a6 * b8 + - a7 * b7 + - a8 * b6 + - a9 * b5 + - a10 * b4 + - a11 * b3; - BigInt s15 = a4 * b11 + - a5 * b10 + - a6 * b9 + - a7 * b8 + - a8 * b7 + - a9 * b6 + - a10 * b5 + - a11 * b4; - BigInt s16 = - a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; - BigInt s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; - BigInt s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; - BigInt s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; - BigInt s20 = a9 * b11 + a10 * b10 + a11 * b9; - BigInt s21 = a10 * b11 + a11 * b10; - BigInt s22 = a11 * b11; - BigInt s23 = BigInt.zero; - carry[0] = (s0 + (BigInt.one << 20)) >> 21; - s1 += carry[0]; - s0 -= carry[0] << 21; - carry[2] = (s2 + (BigInt.one << 20)) >> 21; - s3 += carry[2]; - s2 -= carry[2] << 21; - carry[4] = (s4 + (BigInt.one << 20)) >> 21; - s5 += carry[4]; - s4 -= carry[4] << 21; - carry[6] = (s6 + (BigInt.one << 20)) >> 21; - s7 += carry[6]; - s6 -= carry[6] << 21; - carry[8] = (s8 + (BigInt.one << 20)) >> 21; - s9 += carry[8]; - s8 -= carry[8] << 21; - carry[10] = (s10 + (BigInt.one << 20)) >> 21; - s11 += carry[10]; - s10 -= carry[10] << 21; - carry[12] = (s12 + (BigInt.one << 20)) >> 21; - s13 += carry[12]; - s12 -= carry[12] << 21; - carry[14] = (s14 + (BigInt.one << 20)) >> 21; - s15 += carry[14]; - s14 -= carry[14] << 21; - carry[16] = (s16 + (BigInt.one << 20)) >> 21; - s17 += carry[16]; - s16 -= carry[16] << 21; - carry[18] = (s18 + (BigInt.one << 20)) >> 21; - s19 += carry[18]; - s18 -= carry[18] << 21; - carry[20] = (s20 + (BigInt.one << 20)) >> 21; - s21 += carry[20]; - s20 -= carry[20] << 21; - carry[22] = (s22 + (BigInt.one << 20)) >> 21; - s23 += carry[22]; - s22 -= carry[22] << 21; - // - carry[1] = (s1 + (BigInt.one << 20)) >> 21; - s2 += carry[1]; - s1 -= carry[1] << 21; - carry[3] = (s3 + (BigInt.one << 20)) >> 21; - s4 += carry[3]; - s3 -= carry[3] << 21; - carry[5] = (s5 + (BigInt.one << 20)) >> 21; - s6 += carry[5]; - s5 -= carry[5] << 21; - carry[7] = (s7 + (BigInt.one << 20)) >> 21; - s8 += carry[7]; - s7 -= carry[7] << 21; - carry[9] = (s9 + (BigInt.one << 20)) >> 21; - s10 += carry[9]; - s9 -= carry[9] << 21; - carry[11] = (s11 + (BigInt.one << 20)) >> 21; - s12 += carry[11]; - s11 -= carry[11] << 21; - carry[13] = (s13 + (BigInt.one << 20)) >> 21; - s14 += carry[13]; - s13 -= carry[13] << 21; - carry[15] = (s15 + (BigInt.one << 20)) >> 21; - s16 += carry[15]; - s15 -= carry[15] << 21; - carry[17] = (s17 + (BigInt.one << 20)) >> 21; - s18 += carry[17]; - s17 -= carry[17] << 21; - carry[19] = (s19 + (BigInt.one << 20)) >> 21; - s20 += carry[19]; - s19 -= carry[19] << 21; - carry[21] = (s21 + (BigInt.one << 20)) >> 21; - s22 += carry[21]; - s21 -= carry[21] << 21; - - s11 += s23 * _b666643; - s12 += s23 * _b470296; - s13 += s23 * _b654183; - s14 -= s23 * _b997805; - s15 += s23 * _b136657; - s16 -= s23 * _b683901; - s23 = BigInt.zero; - - s10 += s22 * _b666643; - s11 += s22 * _b470296; - s12 += s22 * _b654183; - s13 -= s22 * _b997805; - s14 += s22 * _b136657; - s15 -= s22 * _b683901; - s22 = BigInt.zero; - - s9 += s21 * _b666643; - s10 += s21 * _b470296; - s11 += s21 * _b654183; - s12 -= s21 * _b997805; - s13 += s21 * _b136657; - s14 -= s21 * _b683901; - s21 = BigInt.zero; - - s8 += s20 * _b666643; - s9 += s20 * _b470296; - s10 += s20 * _b654183; - s11 -= s20 * _b997805; - s12 += s20 * _b136657; - s13 -= s20 * _b683901; - s20 = BigInt.zero; - - s7 += s19 * _b666643; - s8 += s19 * _b470296; - s9 += s19 * _b654183; - s10 -= s19 * _b997805; - s11 += s19 * _b136657; - s12 -= s19 * _b683901; - s19 = BigInt.zero; - - s6 += s18 * _b666643; - s7 += s18 * _b470296; - s8 += s18 * _b654183; - s9 -= s18 * _b997805; - s10 += s18 * _b136657; - s11 -= s18 * _b683901; - s18 = BigInt.zero; - - carry[6] = (s6 + (BigInt.one << 20)) >> 21; - s7 += carry[6]; - s6 -= carry[6] << 21; - carry[8] = (s8 + (BigInt.one << 20)) >> 21; - s9 += carry[8]; - s8 -= carry[8] << 21; - carry[10] = (s10 + (BigInt.one << 20)) >> 21; - s11 += carry[10]; - s10 -= carry[10] << 21; - carry[12] = (s12 + (BigInt.one << 20)) >> 21; - s13 += carry[12]; - s12 -= carry[12] << 21; - carry[14] = (s14 + (BigInt.one << 20)) >> 21; - s15 += carry[14]; - s14 -= carry[14] << 21; - carry[16] = (s16 + (BigInt.one << 20)) >> 21; - s17 += carry[16]; - s16 -= carry[16] << 21; - - carry[7] = (s7 + (BigInt.one << 20)) >> 21; - s8 += carry[7]; - s7 -= carry[7] << 21; - carry[9] = (s9 + (BigInt.one << 20)) >> 21; - s10 += carry[9]; - s9 -= carry[9] << 21; - carry[11] = (s11 + (BigInt.one << 20)) >> 21; - s12 += carry[11]; - s11 -= carry[11] << 21; - carry[13] = (s13 + (BigInt.one << 20)) >> 21; - s14 += carry[13]; - s13 -= carry[13] << 21; - carry[15] = (s15 + (BigInt.one << 20)) >> 21; - s16 += carry[15]; - s15 -= carry[15] << 21; - - s5 += s17 * _b666643; - s6 += s17 * _b470296; - s7 += s17 * _b654183; - s8 -= s17 * _b997805; - s9 += s17 * _b136657; - s10 -= s17 * _b683901; - s17 = BigInt.zero; - - s4 += s16 * _b666643; - s5 += s16 * _b470296; - s6 += s16 * _b654183; - s7 -= s16 * _b997805; - s8 += s16 * _b136657; - s9 -= s16 * _b683901; - s16 = BigInt.zero; - - s3 += s15 * _b666643; - s4 += s15 * _b470296; - s5 += s15 * _b654183; - s6 -= s15 * _b997805; - s7 += s15 * _b136657; - s8 -= s15 * _b683901; - s15 = BigInt.zero; - - s2 += s14 * _b666643; - s3 += s14 * _b470296; - s4 += s14 * _b654183; - s5 -= s14 * _b997805; - s6 += s14 * _b136657; - s7 -= s14 * _b683901; - s14 = BigInt.zero; - - s1 += s13 * _b666643; - s2 += s13 * _b470296; - s3 += s13 * _b654183; - s4 -= s13 * _b997805; - s5 += s13 * _b136657; - s6 -= s13 * _b683901; - s13 = BigInt.zero; - - s0 += s12 * _b666643; - s1 += s12 * _b470296; - s2 += s12 * _b654183; - s3 -= s12 * _b997805; - s4 += s12 * _b136657; - s5 -= s12 * _b683901; - s12 = BigInt.zero; - - carry[0] = (s0 + (BigInt.one << 20)) >> 21; - s1 += carry[0]; - s0 -= carry[0] << 21; - carry[2] = (s2 + (BigInt.one << 20)) >> 21; - s3 += carry[2]; - s2 -= carry[2] << 21; - carry[4] = (s4 + (BigInt.one << 20)) >> 21; - s5 += carry[4]; - s4 -= carry[4] << 21; - carry[6] = (s6 + (BigInt.one << 20)) >> 21; - s7 += carry[6]; - s6 -= carry[6] << 21; - carry[8] = (s8 + (BigInt.one << 20)) >> 21; - s9 += carry[8]; - s8 -= carry[8] << 21; - carry[10] = (s10 + (BigInt.one << 20)) >> 21; - s11 += carry[10]; - s10 -= carry[10] << 21; - - carry[1] = (s1 + (BigInt.one << 20)) >> 21; - s2 += carry[1]; - s1 -= carry[1] << 21; - carry[3] = (s3 + (BigInt.one << 20)) >> 21; - s4 += carry[3]; - s3 -= carry[3] << 21; - carry[5] = (s5 + (BigInt.one << 20)) >> 21; - s6 += carry[5]; - s5 -= carry[5] << 21; - carry[7] = (s7 + (BigInt.one << 20)) >> 21; - s8 += carry[7]; - s7 -= carry[7] << 21; - carry[9] = (s9 + (BigInt.one << 20)) >> 21; - s10 += carry[9]; - s9 -= carry[9] << 21; - carry[11] = (s11 + (BigInt.one << 20)) >> 21; - s12 += carry[11]; - s11 -= carry[11] << 21; - - s0 += s12 * _b666643; - s1 += s12 * _b470296; - s2 += s12 * _b654183; - s3 -= s12 * _b997805; - s4 += s12 * _b136657; - s5 -= s12 * _b683901; - s12 = BigInt.zero; - - carry[0] = s0 >> 21; - s1 += carry[0]; - s0 -= carry[0] << 21; - carry[1] = s1 >> 21; - s2 += carry[1]; - s1 -= carry[1] << 21; - carry[2] = s2 >> 21; - s3 += carry[2]; - s2 -= carry[2] << 21; - carry[3] = s3 >> 21; - s4 += carry[3]; - s3 -= carry[3] << 21; - carry[4] = s4 >> 21; - s5 += carry[4]; - s4 -= carry[4] << 21; - carry[5] = s5 >> 21; - s6 += carry[5]; - s5 -= carry[5] << 21; - carry[6] = s6 >> 21; - s7 += carry[6]; - s6 -= carry[6] << 21; - carry[7] = s7 >> 21; - s8 += carry[7]; - s7 -= carry[7] << 21; - carry[8] = s8 >> 21; - s9 += carry[8]; - s8 -= carry[8] << 21; - carry[9] = s9 >> 21; - s10 += carry[9]; - s9 -= carry[9] << 21; - carry[10] = s10 >> 21; - s11 += carry[10]; - s10 -= carry[10] << 21; - carry[11] = s11 >> 21; - s12 += carry[11]; - s11 -= carry[11] << 21; - - s0 += s12 * _b666643; - s1 += s12 * _b470296; - s2 += s12 * _b654183; - s3 -= s12 * _b997805; - s4 += s12 * _b136657; - s5 -= s12 * _b683901; - s12 = BigInt.zero; - - carry[0] = s0 >> 21; - s1 += carry[0]; - s0 -= carry[0] << 21; - carry[1] = s1 >> 21; - s2 += carry[1]; - s1 -= carry[1] << 21; - carry[2] = s2 >> 21; - s3 += carry[2]; - s2 -= carry[2] << 21; - carry[3] = s3 >> 21; - s4 += carry[3]; - s3 -= carry[3] << 21; - carry[4] = s4 >> 21; - s5 += carry[4]; - s4 -= carry[4] << 21; - carry[5] = s5 >> 21; - s6 += carry[5]; - s5 -= carry[5] << 21; - carry[6] = s6 >> 21; - s7 += carry[6]; - s6 -= carry[6] << 21; - carry[7] = s7 >> 21; - s8 += carry[7]; - s7 -= carry[7] << 21; - carry[8] = s8 >> 21; - s9 += carry[8]; - s8 -= carry[8] << 21; - carry[9] = s9 >> 21; - s10 += carry[9]; - s9 -= carry[9] << 21; - carry[10] = s10 >> 21; - s11 += carry[10]; - s10 -= carry[10] << 21; - - s[0] = (s0 >> 0).toInt(); - s[1] = (s0 >> 8).toInt(); - s[2] = ((s0 >> 16) | (s1 << 5)).toInt(); - s[3] = (s1 >> 3).toInt(); - s[4] = (s1 >> 11).toInt(); - s[5] = ((s1 >> 19) | (s2 << 2)).toInt(); - s[6] = (s2 >> 6).toInt(); - s[7] = ((s2 >> 14) | (s3 << 7)).toInt(); - s[8] = (s3 >> 1).toInt(); - s[9] = (s3 >> 9).toInt(); - s[10] = ((s3 >> 17) | (s4 << 4)).toInt(); - s[11] = (s4 >> 4).toInt(); - s[12] = (s4 >> 12).toInt(); - s[13] = ((s4 >> 20) | (s5 << 1)).toInt(); - s[14] = (s5 >> 7).toInt(); - s[15] = ((s5 >> 15) | (s6 << 6)).toInt(); - s[16] = (s6 >> 2).toInt(); - s[17] = (s6 >> 10).toInt(); - s[18] = ((s6 >> 18) | (s7 << 3)).toInt(); - s[19] = (s7 >> 5).toInt(); - s[20] = (s7 >> 13).toInt(); - s[21] = (s8 >> 0).toInt(); - s[22] = (s8 >> 8).toInt(); - s[23] = ((s8 >> 16) | (s9 << 5)).toInt(); - s[24] = (s9 >> 3).toInt(); - s[25] = (s9 >> 11).toInt(); - s[26] = ((s9 >> 19) | (s10 << 2)).toInt(); - s[27] = (s10 >> 6).toInt(); - s[28] = ((s10 >> 14) | (s11 << 7)).toInt(); - s[29] = (s11 >> 1).toInt(); - s[30] = (s11 >> 9).toInt(); - s[31] = (s11 >> 17).toInt(); -} diff --git a/lib/crypto/crypto/cdsa/utils/utils.dart b/lib/crypto/crypto/cdsa/utils/utils.dart index a222ab9..1930f91 100644 --- a/lib/crypto/crypto/cdsa/utils/utils.dart +++ b/lib/crypto/crypto/cdsa/utils/utils.dart @@ -71,7 +71,7 @@ class ECDSAUtils { if (d == BigInt.one) { return a.modPow((p + BigInt.from(3)) ~/ BigInt.from(8), p); } - assert(d == p - BigInt.one); + // assert(d == p - BigInt.one); return (BigInt.from(2) * a * (BigInt.from(4) * a) diff --git a/lib/crypto/crypto/crc32/crc32.dart b/lib/crypto/crypto/crc32/crc32.dart index 64f9844..7ee806e 100644 --- a/lib/crypto/crypto/crc32/crc32.dart +++ b/lib/crypto/crypto/crc32/crc32.dart @@ -10,13 +10,6 @@ import 'package:blockchain_utils/utils/utils.dart'; /// To use this class, create an instance of `Crc32`, select the CRC32 algorithm you need, and then /// use the provided methods to calculate CRC32 checksums for your data. /// -/// Example: -/// ```dart -/// final data = List.from([0x01, 0x02, 0x03, 0x04]); -/// final checksum = Crc32.quickIntDigest(data); // Calculate CRC32 checksum -/// print('CRC32 Checksum: ${checksum.toRadixString(16)}'); -/// ``` -/// /// Note: The `Crc32` class can be customized with different algorithms and options for specific use cases. class Crc32 { static const List _crcTable = [ diff --git a/lib/crypto/crypto/crypto.dart b/lib/crypto/crypto/crypto.dart index c60f9f6..2ef0e85 100644 --- a/lib/crypto/crypto/crypto.dart +++ b/lib/crypto/crypto/crypto.dart @@ -49,6 +49,7 @@ export 'poly1305/poly1305.dart'; /// Export statement for the Fortuna cryptographic pseudorandom number generator (PRNG). export 'prng/fortuna.dart'; +export 'prng/gamma.dart'; /// Export statement for the 'schnorrkel' library, which provides tools for working with the /// Schnorrkel digital signature scheme, including key management, cryptographic functions, diff --git a/lib/crypto/crypto/prng/fortuna.dart b/lib/crypto/crypto/prng/fortuna.dart index 0189b1b..0773ba2 100644 --- a/lib/crypto/crypto/prng/fortuna.dart +++ b/lib/crypto/crypto/prng/fortuna.dart @@ -138,4 +138,31 @@ class FortunaPRNG { } return out; } + + int get nextUint32 { + if (_c + 4 > _out.length) { + _generateBlocks(_out, 1); + _c = 0; + } + int result = (_out[_c] << 24) | + (_out[_c + 1] << 16) | + (_out[_c + 2] << 8) | + (_out[_c + 3]); + _c += 4; + return result; + } + + double get nextDouble { + // Get a 32-bit integer and scale it to the range [0, 1) + return nextUint32 / 4294967296.0; + } + + int nextInt(int max) { + if (max <= 0) throw ArgumentError("max must be greater than 0"); + + // Generate a random double in the range [0.0, 1.0) + double fraction = + nextUint32 / 4294967296.0; // Divide by 2^32 to get a fraction + return (fraction * max).floor(); + } } diff --git a/lib/crypto/crypto/prng/gamma.dart b/lib/crypto/crypto/prng/gamma.dart new file mode 100644 index 0000000..3683963 --- /dev/null +++ b/lib/crypto/crypto/prng/gamma.dart @@ -0,0 +1,60 @@ +import 'package:blockchain_utils/crypto/quick_crypto.dart'; +import 'package:blockchain_utils/utils/numbers/utils/int_utils.dart'; + +class GammaDistribution { + final double shape; // alpha (k) + final double scale; // beta (θ) + int randomIndex(int upperLimit) { + return QuickCrypto.prng.nextInt(upperLimit); + } + + GammaDistribution(this.shape, this.scale); + + double nextDouble() { + if (shape < 1) { + // Use Johnk's algorithm if shape < 1 + return _gammaLessThanOne(); + } else { + // Use Marsaglia and Tsang's method for shape >= 1 + return _gammaGreaterThanEqualOne(); + } + } + + double _gammaLessThanOne() { + final d = shape + (1.0 / 3.0) - 1; + final c = 1 / IntUtils.sqrt(9 * d); + while (true) { + final x = _nextGaussian(); + final v = IntUtils.pow((1 + c * x), 3); + final u = QuickCrypto.prng.nextDouble; + if (u < 1 - 0.0331 * IntUtils.pow(x, 4)) return scale * d * v; + if (IntUtils.log(u) < + 0.5 * IntUtils.pow(x, 2) + d * (1 - v + IntUtils.log(v))) { + return scale * d * v; + } + } + } + + double _gammaGreaterThanEqualOne() { + final d = shape - 1 / 3; + final c = 1 / IntUtils.sqrt(9 * d); + while (true) { + final x = _nextGaussian(); + final v = IntUtils.pow((1 + c * x), 3); + final u = _nextGaussian(); + if (u < 1 - 0.0331 * IntUtils.pow(x, 4)) return scale * d * v; + if (IntUtils.log(u) < + 0.5 * IntUtils.pow(x, 2) + d * (1 - v + IntUtils.log(v))) { + return scale * d * v; + } + } + } + + /// Box-Muller transform for generating a Gaussian (normal) random value + double _nextGaussian() { + final u1 = QuickCrypto.prng.nextDouble; + final u2 = QuickCrypto.prng.nextDouble; + return IntUtils.sqrt(-2 * IntUtils.log(u1)) * + IntUtils.cos(2 * IntUtils.pi * u2); + } +} diff --git a/lib/crypto/crypto/schnorrkel/keys/keys.dart b/lib/crypto/crypto/schnorrkel/keys/keys.dart index 817d92e..ee728c5 100644 --- a/lib/crypto/crypto/schnorrkel/keys/keys.dart +++ b/lib/crypto/crypto/schnorrkel/keys/keys.dart @@ -6,8 +6,6 @@ import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/ristretto_point.dart'; import 'package:blockchain_utils/crypto/crypto/hash/hash.dart'; import 'package:blockchain_utils/crypto/crypto/prng/fortuna.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/utils/ristretto_utils.dart' - as ristretto_tools; import 'package:blockchain_utils/crypto/crypto/schnorrkel/merlin/transcript.dart'; import 'package:blockchain_utils/crypto/quick_crypto.dart'; import 'package:blockchain_utils/exception/exception.dart'; @@ -532,7 +530,7 @@ class SchnorrkelSecretKey { if (nonce.length != 32) { throw const ArgumentException("invalid random bytes length"); } - final newKey = ristretto_tools.add(key(), derivePub.item1); + final newKey = Ed25519Utils.add(key(), derivePub.item1); final combine = List.from([...newKey, ...nonce]); return Tuple(SchnorrkelSecretKey.fromBytes(combine), derivePub.item2); } @@ -578,8 +576,8 @@ class SchnorrkelSecretKey { signingContextScript.additionalData("sign:R".codeUnits, r.toBytes()); final k = signingContextScript.toBytesWithReduceScalar("sign:c".codeUnits, 64); - final km = ristretto_tools.mul(key(), k); - final s = ristretto_tools.add(km, nonceBytes); + final km = Ed25519Utils.mul(key(), k); + final s = Ed25519Utils.add(km, nonceBytes); final sig = SchnorrkelSignature._(s, r.toBytes()); return sig; } @@ -670,8 +668,8 @@ class SchnorrkelSecretKey { } script.additionalData("vrf:h^sk".codeUnits, out.output); final c = script.toBytesWithReduceScalar("prove".codeUnits, 64); - final multiply = ristretto_tools.mul(c, key()); - final s = ristretto_tools.sub(n, multiply); + final multiply = Ed25519Utils.mul(c, key()); + final s = Ed25519Utils.sub(n, multiply); return VRFProof._(c, s); } diff --git a/lib/crypto/quick_crypto.dart b/lib/crypto/quick_crypto.dart index a0a7aa6..82a9509 100644 --- a/lib/crypto/quick_crypto.dart +++ b/lib/crypto/quick_crypto.dart @@ -280,22 +280,28 @@ class QuickCrypto { /// Define the key size for ChaCha20-Poly1305, which is 32 bytes static const int chacha20Polu1305Keysize = 32; - /// A private field to hold the FortunaRandom instance for generating random numbers. - static FortunaPRNG? _randomGenerator; + /// field to hold the FortunaRandom instance for generating random numbers. + static final FortunaPRNG prng = FortunaPRNG(); static GenerateRandom _generateRandom = (length) { - _randomGenerator ??= FortunaPRNG(); - return _randomGenerator!.nextBytes(length); + return prng.nextBytes(length); }; - /// This function generates a random List of the specified size (default is 32 bytes). - static List generateRandom([int size = 32, GenerateRandom? random]) { - if (random != null) { + static void setupRandom(GenerateRandom? random) { + if (random == null) { + _generateRandom = (length) { + return prng.nextBytes(length); + }; + } else { _generateRandom = random; } + } + /// This function generates a random List of the specified size (default is 32 bytes). + static List generateRandom([int size = 32]) { /// Generate the random bytes of the specified size using the _randomGenerator. final r = _generateRandom(size); + assert(r.length == size, "Incorrect random generted size."); /// Return the generated random bytes. return r; diff --git a/lib/helper/extensions/extensions.dart b/lib/helper/extensions/extensions.dart index 6ac90b0..e4b9ac4 100644 --- a/lib/helper/extensions/extensions.dart +++ b/lib/helper/extensions/extensions.dart @@ -1,6 +1,28 @@ import 'package:blockchain_utils/exception/exception.dart'; import 'package:blockchain_utils/utils/utils.dart'; +typedef ItrableCondition = bool Function(T); + +extension SetHelper on Set { + Set get immutable => Set.unmodifiable(this); + Set clone({bool immutable = false}) { + if (immutable) return this.immutable; + return Set.from(this); + } +} + +extension IterableHelper on Iterable { + Set get toImutableSet => Set.unmodifiable(this); + List get toImutableList => List.unmodifiable(this); + T? firstWhereNullable(bool Function(T) test, {T Function()? orElse}) { + try { + return firstWhere(test); + } on StateError { + return null; + } + } +} + extension ListHelper on List { List get immutable => List.unmodifiable(this); List clone({bool immutable = false}) { @@ -9,6 +31,30 @@ extension ListHelper on List { } List? get emptyAsNull => isEmpty ? null : this; + List exceptedLen(int len, {String? message}) { + if (length != len) { + throw ArgumentException(message ?? 'Invalid length. ', + details: {"excepted": len, "length": length}); + } + return this; + } +} + +extension IterableIntHelper on Iterable { + List get immutable => List.unmodifiable(this); + + List get asImmutableBytes { + BytesUtils.validateBytes(this); + return immutable; + } + + List get toImutableBytes { + return BytesUtils.toBytes(this, unmodifiable: true); + } + + List get toBytes { + return BytesUtils.toBytes(this); + } } extension ListIntHelper on List { @@ -85,4 +131,15 @@ extension IntHelper on int { } return this; } + + int get asUint8 { + if (isNegative || this > mask8) { + throw ArgumentException("Invalid Unsigned int 8.", details: { + "excepted": mask32.bitLength, + "bitLength": bitLength, + "value": toString() + }); + } + return this; + } } diff --git a/lib/layout/constant/constant.dart b/lib/layout/constant/constant.dart index 49c8f9e..a87d603 100644 --- a/lib/layout/constant/constant.dart +++ b/lib/layout/constant/constant.dart @@ -163,7 +163,7 @@ class LayoutConst { StructLayout(fields, property: property, decodePrefixes: decodePrefixes); // /// [StructLayout] values. - static LazyStructLayout lazyStruct(List fields, + static LazyStructLayout lazyStruct(List fields, {String? property, bool decodePrefixes = false}) => LazyStructLayout(fields, property: property, decodePrefixes: decodePrefixes); @@ -299,8 +299,11 @@ class LayoutConst { } /// vector bytes - static CustomLayout vecU8({String? property}) { - final length = padding(u32(property: "length"), propery: "length"); + static CustomLayout vecU8( + {String? property, IntegerLayout? lengthSizeLayout}) { + lengthSizeLayout ??= (lengthSizeLayout?.clone(newProperty: "length") ?? + u32(property: "length")); + final length = padding(lengthSizeLayout, propery: "length"); final layout = struct([ length, blob(offset(length, -length.span), property: 'data'), @@ -457,8 +460,11 @@ class LayoutConst { } /// vectors - static CustomLayout vec(Layout elementLayout, {String? property}) { - final length = padding(u32(property: "length"), propery: "length"); + static CustomLayout vec(Layout elementLayout, + {String? property, IntegerLayout? lengthSizeLayout}) { + lengthSizeLayout ??= (lengthSizeLayout?.clone(newProperty: "length") ?? + u32(property: "length")); + final length = padding(lengthSizeLayout, propery: "length"); final layout = struct([ length, seq(elementLayout, offset(length, -length.span), property: 'values'), diff --git a/lib/layout/core/core/core.dart b/lib/layout/core/core/core.dart index e3b36e5..6a15372 100644 --- a/lib/layout/core/core/core.dart +++ b/lib/layout/core/core/core.dart @@ -51,10 +51,61 @@ import 'package:blockchain_utils/layout/exception/exception.dart'; typedef LayoutFunc = Layout Function({String? property}); -class LazyLayout { - final LayoutFunc layout; +enum LayoutAction { span, encode, decode } + +typedef ConditionalLayoutFunc = Layout Function( + {String? property, + required T? sourceOrResult, + required LayoutAction action, + required int remindBytes}); + +abstract class BaseLazyLayout { + abstract final String? property; + Layout layout( + {required LayoutAction action, + required T? sourceOrResult, + required int remindBytes}); +} + +class LazyLayout extends BaseLazyLayout { + final LayoutFunc _layout; + // final ConditionalLayoutFunc layout; + @override + final String? property; + LazyLayout({ + required LayoutFunc layout, + required this.property, + }) : _layout = layout; + @override + Layout layout( + {required LayoutAction action, + required T? sourceOrResult, + required int remindBytes}) { + return _layout(property: property); + } +} + +class ConditionalLazyLayout extends BaseLazyLayout { + final ConditionalLayoutFunc _layout; + @override final String? property; - const LazyLayout({required this.layout, required this.property}); + ConditionalLazyLayout( + {required ConditionalLayoutFunc layout, required this.property}) + : _layout = layout; + + @override + Layout layout( + {required LayoutAction action, + required T? sourceOrResult, + required int remindBytes}) { + assert(action == LayoutAction.span || sourceOrResult != null, + "source cannot be null in ${action.name}"); + return _layout( + property: property, + action: action, + sourceOrResult: sourceOrResult, + remindBytes: remindBytes); + } } /// Base class for layout objects. @@ -72,7 +123,7 @@ abstract class Layout { LayoutDecodeResult decode(LayoutByteReader bytes, {int offset = 0}); int encode(T source, LayoutByteWriter writer, {int offset = 0}); - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, T? source}) { if (span < 0) { throw LayoutException("Invalid layout span.", details: {"property": property, "span": span}); diff --git a/lib/layout/core/types/array.dart b/lib/layout/core/types/array.dart index fb67783..fc5f39a 100644 --- a/lib/layout/core/types/array.dart +++ b/lib/layout/core/types/array.dart @@ -53,17 +53,24 @@ class SequenceLayout extends Layout> { }) : super(span, property: property); @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, List? source}) { if (this.span >= 0) { return this.span; } int span = 0; int counter = 0; - if (count is CompactOffsetLayout) { + if (count is ConstantLayout) { + counter = (count as ConstantLayout).value; + } else if (count is CompactOffsetLayout) { final decodeLength = bytes!.getCompactLengthInfos(offset); span = decodeLength.item1; counter = decodeLength.item2; + } else if (count is ExternalOffsetLayout) { + final testLayput = count as ExternalOffsetLayout; + final decode = testLayput.decode(bytes!, offset: offset); + span = decode.consumed; + counter = decode.value; } else if (count is ExternalLayout) { counter = count.decode(bytes!, offset: offset).value; } @@ -73,10 +80,15 @@ class SequenceLayout extends Layout> { } else { int idx = 0; while (idx < counter) { - span += this.elementLayout.getSpan(bytes, offset: offset + span); + final lSpan = this + .elementLayout + .getSpan(bytes, offset: offset + span, source: source?[idx]); + assert(lSpan >= 0, "span cannot be negative."); + span += lSpan; ++idx; } } + return span; } @@ -90,6 +102,11 @@ class SequenceLayout extends Layout> { final decodeLength = bytes.getCompactLengthInfos(offset); startOffset += decodeLength.item1; count = decodeLength.item2; + } else if (this.count is ExternalOffsetLayout) { + final testLayput = this.count as ExternalOffsetLayout; + final decode = testLayput.decode(bytes, offset: offset); + startOffset += decode.consumed; + count = decode.value; } else { count = this.count.decode(bytes, offset: offset).value; } @@ -97,7 +114,11 @@ class SequenceLayout extends Layout> { final decodeElement = this.elementLayout.decode(bytes, offset: startOffset); decoded.add(decodeElement.value); - startOffset += this.elementLayout.getSpan(bytes, offset: startOffset); + final lSpan = this + .elementLayout + .getSpan(bytes, offset: startOffset, source: decodeElement.value); + assert(lSpan >= 0, "span cannot be negative."); + startOffset += lSpan; i += 1; } return LayoutDecodeResult(consumed: startOffset - offset, value: decoded); @@ -109,15 +130,18 @@ class SequenceLayout extends Layout> { if (count is CompactOffsetLayout) { span = (count as CompactOffsetLayout) .encode(source.length, writer, offset: offset); + } else if (this.count is ExternalOffsetLayout) { + final testLayput = this.count as ExternalOffsetLayout; + span = testLayput.encode(source.length, writer, offset: offset); } else if (this.count is ExternalLayout) { this.count.encode(source.length, writer, offset: offset); } span = source.fold(span, (span, v) { final encodeLength = elementLayout.encode(v, writer, offset: offset + span); + assert(encodeLength >= 0, "invalid encoded length"); return span + encodeLength; }); - return span; } diff --git a/lib/layout/core/types/bit_sequence.dart b/lib/layout/core/types/bit_sequence.dart index 0dfcffd..3b2fbd8 100644 --- a/lib/layout/core/types/bit_sequence.dart +++ b/lib/layout/core/types/bit_sequence.dart @@ -12,7 +12,7 @@ class BitSequenceLayout extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, List? source}) { return bytes!.getCompactTotalLenght(offset).item2 ~/ 8; } diff --git a/lib/layout/core/types/compact_bytes.dart b/lib/layout/core/types/compact_bytes.dart index 758aa8c..4274d65 100644 --- a/lib/layout/core/types/compact_bytes.dart +++ b/lib/layout/core/types/compact_bytes.dart @@ -12,7 +12,7 @@ class CompactBytes extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, List? source}) { return bytes!.getCompactTotalLenght(offset).item2; } diff --git a/lib/layout/core/types/compact_layout.dart b/lib/layout/core/types/compact_layout.dart index 6bdd3b4..ae86aaf 100644 --- a/lib/layout/core/types/compact_layout.dart +++ b/lib/layout/core/types/compact_layout.dart @@ -25,7 +25,7 @@ class CompactLayout extends Layout { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, T? source}) { return bytes!.getCompactTotalLenght(offset).item2; } diff --git a/lib/layout/core/types/coption_layout.dart b/lib/layout/core/types/coption_layout.dart index f5695fa..83b0204 100644 --- a/lib/layout/core/types/coption_layout.dart +++ b/lib/layout/core/types/coption_layout.dart @@ -39,7 +39,7 @@ class COptionLayout extends Layout { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, T? source}) { if (bytes == null) return layout.span + 1; final decode = discriminator.decode(bytes, offset: offset); if (decode.value == 0) return 1; diff --git a/lib/layout/core/types/custom_layout.dart b/lib/layout/core/types/custom_layout.dart index 347ad2e..4ff5f4e 100644 --- a/lib/layout/core/types/custom_layout.dart +++ b/lib/layout/core/types/custom_layout.dart @@ -36,8 +36,11 @@ class CustomLayout extends Layout { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { - return this.layout.getSpan(bytes, offset: offset); + int getSpan(LayoutByteReader? bytes, {int offset = 0, D? source}) { + final span = this.layout.getSpan(bytes, + offset: offset, source: source == null ? null : encoder(source)); + assert(span >= 0, "span cannot be negative"); + return span; } @override diff --git a/lib/layout/core/types/lazy_struct.dart b/lib/layout/core/types/lazy_struct.dart index d4ce8cf..7f0cbad 100644 --- a/lib/layout/core/types/lazy_struct.dart +++ b/lib/layout/core/types/lazy_struct.dart @@ -10,9 +10,9 @@ import 'package:blockchain_utils/layout/exception/exception.dart'; /// Throws [LayoutException] if [fields] contains an unnamed variable-length layout. /// class LazyStructLayout extends Layout> { - final List fields; + final List fields; final bool decodePrefixes; - factory LazyStructLayout(List fields, + factory LazyStructLayout(List fields, {String? property, bool decodePrefixes = false}) { for (final field in fields) { if (field.property == null) { @@ -31,11 +31,11 @@ class LazyStructLayout extends Layout> { } LazyStructLayout._({ - required List fields, + required List fields, required int span, required this.decodePrefixes, String? property, - }) : fields = List.unmodifiable(fields), + }) : fields = List.unmodifiable(fields), super(span, property: property); @override @@ -48,7 +48,8 @@ class LazyStructLayout extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, + {int offset = 0, Map? source}) { if (this.span >= 0) { return this.span; } @@ -57,15 +58,21 @@ class LazyStructLayout extends Layout> { try { span = fields.fold(0, (span, field) { - final layout = field.layout(property: field.property); - final fsp = layout.getSpan(bytes, offset: offset); - offset += fsp; + final layout = field.layout( + action: LayoutAction.span, sourceOrResult: source, remindBytes: 0); + final lSpan = layout.getSpan(bytes, + offset: offset, source: source?[field.property]); + assert(lSpan >= 0, "span cannot be negative."); + offset += lSpan; - return span + fsp; + return span + lSpan; + }); + } catch (e, s) { + throw LayoutException("indeterminate span", details: { + "property": property, + "error": e, + "stack": s, }); - } catch (_, s) { - throw LayoutException("indeterminate span", - details: {"property": property, "stack": s}); } return span; @@ -75,20 +82,27 @@ class LazyStructLayout extends Layout> { LayoutDecodeResult> decode(LayoutByteReader bytes, {int offset = 0}) { final Map result = {}; + int remindBytes = bytes.length - offset; int consumed = 0; for (final field in fields) { - final layout = field.layout(property: field.property); + final layout = field.layout( + action: LayoutAction.decode, + sourceOrResult: result, + remindBytes: remindBytes); if (field.property != null) { final decode = layout.decode(bytes, offset: offset); consumed += decode.consumed; + remindBytes -= decode.consumed; result[field.property!] = decode.value; } - offset += layout.getSpan(bytes, offset: offset); + final lSpan = + layout.getSpan(bytes, offset: offset, source: result[field.property]); + assert(lSpan >= 0, "span cannot be negative."); + offset += lSpan; if (decodePrefixes && bytes.length == offset) { break; } } - return LayoutDecodeResult(consumed: consumed, value: result); } @@ -100,14 +114,16 @@ class LazyStructLayout extends Layout> { int lastWrote = 0; for (final field in fields) { - final layout = field.layout(property: field.property); + final layout = field.layout( + action: LayoutAction.encode, sourceOrResult: source, remindBytes: 0); int span = layout.span; lastWrote = (span > 0) ? span : 0; if (source.containsKey(field.property)) { final value = source[field.property]; lastWrote = layout.encode(value, writer, offset: offset); if (span < 0) { - span = layout.getSpan(writer.reader, offset: offset); + span = layout.getSpan(writer.reader, offset: offset, source: value); + assert(!span.isNegative, "span cannot be negative."); } } else { if (span < 0 || field is! PaddingLayout) { @@ -121,7 +137,7 @@ class LazyStructLayout extends Layout> { lastOffset = offset; offset += span; } - - return (lastOffset + lastWrote) - firstOffset; + final encodeLen = (lastOffset + lastWrote) - firstOffset; + return encodeLen; } } diff --git a/lib/layout/core/types/lazy_union.dart b/lib/layout/core/types/lazy_union.dart index df9e90d..4cb2344 100644 --- a/lib/layout/core/types/lazy_union.dart +++ b/lib/layout/core/types/lazy_union.dart @@ -29,7 +29,8 @@ class LazyUnion extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, + {int offset = 0, Map? source}) { if (span >= 0) { return span; } @@ -40,7 +41,7 @@ class LazyUnion extends Layout> { details: {"property": property}); } - return vlo.getSpan(bytes, offset: offset); + return vlo.getSpan(bytes, offset: offset, source: source); } LazyVariantLayout? defaultGetSourceVariant(Map source) { @@ -134,16 +135,17 @@ class LazyVariantLayout extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, + {int offset = 0, Map? source}) { if (!this.span.isNegative) { return this.span; } int contentOffset = union.discriminator.layout.span; int span = 0; - span = layout - .layout(property: layout.property) - .getSpan(bytes, offset: offset + contentOffset); + span = layout.layout(property: layout.property).getSpan(bytes, + offset: offset + contentOffset, source: source?[property]); + assert(span >= 0, "span cannot be negative."); return contentOffset + span; } @@ -181,7 +183,10 @@ class LazyVariantLayout extends Layout> { final layout = this.layout.layout(property: this.layout.property); layout.encode(source[property], writer, offset: offset + contentOffset); - span += layout.getSpan(writer.reader, offset: offset + contentOffset); + final lSpan = layout.getSpan(writer.reader, + offset: offset + contentOffset, source: source[property]); + assert(lSpan >= 0, "span cannot be negative."); + span += lSpan; if (union.span >= 0 && span > union.span) { throw LayoutException("encoded variant overruns containing union", diff --git a/lib/layout/core/types/map.dart b/lib/layout/core/types/map.dart index 9aa19a5..7197efd 100644 --- a/lib/layout/core/types/map.dart +++ b/lib/layout/core/types/map.dart @@ -23,7 +23,9 @@ class MapEntryLayout extends Layout { LayoutDecodeResult decode(LayoutByteReader bytes, {int offset = 0}) { final key = keyLayout.decode(bytes, offset: offset); - final keyOffset = keyLayout.getSpan(bytes, offset: offset); + final keyOffset = + keyLayout.getSpan(bytes, offset: offset, source: key.value); + assert(keyOffset >= 0, "span cannot be negative"); final value = valueLayout.decode(bytes, offset: offset + keyOffset); return LayoutDecodeResult( consumed: key.consumed + value.consumed, @@ -39,9 +41,14 @@ class MapEntryLayout extends Layout { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { - final keySpan = keyLayout.getSpan(bytes, offset: offset); - return keySpan + valueLayout.getSpan(bytes, offset: offset + keySpan); + int getSpan(LayoutByteReader? bytes, {int offset = 0, MapEntry? source}) { + final keySpan = + keyLayout.getSpan(bytes, offset: offset, source: source?.key); + assert(keySpan >= 0, "span cannot be negative"); + final valSpan = valueLayout.getSpan(bytes, + offset: offset + keySpan, source: source?.value); + assert(valSpan >= 0, "span cannot be negative"); + return keySpan + valSpan; } @override diff --git a/lib/layout/core/types/numeric.dart b/lib/layout/core/types/numeric.dart index 137d4e8..779d4a3 100644 --- a/lib/layout/core/types/numeric.dart +++ b/lib/layout/core/types/numeric.dart @@ -15,6 +15,12 @@ abstract class ExternalLayout extends Layout { bool isCount() => false; } +abstract class ExternalOffsetLayout extends ExternalLayout { + const ExternalOffsetLayout({String? property}) : super(-1, property: property); + LayoutDecodeResult getLenAndSpan(LayoutByteReader bytes, + {int offset = 0}); +} + /// Represents a layout that greedily consumes bytes until the end. class GreedyCount extends ExternalLayout { int elementSpan; @@ -267,7 +273,7 @@ class CompactIntLayout extends Layout { const CompactIntLayout(this.layout, {String? property}) : super(-1, property: property); @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, int? source}) { return bytes!.getCompactDataOffset(offset); } @@ -297,7 +303,7 @@ class CompactBigIntLayout extends Layout { : super(-1, property: property); final BaseIntiger layout; @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, BigInt? source}) { return bytes!.getCompactDataOffset(offset); } diff --git a/lib/layout/core/types/optional_layout.dart b/lib/layout/core/types/optional_layout.dart index 04a4af8..b0e0358 100644 --- a/lib/layout/core/types/optional_layout.dart +++ b/lib/layout/core/types/optional_layout.dart @@ -65,14 +65,16 @@ class OptionalLayout extends Layout { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, T? source}) { if (size != null) return size!; final decode = discriminator.decode(bytes!, offset: offset); if (decode.value == 0) return discriminator.span; _validateOption(property: property, value: decode.value); - return layout.getSpan(bytes, offset: offset + discriminator.span) + - discriminator.span; + final lSpan = layout.getSpan(bytes, + offset: offset + discriminator.span, source: source); + assert(lSpan >= 0, "span cannot be negative."); + return lSpan + discriminator.span; } @override diff --git a/lib/layout/core/types/padding_layout.dart b/lib/layout/core/types/padding_layout.dart index 18e13c8..9a427ca 100644 --- a/lib/layout/core/types/padding_layout.dart +++ b/lib/layout/core/types/padding_layout.dart @@ -8,8 +8,8 @@ class PaddingLayout extends Layout { : super(layout.span, property: property); @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { - return layout.getSpan(bytes, offset: offset); + int getSpan(LayoutByteReader? bytes, {int offset = 0, T? source}) { + return layout.getSpan(bytes, offset: offset, source: source); } @override diff --git a/lib/layout/core/types/raw.dart b/lib/layout/core/types/raw.dart index e56f0df..5996441 100644 --- a/lib/layout/core/types/raw.dart +++ b/lib/layout/core/types/raw.dart @@ -31,7 +31,7 @@ class RawBytesLayout extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, List? source}) { int span = this.span; if (span < 0) { span = (length as ExternalLayout).decode(bytes!, offset: offset).value; diff --git a/lib/layout/core/types/struct.dart b/lib/layout/core/types/struct.dart index 2cc7207..9e1e299 100644 --- a/lib/layout/core/types/struct.dart +++ b/lib/layout/core/types/struct.dart @@ -66,7 +66,8 @@ class StructLayout extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, + {int offset = 0, Map? source}) { if (this.span >= 0) { return this.span; } @@ -75,12 +76,14 @@ class StructLayout extends Layout> { try { span = fields.fold(0, (span, fd) { - final fsp = fd.getSpan(bytes, offset: offset); + final fsp = + fd.getSpan(bytes, offset: offset, source: source?[fd.property]); + assert(fsp >= 0, "indeterminate span ${fd.property}"); offset += fsp; return span + fsp; }); - } catch (_, s) { + } catch (e, s) { throw LayoutException("indeterminate span", details: {"property": property, "stack": s}); } @@ -99,7 +102,10 @@ class StructLayout extends Layout> { consumed += decode.consumed; result[fd.property!] = decode.value; } - offset += fd.getSpan(bytes, offset: offset); + final lSpan = + fd.getSpan(bytes, offset: offset, source: result[fd.property]); + assert(lSpan >= 0, "span cannot be negative."); + offset += lSpan; if (decodePrefixes && bytes.length == offset) { break; } @@ -112,17 +118,23 @@ class StructLayout extends Layout> { int encode(Map source, LayoutByteWriter writer, {int offset = 0}) { final firstOffset = offset; - int lastOffset = 0; + int lastOffset = firstOffset; int lastWrote = 0; for (final field in fields) { int span = field.span; - lastWrote = (span > 0) ? span : 0; if (source.containsKey(field.property)) { final value = source[field.property]; lastWrote = field.encode(value, writer, offset: offset); if (span < 0) { - span = field.getSpan(writer.reader, offset: offset); + span = field.getSpan(writer.reader, offset: offset, source: value); + if (span.isNegative) { + throw LayoutException("indeterminate span.", details: { + "key": field.property, + "source": source, + "property": property + }); + } } } else { if (span < 0 || field is! PaddingLayout) { diff --git a/lib/layout/core/types/tuple_layout.dart b/lib/layout/core/types/tuple_layout.dart index 1188dd1..d2c89ae 100644 --- a/lib/layout/core/types/tuple_layout.dart +++ b/lib/layout/core/types/tuple_layout.dart @@ -21,7 +21,9 @@ class TupleLayout extends Layout { for (final i in layouts) { final decode = i.decode(bytes, offset: pos); encoded.add(decode.value); - pos += i.getSpan(bytes, offset: pos); + final lSpan = i.getSpan(bytes, offset: pos, source: decode.value); + assert(lSpan >= 0, "span cannot be negative."); + pos += lSpan; } return LayoutDecodeResult(consumed: pos - offset, value: encoded); } @@ -40,10 +42,14 @@ class TupleLayout extends Layout { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, List? source}) { int span = 0; - for (final i in layouts) { - span += i.getSpan(bytes, offset: offset + span); + for (int i = 0; i < layouts.length; i++) { + final layout = layouts[i]; + final lSpan = + layout.getSpan(bytes, offset: offset + span, source: source?[i]); + assert(lSpan >= 0, "span cannot be negative."); + span += lSpan; } return span; } @@ -74,9 +80,13 @@ class TupleCompactLayout extends Layout { } List encoded = []; int pos = decodeLength.item1 + offset; - for (final i in layouts) { - encoded.add(i.decode(bytes, offset: pos)); - pos += i.getSpan(bytes, offset: pos); + for (int i = 0; i < layouts.length; i++) { + final layout = layouts[i]; + final decode = layout.decode(bytes, offset: pos); + encoded.add(decode); + final lSpan = layout.getSpan(bytes, offset: pos, source: decode); + assert(lSpan >= 0, "span cannot be negative."); + pos += lSpan; } return LayoutDecodeResult(consumed: pos - offset, value: encoded); } @@ -97,11 +107,15 @@ class TupleCompactLayout extends Layout { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, {int offset = 0, List? source}) { final decodeLength = bytes!.getCompactLengthInfos(offset); int span = decodeLength.item1; - for (final i in layouts) { - span += i.getSpan(bytes, offset: offset + span); + for (int i = 0; i < layouts.length; i++) { + final layout = layouts[i]; + final lSpan = + layout.getSpan(bytes, offset: offset + span, source: source?[i]); + assert(lSpan >= 0, "span cannot be negative."); + span += lSpan; } return span; } diff --git a/lib/layout/core/types/union.dart b/lib/layout/core/types/union.dart index 0f3eeaa..2486496 100644 --- a/lib/layout/core/types/union.dart +++ b/lib/layout/core/types/union.dart @@ -93,7 +93,8 @@ class Union extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, + {int offset = 0, Map? source}) { if (span >= 0) { return span; } @@ -104,7 +105,7 @@ class Union extends Layout> { details: {"property": property}); } - return vlo.getSpan(bytes, offset: offset); + return vlo.getSpan(bytes, offset: offset, source: source); } VariantLayout? defaultGetSourceVariant(Map source) { @@ -263,7 +264,8 @@ class VariantLayout extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { + int getSpan(LayoutByteReader? bytes, + {int offset = 0, Map? source}) { if (!this.span.isNegative) { return this.span; } @@ -273,7 +275,9 @@ class VariantLayout extends Layout> { } int span = 0; if (layout != null) { - span = layout!.getSpan(bytes, offset: offset + contentOffset); + span = layout!.getSpan(bytes, + offset: offset + contentOffset, source: source?[property]); + assert(span >= 0, "span cannot be negative."); } return contentOffset + span; } @@ -323,7 +327,10 @@ class VariantLayout extends Layout> { if (layout != null) { layout!.encode(source[property], writer, offset: offset + contentOffset); - span += layout!.getSpan(writer.reader, offset: offset + contentOffset); + final lSpan = layout!.getSpan(writer.reader, + offset: offset + contentOffset, source: source[property]); + assert(lSpan >= 0, "span cannot be negative."); + span += lSpan; if (union.span >= 0 && span > union.span) { throw LayoutException("encoded variant overruns containing union", diff --git a/lib/layout/core/types/xdr_bytes.dart b/lib/layout/core/types/xdr_bytes.dart index e7d9b36..087af2f 100644 --- a/lib/layout/core/types/xdr_bytes.dart +++ b/lib/layout/core/types/xdr_bytes.dart @@ -31,8 +31,9 @@ class XDRBytesLayout extends Layout> { } @override - int getSpan(LayoutByteReader? bytes, {int offset = 0}) { - int span = layout.getSpan(bytes, offset: offset); + int getSpan(LayoutByteReader? bytes, {int offset = 0, List? source}) { + int span = layout.getSpan(bytes, offset: offset, source: source); + assert(span >= 0, "span cannot be negative."); span += _reminder(span); return span; } diff --git a/lib/layout/utils/utils.dart b/lib/layout/utils/utils.dart index 217bdcb..6f9be37 100644 --- a/lib/layout/utils/utils.dart +++ b/lib/layout/utils/utils.dart @@ -17,7 +17,6 @@ class LayoutSerializationUtils { } static Tuple decodeLength(List bytes, {bool sign = false}) { - // print("come bytes $bytes ${bytes[0] & 0x03}"); switch (bytes[0] & 0x03) { case 0x00: return Tuple(1, BigInt.from(bytes[0]) >> 2); diff --git a/lib/secret_wallet/web3_storage_defination.dart b/lib/secret_wallet/web3_storage_defination.dart index 4f097d6..a8a5f27 100644 --- a/lib/secret_wallet/web3_storage_defination.dart +++ b/lib/secret_wallet/web3_storage_defination.dart @@ -454,7 +454,6 @@ class Web3SecretStorageDefinationV3 { /// /// Returns the encrypted wallet data as a string in the chosen encoding format. String encrypt({SecretWalletEncoding encoding = SecretWalletEncoding.json}) { - // print("cipher ${BytesUtils.toHexString(ciphertextBytes)}"); if (encoding == SecretWalletEncoding.cbor) { return _crypto.encodeCbor(_password, data, uuid); } diff --git a/lib/utils/binary/binary_operation.dart b/lib/utils/binary/binary_operation.dart index e2b2e1b..06f37ad 100644 --- a/lib/utils/binary/binary_operation.dart +++ b/lib/utils/binary/binary_operation.dart @@ -127,3 +127,6 @@ const int maxInt32 = 2147483647; const int minInt32 = -2147483648; const int maxUint32 = 4294967295; + +const int safeUint = 9007199254740991; +const int safeInt = -9007199254740991; \ No newline at end of file diff --git a/lib/utils/binary/utils.dart b/lib/utils/binary/utils.dart index d37a2ca..4c1f532 100644 --- a/lib/utils/binary/utils.dart +++ b/lib/utils/binary/utils.dart @@ -13,9 +13,7 @@ class BytesUtils { /// of the XOR operation between the corresponding bytes in the input lists. static List xor(List dataBytes1, List dataBytes2) { return List.from(List.generate( - dataBytes1.length, - (index) => dataBytes1[index] ^ dataBytes2[index], - )); + dataBytes1.length, (index) => dataBytes1[index] ^ dataBytes2[index])); } /// Converts a list of bytes to a binary string representation. @@ -134,7 +132,7 @@ class BytesUtils { /// /// Performs a bitwise AND operation with a mask (`mask8`) to ensure that each byte in /// the input list is represented as an 8-bit integer. - static List toBytes(List bytes, {bool unmodifiable = false}) { + static List toBytes(Iterable bytes, {bool unmodifiable = false}) { final toBytes = bytes.map((e) => e & mask8).toList(); if (unmodifiable) { return List.unmodifiable(toBytes); @@ -159,9 +157,9 @@ class BytesUtils { /// Throws: /// - [ArgumentException] if any byte is outside the valid range. /// - static void validateBytes(List bytes, {String? onError}) { + static void validateBytes(Iterable bytes, {String? onError}) { for (int i = 0; i < bytes.length; i++) { - final int byte = bytes[i]; + final int byte = bytes.elementAt(i); if (byte < 0 || byte > mask8) { throw ArgumentException( "${onError ?? "Invalid bytes"} at index $i $byte"); @@ -190,6 +188,13 @@ class BytesUtils { return 0; } + static bool isContains(List> a, List part) { + for (final i in a) { + if (bytesEqual(i, part)) return true; + } + return false; + } + /// Compare two lists of bytes for equality. /// This function compares two lists of bytes 'a' and 'b' for equality. It returns true /// if the lists are equal (including null check), false if they have different lengths diff --git a/lib/utils/compare/hash_code.dart b/lib/utils/compare/hash_code.dart new file mode 100644 index 0000000..1e76aec --- /dev/null +++ b/lib/utils/compare/hash_code.dart @@ -0,0 +1,24 @@ +import '../binary/binary_operation.dart'; + +class HashCodeGenerator { + static int generateBytesHashCode(List bytes, + [List optional = const []]) { + int hash = 12; + for (var element in bytes) { + hash ^= element; // XOR each element into the hash + hash = (hash * 31) & mask32; + } + for (var element in optional) { + hash = (hash ^ element.hashCode) & mask32; + } + return hash; + } + + static int generateHashCode(List objects) { + int hash = 12; + for (var element in objects) { + hash = (hash ^ element.hashCode) & mask32; + } + return hash; + } +} diff --git a/lib/utils/numbers/utils/bigint_utils.dart b/lib/utils/numbers/utils/bigint_utils.dart index fd208be..1f14b53 100644 --- a/lib/utils/numbers/utils/bigint_utils.dart +++ b/lib/utils/numbers/utils/bigint_utils.dart @@ -211,15 +211,6 @@ class BigintUtils { /// Returns: /// A tuple of two BigInt values where the first element is the quotient, and the second element /// is the remainder of the division. - /// - /// Example: - /// ```dart - /// BigInt number = BigInt.parse('12345'); - /// int radix = 10; // Decimal base - /// var result = divmod(number, radix); - /// print('Quotient: ${result.item1}, Remainder: ${result.item2}'); - /// ``` - /// /// This method is useful for performing division and obtaining both the quotient and the remainder. /// static Tuple divmod(BigInt value, int radix) { diff --git a/lib/utils/numbers/utils/int_utils.dart b/lib/utils/numbers/utils/int_utils.dart index 137e0ae..c5f1b21 100644 --- a/lib/utils/numbers/utils/int_utils.dart +++ b/lib/utils/numbers/utils/int_utils.dart @@ -4,6 +4,7 @@ import 'package:blockchain_utils/utils/numbers/utils/bigint_utils.dart'; import 'package:blockchain_utils/utils/string/string.dart'; import 'package:blockchain_utils/utils/tuple/tuple.dart'; import 'package:blockchain_utils/exception/exception.dart'; +import 'dart:math' as math; /// Utility class for integer-related operations and conversions. class IntUtils { @@ -208,4 +209,20 @@ class IntUtils { return null; } } + + static double sqrt(num x) => math.sqrt(x); + static double log(num x) => math.log(x); + static double cos(num x) => math.cos(x); + static double exp(num x) => math.exp(x); + static num pow(num x, num exponent) => math.pow(x, exponent); + static double get pi => math.pi; + static int max(int a, int b) { + if (a > b) return a; + return b; + } + + static int min(int a, int b) { + if (a > b) return b; + return a; + } } diff --git a/lib/utils/string/string.dart b/lib/utils/string/string.dart index 6ac3f2a..87c5fdd 100644 --- a/lib/utils/string/string.dart +++ b/lib/utils/string/string.dart @@ -146,13 +146,22 @@ class StringUtils { /// /// The input [data] is a JSON-encoded string. /// Returns a Map representing the Dart object. - static T toJson(String data) { - final decode = jsonDecode(data); + static T toJson(Object? data, + {Object? Function(Object?, Object?)? reviver}) { + if (data is! String) { + if (data is! T) { + throw ArgumentException( + "Invalid data encountered during JSON conversion.", + details: {"data": data}); + } + return data; + } + final decode = jsonDecode(data, reviver: reviver); if (decode is! T) { throw ArgumentException( "Invalid json casting. excepted: $T got: ${decode.runtimeType}"); } - return jsonDecode(data); + return decode; } /// Converts a Dart object represented as a Map to a JSON-encoded string if possible. @@ -172,9 +181,10 @@ class StringUtils { /// /// The input [data] is a JSON-encoded string. /// Returns a Map representing the Dart object. - static T? tryToJson(String? data) { + static T? tryToJson(Object? data, + {Object? Function(Object?, Object?)? reviver}) { try { - return toJson(data!); + return toJson(data, reviver: reviver); } catch (_) { return null; } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 28688e3..abe6f91 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -4,6 +4,7 @@ export 'binary/utils.dart'; export 'binary/bytes_tracker.dart'; export 'compare/compare.dart'; +export 'compare/hash_code.dart'; export 'numbers/numbers.dart'; export 'string/string.dart'; export 'tuple/tuple.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index abfc819..b138ec1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: blockchain_utils description: Comprehensive Crypto & Blockchain Toolkit, Pure Dart, Cross-Platform, Encoding, Cryptography, Addresses, Mnemonics, & More. -version: 3.4.0 +version: 3.5.0 homepage: "https://github.com/mrtnetwork/blockchain_utils" repository: "https://github.com/mrtnetwork/blockchain_utils" Author: mrhaydari.t@gmail.com @@ -21,7 +21,7 @@ dependencies: dev_dependencies: lints: ^4.0.0 - test: ^1.25.8 + test: ^1.25.2 flutter_lints: ^4.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/test/bip/bip44/bip44_test.dart b/test/bip/bip44/bip44_test.dart index 43f3c99..6106d6e 100644 --- a/test/bip/bip44/bip44_test.dart +++ b/test/bip/bip44/bip44_test.dart @@ -27,7 +27,7 @@ void main() { expect(account.publicKey.toExtended, accountInfo["account_public"]); if (coin == Bip44Coins.moneroEd25519Slip || coin == Bip44Coins.moneroSecp256k1) { - final addrClass = Monero.fromBip44PrivateKey(account.privateKey.raw); + final addrClass = MoneroAccount.fromBip44PrivateKey(account.privateKey.raw); expect(addrClass.primaryAddress, accountInfo["address"]); continue; } diff --git a/test/ecdsa/ed_test.dart b/test/ecdsa/ed_test.dart index cb1e94b..a43e255 100644 --- a/test/ecdsa/ed_test.dart +++ b/test/ecdsa/ed_test.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart'; -import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/privatekey.dart'; +import 'package:blockchain_utils/crypto/crypto/cdsa/eddsa/keys/privatekey.dart'; import 'package:blockchain_utils/crypto/crypto/cdsa/point/edwards.dart'; import 'package:blockchain_utils/crypto/crypto/hash/hash.dart'; import 'package:blockchain_utils/utils/utils.dart'; diff --git a/test/monero/monero_test.dart b/test/monero/monero_test.dart index d70951f..86f95e3 100644 --- a/test/monero/monero_test.dart +++ b/test/monero/monero_test.dart @@ -6,27 +6,25 @@ import '../quick_hex.dart'; import 'test_vector.dart'; void main() { - test("monero", () { - for (final i in testVector) { - final seed = BytesUtils.fromHexString(i["seed"]); - final coin = MoneroCoins.values.firstWhere((element) => - element.name.toLowerCase() == - (i["coin"] as String).replaceAll("_", "").toLowerCase()); - final w = Monero.fromSeed(seed, coinType: coin); - expect(w.privateSpendKey.raw.toHex(), i["private_sky"]); - expect(w.privateViewKey.raw.toHex(), i["private_vkey"]); - expect(w.publicSpendKey.compressed.toHex(), i["public_sky"]); - expect(w.publicViewKey.compressed.toHex(), i["public_vsky"]); - expect(w.primaryAddress, i["primary_address"]); - final paymentId = BytesUtils.fromHexString(i["payment_id"]); - expect(w.integratedAddress(paymentId), i["integrated_address"]); - final addresses = List.from(i["addresses"]); - for (final a in addresses) { - final minorIndex = a["minor_idx"]; - final majorIndex = a["major_idx"]; - final addr = w.subaddress(minorIndex, majorIndex: majorIndex); - expect(a["address"], addr); - } + for (final i in testVector) { + final seed = BytesUtils.fromHexString(i["seed"]); + final coin = MoneroCoins.values.firstWhere((element) => + element.name.toLowerCase() == + (i["coin"] as String).replaceAll("_", "").toLowerCase()); + final w = MoneroAccount.fromSeed(seed, coinType: coin); + expect(w.privateSpendKey.raw.toHex(), i["private_sky"]); + expect(w.privateViewKey.raw.toHex(), i["private_vkey"]); + expect(w.publicSpendKey.compressed.toHex(), i["public_sky"]); + expect(w.publicViewKey.compressed.toHex(), i["public_vsky"]); + expect(w.primaryAddress, i["primary_address"]); + final paymentId = BytesUtils.fromHexString(i["payment_id"]); + expect(w.integratedAddress(paymentId), i["integrated_address"]); + final addresses = List.from(i["addresses"]); + for (final a in addresses) { + final minorIndex = a["minor_idx"]; + final majorIndex = a["major_idx"]; + final addr = w.subaddress(minorIndex, majorIndex: majorIndex); + expect(a["address"], addr); } - }); + } } diff --git a/test/my_test.dart b/test/my_test.dart new file mode 100644 index 0000000..ab73b3a --- /dev/null +++ b/test/my_test.dart @@ -0,0 +1 @@ +void main() {} diff --git a/test/uuid_test.dart b/test/uuid_test.dart index 5c3c8cc..7fce058 100644 --- a/test/uuid_test.dart +++ b/test/uuid_test.dart @@ -1,6 +1,5 @@ import 'package:blockchain_utils/blockchain_utils.dart'; import 'package:test/test.dart'; - void main() { List buffer1 = List.from( [174, 91, 168, 91, 107, 15, 78, 26, 181, 132, 151, 91, 160, 7, 157, 152]);