What changed, and why it matters
This commit adds new cryptographic code to Monero that converts points on the Ed25519 curve into Weierstraß (short Weierstrass) form. It introduces helper functions, new curve constants, and unit tests, but does not appear to fix any known vulnerability. The change is a feature addition for the FCMP++ (Full Chain Membership Proofs) work. There is no direct evidence in the commit or supplied references that this patch addresses a security bug, but any new elliptic-curve conversion code carries implementation-risk that could affect correctness or side-channel resistance if used incorrectly.
Treat as a routine feature commit. Reviewers should verify the Ed25519-to-Weierstraß mapping is implemented exactly per the referenced IETF draft, that the newly exposed field-element functions maintain constant-time behavior where required, and that the conversion is only called on torsion-cleared points as documented. No urgent security patch action is indicated by the available materials.
Security signals we found
New elliptic-curve point conversion code added
Previously static low-level field-element functions exposed in public header
New curve constants introduced and validated against an IETF draft
No security-relevant description or CVE reference in commit message
No vendor acknowledgment of a vulnerability
Evidence from the diff
The patch implements Ed25519 (twisted Edwards) to short Weierstraß coordinate conversion following draft-ietf-lwig-curve-representations-02 Appendix E.2. It adds constants fe_a, fe_a_inv_3, fe_c, exposes previously static field-element helpers (fe_1, fe_neg, fe_sq, fe_sub), adds an ec_coord POD type, and introduces point_to_ed_derivatives / ed_derivatives_to_wei_x_y / point_to_wei_x_y in src/fcmp_pp/fcmp_pp_crypto.cpp. Tests and test vectors are included. The conversion is intended for FCMP++ cryptography. The commit does not modify existing signature/transaction verification paths and does not disclose or acknowledge a security issue.
Changed components
src/crypto/crypto-ops-data.csrc/crypto/crypto-ops.csrc/crypto/crypto-ops.hsrc/crypto/crypto.hsrc/fcmp_pp/fcmp_pp_crypto.cppsrc/fcmp_pp/fcmp_pp_crypto.htests/crypto/main.cpptests/crypto/tests.txttests/unit_tests/crypto.cppInspect captured patch +408 / −6
diff --git a/src/crypto/crypto-ops-data.c b/src/crypto/crypto-ops-data.c
index edaa464..c5b0b08 100644
--- a/src/crypto/crypto-ops-data.c
+++ b/src/crypto/crypto-ops-data.c
@@ -864,12 +864,15 @@ const ge_precomp ge_Bi[8] = {
};
/* A = 2 * (1 - d) / (1 + d) = 486662 */
+const fe fe_a = {486662, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* A */
const fe fe_ma2 = {-12721188, -3529, 0, 0, 0, 0, 0, 0, 0, 0}; /* -A^2 */
const fe fe_ma = {-486662, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* -A */
const fe fe_fffb1 = {-31702527, -2466483, -26106795, -12203692, -12169197, -321052, 14850977, -10296299, -16929438, -407568}; /* sqrt(-2 * A * (A + 2)) */
const fe fe_fffb2 = {8166131, -6741800, -17040804, 3154616, 21461005, 1466302, -30876704, -6368709, 10503587, -13363080}; /* sqrt(2 * A * (A + 2)) */
const fe fe_fffb3 = {-13620103, 14639558, 4532995, 7679154, 16815101, -15883539, -22863840, -14813421, 13716513, -6477756}; /* sqrt(-sqrt(-1) * A * (A + 2)) */
const fe fe_fffb4 = {-21786234, -12173074, 21573800, 4524538, -4645904, 16204591, 8012863, -8444712, 3212926, 6885324}; /* sqrt(sqrt(-1) * A * (A + 2)) */
+const fe fe_a_inv_3 = {-22207407, 11184811, 22369621, -11184811, -22369621, 11184811, 22369621, -11184811, -22369621, 11184811}; /* A / 3*/
+const fe fe_c = {12222970, 8312128, 11511410, -9067497, 15300785, 241793, -25456130, -14121551, 12187136, -3972024}; /* sqrt(-(A + 2))*/
const ge_p3 ge_p3_identity = { {0}, {1, 0}, {1, 0}, {0} };
const ge_p3 ge_p3_H = {
{7329926, -15101362, 31411471, 7614783, 27996851, -3197071, -11157635, -6878293, 466949, -7986503},
diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c
index 788dd4d..12745cd 100644
--- a/src/crypto/crypto-ops.c
+++ b/src/crypto/crypto-ops.c
@@ -39,7 +39,6 @@ DISABLE_VS_WARNINGS(4146 4244)
/* Predeclarations */
-static void fe_sq(fe, const fe);
static void ge_madd(ge_p1p1 *, const ge_p3 *, const ge_precomp *);
static void ge_msub(ge_p1p1 *, const ge_p3 *, const ge_precomp *);
static void ge_p2_0(ge_p2 *);
@@ -90,7 +89,7 @@ void fe_0(fe h) {
h = 1
*/
-static void fe_1(fe h) {
+void fe_1(fe h) {
h[0] = 1;
h[1] = 0;
h[2] = 0;
@@ -648,7 +647,7 @@ Postconditions:
|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
*/
-static void fe_neg(fe h, const fe f) {
+void fe_neg(fe h, const fe f) {
int32_t f0 = f[0];
int32_t f1 = f[1];
int32_t f2 = f[2];
@@ -698,7 +697,7 @@ Postconditions:
See fe_mul.c for discussion of implementation strategy.
*/
-static void fe_sq(fe h, const fe f) {
+void fe_sq(fe h, const fe f) {
int32_t f0 = f[0];
int32_t f1 = f[1];
int32_t f2 = f[2];
@@ -1002,7 +1001,7 @@ Postconditions:
|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
*/
-static void fe_sub(fe h, const fe f, const fe g) {
+void fe_sub(fe h, const fe f, const fe g) {
int32_t f0 = f[0];
int32_t f1 = f[1];
int32_t f2 = f[2];
@@ -3980,3 +3979,31 @@ int fe_reduce_vartime(fe reduced_f, const fe f)
fe_tobytes(f_bytes, f);
return fe_frombytes_vartime(reduced_f, f_bytes);
}
+
+// https://www.ietf.org/archive/id/draft-ietf-lwig-curve-representations-02.pdf E.2
+static void fe_ed_derivatives_to_wei_x(unsigned char *wei_x, const fe inv_one_minus_y, const fe one_plus_y)
+{
+ // (1/(1-y))*(1+y)
+ fe inv_one_minus_y_mul_one_plus_y;
+ fe_mul(inv_one_minus_y_mul_one_plus_y, inv_one_minus_y, one_plus_y);
+
+ // wei x = (1/(1-y))*(1+y) + (A/3)
+ fe wei_x_fe;
+ fe_add(wei_x_fe, inv_one_minus_y_mul_one_plus_y, fe_a_inv_3);
+ fe_tobytes(wei_x, wei_x_fe);
+}
+
+// https://www.ietf.org/archive/id/draft-ietf-lwig-curve-representations-02.pdf E.2
+void fe_ed_derivatives_to_wei_x_y(unsigned char *wei_x, unsigned char *wei_y, const fe inv_one_minus_y, const fe one_plus_y, const fe inv_one_minus_y_mul_x)
+{
+ fe_ed_derivatives_to_wei_x(wei_x, inv_one_minus_y, one_plus_y);
+
+ // c*(1+y)
+ fe fe_c_mul_one_plus_y;
+ fe_mul(fe_c_mul_one_plus_y, fe_c, one_plus_y);
+
+ // wei y = c * (1+y) * (1/((1-y)*x))
+ fe wei_y_fe;
+ fe_mul(wei_y_fe, fe_c_mul_one_plus_y, inv_one_minus_y_mul_x);
+ fe_tobytes(wei_y, wei_y_fe);
+}
diff --git a/src/crypto/crypto-ops.h b/src/crypto/crypto-ops.h
index 7b0cbc4..7b6b9ff 100644
--- a/src/crypto/crypto-ops.h
+++ b/src/crypto/crypto-ops.h
@@ -142,12 +142,15 @@ void ge_triple_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const
void ge_double_scalarmult_precomp_vartime2(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
void ge_mul8(ge_p1p1 *, const ge_p2 *);
+extern const fe fe_a;
extern const fe fe_ma2;
extern const fe fe_ma;
extern const fe fe_fffb1;
extern const fe fe_fffb2;
extern const fe fe_fffb3;
extern const fe fe_fffb4;
+extern const fe fe_a_inv_3;
+extern const fe fe_c;
extern const ge_p3 ge_p3_identity;
extern const ge_p3 ge_p3_H;
void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *);
@@ -181,8 +184,14 @@ No 0 fe's are expected for `in`, otherwise fails.
**/
int fe_batch_invert(fe* __restrict out, const fe* __restrict in, const unsigned int n);
void fe_mul(fe out, const fe, const fe);
+void fe_neg(fe h, const fe f);
+void fe_sq(fe h, const fe f);
+void fe_sub(fe h, const fe f, const fe g);
void fe_0(fe h);
+void fe_1(fe h);
int ge_p3_is_point_at_infinity_vartime(const ge_p3 *p);
int fe_reduce_vartime(fe reduced_f, const fe f);
+
+void fe_ed_derivatives_to_wei_x_y(unsigned char *, unsigned char *, const fe, const fe, const fe);
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 4a6b20a..da3ae13 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -59,6 +59,11 @@ namespace crypto {
char data[32];
};
+ // x or y coordinate
+ POD_CLASS ec_coord {
+ char data[32];
+ };
+
POD_CLASS public_key: ec_point {
friend class crypto_ops;
};
@@ -338,6 +343,8 @@ inline unsigned char* to_bytes(crypto::ec_scalar &scalar) { return &reinterpret_
inline const unsigned char* to_bytes(const crypto::ec_scalar &scalar) { return &reinterpret_cast<const unsigned char&>(scalar); }
inline unsigned char* to_bytes(crypto::ec_point &point) { return &reinterpret_cast<unsigned char&>(point); }
inline const unsigned char* to_bytes(const crypto::ec_point &point) { return &reinterpret_cast<const unsigned char&>(point); }
+inline unsigned char* to_bytes(crypto::ec_coord &coord) { return &reinterpret_cast<unsigned char&>(coord); }
+inline const unsigned char* to_bytes(const crypto::ec_coord &coord) { return &reinterpret_cast<const unsigned char&>(coord); }
CRYPTO_MAKE_HASHABLE(ec_point)
CRYPTO_MAKE_HASHABLE(public_key)
diff --git a/src/fcmp_pp/fcmp_pp_crypto.cpp b/src/fcmp_pp/fcmp_pp_crypto.cpp
index 39b95db..313c11b 100644
--- a/src/fcmp_pp/fcmp_pp_crypto.cpp
+++ b/src/fcmp_pp/fcmp_pp_crypto.cpp
@@ -64,5 +64,60 @@ bool get_valid_torsion_cleared_point_vartime(const crypto::ec_point &point, cryp
return true;
}
//----------------------------------------------------------------------------------------------------------------------
+bool point_to_ed_derivatives(const crypto::ec_point &torsion_free_point, EdDerivatives &ed_derivatives) {
+ // The point SHOULD not have torsion and should pass get_valid_torsion_cleared_point_vartime
+#if !defined(NDEBUG)
+ {
+ crypto::ec_point expected;
+ assert(get_valid_torsion_cleared_point_vartime(torsion_free_point, expected));
+ assert(torsion_free_point == expected);
+ }
+#endif
+ if (torsion_free_point == EC_I)
+ return false;
+ // fe y;
+ ge_p3 p3;
+ if (ge_frombytes_vartime(&p3, to_bytes(torsion_free_point)) != 0)
+ return false;
+ fe one;
+ fe_1(one);
+ // (1+y),(1-y)
+ fe_add(ed_derivatives.one_plus_y, one, p3.Y);
+ fe_sub(ed_derivatives.one_minus_y, one, p3.Y);
+ // (1-y) * x
+ fe_mul(ed_derivatives.one_minus_y_mul_x, ed_derivatives.one_minus_y, p3.X);
+ return true;
+}
+//----------------------------------------------------------------------------------------------------------------------
+bool ed_derivatives_to_wei_x_y(const EdDerivatives &ed_derivatives, crypto::ec_coord &wei_x, crypto::ec_coord &wei_y) {
+ static const int N_ELEMS = 2;
+
+ // Get inverse of (1-y) and ((1-y)*x)
+ std::unique_ptr<fe[]> fe_batch = std::make_unique<fe[]>(N_ELEMS);
+ std::unique_ptr<fe[]> inv_res = std::make_unique<fe[]>(N_ELEMS);
+
+ memcpy(&fe_batch[0], &ed_derivatives.one_minus_y, sizeof(fe));
+ memcpy(&fe_batch[1], &ed_derivatives.one_minus_y_mul_x, sizeof(fe));
+
+ if (fe_batch_invert(inv_res.get(), fe_batch.get(), N_ELEMS) != 0)
+ return false;
+
+ fe_ed_derivatives_to_wei_x_y(
+ to_bytes(wei_x),
+ to_bytes(wei_y),
+ inv_res[0]/*(1/(1-y))*/,
+ ed_derivatives.one_plus_y,
+ inv_res[1]/*(1/((1-y)*x))*/);
+
+ return true;
+}
+//----------------------------------------------------------------------------------------------------------------------
+bool point_to_wei_x_y(const crypto::ec_point &torsion_free_point, crypto::ec_coord &wei_x, crypto::ec_coord &wei_y) {
+ EdDerivatives ed_derivatives;
+ if (!point_to_ed_derivatives(torsion_free_point, ed_derivatives))
+ return false;
+ return ed_derivatives_to_wei_x_y(ed_derivatives, wei_x, wei_y);
+}
+//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
}//namespace fcmp_pp
diff --git a/src/fcmp_pp/fcmp_pp_crypto.h b/src/fcmp_pp/fcmp_pp_crypto.h
index d1d2b1b..8af4ae1 100644
--- a/src/fcmp_pp/fcmp_pp_crypto.h
+++ b/src/fcmp_pp/fcmp_pp_crypto.h
@@ -59,10 +59,44 @@ static const crypto::ec_scalar EC_INV_EIGHT = {{
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(6))
}};
//----------------------------------------------------------------------------------------------------------------------
+// Field elems needed to get wei x and y coords
+// Take note of the bounds, and make sure downstream field ops can take said bounds as input.
+struct EdDerivatives final
+{
+ fe one_plus_y; // bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ fe one_minus_y; // bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ fe one_minus_y_mul_x; // bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+};
+//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
bool mul8_is_identity_vartime(const ge_p3 &point);
crypto::ec_point clear_torsion_vartime(const ge_p3 &point);
bool get_valid_torsion_cleared_point_vartime(const crypto::ec_point &point, crypto::ec_point &torsion_cleared_out);
+
+/*
+point_to_ed_derivatives converts an Ed25519 point to Ed25519 derivatives used for converting to
+Weierstrauss coords, as per https://www.ietf.org/archive/id/draft-ietf-lwig-curve-representations-02.pdf E.2.
+
+We expect that a point passed in this function has been validated to be in the main subgroup with no torsion,
+and does not equal identity. The `torsion_free_point` param is expected to be the output of
+get_valid_torsion_cleared_point_vartime.
+*/
+bool point_to_ed_derivatives(const crypto::ec_point &torsion_free_point, EdDerivatives &ed_derivatives);
+
+/*
+ed_derivatives_to_wei_x_y expects as input the output from point_to_ed_derivatives. No point passed in to
+point_to_ed_derivatives can have torsion, otherwise this function has undefined behavior.
+*/
+bool ed_derivatives_to_wei_x_y(const EdDerivatives &ed_derivatives, crypto::ec_coord &wei_x, crypto::ec_coord &wei_y);
+
+/*
+point_to_wei_x_y takes a torsion free point as input, and coverts to Weierstrauss coordinates.
+
+We expect that a point passed in this function has been validated to be in the main subgroup with no torsion,
+and does not equal identity. The `torsion_free_point` param is expected to be the output of
+get_valid_torsion_cleared_point_vartime.
+*/
+bool point_to_wei_x_y(const crypto::ec_point &torsion_free_point, crypto::ec_coord &wei_x, crypto::ec_coord &wei_y);
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
}//namespace fcmp_pp
diff --git a/tests/crypto/main.cpp b/tests/crypto/main.cpp
index 913f8ab..ff644e1 100644
--- a/tests/crypto/main.cpp
+++ b/tests/crypto/main.cpp
@@ -39,6 +39,7 @@
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "crypto-tests.h"
+#include "fcmp_pp/fcmp_pp_crypto.cpp"
#include "../io.h"
using namespace std;
@@ -53,6 +54,9 @@ bool operator !=(const key_derivation &a, const key_derivation &b) {
return 0 != memcmp(&a, &b, sizeof(key_derivation));
}
+bool operator !=(const ec_coord &a, const ec_coord &b) {
+ return 0 != memcmp(&a, &b, sizeof(ec_coord));
+}
DISABLE_GCC_WARNING(maybe-uninitialized)
int main(int argc, char *argv[]) {
@@ -273,6 +277,16 @@ int main(int argc, char *argv[]) {
if (expected != actual) {
goto error;
}
+ } else if (cmd == "point_to_wei_x_y") {
+ crypto::ec_point point;
+ crypto::ec_coord expected_wei_x, expected_wei_y, actual_wei_x, actual_wei_y;
+ get(input, point, expected_wei_x, expected_wei_y);
+ if (!fcmp_pp::point_to_wei_x_y(point, actual_wei_x, actual_wei_y)) {
+ goto error;
+ }
+ if (expected_wei_x != actual_wei_x || expected_wei_y != actual_wei_y) {
+ goto error;
+ }
} else {
throw ios_base::failure("Unknown function: " + cmd);
}
diff --git a/tests/crypto/tests.txt b/tests/crypto/tests.txt
index 32e3b2d..2331e33 100644
--- a/tests/crypto/tests.txt
+++ b/tests/crypto/tests.txt
@@ -5543,3 +5543,203 @@ derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8
derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 15 00
derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 127 a6
derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 128 0d
+point_to_wei_x_y b8a5b0bd22b3d159a6f7dbcd27af3b8e4901c35acdfd0ed64f56e737390ce0e7 c2a6a1acacbadddd5f71a4cda5dfe006a482ef0154582dd626d2420036deb00d f6c7c5105db2a8a884ea820bdf298e2bb682f63dc554849f2ea27fe1cc2e372b
+point_to_wei_x_y 40a708680c68bdd2268e80d085ca540e3310e0b2271711bf53567d87425a7ac7 b18dc63d80395ca42736deff5992b865868a2c3c25ce5e3e783188e8b9372d6d 6b8b7aef67dfaf438b8cb6d04b7f2ea115e9b31e98efb5f7dbae301ee0df6771
+point_to_wei_x_y a4593c822968ea1eb1fd08d37db080ca1ad577ffa6ece1058e19223dab670bf7 53f607d6ac6dafd0ad4a49a05f6978c57f71607578a0d7aeb43307ce193f3a42 49ec310341f2499f660749941c14ead44b619d9a10f8d7efb29c7ad06202f429
+point_to_wei_x_y 852bc3feeb51ac794029c4335d517e9c22ded7b69238c692e2647283e124ee9c 4145ad496dde3037c17ae18bedcca25ded97df93dd003f856eeede3001b48968 e3ae89c64edd6e81bacd145551cdfe1c6903a65151ee15e6d91959aff7c9e466
+point_to_wei_x_y 069ec718defc4726dcd6862d60555240e3216bcd168bd15bb881f8157de3c67d 53aca964cbe386f1581f805f7e808d0a0153ea10e7ec0beff5e8ca0544831c33 46f6adb444301368cda44644239c441e1529ad7f165513a84356b108f72bb131
+point_to_wei_x_y c2dce43e0ef077826d95769aecf058e4ba678f4bad17eaf0abea333c35b91ee0 11d1a6a394f0ebb9f401c0bb52699ba87486016429c44033019569b41ecec923 edc48d15df5da457bd1d1eb22a72be0ab34b15e1ff44cdf0f2e5e38bcc3c036a
+point_to_wei_x_y 76fca5f8a05af2dfe668c5d251bb1f2e427c12581439987df597c1ceb3107a49 4f37d6e156493728b6fa2f87354ef4bbb428bb2dd2a3ecaae44b390949e0ba64 ef767e1a0f56b6404e8c5b0642a37372d71cb7e32b2543c7985976d1b9a3bd6a
+point_to_wei_x_y 3ab643e7b7bf694ea195955e73c3b12130dc523ba00a35e8f19e1ec1127d33be 26389928af9093cf3d62a1fde06c37defc94df063f5bd15795e7127c861e527d 6e634221441db6a301d37305d5a892f22a90ee0cd2a5aaa8148db37d35370972
+point_to_wei_x_y a79d9f4ed5f10b23dca803e5ec2af55564e818d351fa586477f1a87e09615bb4 70b9169301f8b90c7050166298ad7d135afafdc9d5823682de0db28b9d1ff21b 2bb06b182cec39fe9c2a7b6ec9dd82a058aec20c7a2346ffcd7a0b83e1a7d239
+point_to_wei_x_y 1e026878c73bf8946b105e7694ba4197aec9b872498a3d90f389957118312478 0ae6c4d105d738e130615ce80d78df3bf068d86f07279c00d36d6cb46f85fd5e 2160fb52edeb93722b0d960f485376a334fc3f8d4a71b4bee3d0ac34390c5660
+point_to_wei_x_y b3c17ce4cdc8b89121481600b81d0d667a16765876e15782ab76366215a39dc8 7a86e2acc01f20344246124ad55ac7a1bfd52caca3947dfd814124118af21b5d a4ba9d603a076f5c324ab9ac66479ea7b2baa812f12e526a630e62ccd02f5238
+point_to_wei_x_y 5273d1473d478a56bfafb2400658181637266eda76ddcf68470081b6c9634344 d44c482c138836176e9179d1f780a6d692e164af3351c9c45009af5c47ee3459 52cc0b1ca8b866f593059b41e814e643eb83232e6a6f175e9508e98f5cf8da45
+point_to_wei_x_y cc2a11fa959cff95537b4537b00c985e84da3c527ec8c69656b262317c67a337 ae2e35c25df9e81b5cdf8f61dacf20eefc58b6f6101dd875e53d11f04d633e7c 4293a2065cd032a16dc31e455f05dcc288b1cbbcb05c93de4ee99644fcfcf306
+point_to_wei_x_y bc91fc8d1d5608953fd473c13439cc608938f1b47831847a3e60f06bb5324a4d 9e99116511ab455044b216a18277bec184a61f4e577db81151341c5354b88177 f564bddaf7a9da2b9a3268b316a4698639722196d50db832d1b7b9761b23c365
+point_to_wei_x_y fca8fe7356b5b480fd4e381cdaa9532adf62d5de13891a35d3faf2da0e8b0dec 38842e01a04511c57dc13d32795eb444f98ccddd01725b432fb8c3b9838ca631 347baa65d720202d379cd2022331b7813b9da19474070e404a30c4f20da8fe1e
+point_to_wei_x_y a94536721db61cb1b53b100959678b80a2d649a3cef885fa335905418aa9a99f 81afc28d23f2ebfa21c02f00f87bc8721036b7c25fa1beaa95e8791e0f6e2d6e 04b3f941f5fd7909efc52ea0f1e80fe76bf635cb8e47cbc6fa1c2a6d3f3b3f03
+point_to_wei_x_y d9846ed4a6a605de5629d49650311578c6a63aa49efdb79c30332b030468c553 25b11396b73acd9c170173fefb2fabb0e9dea6e2d7b88355dddf0b8ab71cf451 b85579851a353c368b6c933128f7e11353cb078f6478ec48a6d366321be27944
+point_to_wei_x_y 189465102f0908aedf0a8837ddb680ec9a9f0145776517dde3d36b806c42a6da a442909cb77bacbd894efc6b7e54ed7378381bd1cf098ba3d6d9be017786880c d30392a9d192db1f5c34eefc57847ed2bb76fe1b1134733ccee94afa2859a95a
+point_to_wei_x_y 17df24051d4e0ca2d2e100daa99abf829d46e80106ae3547c227e8dbd3b32772 4e73ee619e26d424f9a75063524450c824bddbc42d17af03583cd29401712617 96451359bcc14634fd7a8809db4fb5b798eb9657a33c7acfdcc689ac7559406c
+point_to_wei_x_y 1f27f5142ac7db1769e12accf3bf8a65935d08ca7447d176a73bfffc24f6a789 1ea00b0e6deb26930c126774d1d6a2181c24d9cfe408b7fb3cdf5f5f28f53f43 bdf021a6f71927a85e1b10e30f488d78daa0444ee82b17030fb1489e47a8e259
+point_to_wei_x_y 8e95b1184f49c51d047986d56ab565c1c3fe992539d589696c93ed0005a9825f 5b2f10d6b6e4aca1ead916d9067ec6e12a002e1e6419c049bfe90af1ff17643c 815b9b3d9ec97735179bbb2c3d7118a0a9193673860e2798dd1adf442f9cc125
+point_to_wei_x_y 4915f32d2ebed07214c8cc941c2df1d0ff2c6f2f9612762a795d62d88a813c3f 697077337e8b6c3e7c8bfca0cc236caab6d9a3c3a70c81dcccb06fecd34bd814 15941173b4b1f64b29b85bcc87ab0641c2c03f5fb76e2dfcc1cb4409fe700e7d
+point_to_wei_x_y dcea3b678c0c13977089ca0f82586cd55b5d9678e5ccf5adae6691a0e8f58343 3b9d5b391bfe68b00527c5b865d8a9488dbec256ffd3a7136f36d425adfefe59 737597608c8c004a000ce2157496b6d85720f1782944181522476b084a7e1251
+point_to_wei_x_y 210750323186b8317d18a2cd2becd95bc0092a18d90d52ef3d714926e43f2601 b5e5618ad354cba233568c22f83dd524df2faa4d3bd797575f7b50b4b2bfdc37 a64f7e4bf829a12a2b5646c00cea5af481b1b2ec7a25266dfa1b7e5806ef203f
+point_to_wei_x_y a5bf2f3238f269aefa95c4737e84fcda8c976a41f5a8547749bb040eca6a05eb 8fa2b99e5cc93fbfb84a9c8649b07d8921fec3af47bf04c3cd022c1221cada05 f87c4a33e1dfceb098aa5b05448234a0c43f5dc3f5233cee3401df0becff3470
+point_to_wei_x_y 7959fc22c2eed2d04e3f1f2adb12fb5b24a07eb3018850844158c8a5bd97ccab 49d02c57479f2313d4ebef06cd24f0401859aa3fdff519e402c97d95b73caa21 85b15c5c3869d32b5839c359c654d87422997d84786f16ab1c9b4d7e0ef6856e
+point_to_wei_x_y 4dadebbfdf491db7a409aaa1f7fb72a8f11e9ad6d3945d1930fa8e438e4c24c3 d3c1f4274bb6ef83b6416d1d6531a7bce2f837d9583b0d3a70b7712741916c0b 72babec141c7434b97fe497ee0d9da749583c9a4dfbb3ce2f2d290412253a625
+point_to_wei_x_y 0b3ce9f180597d720079c2fa25093a8e98307ee8b362074a4a2eefdb9b2e59dc ea81bdf454ea29e8f1c81759aadfa4b20173fc36500b5d346ce745bd94f3504c 747fed75ff95bec02288b597e4b6bcac8e8d834a6d151ad789b8d6ab7381b874
+point_to_wei_x_y 622e04b38274baba914f8b5570f0457645422f7d327b510d289b5748ccf469c0 923cc39e62d4ebc059ee1fa00a4b0f8dd69681b9e7fb6e91c7c77b8fc16b504e 8bd5f2642476b496abb80ab2480d1dc1a43f3dfe277463f568e69103f365221b
+point_to_wei_x_y 480592c77dd098ece1576825f0918e72fc28f52133c4557c414325c3d77d8ded 6f2fe4b677f1651afdd4e30c912175bd4a8f805fa6ae59f0337afda1935f3933 516c6ee8258eacdab48584d893ec78679d9542c8b01edf2711e5d4020860cb4b
+point_to_wei_x_y 8b6d4e17edc5bdd14ae289801f16d92e484a70831a5f5226c831e969fdd8d96d 7a4fcd105f9d874e06bf66f2e14c2b7b4f1d8117e7a45b0344540226d2fbff53 80db4222fc899e14d2424748a3715360f0e993960f7277646fa361cb635c6711
+point_to_wei_x_y b32c342b64a3145f53f2d324758d1fb4d2a18f67bfb46412842f43e59e4cd2f2 f8e87e20c7b68be080cf41805c55f10c73aa60cb82b9615068abe9e82f049b65 ab57bee267e130a55148c21c01ed9747b136a0394d0ef9db64f2402b2578d802
+point_to_wei_x_y 41898dde3dd96a538f54b17d19258f2075a5b119b4d550066aca72a805f23ae9 ada62b73ce6c96e9412746b7ff35e9542031a92b30667ba10c0788fd62aeec11 4462158ddf7b75cfecdb2f9ae4e3f5d493398f94b3132494dc888f080b9c6262
+point_to_wei_x_y f339be4ea147537b17969c4d4c586f7f412618840df8a87fb25de0baae00474c 672863008ff860fcdc30e88d27a2a9c4665317120e5d7d29bced393702afb371 4e2e35ad4ccc8bd685a5192c6a1761a646166147fd73a79eb8c3cc3142a8585d
+point_to_wei_x_y 99ca2b37414b6ac427e996f90babdf391ba87f6eafb3e1c6c3a9fb5c09fb01c6 62b5297aca7c40504829454e0771b3aaf5c0b3275fa804d90abd00a3b8107701 fd9676836f45afcdafa78bbf166de0f5d861b092e64ba672f50085b8aeeb7b34
+point_to_wei_x_y 2770e7d83a0b503fd93f88d68fb2161e050b1fe3a72fd2eafc63dcc6d204d1df e1cf386efeb02df3e097ec7afd4176355d3fa34fbf9a2ef91e5c0fd0f86b965b 31397bcafdbafa0b91cb27077a0bb00fc25982e2fbbb255980325ac4e246d662
+point_to_wei_x_y c0e6be5239a65a10209e75572c6cb455e8eb0ec0481a29a1f061abc7dc08a247 77dcd5c78e6183f1444d585f6425fecc1a4611c79bff2fb8d35cc7f0d77ffd32 6760cd9c6526a3c56a40debf371602068e9a79fa0c126e0a078f398f058d1455
+point_to_wei_x_y 9ba0329bf9f56ef36f74006482969c623db82011006186ee0961b4ec7dcd5e20 9239502692fdab0e0117303210ed7e1b577cab1bdba3cc0d039e742f9a65296c e3d465c62be811ee41b4e6164ae8f978510e6e93d133eefc24e7c7c563659e23
+point_to_wei_x_y 6fef5aea912a7347d0f8e04f0333d8cd0b9962650a2e4a6f9f49c5472547403e 9fd61772a953bcacc180ea8df941bcad24b37e613d990757fa4b134f8a51e775 4e303b9e07c4bb78c370f74f7a593a72bc4f145a3c08c1157521d83e2992143e
+point_to_wei_x_y 1d407aabe454ac1c85c03a87a7be85162ad7370854afc5d13e3066f667050e94 8452bc75b915ab49d8aae15091dcc85d61df06781761785869558391369dc13a 2b1e10de3d8d1433c8c6e37e560d372667b00d1d9da094a88b8b128907cd1876
+point_to_wei_x_y 7c0533b2e11c23071eebff0a224898cdec1c495928c311b1a2c5eb2981adee78 44cd02d832d380b8c0a15f1a52b51337e0b853adeb57a3c50b6b3e31bb5cfa7e 529f1eb11ba32e2c1858ff2411ee685392d345da4bbdd39eea2be2b0ae270e7a
+point_to_wei_x_y 6f001dd174deb0185701c7564a5f2554032d0b33858360160a2a3059096f1cfd 1ce687093054ccc0adaab112f91174272cfec7ac49b9886fee313daa62f5001d 0d6efe5501b51be65aa4e944236f6e3424c279c696bafd31c058b99c7220a424
+point_to_wei_x_y a37f84f344116bcc850576af96077f80105e73b647bb692c35cde96556e6b9e3 25bcac19fc5402f05910bd5afa5eb670c42e4a92029c44e0e73779fd43d3883a bb5f1b5f3db12bb7c2f06f35b79ccfdf7e4507c62f115751717bec816a654d47
+point_to_wei_x_y 0e48b7c91033742a16a7a41516d327364bfa0f7712909f5084f84c8193c95f5b d238fdd603b3ec474fda13dd1baef41a157d81e439d83d54bd16651bbbc3e630 bc0ed6518a76106f5e3f7b7cba3abfaded6f690dab439477493e1c3631d4b366
+point_to_wei_x_y f93f0216c6215af36c444de6683f0e0588542c3c492fcf0a4b16c144f689ee86 945e4a3b9b043836516f8e3ee783ba6225bc5671d8b2a039d166aa37f0b40526 a7f2df96312af6b35a802bdd066c21dc498eb7f7705822804c290e31f3f4654c
+point_to_wei_x_y 3a36b773cc5a27426a2a8035ad18f891d80eb6700dbc5095f94a3087304bbaa3 c32268b5bac086a820757b1d98b616c7befbf98a6805ae000aa86655bcd9f673 fdfe689e77f0481a1b4ab03a71719f68b1751bbe2b2b135c8da772c6d5d24c2b
+point_to_wei_x_y aae4f26aec5724603dc677c55c5cd1d3c5bed2b1b27eedcc62e0765d9b06ecd5 09e2c2d1edd7209ea7e82204ddffe335f37405d375c1b01b3586174cafe96113 aacc4624c09d570c14644b4938fe1ac5c167fea1912a979a23fb9fd2690adf71
+point_to_wei_x_y f4b371d048a233d9f0917321142c0c4dc9bd92c124cb823e7aa1095c6dbbb792 064a5016ffb1539e319d7081d5d612f4c8fc98454e60d8f791288b865e3ae729 a27fe85e85c099d2f9cf95701eeef6c54015eb6872501e1ada10270243df986e
+point_to_wei_x_y e55044e28a4b05889179d6da00ec908e43e40aca0a2cdde30d75c886fbfbf7eb 1c8d571f3f5e64a13a224714ba2615e1c47e6c6308625cce94daf53c9ab8190d 3f02ad00e78d56ec8a08615239f486feb6b8324618063ea370a3cc8c1d51f92b
+point_to_wei_x_y 0df539f36d6fcc0f652ec7d8b3877b0b0b8c28d8cb4da38c8f878005d66e7639 385cb31aa4fafce8107d95057bafd670f519718b3d1c8f61311aa0fb93d4754b 2e950414332c206f5fc3c5fd3f1164f0f4728f3c34258c85045be62d49994a16
+point_to_wei_x_y 312bec2882dcfb8fec73d3589c0c0a8429327b3dbb5683931ea7ef6b7f55f274 dd2a8de4a0ca266ad5f50f1ff1ab5c2f5589065131ed469da883ce78afb1e86d bf204d7b84095998bc8b80bf77c5cb4b2b6e4ef89c6be6c0b0de141b5c692167
+point_to_wei_x_y 6112f4bb255faba9996155f2472627b5f6ee7a306e0cb8ca42601a752d191600 e1257c6982370d398da5a855e80031a7d222fefd24d0b3ee9456cafa2de2cf20 a38c5256d9f7dd42e73b9e4b27bd1c07031223f125f034432d868e66d212d502
+point_to_wei_x_y f4a524123aefbf6eb7ecda1d88189871876c1bfecc7df7921c7b44e15a7a812d dc427f4205238fcb0a9677e162c6ed3a438d526f16fa2a3f0a3ab8254e317c66 a7018c67c11b751d65e57b8fafa6ff10cb0e87d86377bfcac48878ba4de3b44d
+point_to_wei_x_y c990bc04900dd489b7b2883f746cf7fad1d4da188acfd6307e63f0d1a4fcba68 886997414791c2581bb315144e1ab36705b00f683542e5a5bd1d3e9191653d7f b6b3bb111fa806d646078050285a39cf04092a54e2103feb8ed0b00c872ab54e
+point_to_wei_x_y d9c5a7db47ceb9377266fe377fd521f8be14982e0b10ccd96d738c23a7d43fff 77849505046412ecc3e28f9b154e7f4b957a9fa9c52f1ad5300f2f4b696c9625 819414d37a3b81778c4fad88d84cf0e417bbb8d489c823706adff71ce8281349
+point_to_wei_x_y a0ea5748e324f418f948729640413c8b6aa78c0c5b139469a6d40d0ae4964182 a0216b38c129bd12dd8499baad9a8ee7bf8266268c0c200bafa4b8bb3a01756f 0ff13eed97172d7d53e3683f218004a52e9753e06c70e0ad810fd35820b7e164
+point_to_wei_x_y e94cb6f9f71bf65b146fcc9945c28fe17da1d7d837499d57f7ea08ceb7150a02 287992049d1ab9a1998e84ffa891fabacd5f9f29e8674d1879d36e30cc682166 03ccc88a1f417e068bf636ce8a61b4f6fafb2cdf38a4db16d75c08e988b5d373
+point_to_wei_x_y 6ea34558a62bc9d681bcfe97ed4f2fdae2a66e377601dbf649df2707f072539e a4905fb7edf51facee5cde95b292fe478e137c1d2668ddffe4242ff127cc891c db9f459d74e49b769182b896daa42187597705a045ac4fe84d949038bd02fd4d
+point_to_wei_x_y 9d92c3bfdd2b1924b9c5bf38f916fa7b3da0088f03f3ef83ea417137d48e785f 0f51d67f2bd12f27dea6e7b830ddbd74bdf985077cf996ccd511b5dc16e9be22 6a29807688807bd2fd2d43844c7d1a3def18bb839f8600844d9182ec30f3c62d
+point_to_wei_x_y 93627e369143c1a8753f8bf701233f865513359215a874f4d714bc8852370a43 549fb8ff44e85a497ae27bad369a688dc1bd9a539781ab0dfbdd2db58908af4d e5c539c3338dd31862f7b37479771893a163c607b18b7e555aa94ecdca642753
+point_to_wei_x_y 07072ee347cebaf4eddc9cf1c27397e3b8e412afbf5c623f6839e95d551344c8 c77cbb4765008cdbcc9bcab738e43bac7284467ab87450db0361dff5bdbc1d5d da39a1ae086a11ddeb0201393bacd08ca3855a6eaa26d6609aef1d2986f16901
+point_to_wei_x_y 491ecb2ca217174d97c595b1fd6df3a08d981806d6c8354761781894cfece25a 47076d28f9a3d78125eebb1e350343de82c7edbc02613f0e7256f6dcdce4b31d 56787cdb16ab3de072d4055aaff0791e52b5b34a8dd6500394eb9217c6e77633
+point_to_wei_x_y 2b82e732d6c73f8f0af04f9d85c480b71e6ffb3f4c296f5d003f4896498f4d71 6ce67c1d68334a39f550bf475ba63ab7049a4007a1c3fa105f7dab77c439c71a 44545edbaf5a761ce269ea31861ef99a58b99fa5d94ba59014a83aa27e71ab05
+point_to_wei_x_y 7447931631d8d502a8a7cc257103d75d5010bc15dc84efba0ff8851ed4f31388 0522b5c569a1ad25406f0e0e2146c3bc30d5e5cbb90b49009071ec7b12772312 4448f873b6a7e541107a880ff45e8347194adef63dcab8e8c966953559613d58
+point_to_wei_x_y 412587ae73d7c95f110180de0b75f0a95e196473b0ea5b2884b1ca25fbf94e8e da67896bdde39be25fa4031af376ecc50e91d69e898267a4bc6fb3ab4b14d002 ce15d66cbfb7759c69c961edb748c27068614ba0b192cd05b1fc68571cb5441d
+point_to_wei_x_y 9bcc89ba6b1064f0f7a9006d2756450625abdca799b17a15f8677738db33a7fe 909d788416d5d77beb410f00068b06e2e0aabe9cd9b388f0c771340f7b2abe69 97a42e4da3c244d34ad4abfa53edc6dd8859f01a5e31a3f0ee677b429b578715
+point_to_wei_x_y fcbd4726595c6dc56b59f0dab19f714bc7bf2ad9fc5f912ea89a8d57192b3e43 276f5ae737acf4bed10262f8922a52069fcc4faa9e05a6cc47f7dbe1ac023f5c e5f8145279935585435f14e799cb11d8477af2b7c9ea888e3507dbb7e761d140
+point_to_wei_x_y a3a9c5f37cce8d065f9d179e0a3f5e49d76f442eba69875afd2611fdddead198 5fda1574635636b682445cad3423bda6d1d4dfcb89fed4a2cf1823f2539a4e6d ae9f7579c6d6c85051f78ab20c87817973c94a4d2a374c26a12a8a88a79abb32
+point_to_wei_x_y 5295b632b1297effa5330311a88e66ed4271fc6139c5795928007937f93df38f 65a7393d3e27b30d1766a88ae8b62f1045c51acb8163f1f02979100632884e52 3e922579ed6f13c10344d6aece227976862032d7fc7c4f627e5a68c78cdc4721
+point_to_wei_x_y 8e3ae4c23b32c2ec78b19b096f1a9fc662c01d7208b210956e4cb6edef832380 c6b260d8edc3df14d2750451cdc5e9a16a526f05928cd310035521cae4407040 4765de32f2deb6c01800abbc32c4f422d4643adb803c0c8ac37d526a6ca9a920
+point_to_wei_x_y af6983c4e1aad0be5d0d22c170f1eeb6a2cc4d587c5a1593dc5503089e78c6cf 9eb03845984835fa1ba74b46b2e239ef17603217467db3214fb58021c71c3a7b 6ca19f787c8e221f8e74d4123b4f1a8694c7c39edefd2ee2462f68f7e6677643
+point_to_wei_x_y f7f29eeaf40f5e62300dd7410d03e39d0c4c9d368b5412cddee4b681e93d72bc 91250a60e841d082f05c82158ced038c746ce817f296eb82d633972dccfc8357 2708f4d52896070e2f18753dfb4484ee7038c2a7493c045a62cc7fdb09988b49
+point_to_wei_x_y 4108b1e8efc93e9c5bb709e1ddd61e9db33188ae2ed63c3545aedd1ed8040d00 43be2858379f138ba33dc7904062b558e6d3ffacdc90617dbc4a9f94a9e3a16c ddc42349d0b6f84eb0d3cc9a421aacc9c15928c5bb3a47a4e95bea1f5f6eaa30
+point_to_wei_x_y 4bb3b2658ecd445976e526f5ff764b53679aed5568bbc7e294b29d6f3dc70a2e f6409fa982b2a3bdd2a60b0d61dc7362c3e8023d07cb62a0b96cadc02b7e5a00 7c69c150155e0098ecdd8ed63afc839c64c8a97be52adf774af7795ef67d702c
+point_to_wei_x_y 47661ae8e3a6697aa27433708f4b9e1c6e3989e316911e2dd6b1298417c84837 b62a6219c8a1bf2ebbb9879f93bbe63dd8fc0343caf0fa10d8ff7a2c525a5149 f6da2adaf7ea38636287b80f7ae75694bdc26479664424b32709c9940f28f10c
+point_to_wei_x_y a5814d5cc2f52e438748e496154719773a45cd6395f82d95446d4b400804b979 e960594275e07e58762eb01337abddba9333a136fbcbc4ffb81f0ff080946505 09c1d6aacf5dbb904d6fd240b72ad58317b656198b20412143c2d74a3b5aaf36
+point_to_wei_x_y deb4551fe6d4de189fe8fc83a6f272fdd2249df125bf8b117ba9d4e9649671c9 233f7b83ec02fefcbe407467a323fb07a6524122cba2e186bd01c65853d2926a 5c6f0438f926bc84c48f53a0db2faab30ce2c254ef25c5619e304aee65049049
+point_to_wei_x_y e3d52956b2c59a65804f861d827ae6378fa8672a00a709a1d9f584986c62105f d8fbff9a0cd5766d4b99d6ce3615fbf011d9535deedb324773f19c209d87570c e5621fcfea0389c822cda9c1ff9d679c931e6da3d430034a9da34f772ebc192c
+point_to_wei_x_y 0bc188d3c3913e35ce668fa45e899f09a64bce62463f8f65ee4d68c5d3748dcf 11f578a503845de692e15660184a4e7356335dd217830ff7a920d30d5250270b 11a74faf91c0bd1955222e4ca9527943450dd0b6ee31c3f63546f3bc58e55c5b
+point_to_wei_x_y 416ec3d1db10dd9e01f2559c8a0599d498f58b82444f12e45c07277f1820537c cd46d5820b68ff64e933712b2d3d626b96fc0942e701684bbd0d789540f1d257 de6bf5c387bc99a73207c206d237d0fd4ca35240a72dd5c30c0d710c00f42460
+point_to_wei_x_y 78896b5887a05ea52ec1678ba33ab4a5fa6555911ac472d6e770b4632edf0219 949c3a3d7831754d2847c127d76ce54e31e8d6ad04c01920af2eee2d58e06b3e 32c5cd99af39628423892d5dbdee6ad342a6c2f4717b1a93c774166ba0633338
+point_to_wei_x_y a2b7a4564b2a8008c526d38c47286009c02b48413d88ca2f7c4cf1a37a49bb94 379699fff37ce75ef34080ae748ab6dd411832c54bd39920cb66e9c5c911a868 1a9ac128cbbb120355ae45a80df3edbb94dc0828f841f996352104d7c903e115
+point_to_wei_x_y fb699eec4da83ebe672487846aabd2ee11933023496053beb476e90a533527d6 bdcd89db2180ab7a6d71e05548b0c763b602e81cd2c1897f4823c9be7923ef44 28c7cd800266ce5dbd39a9d8d601ace492be6fa4c47e999937cb71527f37e223
+point_to_wei_x_y e6c5ab98d1b5cb8cce2d4a0aba9d72b79cd4315d0c80a39773b26b3ca7446100 8a4c49089539467ca0d8790efd1d35e509c75e1ee84f86df0e8e9c111e6d5d47 9031bcbd69b541cb46998bba1bd0d89eeee18a9891cf6ee4bb69a00baf2abf0d
+point_to_wei_x_y 7e90511eaa63debcf997297f9f2f92545da79a8973da426a7fe937167504e87b 86eb6ea874e3c9f47227cc65e42891bc3a72b047b1fcc75f31cb45c9d9a0bd1e 6fb8b477720830f62796adbfa19541968959f8659efdedfb53ded15dae08f440
+point_to_wei_x_y ea51d364003c35be2063384998fc21c605109192996c421690b58029c8ddd1fb 649b5ff7173c4057faf0331d77803a1a9f0b2f72680150a62678656c67e0e014 d2bfea7bf88943a8778caf2abcbe4389c90cb0418e8fd2162d9790473ad2ca50
+point_to_wei_x_y 16c2e70a9c264a1b49a3ff685c116b49dac92e14d49706ef567e8269f1f6b2d9 164e286e350199a804e4367ce43a94f936badf375eac0539803054caf47f4d77 2a1c5ebe7a51358cc623e3c7e4c6f87a2b28266d93ed1cfb0ee356abbce79320
+point_to_wei_x_y cbeb5b3d14ac7e0d38e5b9346ad961ab01b6da462a724020cbc1bcf7f3b8f4b3 4ac0454659ecf56f8c3b829d5e919dcdddeecb8486f6dfa3c978ab9ff5b7c776 c77338395d66991eaa2d2bc5d4f2d050f2f74d40d2e4b99eadfe1e835f8dc237
+point_to_wei_x_y 17e2979651a01838f0434cb97cc2373546139f5e3ce22e7e8381e3c481572d1b cd39279d769d2c9b472d5d37e8537b0b4d8db38f38718f45379c895496237f69 a0e4b799fac6dd6831fdb73bf9944e868c115f6f0fc89a9421ba871142972d27
+point_to_wei_x_y e55259733847acceb075e1418e91fffdc5dc124aa5b1f2a247b13f0169ea29a6 3e50aa462ac7fd4864306e3c3426355992dcb3e63b4784714ecacb335e10f979 7e70a974e6e6c8ff35647dae814d81ac9b45ccf627a8173b04b98a2aa864ab19
+point_to_wei_x_y 95f3367c0f160e0598e65a2ec9972cfcd23c2bca7a8933c7a5a76ac72687ab89 06b6c04f6373c7448516f21b8260c88a3e8473456ba7fbfeebaef35bc913ac2f 7fa3924ca9840bf340499902285d97eb0ff246091d2f92ff35ba08a12960fc56
+point_to_wei_x_y 0c92e7161c9f1e277c21062555b451153cd65efa381d628a1a7d1d7e87112f9d 822495fd8b2d8fc4b24ca8671c0371d0fa6a7fd2abd24450117c76349828e528 2e7ae4071cf37d5242e6b5e8ba76c1d443aab35a0e6e90594a61569b17a8dd32
+point_to_wei_x_y c532245433864783e6fd0494f4b34fa4ec2c533fe9c2b9a5850d8ec4958000ea ff702e7837bbf94b9777c158c2a7d9ceec46f44bda40cb274afab512eca4927f 314a7993a5a432f678734c8eec7c73e17497ca961f0f1e94de182626000ecd7c
+point_to_wei_x_y 7ba551afd6d2ecd7a594214b3231e6c477e9a6eba77040e2abb5ab24b250f421 3b95bb0e6f59d4f1a2a6b0c9d56ff8be7d91b2df12ffce92ba1971c364ac645d 5c03eb46dbe766d93fa2197023da47f7703a260e77741ebbbf45f7de703c7669
+point_to_wei_x_y 272747d5a98dc85146c3df26b220bb78a0f2f2c059784e9ea0f58f6bca304c5c eef67d04d71230a4be103e21dd3650c3639131cc71d7def8be2c3b0c1765c959 8e234fb1dcf44fadbfed25d97016226726ffb035765c74fac3447447366a7b75
+point_to_wei_x_y 01d49146c333747d10c6215cfef6ac58786ce9ae6dd41fecee6f7c327c956db0 97040fbff879c01395bea1ba5c41327d68ac4151929850e83ad9101c28dd736c 2a8dfd2b238fe0ea9e40bc18b54d235565b00ac63f66e8310e9d811f3128390a
+point_to_wei_x_y 09d3169057a1827076c532f81968fa20cc0875ec2cef702f8ce2c880967a8611 2895d887faf8fc2ae5747e2d3bfd81da4cdcaaf2b37e87b18db12b1ff4e41757 43f5735d4439078cea8543814ec3c10d1a67f97a95c397add7251c5520fb393f
+point_to_wei_x_y 860b87663ccd2ad588ce45abab448a7775cdb15aa9cc157a816bccc13c3f8bda 2f74af85cf9708b45d7bcd73aeff47c2216803336e2542e1f02aa5400f2f6a58 fbcd08dcae752174d970998153425424fa94af3c89cebd7c4a47702e3d26b354
+point_to_wei_x_y e67dc9b9d1c4b115e349af78ef2fbefc557d247b588d4cece48a5bd0ff73f8d7 ea1ab90f5677f5b83867e624ed69fc0764bd30998bac715a1b9ee76944c8dd6f 760a05671a9a59b6f0910b8f2d1c1a7c45919a574eed62595fcfe1818f695f5f
+point_to_wei_x_y 7ed5e93a9db284b2bda19e1835d2afaa7786a7dcd18bef10e0554ef9b875dbbe 97d3474b28614fdcef3cd49d8c9630d76b8fe3c5d0a33ef46a1a0cc177f5c910 9195a5b7250f6cf81330db0a93ddddc74888e10372d9b29ab619bd0c30dbc921
+point_to_wei_x_y f963a47610eac119c9069184b69d281de5dce482a3228ea769b55b9830b96a1f 833629c2bc8f88c0d8bdf426109667ee59787b6799600d2ba141db9fc370ac21 9eb92c94453dfc6f217b4182bf52858c8a0d3035cea068af1c602b14de562534
+point_to_wei_x_y f254773fd3ecc6aeff3e5d0b761652a9d59848b76bdce5f7b39bd964d25d0308 f2f31e7f66c9475716811e20cc7eb4fc711f18e6859df40509bc81e89ca5b843 5846233ebfeaa2b0cb38833140993a9ac29b40506992f11fac59083514414906
+point_to_wei_x_y 9c59bca12e9d922224f8e9ebb4d88f0d06f14aa21cdcacc6fb27801ef7ce2fec 737a53b940847543782d93ca6bceedd476afead30d6ae1d61d57b9c68df7c775 70c0e287f626a951912ff85aff7aeeae6dd5090a1ebc1385f1ce1a6428f7ea0d
+point_to_wei_x_y 1cf02b233d4aad3afbdcc4e80b762115cbbca4e196456fc3d05da626391346b1 369af2847a2b91157bec01df8afa862dd5a1927ccd8921fae24ddcf62aae9e3d e7458b7ecfe12b4e2f8eec4281a41455a99926dff17db655b57adc3f35e83c43
+point_to_wei_x_y a498f33f5df8cb7ac457b54ddb6dd2f0709bcff3d6572535b46884c19ed8088a 7fba128f63085bdf436382ffc1e367d09f65eb53426888e6b2fd6eab3b89fb51 147b087887f8044e888dd2d0203df1394a6550cdf29d32640f3ee8ab38a94e12
+point_to_wei_x_y 5dfc937a06ab25ae00b6466bd5eb10341840d8bbb2448de9ea0a48fe59a9715c e665c025337855ae4a7b38afa5ed1725815a1a914bb6c109db910b82000a634b 7d6bebc7004aef71518ab149d58c417b28a79d3c49dc2bf9c7a80d175c062b5d
+point_to_wei_x_y 6129fe82523a216d623b3ed6d81cc32792cdb2fb3e4c1c17f121d503e6bd616c 29c07b7bdbe0870f74fe89b82a9be81abf7327773ec777b66db237eab737912f 4215f098a2edf814764f3315bd707fc025d3e621c3361596656f679a26211117
+point_to_wei_x_y 9e4b5b2618a1234fe1321475e8a5bd9cf1e01b34f3e86e879685bd97d73fc8b3 896d3a45bb666ab7225eee70089a14f95522746ff4b9cb0e94fbe7d8b9708d20 d1416e25af84a6bb1372ef36e9708fa36e1e2dd2e2d89c9417b9763eaf335d61
+point_to_wei_x_y ad97147b21dcbe67df48ad97c797fbb78a04a818012c8d78a891c918bc6a349e 74bf167067cd94c399b1e8d4f3d73586963cbc28c900ea4c41a45235818c9c0d c47400a73990b2d9d0399066582e927594f320bd38e7c1439859b27a270c3b1c
+point_to_wei_x_y 873724fd78fa6d247714cab86d686f0a58a540563ffb0836e89c5bb02d050ff3 dc7a33ca97ebeb2858d8b1f2a3d942a2a51c6c34023f73934e92c6a31e25e90b 39fedd467da69aefb5bad6047cf6538ac9e2ddedc126fadaa18d0535822a5442
+point_to_wei_x_y 5d4a5b49a72d250cc95f63f29e2bf3146e14ecc303c4fdf49705403316abcc57 c8e0f14717c637e09f1380413cbd0357d05afb782acaa76cd875448ddccea162 6e1ccae60f5e5cc491462d1f261c2e0bcfe70e5549a62506f65d58d7984cbb3a
+point_to_wei_x_y c54126cc180ea9a8995dcab1ebdf9a077c072cc13bc2bcfb9b9601a171844e82 e26d34ef1c58126e5045dbc27d3c8d46e43cd04675738654d71a81be889c3e40 a1c278624d2d06a514e8dab2548bea27acb2cb20c2a5fdc6b1843ad3f156d06f
+point_to_wei_x_y a1f6854cac3befbe342f0e5cec306308c2ead056b6b5b8bd51223f46e9796b66 5f344e0c162cbece99ba4496aa6caca3c09872ec70e1e388dff51600300afc12 df09cbdf5602fa96912d624443e5770b0a8624f30f7c6c236270ccd183947d0b
+point_to_wei_x_y 84383e47d63ddd13e0dc1cd0e113c514d9ab5b0646c050be8861a33d2ee312bf 73159900ec94069f3eb524b1b840c8b18fd52c41177166f0185823845325b057 27ab39472da77432d979b2f6d0aa260cb7247d83bba67dfe649c574b7e626b38
+point_to_wei_x_y fade9a9701c45a78ff71e08b21ff913947c6fd1f9d80b2ed372302e947634f7a f35e5a147724b299c3da029ad17d6a58213751329ece14e0538bcf9018c3d543 9ec4fded5aa6e01a5fb8c82c5456988b2e6b60f189676b1fbd96243f0858b755
+point_to_wei_x_y 33d49e643954c303c8720374d5201925fb51748cc264bd68a14ade10163b3912 76d65e08994785104fc42fc0bd6cbb619284b256c12952286172df46b38f4a2c 251745a9a1afe17647793b17ac1ee38de8f58f371b5207edf877100fdaa80866
+point_to_wei_x_y 0f5b0a9fe7417fba8ed5053353c1125cf7f1211867b9ac3ff3f83dda0d7d27f7 b521150b86446d80397318a69ddc3169d8bd772bc2f457ef0d89410b4780426d 0f74a9fd7fb5ef9822c708682f57bcd154d65506ef71211ffb3b83345e464210
+point_to_wei_x_y f769b35af69dfafb72300ca8e230348056155e397ea416178f8b7a230913e87b 4be3391c023df7a47f40e5698a3335ff7e1d08e8a7cbcd65195280a656518c09 9fcd5ffd5c0d4ab6b8228cf8e53c300eb66f8140d9ec3fc56d43b7ba500c884d
+point_to_wei_x_y 30a2e840d24f89ba1998065b7f8a7845e835afa3ea3bdae2649b5c99d5359614 4242466cf11e3f2c16ef3a59321bb37e827e9394329a79ac3f76e31967f86007 5244d4f4e12f3a248175e8b5e19cf678ae108abefb511945d3690b0c12cf9c4e
+point_to_wei_x_y bd0ed364dd12df08f2dcec722b9dca92eb38f4289843158239afefe8200c4efc 0ca6166b57ecb618dd0aafc452560b4c2b0d23271c304e8bbe83ce44fbeede4e 9516d0de4d2dddb5d50a18c3f7d6698323d6cb4b41b74d97a38739e4bdcf8516
+point_to_wei_x_y d9e9d670fb60e9a1b6f476c60051692d90561b3ff072d12b54abdf131b6f3789 fe89fc9c3b14194b7ac37dbf1a51235b8f4d67a6acb4008cff958e628515bd08 2fd729082a36d381137657e8d59390b805dcd3140305c7f4105a2f1087e3924b
+point_to_wei_x_y b4c9fc507899e9d563bfa6394e289a5be6857cb110b3b18ce379314b3ac10f83 30e6d2567e0e6c48851087506480b87b6f8dbc8db7c361700ca5c1cf51223150 58de5601ea80b5271f3ddb533fb6fc081370c034609d84cf164112fa4e1c6972
+point_to_wei_x_y 7bc974027a3320b9a309deeef43a784582e1e9333ea8ea7ecaf4773e572ac1a9 8a69ca4fabf5d0c0357e45448ad816fce5255820d57c844f7306bf3ee0dd252d fecb4c5604c71633b24781c6ec97f588ca9c7d67da89ef916c0c327334e54f2d
+point_to_wei_x_y 24e394f0e857b1260f0092d30ac81f49cf8fbb9829c2195e8e4530a0ec5c056e 6aae2e2f8773fcad382f7440f826f7e9f89790cd6eefb2bcebbaa0634c2d964f 7c365e6151aada8109a058c0f18b66627412430225cc03b292ac47710c437217
+point_to_wei_x_y 6648de60ebf2c3a8fb357c6d19312bd0587cc1912e4f89d23ed4a1ae11f49b83 43a1261c5f3c13fcc57426b947f5608207a4e99f3285d320e9fc1c5c6f407960 44ba5b48cbc9da2945317daada8d52aeabacc983b0e6542931687c94575ffb2f
+point_to_wei_x_y b399bbb79f3783422c7d6b4439bed579a68d89c5acd191e458fb1719d03d720a 4627a15627c52c6bdb1794504e5f23822ae5621ba60f0f6fb26d31c9e44b8c33 d0dbdea54d97255b3cfa3a5100b5c2da5e8690139a46b4cdec9f51cf8942bc5d
+point_to_wei_x_y a107805255f658c1652b8bb20fadb6984cfc574371647f20617430e9b36114d5 ba4ce4e3a6f72def66988788672e237e85aadda53c2c9d4d13c9788e56e8ab64 b9db6775f421fdc41bfeb0c450a1ab3a611b60e2d0f2978ac162143ef641a14e
+point_to_wei_x_y 63ba94038f7dcd23023201bd55e84bf9cbaff14705e3c9d5a2ebfc8c438cd46a d1fec9dd8b83e311c1f8bee274f9bdcc54c8c4edd8d7d984d8344c3c4e80da72 096d9770435b00c31fc51e5edba8a34261e6ea24b96e97d044e17629e98a241e
+point_to_wei_x_y 685820894ab6542df6a19a443036dfd7b9642bae7b759373148483ac2b01ff6a fb4e03938f4553ed2acaf8190c4c08f759c82570a6c340983696a19cc63cff26 c7e09cccd2662ab9fd2bd8023c013bb433481024dd07d95f0b6d2666b660586f
+point_to_wei_x_y 90f068035a84b6afdbbb9a5745398d3dd863094f569d53da5428d59c98f0bb4e 8b38ed7f31ffd5d06e9c7c82d8fa61a01812f3095dc30d28f58cc2aa130a8d2f 15a871cfbbf16b8e2bfa8d4e435c177f0bae6ade1ba9f63b8228ab12c6bd7b45
+point_to_wei_x_y 93419645b6cc137af826078512f902846562781e5e4f9f2fab2dbeb9e69785c2 fadba315470bb981a0ed344c1db155d454557898bd168d88801f33bcfa0a303d 4283b5ef4ee795f32603539e5d05dd81b853d83cce0443ae31b1d6f81da22947
+point_to_wei_x_y 0bd6f43b22da0cdb08bd71df0db773fba32fe6c172ce04cf74899a40dd43b500 c4dc6847bd81b53d6a1b0b824b63c276f07516a945a1fe8ef722b301e1e8653f 2b6aea060a54ff54887e0b3307e2faacf40438de1584b49d0e75d526e1ff3a69
+point_to_wei_x_y 80eebafb49d91f51a3e51a7bd639a5990923020a29b380bdf00cbdcc1db5be7e 903a4abfba08d23e1b4dece4e8f83e31736b52ea8813793d71335467c4ba5f0a 2affb92c6bdae09fcbf1bb18c6f63f9a321dbdd23381a8ebfec5df45b4bf8263
+point_to_wei_x_y b8d1019da9cb10cd29ce145fe2db710bc4d25c9243b9f8888a8fb482548c471e 6683950ce528e447184fc2dd5eceae7b8a1bc98719b0f95b6e75a57820c73024 c6bfcdeb3f0d8d3154af918232a78e132d731d10cf5362c235c08df8fe174d1f
+point_to_wei_x_y 23a61f7be68948375051fcb526683a9fb1001e36349241a10792dc618edd444e bd60b5db5422045517f58ac5ea5142ab4aee19892753d9b361eb070b5bab3051 856e5e9a1759d2fbca2f0d0566bab9a336414408b8b647999bc97745ba8df948
+point_to_wei_x_y 73df96ab25c72add337546a16681dce6d5b6a1fd85929be00f2e212ca541dcfa 7419f78f2be40fd45ad21973f2461c825c59565e564ea987a5b6382d76c4a766 8b7e63a5f8cd0d33f12306263c341d4836235cd779fd88d1f1ee7d7c6241d11e
+point_to_wei_x_y 5541a8717e84452acb0d7b2ca04079db8e8a868001c23d94bf6ef5a644f5d736 765e70e8ca41409cf234c396cbae942e885af49e154dfd217c3a90d9b9bc9e7a 0d14440dc56cc7a5942964f78a3af9176fdd7b482b3519abd019c7dc3f48a83e
+point_to_wei_x_y 83dd57cbb7ff640b7805bee0d5075a483fe672c1c654c6fea0619e7bbc591cbd 2fd21ef93bef9914b81f48c3db88b1293ed06cdd89cc5d5957fe514d07fe284f 1c08a3e8ce31f0129a2db07da0e40c10047070e1b05ac2d6998842cca3641a30
+point_to_wei_x_y e71ae94a17794f55a9a07c7f69beb139b34a2d951d4de270336bbfca09b7f408 5ec5ef53ab94c82358f1de15d174ace9cc41e1769a69c205a95b375aecc8ef71 b61b7667029c6b4e39e47509e026356b1e055d1b6cf3f94d7e8ebfc6fbb6ae6b
+point_to_wei_x_y 3fd9c113978f3d0d304a92887c994d01e702dcb801c9e67681d624478daa7043 e82b7236ee071605e1a51c2d05a73e2e408839d34a471afb32c805a687ffbc2b f9e6f0aac7d534b2b0f3d391851683661e078a481d08d2589600aea996dfe94e
+point_to_wei_x_y 46a027bf59730f962bb391c4c478efb21755b59b35ed0d447ffe253caaca88c5 099e6b713720760f3e88dd75f2ed82fb5ce87f8870958b427320861a9cd09722 9c670039d224094f5a3756fa75cf81ca2c63fd8656d804c3f223bdd31645f92f
+point_to_wei_x_y 3d4f54a4d860c802c6e97e2fdfa12b99033fc78625fab76aee5e4d8657fec1b2 ac85907151e4c38d43633e1c19a8f09064fa5468edf35880d9deacaa20c05923 c7804bea48ff44e1034dff3cd4534ee718157f99201e003c54e158c66fec2a01
+point_to_wei_x_y 80697788832f205584efb52892a9b30855ee03de972240dd7ecd7ff64861a860 778927644b807b8c68135d06b48e8605a8a068c5806aea189d4a8f2de1d71e52 84dbde111a4da6e249ac2ec2f686ef47c1e2ea2a275857fa6431cbb618ce052a
+point_to_wei_x_y 56381dce70969aba7af8a6f1390a3fa72ec0de1e041e7433380a4033c135329a a1c922677846b00ddca7dbc66d6870d0088e171bc826e3f86909e77200cced47 a490068f673bc08e9b03133d3c0c1d4e26c3f242167de33d973baa39f5ca9821
+point_to_wei_x_y 24134e2d3e916c2a490011d9b833a5b2abcf88c74b9aad1b37c485db28d10781 0f1651794d01e3fcfc3ca5b3c0ce6f6f4a9be71e57e95c065d98e9fe9b23d121 75dd9017cbb460616ec4133615069bfbe02d45e8cce09d6f14d6c3f022385156
+point_to_wei_x_y c952a41566befd0f3e3ab019604c7881c0ca16f203ae8e7779cf46296b15976c 6058024ed08bc6408e1bee423037c1ae90a07ea1bc0f26c15f2a3c7b281acd2b ee02df0ec8be8a65a6f357678d81b50389ac9b22f167f192860059a7d935c65c
+point_to_wei_x_y bd64d7515338fa43010077739b82276693c3d93ca7b4b12a55497b0f3edb9508 8605b791b9531c4605cea297fc3c7dcf1e6d3a39133beeec8e7e392114cc2a56 33f2920eb5ddba07c65ff01c534d3b45cbe47207d93fa4321dc39ae5f9a45110
+point_to_wei_x_y a7462c407155d3bd32fbe2998b02dad535f1bb27994250c0134a20ba8d770618 7adaf08a6295591aa1cf196f797f50930debda357e8e2136d1c552893976302a a08f3764f6d4f5cd2fc3c643c2aed2931c92cdd6f91faf71219786b863637841
+point_to_wei_x_y c3a5bde429caf6d1408fb121bf67f2c2d4a82c9c06939d1360fb2231d992046f 544af520bb7b0dcceb10d2bba64b2017a4760ee6c47b14120e6846573c69bb6e c7533c2a99acbca5a9de157fb0041537d1416b34eb14a599afa670428f97ff62
+point_to_wei_x_y b5fd4f6be3cd2b3caa362a9466066c669f29bb5cd55103ca00f10f5c5cedf8c2 bb94c7fd08fc375f37f01c50264c2ec7a46b48517c6d584606d4a0c8753c3514 f551a6e4d388afefcdefc01290da76551eaa0a1aa23f08ab74cf6621953c4515
+point_to_wei_x_y 9a2520dcc66589e94784892e14c4873fd9e146df13776cfa030da0599391aab5 9edc195a7383015fea6f4e74a84683dc8bc609132cbdea00e256685b58917c73 4780451006ed9e02cfb72a1a38fd66250bc7a8d76846042b2790a0e049ad282a
+point_to_wei_x_y b00605959d6de17fe05c143a910eaf71338ef762024441992c8792bcd7476232 4da2af4be11d9671453bf5da2c2e81eaa0f9397e14b206e3ae832ea1f8df3a23 60b87462a119dbaa843c46522bc06dde4a4ae180b7d27b7f3cb3d88e5f6e832b
+point_to_wei_x_y 4dc168ecaae49c4901e8e6bfb3e6a421c634306191de079b79da230dbddaa489 f1bce9097477d8718e763b569ea0863e57d662af98c196421e140cab814fe715 2b175f5c797aaba26ed124d6314566d2007a974829cec35961b35319a985d60b
+point_to_wei_x_y 86f079405aa2fdf4e7ee7ec0068e17a9f408899d3d3e871a5f417e9b8bde01a3 43c0a2011906d759b16a6f52b9b021621e4c0cffd84785866f56f2d0813a0758 129522b9c1ae3402e344f73b9a0279d42f95568c006dc936f7f4d10891cbc213
+point_to_wei_x_y daba9177331ee44cc2bdfaa85973bdc376651ea37ce7cd9ef448fe2a75b4eaf7 cb0acb610699b35154e39dd3d882818481f921021244e234324e3ee792306055 f7ddf487baadd782b8440ea614d6e4e547c5f8a1bf1f85d71e1dd8fbaf8cf065
+point_to_wei_x_y 8c551adfeb64b1c29a9505b20a27060dbb89d189afe725330644504bcd455180 064608ea30a29a6004157ee58633759e465f2e9d374c69c2cbcf81e1743b9141 0a915f92500579aed64b28b7dd7bd209f8c1906bcde244333fa568becbeef11b
+point_to_wei_x_y 075f5b4136f77f07a62ed79b74eb629a4abd0a7b44a2d49b57949de15d5f0e4e 4c5a40b98c6d20b4abf7e5acb1f7e8e7e6410c45fed6fa2e8592c9e86dfeaa0f aef00c1438f6243e3cea5ed143997976d01a2011d6ff8f15491c07d8eefca137
+point_to_wei_x_y f0658113a4bd34312f030ba2ca4e39bd51914afcec2e95914080ae5e78af3caa 020e80e25a121ff1d9186ff7b7679f9c12f7bee67cb903903ca03e1906af662e c617c00277846a5f77bf0178093d01b1ce5502b4a0953fea2dbc354a205b0b3d
+point_to_wei_x_y aaeb1244f1dbdf41492ef8e18a543215d0d4ea309b8e19d75bb908f7ef9eb9f7 80ed727d12cb10be335dd3579799a37667f405d315241a4af8e17964af74b24a e7f6613e6d48f45c64908fd4278f646b4f0be0f36bfed00cff884bfbbc577c56
+point_to_wei_x_y 01c21f22d164f0e0ecae224367eeb6a23f3214c6381ed470a90868c2227fac4a 72e6977f5a4e72ed297cb6f5b73c643a064bfd4fdee153c26cf2a5c46ad92b00 a7a888dde78bb2ceb7220d7f42b7eab3007aa642c6692f64d5a96aff3cf0d64e
+point_to_wei_x_y cae0e00afc4942cb72cbda94c604b57b2620c506182b2b62bc2b69011aba8810 ff69279a879e77ac81c22f0ee05451b68af2f5c30923a64ed6f8ab8e1a7e5b28 8c47306757c92b06a48b72eac44769e540ead8895188232e79459bbbc6b68864
+point_to_wei_x_y 720fc44d776b14a34c69fb8f842e334fd199db0456229c93a6accab7d125134d f4b85ab191d9fd2b9a84f4295ba5a64ec2a5ca00b264234c9fcc27040981da08 60ff87edb67feb30817b73498f299a714b93439ec28df9f46cd9e2d03989f33a
+point_to_wei_x_y e03b7e902bd1a20c81bd3090e1db451bdebe34d0b2fb92ef1e79ecb86c39051c 6a547a52b338bab3f3830a03976c31e05063c2810f121b677380a7af94575d0b 65063b90dd30e383ee4288c921878c3360ba65070671f0db64bf6a5716db5b52
+point_to_wei_x_y 5849808e426bd1875f3298d41590e1e1423153077677e7b0cabf3d84f36a9b73 ab883c75c17a001d3a511a1f74bf9948c7fea479c7c24dd9c1c955883b98b47b 98a9ef9d0c3f45bdd7752ca90be78652aeb358e7a5f7153233a3e554929f3f61
+point_to_wei_x_y 671118dd9fcc5f62de63768501b81240703b96e777aef02d3a47e9ded60fb042 562a89245279c8ae2d579aaad8e6e2af65291fd3124413173eec0b9d0344f86d 264041dd6c0c6d24b7d8d4babbb61f2b9e43569d0e313be80665ebc77d121b1b
+point_to_wei_x_y 2f40fc31988f89ab9fc6593df84890702f789c1ac5482493beb7e6098ba3e67a 041287ca4dc3bdc972269108679f69604ddc0ac96e42c3c4d2102f212dd9d452 dc42349c4cfa782d84d798eaa2ec1df9a685fa3caff7d9de82c1edcfb6413e6f
+point_to_wei_x_y 256b74e3bfd40e7df41fdc42a1365111e37820f599860fd08174ac3e519c3a1b 1e2abf568b5eead3511d472c493c124df7e3991705899c8d4263884edf7ba73c 2d03adbcc151cc49eeb6480476750a1d36a09d3c06f4132fef908739d9cedb58
+point_to_wei_x_y 33d3d33a9ce671f73c6527919aa0d589d83781775aff22ff0361ec4d3da1961a a38147204f84d2d9426bd08fc7928c11983c6ab966c83f6fd93259558de07200 2578ea52f30518ef5108641c0fe9d66be0bef214d906d63e478c765cf33ee017
+point_to_wei_x_y 34fe2c64f6ba7962e4e3046e571ab63b24ab39837a20cdb3f1d43ca55d19f3e1 08dc80f48a0415d85662ae1803273740b8f9eae2ac531250398c0f532b1cb024 53caf0b98f016fe55889fa4d2e55e5bf8d3caba069b75d392febc76c29e8f37b
+point_to_wei_x_y 67e51c2a70794f6c947d2b751fbe1a22c8bd2370b525d387cad99254aca3d39b 5533d10547a5d2012c21fb1a0fcee6f47f541bbc3358732063b55db491b2a432 cf2a19d0fb538cc82b1ffb79f86c2db8a54c85bf108efa606a62bd2f7888914d
+point_to_wei_x_y 26a261beba5200268ee12efc671c3fbbd0657cabac536d5d678a359429b2a03e 6612a6dc46432762eecfd7c614aa5b6b075c4f3165eb43fe6df9483a15f2cc46 d890be0d54b4648abef0c6284123dabd8ac88750d9d298deec0b8d5aceed140b
+point_to_wei_x_y 223392bbc9627e8f3a8bbb83ee07a7368fc9b8077ddc13087534136f923a6fdd 1c99935e8070d403e1295524cbbf768a7412090c2fb72d56a2820150bd28f00f 210f42999e0c83bd5c967d610d443358115397213cda1ebd5486c3f1b521550f
+point_to_wei_x_y f4692ec5d9a8958d066017de8e69b97fd5fe4ea6a72f74298bb9d0e348402249 a28dd0997244a94e70ae7f17e5b670c9409fa6f01207e73cfc49c3d88254341b 1eda724d651d9078b02c4ec0b86051428f5539289c3d8781246a975ec1824c60
+point_to_wei_x_y 6fb90db7238f27da5a014c9beef3ca7d85c7f3efbf258af95691df67010a6855 1d2b79b060a613a889f914e6c6131eeedce66ada0c2909b9d448843e5c2a7b6d 23a38f62b0e54c2d632da9b51af55087840db0e045ba4746e73b0998beb6c35e
+point_to_wei_x_y d06976fa132dd8156e0f0a64ca56bf2d46dcb3580e6a505a6f85c63c9ef421a4 2579702ec276fbe88a811e270f1119847abd6ae3573d022f5f92c32070650774 8de5fb1b5bd4762aa434cb459e264ed0fba70561b0f91577ca1581f57863e468
+point_to_wei_x_y 0ac39e265daf2600c3278ec306c67fd73e5fa1bbef3b1095592918cbd893e7b2 cc277c6d11d1968726e77265ce4b64d70bc8ec60573d6f747d2c9ef531fa3649 9bb1424d1db435f70adf6fa0128727cf61fe0762a1567931fb75d5f4431ab138
+point_to_wei_x_y 0832e8ba4df998c830172b8f5ca78d3489fd4034921db66d03098b9d6e7565a6 8275425580d144a458ac2359c69b453d61d67b72d1a07ef3a1a26b97ae39617b e7b7d10ab4182bd0f94ab882f52220c673953cdda00a55a8019827d3438c5f55
+point_to_wei_x_y ce4d0234d1a4014ad349c15f82d3fa2466f52a9887693e40d25ac56330ddb559 f7e082ae02abbb8eb61e2502bfd74600955f2ad6429a64431c059272f42cd257 c801a2ed709bc1b4cef50e1f8e20d43b8f8c4a344de58f57e3cc93391a30c277
+point_to_wei_x_y 459662dc4e0c780828281fd63720c4e152b8e4715bdd8c1449b29bf3719e9017 5d469ad1aa2577924da7bde6c02c67f2cca2839e96d4c3ae096390b8792f666e ec9fb4b91f9a890da52694c21efe447f5dda6fd1374defc9f96fd0b19fe5d250
+point_to_wei_x_y 4e0e49093e7d7de35e3635f95f1553dc1ad1f648a439b30d0a970b853dbd766f d713a297a759193018c68d14f2c3f9eb0a7e9dbfce7375e33e6c1157f56d676a d044549dbf9b64ae119478e0cd78ef2a4e8e9057826bce28b3acc3d493048754
+point_to_wei_x_y 31171b0bde9dfcfca587c2f24c7d4b850b290cc76236f2f95deefc2f50fe2f97 13c5d9f4e8342d0efbea281dd1c2e97ddf3978540d6603adcffe7fe49dc5d120 c92879c1760a99e2dfaee31df31f4ddc6452ff92fbc75ff41cd478751e7b0e0c
+point_to_wei_x_y 3614a81a4db8c39986fb3715203d8045bd09072d81da24360de2a5d269bfd935 f06605108d4cb94c99ee58f3b8e8a6766e583c57d49939e9c2ef3e4b47bea078 6cd8cfcac12e08a5e7fd2aa85a7b38bacb38cac8a1efc982acc18c996b7d0740
+point_to_wei_x_y 88d2acf4014422c754d5b67e3faba8389c4b7afc6216d0e68974dbe18863cfac 30db8807076660fbd7a2702aaea4a6a2b7f8554e3cc4bced2200790579165f60 5d3a136cdc566bdd7165092931a074658f260a88a37fee91de74372ed19b9b4d
+point_to_wei_x_y 6b07880b22b55e186a8262051fc9d72ee74419a7603f33feb68cb82f448e9820 b145a928db823205386beedf8a81503c6c10107ba36454e33955d8b3f89a1d04 af8929f153f227cfa5a7a643679089c1569332f425ca0d46f54e04ed0eeafd1f
+point_to_wei_x_y c3fae32179634536eca274fd3e5bd42fcbcfbebeda0a8aed49fdaffcf4c9fdce dc83c6668e2a6a3f4a0523c9ef99e6ac45eeb842c79807a14d2554d6f79cdb7f 39fcb80c1f2b93ecdf4420397817561391ab0971db09f2e43471371fb0fc2873
+point_to_wei_x_y 02e960342425961674014d7f902599b4697bd0e11bfa63f1f63478999f8d675e 21ec060cd3d4554ae94b3b6216a6b9b34dbdc3254f91567f1de20b312e806d44 a30346dc9b54ed3376ba3624719a9e4643e74009bd7fb97ad394eb2ab5c38542
+point_to_wei_x_y 66ae764eaa33de22cb4028f3e77d597bc50c5ada3002bdbcc808c946d3f0febe ab229695f8fb007ff6b0e94ef117da31c10d1614edfe6ed2c76062a856026e5f 5c4961a9ce61052c7c38b3086a7eb1663b3d9a61113bb9c7c82c472bad12eb1e
+point_to_wei_x_y 6c4847a491b3e91747fb701a36700eb993d5152a23cf6a39ac32352e0b054888 e88e31b7458fd3fe3499d1f567c71d29ba6b9f9a4eec25b7358dca25173edc09 360c3bddf4848d4b46780282bfe2276e0e29252c18a4536c6b54b7c0fdd3b314
+point_to_wei_x_y bf14ec038d85c18c75a7dca922c88165bfeeb8a47f25432f7d127bc74ff5e493 f95f19d285cf008710ca94b21af2e8565f0ec0e68483249ae12bc5cf85a0cc1c 486089ea042e38e102f3a531ef6ca41840f884c01c7cb9fcaa33e558faab6943
+point_to_wei_x_y 888be5a338b73870be490803cf00ef9af57a5a80ce6e53dd777d0bc126824ba7 bfccdc168d59fe1ff122bd91fa447017beba3ef59f7b78be49ce7e72587ddc0a 59ec180787f986fb6f13a3d426213e077512777338311f4c852cbb171d7db602
+point_to_wei_x_y e4b51f1976b66870a41eafd72e72072dc3caa56eed593b8ae008da432a232b66 57e341d2b32b2aaa5e4bd9f8b0beb23eacd153de6c24c72425d215acbc22a576 643eae47d862e2014ab377d78e1cff4bf938be83349e3f7f472729acfc55d91d
+point_to_wei_x_y fa6298012493abbe330a114fba1aaa1416a04ad89ebe755b1576a8acaeb56c09 1812b25b98c3ab49185ccc6d11cf24b63e2ca1230d7c72a018bcd31ba3e25656 0a1e88d92ecd7159041a1f544e269e21a1a18297457c965d3c0e4d7cd4dee73e
+point_to_wei_x_y 335f7273f399516405ff1e43d5612bb4f759502729ddb33a45f9023dd59e9e73 cc99c41d2e234ae2a06f9e7d1c6dabd1a2bb532d2169d0a1b954207665c52e40 20aa771e2f9d83174e3aa65e128cd76d554f9767989024df8d024c8c33377a3c
+point_to_wei_x_y d39cd4e6b3a008d88c63d0458f60d683f2a1bcb7133cb69b20627edc53a950dc cf5c5886834053069009858f5dfcdffb5ba6b0e576e90540c192a90f078aac7a b10346b3063e2d9127bc85d8df329b0f2ff1eff7f66d73ea3aa5f60b7649a15a
+point_to_wei_x_y e11ca97deda6e661f995d3727962046cfe2f36d98e7e17433c5cad9772fb372f ba0b4cb9eb96c0d54c77f744af61e84f3a77d30f13b1026955dc7724b8851152 a99537b6aa47758ca774e26018f3e624a657696603165e70e4f4e6f9290b686b
+point_to_wei_x_y 8f6bc60b5e3a09b5f603ed5d304c224346f635e24e99fc19407aae034960a7e4 0ca10bd420cc858fc8932428c14a5871efc9ea7990b3beb5cf09514044f6c635 07a3098da13b081a04f77e7c52563fd7c4ab28582d05dd11e337267c84fdf808
+point_to_wei_x_y b40487632d252fb54e86586720f1ccdc581f2a1f71571c1c7e675f6922f34900 462d9e5fa6023f43bfde63db5297b50ec38fb4cd698cfb99ead57519febf5c1e b8474c83743e779ae83c50d6a0b65f24b135f0bd244ffd735e5b8d6daa9b1407
+point_to_wei_x_y 7b5dc3036612d38132ce6681713431aa3659f805b78fa18e86009e8595aa27d0 549e5dc37037da8155434a7651a0cfb5d1fcda316edddedceda69d8a0c909e6b b9a0e46f4dc12c72f672a99e6eb2885c7d923df0ee3edb119dbe2a19cae82553
+point_to_wei_x_y c4092a49ee9a033883c2f2af9588b25bb06faed117dd84f7460adbd8a91734d2 11dd5a8aa1f970acc1c1709ed2d6a8a0718ea455fa243455ab25d3d30304343e b17199f31e269cc490aea95ab3b8be455a6ad45232402e4909fb3a9c17c69d20
+point_to_wei_x_y 0fbb8c6731a7d20d602b61d2c65ff2b075582253c957a2d2b59b35bdca8b81d2 f7f3103848c674542a500ca2d56d8033895d4abecc3b8e161f1b07f17e28eb73 7d956db0b82d071d4f6f0adb49c85c694b80c14ce0e007377533923823017e02
diff --git a/tests/unit_tests/crypto.cpp b/tests/unit_tests/crypto.cpp
index 2cd260c..e0e4713 100644
--- a/tests/unit_tests/crypto.cpp
+++ b/tests/unit_tests/crypto.cpp
@@ -388,7 +388,7 @@ TEST(Crypto, batch_inversion_touching)
for (std::size_t i = 0; i < 2; ++i)
random_fe(vals[i]);
- fe_batch_invert(vals + 2, vals, 2);
+ ASSERT_EQ(0, fe_batch_invert(vals + 2, vals, 2));
// Do batch inversions and compare to individual inversions
for (std::size_t i = 0; i < 2; ++i)
@@ -521,3 +521,56 @@ TEST(Crypto, mul8_is_identity_vartime)
ASSERT_FALSE(fcmp_pp::get_valid_torsion_cleared_point_vartime(rct::rct2pt(point), _));
}
}
+
+TEST(Crypto, fe_constants)
+{
+ // A / 3
+ fe inv_3;
+ static const fe fe_3{3, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ fe_invert(inv_3, fe_3);
+ fe a_inv_3;
+ fe_mul(a_inv_3, fe_a, inv_3);
+
+ // c = sqrt(-(A + 2))
+ // Since sqrt isn't implemented, instead showing: c^2 = -(A + 2)
+ // TODO: test fe_c directly once sqrt is implemented
+ fe c_sq;
+ fe_sq(c_sq, fe_c);
+ // -(A + 2) = -A - 2
+ static const fe fe_2{2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ fe ma_sub_2;
+ fe_sub(ma_sub_2, fe_ma, fe_2);
+ fe_reduce_vartime(ma_sub_2, ma_sub_2);
+
+ ASSERT_TRUE(memcmp(fe_a_inv_3, a_inv_3, sizeof(fe)) == 0);
+ ASSERT_TRUE(memcmp(c_sq, ma_sub_2, sizeof(fe)) == 0);
+
+ // Parity with spec
+ // https://www.ietf.org/archive/id/draft-ietf-lwig-curve-representations-02.pdf E.2 Page 19
+ unsigned char A_INV_3_PAPER[32] = {
+ 0x2a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xad, 0x24, 0x51
+ };
+
+ // https://www.ietf.org/archive/id/draft-ietf-lwig-curve-representations-02.pdf E.2 Pages 19-20
+ unsigned char FE_C_PAPER[32] = {
+ 0x70, 0xd9, 0x12, 0x0b, 0x9f, 0x5f, 0xf9, 0x44,
+ 0x2d, 0x84, 0xf7, 0x23, 0xfc, 0x03, 0xb0, 0x81,
+ 0x3a, 0x5e, 0x2c, 0x2e, 0xb4, 0x82, 0xe5, 0x7d,
+ 0x33, 0x91, 0xfb, 0x55, 0x00, 0xba, 0x81, 0xe7
+ };
+
+ // Reverse to have comparable endian order
+ unsigned char a_inv_3_bytes[32];
+ fe_tobytes(a_inv_3_bytes, fe_a_inv_3);
+ std::reverse(a_inv_3_bytes, a_inv_3_bytes + 32);
+
+ unsigned char fe_c_bytes[32];
+ fe_tobytes(fe_c_bytes, fe_c);
+ std::reverse(fe_c_bytes, fe_c_bytes + 32);
+
+ ASSERT_TRUE(memcmp(a_inv_3_bytes, A_INV_3_PAPER, 32) == 0);
+ ASSERT_TRUE(memcmp(fe_c_bytes, FE_C_PAPER, 32) == 0);
+}
Why this scored 29/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.