1
0
Fork 0
forked from lthn/blockchain

point_t::operator==() fixed and optimized + various tests

This commit is contained in:
sowle 2024-10-12 03:01:33 +02:00
parent b1c70ac2bb
commit 5d15ed1c15
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
3 changed files with 197 additions and 32 deletions

View file

@ -812,26 +812,7 @@ namespace crypto
friend bool operator==(const point_t& lhs, const point_t& rhs)
{
// TODO: @#@# (performance) consider checking (lhs - rhs).is_zero() instead
// convert to xy form, then compare components (because (x, y, z, t) representation is not unique)
fe lrecip, lx, ly;
fe rrecip, rx, ry;
fe_invert(lrecip, lhs.m_p3.Z);
fe_invert(rrecip, rhs.m_p3.Z);
fe_mul(lx, lhs.m_p3.X, lrecip);
fe_mul(rx, rhs.m_p3.X, rrecip);
if (memcmp(&lx, &rx, sizeof lx) != 0)
return false;
fe_mul(ly, lhs.m_p3.Y, lrecip);
fe_mul(ry, rhs.m_p3.Y, rrecip);
if (memcmp(&ly, &ry, sizeof ly) != 0)
return false;
return true;
return (lhs - rhs).is_zero();
}
friend bool operator!=(const point_t& lhs, const point_t& rhs)

View file

