diff --git a/src/crypto/crypto-ops-data.c b/src/crypto/crypto-ops-data.c index edaa4644f..c5b0b08d4 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 788dd4d6b..12745cd68 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 7b0cbc487..7b6b9ffc2 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 4a6b20a57..da3ae135a 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(scalar); } inline unsigned char* to_bytes(crypto::ec_point &point) { return &reinterpret_cast(point); } inline const unsigned char* to_bytes(const crypto::ec_point &point) { return &reinterpret_cast(point); } +inline unsigned char* to_bytes(crypto::ec_coord &coord) { return &reinterpret_cast(coord); } +inline const unsigned char* to_bytes(const crypto::ec_coord &coord) { return &reinterpret_cast(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 39b95dbbc..313c11bb7 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_batch = std::make_unique(N_ELEMS); + std::unique_ptr inv_res = std::make_unique(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 d1d2b1bd4..8af4ae164 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(static_cast(0)), static_cast(static_cast(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 913f8abfd..ff644e1d7 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 32e3b2d09..2331e33f5 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 2cd260c9e..e0e47130c 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); +}