@ -317,7 +317,7 @@ inline std::ostream& operator<<(std::ostream& ss, const fe &f)
{
constexpr size_t fe_index_max = (sizeof f / sizeof f[0]) - 1;
ss << "{";
for (size_t i = 0; i <= fe_index_max; ++i)
for (size_t i = 0; i < fe_index_max; ++i)
ss << f[i] << ", ";
return ss << f[fe_index_max] << "}";
}
@ -490,14 +490,6 @@ struct test_keeper_t
};
////////////////////////////////////////////////////////////////////////////////
// #include "crypto_tests_ml2s.h"
#include "crypto_tests_range_proofs.h"
#include "crypto_tests_clsag.h"
#include "crypto_tests_one_out_of_many_proofs.h"
////////////////////////////////////////////////////////////////////////////////
//
// Tests
@ -609,8 +601,6 @@ TEST(crypto, constants)
#include "crypto_tests_performance.h"
TEST(crypto, ge_scalarmult_vartime_p3)
{
// make sure that my ge_scalarmult_vartime_p3 gives the same result as ge_scalarmul_p3
@ -1501,6 +1491,86 @@ TEST(crypto, point_is_zero)
return true;
}
// pairs of the same points but with different fe representation (that caused old eq op to fail)
std::vector<std::pair<point_t, point_t>> twin_point_pairs {
{
point_t{{-21128868, 3837998, 33062696, -4394645, -14632370, -4032942, -13494326, 9949403, -22877702, 12347080, -23842113, 10741520, -31317130, 13501783, -30346713, 9537971, -4230538, 5133263, 19202715, 304530, 11783766, -14713954, 31928743, -15802260, -23524982, -12132264, -2221079, -13294882, 15351986, -12208940, -25429666, -10630821, 10586935, 3680531, -5196293, 15100068, -4109273, 2588076, -22807834, 9178747}},
point_t{{-9713365, -9829929, 12195149, -3403928, -26261133, -16229257, -31293898, -3007350, 14656870, -441189, -21842901, -10684017, -14933612, -15577968, 6355936, -12616303, 17881365, 2613091, -29791631, 8160616, -6564960, 3860717, -32409761, 10253039, -32570848, -3563771, -7755841, 14547843, -12480489, 13372339, 21802122, 15976373, -16158840, -2718080, -16676669, 14276439, -7192951, 11049430, 27384949, 10563297}}
},
{
point_t{{3695219, -9621154, -17709499, 2939106, 3744267, -14575097, -23519506, -10091102, -2604099, 14269408, -3229226, 6334758, -32391005, -2351680, -8798530, -2266840, 32921382, -2519414, -18691041, 3881653, -15053990, 9136740, -3226527, -4942926, 1506694, -9001375, 27935490, -14623776, -3948473, 4210796, 18939736, -15596865, -13293120, 1337568, -18317440, -5143258, 16723454, 14691110, 9769827, -3118966}},
point_t{{-11397382, -16642076, -15110371, -3127178, -20841265, -8333469, -8416820, -11641211, -24444275, -1309821, -3258975, -14590075, 2704495, -11408556, -1158440, -13417600, -17702918, 15792391, -17674166, 7544500, -30233403, -6317281, -29573467, 13768629, -1805743, 10305936, -5964981, 2553131, 25279025, 5554228, 24015913, 3005849, 25526408, -4040648, 14468366, 14790756, 25816013, 15853930, 18508209, -16582046}}
},
{
point_t{{3469318, -85183, 29056087, 13528494, -23149977, 16623454, 3373881, 7763807, 24097266, 11526397, 8089099, -2103871, -32120521, 1046529, 28087844, 6858112, -27963932, -3359170, 21430085, -5312246, 21764518, -13443543, -12702889, -12398634, 10157405, 4858225, 26174527, -11743221, -30269431, -10050502, 25862179, 4744514, 32296603, 6270322, -28198957, 1471820, -13801749, -3295909, 17760181, -12065527}},
point_t{{-28763218, -1114036, 4671232, -1599732, -14823984, -9622687, 15430161, 12840558, 30741788, -11449341, -28556261, 3623611, 25689145, -14680141, -7832784, 14819387, 2481189, -13167197, -28732414, -14312280, -32965162, -7714625, 33268896, -2408169, -10811971, -4363847, -26138329, 5165910, -18544903, -7502120, 10360740, 6034706, 28458994, -5675091, -28036374, -702149, -8660662, -13290682, 9067253, 4344694}}
},
{
point_t{{-5841866, -15636514, 12367718, 16116867, -26645766, 5140632, 33476033, -3893277, -6807986, -6188111, -18150893, -7313585, -22559821, 14208716, -5344811, -581281, 24672694, -6638035, -10808134, -3046, -7472033, -8901879, 15120908, -7133930, 15015498, 12440181, -27737720, 396004, 3105271, 11399924, 12739797, -10781030, -27655617, 10547004, -1517603, -14788397, -16728565, 5538806, 27633091, 5635300}},
point_t{{29738502, -9099722, 18969328, -5041586, -17865763, 3799509, -8535672, 15345696, 760867, -3647512, 21227601, 2877796, 21366975, -5870266, 14750680, 10962526, 10279514, 12394109, -15626344, -10182797, 3199874, -24046, -14148768, -14198371, -29493512, -16221096, -3714752, -8636183, 5751940, -7670476, 1204040, 8561908, -16290929, 13125810, -24274070, -7039328, -21149730, -9157888, -16370207, -4817989}}
},
{
point_t{{5583931, 3584727, 352648, -3282339, -25634902, 4982415, 6570289, -7123343, 28056356, -14753772, 15464638, -10030089, 13934473, 10182538, -32633085, -3344322, 10345546, -6010634, -11737756, 7740657, 12017410, -3538127, -21949796, -16720911, 18521392, -7746707, -25163322, 16438097, -14488853, -11100914, 11664826, -4058927, 13298397, 10849774, 22800849, -8941814, 31033013, 362090, -20721545, 10379502}},
point_t{{-15413065, 10389318, 28684750, 9129051, 13176029, -15599624, 16333382, -15196190, 5299760, 5379067, -11298666, -10943555, 24033630, -10331364, -6271762, 15703052, -6168555, -10342077, -17144019, -3303678, 32460403, 15294706, 19144257, 16248865, 22506488, 5505084, -401821, 9347950, -6513204, 7226066, -26715856, 11994906, -13302883, -8556677, 15797496, -3086516, 23027165, 1637560, -29381930, 12262558}}
},
{
point_t{{-26548919, 11392979, 28773327, 197314, 13888676, 5289903, 14156094, -3215467, 12204802, 11098576, -15494111, 10812748, -11869915, -343850, -20456404, -12577384, -4979562, 15251598, -487043, 11571657, -16066121, -2338179, -16228507, 5602197, 25353942, -7225080, 22718433, -11309476, -10403076, 11326705, -296493, -4563931, 10628858, 16672320, 24967340, 210989, -11332864, -13045242, -32517393, 9220843}},
point_t{{-8809414, 1276711, 5724117, -10893002, 16836911, -10562554, 7928860, 4905731, -30890761, -16272783, 15099435, 7209265, -17062927, -15647371, -26068760, -10022538, 15199805, 11039218, -17427534, -3334404, 9597778, 5993687, -14091491, -6035380, -18428597, -4056089, -14203111, 349297, 20316350, 1399705, 2972501, -1228750, -23459865, -88574, 9071309, 11300857, 9425425, 596628, 3627198, -1613531}}
},
{
point_t{{-15051466, -12717864, -1094059, 9523511, -9851421, 6693669, -6491711, -14360212, -10025337, 5146942, -15213537, -14748468, -16189919, 6643542, -22303813, -6712277, 12722420, 3747576, -11411745, -5170831, 6906842, -3442874, 13923053, 5056698, 14272344, 2297302, 24147707, 1505741, 23445765, 7170090, -14014582, 6539085, -25379082, 15881906, 9955130, -10830876, -6331971, -9745690, 19301861, -3693027}},
point_t{{-23568458, 9628844, -26909663, -2205696, 16765570, 12703337, -19733659, -1311798, 6240000, -3186465, -12848561, -9029739, -21391036, 5644922, 29142361, -8070730, 15491500, 5159583, -15039215, -3782415, 17864864, 13111010, -24101940, 9297110, -23296716, 9763494, -33210081, 12312114, -30144102, 10080914, 31682399, 7452145, 19314287, -7581029, -24620989, -3233342, -25926522, -14260964, 24233736, 13681782}}
},
{
point_t{{19211265, 2757185, 22841428, 4384196, -5344236, -6665958, 13817937, -15401311, 11324591, 13548371, 5920675, -7720845, -26190512, 80906, 11282325, -16150822, 18149158, -15519773, 2721716, -11983296, -14418387, -11153557, 13957160, -3743225, 22506862, -3245854, 4494361, 13510745, -5656988, 5588269, 28354819, -13495704, -13208982, -495328, 17363458, -10857316, -5302126, -7875123, 26008688, -13624830}},
point_t{{9615635, 11456756, -23929642, 1059944, 1030437, -11895019, 12717341, 14376320, 18760933, -13214228, 28877065, 8204034, -13488237, -4234088, -16433228, 12293567, 22065763, 1258393, 20249733, -7792923, -28493355, -10099755, 9817133, 10497183, 7163689, 3742107, -24288334, 7485474, 17332829, 1167562, -7414283, -2724061, 32933754, 3732809, 18401256, 10890894, -28075941, -4870953, 21081310, 10942194}}
},
{
point_t{{15697801, -6534008, 10450035, -1554623, -18762845, 11804480, 30164267, 4203906, 28533676, 10647395, 30633476, 9271811, 8721644, -7564181, 5372849, -11987056, 21870223, -770830, -23302500, 5628035, -12397032, 14456892, 14966767, -4384854, 6238573, 5721532, -3482707, 93803, 17582081, -8642913, 10405075, -7178396, -5588624, 15751945, 21474071, 14634321, 2195436, -9319762, -31171521, 3257219}},
point_t{{-9159868, 13485045, -1816502, 9498441, 12599869, -9143471, -3235081, -7400456, -11042456, 10726811, 30758369, 2034330, -10446636, -12818157, 15789290, 11476501, 12893075, -11738407, 5385991, -11602328, -12578961, -5727994, -3242915, -14123261, 18142422, 9302871, -27881894, 1412251, 13445358, 3794224, 30076600, 12194158, 27928330, -11549668, -21526967, 908741, 7889436, 11312182, 479283, 3079906}}
}
};
TEST(crypto, point_eq_op)
{
for(auto& pp : twin_point_pairs)
{
ASSERT_TRUE((pp.first - pp.second).is_zero());
ASSERT_TRUE((pp.second - pp.first).is_zero());
scalar_t r = scalar_t::random();
ASSERT_TRUE((r * pp.first - r * pp.second).is_zero());
ASSERT_TRUE((r * pp.second - r * pp.first).is_zero());
ASSERT_TRUE (pp.first == pp.second);
ASSERT_FALSE(pp.first != pp.second);
ASSERT_TRUE (pp.second == pp.first);
ASSERT_FALSE(pp.second != pp.first);
}
//// twin points generator
//size_t N = 10000000;
//size_t hits = 0;
//scalar_t r = scalar_t::random();
//point_t R = r * c_point_G;
//for(size_t i = 0; i < N; ++i)
//{
// scalar_t s = scalar_t::random();
// point_t X = (r + s) * c_point_G;
// point_t Y = R + s * c_point_G;
// if (!(X == Y))
// {
// ++hits;
// std::cout << hits << ENDL
// << " X: " << X << " {" << X.to_comma_separated_int32_str() << "}" << ENDL
// << " Y: " << Y << " {" << Y.to_comma_separated_int32_str() << "}" << ENDL;
// }
//}
//std::cout << ENDL << hits << " hits of " << N << ENDL;
return true;
}
TEST(crypto, sc_get_bit)
{
@ -1985,6 +2055,15 @@ TEST(crypto, eth_signature_basics)
////////////////////////////////////////////////////////////////////////////////
// #include "crypto_tests_ml2s.h"
#include "crypto_tests_range_proofs.h"
#include "crypto_tests_clsag.h"
#include "crypto_tests_one_out_of_many_proofs.h"
#include "crypto_tests_performance.h"
////////////////////////////////////////////////////////////////////////////////
//
// test's runner

View file

@ -1,6 +1,8 @@
// Copyright (c) 2021 Zano Project
// Copyright (c) 2021-2024 Zano Project
// Copyright (c) 2021-2024 sowle (val@zano.org, crypto.sowle@gmail.com)
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
#pragma once
#include <numeric>
@ -1233,3 +1235,106 @@ TEST(perf, generators)
return true;
}
bool old_point_eq_operator_bugous(const point_t& lhs, const point_t& rhs)
{
// convert to xy form, then compare components (because (x, y, z, t) representation is not unique)
fe lrecip, lx, ly;
fe rrecip, rx, ry;
fe_invert(lrecip, lhs.m_p3.Z);
fe_invert(rrecip, rhs.m_p3.Z);
fe_mul(lx, lhs.m_p3.X, lrecip);
fe_mul(rx, rhs.m_p3.X, rrecip);
if (memcmp(&lx, &rx, sizeof lx) != 0)
return false;
fe_mul(ly, lhs.m_p3.Y, lrecip);
fe_mul(ry, rhs.m_p3.Y, rrecip);
if (memcmp(&ly, &ry, sizeof ly) != 0)
return false;
return true;
}
bool old_point_eq_operator(const point_t& lhs, const point_t& rhs)
{
// convert to xy form, then compare components (because (x, y, z, t) representation is not unique)
fe lrecip, lx, ly, dx;
fe rrecip, rx, ry, dy;
fe_invert(lrecip, lhs.m_p3.Z);
fe_invert(rrecip, rhs.m_p3.Z);
fe_mul(lx, lhs.m_p3.X, lrecip);
fe_mul(rx, rhs.m_p3.X, rrecip);
fe_sub(dx, lx, rx);
if (fe_isnonzero(dx) != 0)
return false;
fe_mul(ly, lhs.m_p3.Y, lrecip);
fe_mul(ry, rhs.m_p3.Y, rrecip);
fe_sub(dy, ly, ry);
if (fe_isnonzero(dy) != 0)
return false;
return true;
}
TEST(perf, point_eq_vs_iszero)
{
const size_t warmup_rounds = 20;
const size_t rounds = 200;
const size_t inner_rounds = 64;
std::vector<uint64_t> timings1, timings2;
size_t N = inner_rounds - twin_point_pairs.size() * 2; // number of random points
scalar_vec_t scalars;
scalars.resize_and_make_random(N);
std::vector<point_t> points(N);
std::transform(scalars.cbegin(), scalars.cend(), points.begin(), [](const scalar_t& s){ return s * c_point_G; });
// add twin points
for(auto& p : twin_point_pairs)
points.push_back(p.first), points.push_back(p.second);
ASSERT_EQ(points.size(), inner_rounds);
// and shuffle
std::shuffle(points.begin(), points.end(), crypto::uniform_random_bit_generator{});
for(size_t i = 0; i < rounds + warmup_rounds; ++i)
{
std::vector<uint8_t> results1(inner_rounds), results2(inner_rounds);
TIME_MEASURE_START(t1);
for(size_t j = 0; j < inner_rounds; ++j)
for(size_t k = j + 1; k < inner_rounds; ++k)
results1[j] ^= uint8_t(old_point_eq_operator(points[j], points[k]) ? j : k);
TIME_MEASURE_FINISH(t1);
uint64_t h1 = hash_64(results1.data(), results1.size() * sizeof(results1[0]));
TIME_MEASURE_START(t2);
for(size_t j = 0; j < inner_rounds; ++j)
for(size_t k = j + 1; k < inner_rounds; ++k)
results2[j] ^= uint8_t((points[j] - points[k]).is_zero() ? j : k);
TIME_MEASURE_FINISH(t2);
uint64_t h2 = hash_64(results2.data(), results2.size() * sizeof(results2[0]));
ASSERT_EQ(h1, h2);
if (i >= warmup_rounds)
{
timings1.push_back(t1);
timings2.push_back(t2);
}
}
std::cout << "After " << rounds << " rounds:" << ENDL <<
"point_t operator== : " << epee::misc_utils::median(timings1) << " mcs" << ENDL <<
"point_t is_zero() : " << epee::misc_utils::median(timings2) << " mcs" << ENDL;
return true;
}