Merge branch 'add_block_performance_mes' into decoy_selection
This commit is contained in:
commit
27bb395542
9 changed files with 2907 additions and 56 deletions
|
|
@ -307,26 +307,25 @@ namespace misc_utils
|
|||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
template<class type_vec_type>
|
||||
type_vec_type median(std::vector<type_vec_type> &v)
|
||||
template<typename container_t>
|
||||
typename container_t::value_type median(container_t &v)
|
||||
{
|
||||
//CRITICAL_REGION_LOCAL(m_lock);
|
||||
typename container_t::value_type median{};
|
||||
if(v.empty())
|
||||
return boost::value_initialized<type_vec_type>();
|
||||
return median;
|
||||
if(v.size() == 1)
|
||||
return v[0];
|
||||
|
||||
size_t n = (v.size()) / 2;
|
||||
std::sort(v.begin(), v.end());
|
||||
//nth_element(v.begin(), v.begin()+n-1, v.end());
|
||||
if(v.size()%2)
|
||||
{//1, 3, 5...
|
||||
return v[n];
|
||||
}else
|
||||
{//2, 4, 6...
|
||||
return (v[n-1] + v[n])/2;
|
||||
auto median_it = v.begin() + v.size() / 2;
|
||||
std::nth_element(v.begin(), median_it, v.end());
|
||||
median = *median_it;
|
||||
if (v.size() % 2 == 0)
|
||||
{
|
||||
auto max_it = std::max_element(v.begin(), median_it); // it's garanteed that after nth_element() the necessary element is in this interval
|
||||
median = (median + *max_it) / 2; // average of [size/2-1] and [size/2] elements
|
||||
}
|
||||
|
||||
return median;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ DISABLE_VS_WARNINGS(4146 4244)
|
|||
void fe_mul(fe, const fe, const fe);
|
||||
void fe_sq(fe, const fe);
|
||||
void fe_tobytes(unsigned char *, 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 *);
|
||||
static void ge_p3_dbl(ge_p1p1 *, const ge_p3 *);
|
||||
|
|
@ -119,7 +118,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_add(fe h, const fe f, const fe g) {
|
||||
void fe_add(fe h, const fe f, const fe g) {
|
||||
int32_t f0 = f[0];
|
||||
int32_t f1 = f[1];
|
||||
int32_t f2 = f[2];
|
||||
|
|
@ -1425,7 +1424,7 @@ int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) {
|
|||
r = p + q
|
||||
*/
|
||||
|
||||
static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
||||
void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
||||
fe t0;
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
|
|
@ -4314,3 +4313,171 @@ void ge_cached_to_p2(ge_p2 *r, const ge_cached *c)
|
|||
|
||||
fe_copy(r->Z, c->Z);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// EXPERIMENTAL
|
||||
//
|
||||
|
||||
// With these select_vartime/ge_scalarmult_base_vartime I got ~25% speed up comparing to the select/ge_scalarmult_base -- sowle
|
||||
static void select_vartime(ge_precomp *t, int pos, signed char b)
|
||||
{
|
||||
unsigned char bnegative = negative(b);
|
||||
unsigned char babs = b - (((-bnegative) & b) << 1);
|
||||
const ge_precomp* base;
|
||||
|
||||
if (babs == 0)
|
||||
{
|
||||
ge_precomp_0(t);
|
||||
}
|
||||
else if (bnegative == 0)
|
||||
{
|
||||
base = &ge_base[pos][babs - 1];
|
||||
fe_copy(t->yplusx, base->yplusx);
|
||||
fe_copy(t->yminusx, base->yminusx);
|
||||
fe_copy(t->xy2d, base->xy2d);
|
||||
}
|
||||
else
|
||||
{
|
||||
base = &ge_base[pos][babs - 1];
|
||||
fe_copy(t->yplusx, base->yminusx);
|
||||
fe_copy(t->yminusx, base->yplusx);
|
||||
fe_neg(t->xy2d, base->xy2d);
|
||||
}
|
||||
}
|
||||
|
||||
void ge_scalarmult_base_vartime(ge_p3 *h, const unsigned char *a)
|
||||
{
|
||||
signed char e[64];
|
||||
signed char carry;
|
||||
ge_p1p1 r;
|
||||
ge_p2 s;
|
||||
ge_precomp t;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
e[2 * i + 0] = (a[i] >> 0) & 15;
|
||||
e[2 * i + 1] = (a[i] >> 4) & 15;
|
||||
}
|
||||
/* each e[i] is between 0 and 15 */
|
||||
/* e[63] is between 0 and 7 */
|
||||
|
||||
carry = 0;
|
||||
for (i = 0; i < 63; ++i) {
|
||||
e[i] += carry;
|
||||
carry = e[i] + 8;
|
||||
carry >>= 4;
|
||||
e[i] -= carry << 4;
|
||||
}
|
||||
e[63] += carry;
|
||||
/* each e[i] is between -8 and 8 */
|
||||
|
||||
ge_p3_0(h);
|
||||
for (i = 1; i < 64; i += 2) {
|
||||
select_vartime(&t, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
|
||||
ge_p3_dbl(&r, h); ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s); ge_p1p1_to_p3(h, &r);
|
||||
|
||||
for (i = 0; i < 64; i += 2) {
|
||||
select_vartime(&t, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void select_custom_precomp_vartime(ge_precomp *t, const precomp_data_t base_precomp, int pos, signed char b)
|
||||
{
|
||||
unsigned char bnegative = negative(b);
|
||||
unsigned char babs = b - (((-bnegative) & b) << 1);
|
||||
const ge_precomp* base;
|
||||
|
||||
if (babs == 0)
|
||||
{
|
||||
ge_precomp_0(t);
|
||||
}
|
||||
else if (bnegative == 0)
|
||||
{
|
||||
base = &base_precomp[pos][babs - 1];
|
||||
fe_copy(t->yplusx, base->yplusx);
|
||||
fe_copy(t->yminusx, base->yminusx);
|
||||
fe_copy(t->xy2d, base->xy2d);
|
||||
}
|
||||
else
|
||||
{
|
||||
base = &base_precomp[pos][babs - 1];
|
||||
fe_copy(t->yplusx, base->yminusx);
|
||||
fe_copy(t->yminusx, base->yplusx);
|
||||
fe_neg(t->xy2d, base->xy2d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ge_scalarmult_precomp_vartime(ge_p3 *h, const precomp_data_t base_precomp, const unsigned char *a)
|
||||
{
|
||||
signed char e[64];
|
||||
signed char carry;
|
||||
ge_p1p1 r;
|
||||
ge_p2 s;
|
||||
ge_precomp t;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
e[2 * i + 0] = (a[i] >> 0) & 15;
|
||||
e[2 * i + 1] = (a[i] >> 4) & 15;
|
||||
}
|
||||
/* each e[i] is between 0 and 15 */
|
||||
/* e[63] is between 0 and 7 */
|
||||
|
||||
carry = 0;
|
||||
for (i = 0; i < 63; ++i) {
|
||||
e[i] += carry;
|
||||
carry = e[i] + 8;
|
||||
carry >>= 4;
|
||||
e[i] -= carry << 4;
|
||||
}
|
||||
e[63] += carry;
|
||||
/* each e[i] is between -8 and 8 */
|
||||
|
||||
ge_p3_0(h);
|
||||
for (i = 1; i < 64; i += 2) {
|
||||
select_custom_precomp_vartime(&t, base_precomp, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
|
||||
ge_p3_dbl(&r, h); ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s); ge_p1p1_to_p3(h, &r);
|
||||
|
||||
for (i = 0; i < 64; i += 2) {
|
||||
select_custom_precomp_vartime(&t, base_precomp, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
}
|
||||
|
||||
void ge_p3_to_precomp(ge_precomp *r, const ge_p3* p)
|
||||
{
|
||||
fe recip;
|
||||
fe x;
|
||||
fe y;
|
||||
//unsigned char s[32];
|
||||
|
||||
fe_invert(recip, p->Z);
|
||||
fe_mul(x, p->X, recip);
|
||||
fe_mul(y, p->Y, recip);
|
||||
fe_sub(r->yminusx, y, x);
|
||||
fe_add(r->yplusx, y, x);
|
||||
fe_mul(r->xy2d, x, y);
|
||||
fe_mul(r->xy2d, r->xy2d, fe_d2);
|
||||
|
||||
// to get canonical representation and obtain the very same beautiful numbers for ge_base in crypto-ops-data.c (maybe unnecessary, TODO -- sowle)
|
||||
//fe_tobytes(s, r->yminusx); fe_frombytes(r->yminusx, s);
|
||||
//fe_tobytes(s, r->yplusx); fe_frombytes(r->yplusx, s);
|
||||
//fe_tobytes(s, r->xy2d); fe_frombytes(r->xy2d, s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_
|
|||
|
||||
extern const fe fe_sqrtm1;
|
||||
extern const fe fe_d;
|
||||
extern const fe fe_d2;
|
||||
int ge_frombytes_vartime(ge_p3 *, const unsigned char *);
|
||||
|
||||
/* From ge_p1p1_to_p2.c */
|
||||
|
|
@ -112,12 +113,19 @@ void ge_p2_to_p3(ge_p3 *r, const ge_p2 *t);
|
|||
void ge_bytes_hash_to_ec(ge_p3 *, const void *, size_t);
|
||||
void ge_bytes_hash_to_ec_32(ge_p3 *, const unsigned char *);
|
||||
void ge_cached_to_p2(ge_p2 *r, const ge_cached *c);
|
||||
void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q);
|
||||
|
||||
void ge_p3_0(ge_p3 *h);
|
||||
void ge_sub(ge_p1p1 *, const ge_p3 *, const ge_cached *);
|
||||
void ge_double_scalarmult_base_vartime_p3(ge_p3 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b);
|
||||
void ge_scalarmult_vartime_p3(ge_p3 *r, const unsigned char *a, const ge_p3 *A);
|
||||
void ge_scalarmult_vartime_p3_v2(ge_p3 *r, const unsigned char *a, const ge_p3 *A);
|
||||
void ge_scalarmult_base_vartime(ge_p3 *h, const unsigned char *a);
|
||||
|
||||
/* precomp_data[i][j] = (j + 1) * 256^i * G */
|
||||
typedef ge_precomp (precomp_data_t)[32][8];
|
||||
void ge_scalarmult_precomp_vartime(ge_p3 *h, const precomp_data_t base_precomp, const unsigned char *a);
|
||||
void ge_p3_to_precomp(ge_precomp *r, const ge_p3* p);
|
||||
|
||||
extern const fe fe_ma2;
|
||||
extern const fe fe_ma;
|
||||
|
|
@ -139,6 +147,7 @@ void sc_invert(unsigned char*, const unsigned char*);
|
|||
|
||||
void fe_sq(fe h, const fe f);
|
||||
int fe_isnonzero(const fe f);
|
||||
void fe_add(fe h, const fe f, const fe g);
|
||||
void fe_sub(fe h, const fe f, const fe g);
|
||||
void fe_mul(fe, const fe, const fe);
|
||||
void fe_frombytes(fe h, const unsigned char *s);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -729,14 +729,15 @@ namespace crypto
|
|||
friend point_t operator*(const scalar_t& lhs, const point_t& rhs)
|
||||
{
|
||||
point_t result;
|
||||
ge_scalarmult_p3(&result.m_p3, lhs.m_s, &rhs.m_p3);
|
||||
//ge_scalarmult_p3(&result.m_p3, lhs.m_s, &rhs.m_p3);
|
||||
ge_scalarmult_vartime_p3(&result.m_p3, lhs.m_s, &rhs.m_p3);
|
||||
return result;
|
||||
}
|
||||
|
||||
point_t& operator*=(const scalar_t& rhs)
|
||||
{
|
||||
// TODO: ge_scalarmult_vartime_p3
|
||||
ge_scalarmult_p3(&m_p3, rhs.m_s, &m_p3);
|
||||
//ge_scalarmult_p3(&m_p3, rhs.m_s, &m_p3);
|
||||
ge_scalarmult_vartime_p3(&m_p3, rhs.m_s, &m_p3);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -745,7 +746,8 @@ namespace crypto
|
|||
point_t result;
|
||||
scalar_t reciprocal;
|
||||
sc_invert(&reciprocal.m_s[0], &rhs.m_s[0]);
|
||||
ge_scalarmult_p3(&result.m_p3, &reciprocal.m_s[0], &lhs.m_p3);
|
||||
//ge_scalarmult_p3(&result.m_p3, &reciprocal.m_s[0], &lhs.m_p3);
|
||||
ge_scalarmult_vartime_p3(&result.m_p3, &reciprocal.m_s[0], &lhs.m_p3);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -907,7 +909,8 @@ namespace crypto
|
|||
friend point_t operator*(const scalar_t& lhs, const point_g_t&)
|
||||
{
|
||||
point_t result;
|
||||
ge_scalarmult_base(&result.m_p3, &lhs.m_s[0]);
|
||||
//ge_scalarmult_base(&result.m_p3, &lhs.m_s[0]);
|
||||
ge_scalarmult_base_vartime(&result.m_p3, &lhs.m_s[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -916,7 +919,8 @@ namespace crypto
|
|||
point_t result;
|
||||
scalar_t reciprocal;
|
||||
sc_invert(&reciprocal.m_s[0], &rhs.m_s[0]);
|
||||
ge_scalarmult_base(&result.m_p3, &reciprocal.m_s[0]);
|
||||
//ge_scalarmult_base(&result.m_p3, &reciprocal.m_s[0]);
|
||||
ge_scalarmult_base_vartime(&result.m_p3, &reciprocal.m_s[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -925,6 +929,42 @@ namespace crypto
|
|||
}; // struct point_g_t
|
||||
|
||||
|
||||
void construct_precomp_data(precomp_data_t precomp_data, const point_t& point);
|
||||
|
||||
//
|
||||
// point_pc_t -- point with 30kB of precomputed data, which make possible to do very fast single scalar multiplication
|
||||
//
|
||||
struct point_pc_t : public point_t
|
||||
{
|
||||
constexpr point_pc_t(const int32_t(&v)[40], const precomp_data_t* precomp_data_p)
|
||||
: point_t(v)
|
||||
, m_precomp_data_p(precomp_data_p)
|
||||
{
|
||||
//construct_precomp_data(m_precomp_data, *this);
|
||||
}
|
||||
|
||||
friend point_t operator*(const scalar_t& lhs, const point_pc_t& self)
|
||||
{
|
||||
point_t result;
|
||||
ge_scalarmult_precomp_vartime(&result.m_p3, *self.m_precomp_data_p, &lhs.m_s[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
friend point_t operator/(const point_pc_t& self, const scalar_t& rhs)
|
||||
{
|
||||
point_t result;
|
||||
scalar_t reciprocal;
|
||||
sc_invert(&reciprocal.m_s[0], &rhs.m_s[0]);
|
||||
ge_scalarmult_precomp_vartime(&result.m_p3, *self.m_precomp_data_p, &reciprocal.m_s[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
static_assert(sizeof(crypto::public_key) == 32, "size error");
|
||||
|
||||
const precomp_data_t* m_precomp_data_p;
|
||||
}; // struct point_pc_t
|
||||
|
||||
|
||||
//
|
||||
// vector of scalars
|
||||
//
|
||||
|
|
@ -1082,18 +1122,30 @@ namespace crypto
|
|||
|
||||
|
||||
//
|
||||
// Global constants (checked in crypto_constants test)
|
||||
// Global constants (checked in crypto_constants and crypto_generators_precomp tests)
|
||||
//
|
||||
|
||||
static constexpr point_t c_point_0 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }};
|
||||
static constexpr point_g_t c_point_G {{ 25485296, 5318399, 8791791, -8299916, -14349720, 6939349, -3324311, -7717049, 7287234, -6577708, -758052, -1832720, 13046421, -4857925, 6576754, 14371947, -13139572, 6845540, -2198883, -4003719, -947565, 6097708, -469190, 10704810, -8556274, -15589498, -16424464, -16608899, 14028613, -5004649, 6966464, -2456167, 7033433, 6781840, 28785542, 12262365, -2659449, 13959020, -21013759, -5262166 }};
|
||||
static constexpr point_t c_point_H {{ 20574939, 16670001, -29137604, 14614582, 24883426, 3503293, 2667523, 420631, 2267646, -4769165, -11764015, -12206428, -14187565, -2328122, -16242653, -788308, -12595746, -8251557, -10110987, 853396, -4982135, 6035602, -21214320, 16156349, 977218, 2807645, 31002271, 5694305, -16054128, 5644146, -15047429, -568775, -22568195, -8089957, -27721961, -10101877, -29459620, -13359100, -31515170, -6994674 }};
|
||||
static constexpr point_t c_point_H2 {{ 1318371, 14804112, 12545972, -13482561, -12089798, -16020744, -21221907, -8410994, -33080606, 11275578, 3807637, 11185450, -23227561, -12892068, 1356866, -1025012, -8022738, -8139671, -20315029, -13916324, -6475650, -7025596, 12403179, -5139984, -12068178, 10445584, -14826705, -4927780, 13964546, 12525942, -2314107, -10566315, 32243863, 15603849, 5154154, 4276633, -20918372, -15718796, -26386151, 8434696 }};
|
||||
static constexpr point_t c_point_U {{ 30807552, 984924, 23426137, -5598760, 7545909, 16325843, 993742, 2594106, -31962071, -959867, 16454190, -4091093, 1197656, 13586872, -9269020, -14133290, 1869274, 13360979, -24627258, -10663086, 2212027, 1198856, 20515811, 15870563, -23833732, 9839517, -19416306, 11567295, -4212053, 348531, -2671541, 484270, -19128078, 1236698, -16002690, 9321345, 9776066, 10711838, 11187722, -16371275 }};
|
||||
static constexpr point_t c_point_X {{ 25635916, -5459446, 5768861, 5666160, -6357364, -12939311, 29490001, -4543704, -31266450, -2582476, 23705213, 9562626, -716512, 16560168, 7947407, 2039790, -2752711, 4742449, 3356761, 16338966, 17303421, -5790717, -5684800, 12062431, -3307947, 8139265, -26544839, 12058874, 3452748, 3359034, 26514848, -6060876, 31255039, 11154418, -21741975, -3782423, -19871841, 5729859, 21754676, -12454027 }};
|
||||
static constexpr point_t c_point_H_plus_G {{ 12291435, 3330843, -3390294, 13894858, -1099584, -6848191, 12040668, -15950068, -7494633, 12566672, -5526901, -16645799, -31081168, -1095427, -13082463, 4573480, -11255691, 4344628, 33477173, 11137213, -3837023, -12436594, -8471924, -814016, 10785607, 9492721, 10992667, 7406385, -5687296, -127915, -6229107, -9324867, 558657, 6493750, 4895261, 12642545, 9549220, 696086, 21894285, -10521807 }};
|
||||
static constexpr point_t c_point_H_minus_G {{ -28347682, 3523701, -3380175, -14453727, 4238027, -6032522, 20235758, 4091609, 12557126, -8064113, 4212476, -13419094, -114185, -7650727, -24238, 16663404, 23676363, -6819610, 18286466, 8714527, -3837023, -12436594, -8471924, -814016, 10785607, 9492721, 10992667, 7406385, -5687296, -127915, -20450317, 13815641, -11604061, -447489, 27380225, 9400847, -8551293, -1173627, -28110171, 14241295 }};
|
||||
|
||||
namespace xdetails
|
||||
{
|
||||
extern const precomp_data_t c_point_H_precomp_data;
|
||||
extern const precomp_data_t c_point_H2_precomp_data;
|
||||
extern const precomp_data_t c_point_U_precomp_data;
|
||||
extern const precomp_data_t c_point_X_precomp_data;
|
||||
extern const precomp_data_t c_point_H_plus_G_precomp_data;
|
||||
extern const precomp_data_t c_point_H_minus_G_precomp_data;
|
||||
};
|
||||
|
||||
inline constexpr point_t c_point_0 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }};
|
||||
inline constexpr point_g_t c_point_G {{ 25485296, 5318399, 8791791, -8299916, -14349720, 6939349, -3324311, -7717049, 7287234, -6577708, -758052, -1832720, 13046421, -4857925, 6576754, 14371947, -13139572, 6845540, -2198883, -4003719, -947565, 6097708, -469190, 10704810, -8556274, -15589498, -16424464, -16608899, 14028613, -5004649, 6966464, -2456167, 7033433, 6781840, 28785542, 12262365, -2659449, 13959020, -21013759, -5262166 }};
|
||||
|
||||
inline constexpr point_pc_t c_point_H {{ 20574939, 16670001, -29137604, 14614582, 24883426, 3503293, 2667523, 420631, 2267646, -4769165, -11764015, -12206428, -14187565, -2328122, -16242653, -788308, -12595746, -8251557, -10110987, 853396, -4982135, 6035602, -21214320, 16156349, 977218, 2807645, 31002271, 5694305, -16054128, 5644146, -15047429, -568775, -22568195, -8089957, -27721961, -10101877, -29459620, -13359100, -31515170, -6994674 }, &xdetails::c_point_H_precomp_data };
|
||||
inline constexpr point_pc_t c_point_H2 {{ 1318371, 14804112, 12545972, -13482561, -12089798, -16020744, -21221907, -8410994, -33080606, 11275578, 3807637, 11185450, -23227561, -12892068, 1356866, -1025012, -8022738, -8139671, -20315029, -13916324, -6475650, -7025596, 12403179, -5139984, -12068178, 10445584, -14826705, -4927780, 13964546, 12525942, -2314107, -10566315, 32243863, 15603849, 5154154, 4276633, -20918372, -15718796, -26386151, 8434696 }, &xdetails::c_point_H2_precomp_data };
|
||||
inline constexpr point_pc_t c_point_U {{ 30807552, 984924, 23426137, -5598760, 7545909, 16325843, 993742, 2594106, -31962071, -959867, 16454190, -4091093, 1197656, 13586872, -9269020, -14133290, 1869274, 13360979, -24627258, -10663086, 2212027, 1198856, 20515811, 15870563, -23833732, 9839517, -19416306, 11567295, -4212053, 348531, -2671541, 484270, -19128078, 1236698, -16002690, 9321345, 9776066, 10711838, 11187722, -16371275 }, &xdetails::c_point_U_precomp_data };
|
||||
inline constexpr point_pc_t c_point_X {{ 25635916, -5459446, 5768861, 5666160, -6357364, -12939311, 29490001, -4543704, -31266450, -2582476, 23705213, 9562626, -716512, 16560168, 7947407, 2039790, -2752711, 4742449, 3356761, 16338966, 17303421, -5790717, -5684800, 12062431, -3307947, 8139265, -26544839, 12058874, 3452748, 3359034, 26514848, -6060876, 31255039, 11154418, -21741975, -3782423, -19871841, 5729859, 21754676, -12454027 }, &xdetails::c_point_X_precomp_data };
|
||||
inline constexpr point_pc_t c_point_H_plus_G {{ 12291435, 3330843, -3390294, 13894858, -1099584, -6848191, 12040668, -15950068, -7494633, 12566672, -5526901, -16645799, -31081168, -1095427, -13082463, 4573480, -11255691, 4344628, 33477173, 11137213, -3837023, -12436594, -8471924, -814016, 10785607, 9492721, 10992667, 7406385, -5687296, -127915, -6229107, -9324867, 558657, 6493750, 4895261, 12642545, 9549220, 696086, 21894285, -10521807 }, &xdetails::c_point_H_plus_G_precomp_data };
|
||||
inline constexpr point_pc_t c_point_H_minus_G {{ -28347682, 3523701, -3380175, -14453727, 4238027, -6032522, 20235758, 4091609, 12557126, -8064113, 4212476, -13419094, -114185, -7650727, -24238, 16663404, 23676363, -6819610, 18286466, 8714527, -3837023, -12436594, -8471924, -814016, 10785607, 9492721, 10992667, 7406385, -5687296, -127915, -20450317, 13815641, -11604061, -447489, 27380225, 9400847, -8551293, -1173627, -28110171, 14241295 }, &xdetails::c_point_H_minus_G_precomp_data };
|
||||
|
||||
|
||||
//
|
||||
// hash functions' helper
|
||||
//
|
||||
|
|
|
|||
|
|
@ -6012,6 +6012,7 @@ bool blockchain_storage::validate_pos_block(const block& b,
|
|||
CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1, false, "incorrect number of stake input signatures: " << b.miner_tx.signatures.size());
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.signatures[0].type() == typeid(zarcanum_sig), false, "incorrect sig 0 type: " << b.miner_tx.signatures[0].type().name());
|
||||
|
||||
//std::stringstream ss;
|
||||
if (!for_altchain)
|
||||
{
|
||||
TIME_MEASURE_START_PD(pos_validate_get_out_keys_for_inputs);
|
||||
|
|
@ -6023,6 +6024,18 @@ bool blockchain_storage::validate_pos_block(const block& b,
|
|||
uint64_t dummy_source_max_unlock_time_for_pos_coinbase_dummy = 0; // won't be used
|
||||
scan_for_keys_context scan_contex = AUTO_VAL_INIT(scan_contex);
|
||||
r = get_output_keys_for_input_with_checks(b.miner_tx, stake_input, dummy_output_keys, max_related_block_height, dummy_source_max_unlock_time_for_pos_coinbase_dummy, scan_contex);
|
||||
|
||||
//#define ADD_ITEM_TO_SS(item) ss << " " #item ": " << m_performance_data.item.get_last_val() << ENDL
|
||||
// ADD_ITEM_TO_SS(tx_check_inputs_loop_scan_outputkeys_get_item_size);
|
||||
// ADD_ITEM_TO_SS(tx_check_inputs_loop_scan_outputkeys_relative_to_absolute);
|
||||
// ADD_ITEM_TO_SS(tx_check_inputs_loop_scan_outputkeys_loop);
|
||||
// ADD_ITEM_TO_SS(tx_check_inputs_loop_scan_outputkeys_loop_iteration);
|
||||
// ss << " tx_check_inputs_loop_scan_outputkeys_loop_iteration (avg): " << m_performance_data.tx_check_inputs_loop_scan_outputkeys_loop_iteration.get_avg() << ENDL;
|
||||
// ADD_ITEM_TO_SS(tx_check_inputs_loop_scan_outputkeys_loop_get_subitem);
|
||||
// ADD_ITEM_TO_SS(tx_check_inputs_loop_scan_outputkeys_loop_find_tx);
|
||||
// ADD_ITEM_TO_SS(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
|
||||
//#undef ADD_ITEM_TO_SS
|
||||
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_output_keys_for_input_with_checks failed for stake input");
|
||||
CHECK_AND_ASSERT_MES(scan_contex.zc_outs.size() == stake_input.key_offsets.size(), false, "incorrect number of referenced outputs found: " << scan_contex.zc_outs.size() << ", while " << stake_input.key_offsets.size() << " is expected.");
|
||||
// make sure that all referring inputs are either older then, or the same age as, the most resent PoW block.
|
||||
|
|
@ -6043,6 +6056,8 @@ bool blockchain_storage::validate_pos_block(const block& b,
|
|||
r = crypto::zarcanum_verify_proof(id, kernel_hash, ring, last_pow_block_id_hashed, stake_input.k_image, basic_diff, sig, &err);
|
||||
TIME_MEASURE_FINISH_PD(pos_validate_zvp);
|
||||
CHECK_AND_ASSERT_MES(r, false, "zarcanum_verify_proof failed with code " << (int)err);
|
||||
//std::stringstream ss;
|
||||
//std::cout << " validate_pos_block > get_output_keys_for_input_with_checks: " << ENDL << ss.str();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -6746,6 +6761,23 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
<< ")"
|
||||
<< "))");
|
||||
|
||||
{
|
||||
static epee::math_helper::average<uint64_t, 30> blocks_processing_time_avg_pos, blocks_processing_time_avg_pow;
|
||||
(is_pos_bl ? blocks_processing_time_avg_pos : blocks_processing_time_avg_pow).push(block_processing_time_0_ms);
|
||||
|
||||
static std::deque<uint64_t> blocks_processing_time_median_pos, blocks_processing_time_median_pow;
|
||||
std::deque<uint64_t>& d = (is_pos_bl ? blocks_processing_time_median_pos : blocks_processing_time_median_pow);
|
||||
d.push_back(block_processing_time_0_ms);
|
||||
if (d.size() > 200)
|
||||
d.pop_front();
|
||||
|
||||
uint64_t median_pow = epee::misc_utils::median(blocks_processing_time_median_pow);
|
||||
uint64_t median_pos = epee::misc_utils::median(blocks_processing_time_median_pos);
|
||||
|
||||
LOG_PRINT_YELLOW("last 30 blocks of type processing time (ms): PoW: " << std::setw(3) << (uint64_t)blocks_processing_time_avg_pow.get_avg() << ", PoS: " << (uint64_t)blocks_processing_time_avg_pos.get_avg(), LOG_LEVEL_1);
|
||||
LOG_PRINT_YELLOW("last 200 blocks of type processing time (median, ms): PoW: " << std::setw(3) << median_pow << ", PoS: " << median_pos, LOG_LEVEL_1);
|
||||
}
|
||||
|
||||
on_block_added(bei, id, block_summary_kimages);
|
||||
|
||||
bvc.m_added_to_main_chain = true;
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ namespace currency
|
|||
// Using C++17 extended aggregate initialization (P0017R1). C++17, finally! -- sowle
|
||||
const static crypto::public_key native_coin_asset_id = {{'\xd6', '\x32', '\x9b', '\x5b', '\x1f', '\x7c', '\x08', '\x05', '\xb5', '\xc3', '\x45', '\xf4', '\x95', '\x75', '\x54', '\x00', '\x2a', '\x2f', '\x55', '\x78', '\x45', '\xf6', '\x4d', '\x76', '\x45', '\xda', '\xe0', '\xe0', '\x51', '\xa6', '\x49', '\x8a'}}; // == crypto::c_point_H, checked in crypto_constants
|
||||
const static crypto::public_key native_coin_asset_id_1div8 = {{'\x74', '\xc3', '\x2d', '\x3e', '\xaa', '\xfa', '\xfc', '\x62', '\x3b', '\xf4', '\x83', '\xe8', '\x58', '\xd4', '\x2e', '\x8b', '\xf4', '\xec', '\x7d', '\xf0', '\x64', '\xad', '\xa2', '\xe3', '\x49', '\x34', '\x46', '\x9c', '\xff', '\x6b', '\x62', '\x68'}}; // == 1/8 * crypto::c_point_H, checked in crypto_constants
|
||||
const static crypto::point_t native_coin_asset_id_pt = crypto::c_point_H;
|
||||
const static crypto::point_t native_coin_asset_id_pt {{ 20574939, 16670001, -29137604, 14614582, 24883426, 3503293, 2667523, 420631, 2267646, -4769165, -11764015, -12206428, -14187565, -2328122, -16242653, -788308, -12595746, -8251557, -10110987, 853396, -4982135, 6035602, -21214320, 16156349, 977218, 2807645, 31002271, 5694305, -16054128, 5644146, -15047429, -568775, -22568195, -8089957, -27721961, -10101877, -29459620, -13359100, -31515170, -6994674 }}; // c_point_H
|
||||
|
||||
const static wide_difficulty_type global_difficulty_pow_starter = DIFFICULTY_POW_STARTER;
|
||||
const static wide_difficulty_type global_difficulty_pos_starter = DIFFICULTY_POS_STARTER;
|
||||
|
|
|
|||
|
|
@ -1658,7 +1658,7 @@ TEST(crypto, scalar_get_bits)
|
|||
for(size_t i = 0; i < 256; ++i)
|
||||
ASSERT_EQ(x.get_bits(i, 0), 0);
|
||||
for(size_t i = 0; i < 256; ++i)
|
||||
ASSERT_EQ(x.get_bits(i, std::min(255ull, i + 65)), 0);
|
||||
ASSERT_EQ(x.get_bits(i, std::min((size_t)255, i + 65)), 0);
|
||||
|
||||
ASSERT_EQ(x.get_bits(0, 64), x.m_u64[0]);
|
||||
ASSERT_EQ(x.get_bits(64, 64), x.m_u64[1]);
|
||||
|
|
@ -1695,6 +1695,32 @@ TEST(crypto, scalar_get_bits)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
TEST(crypto, scalarmult_base_vartime)
|
||||
{
|
||||
auto check_for_x = [&](const scalar_t& x) -> bool {
|
||||
point_t P, P2;
|
||||
ge_scalarmult_base_vartime(&P.m_p3, x.m_s);
|
||||
ge_scalarmult_base(&P2.m_p3, x.m_s);
|
||||
return (P - P2).is_zero();
|
||||
};
|
||||
|
||||
ASSERT_TRUE(check_for_x(c_scalar_0));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_1));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_1div8));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_Lm1));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_L));
|
||||
|
||||
for(size_t i = 0; i < 1000; ++i)
|
||||
{
|
||||
scalar_t x = scalar_t::random();
|
||||
ASSERT_TRUE(check_for_x(x));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename CT>
|
||||
bool crypto_msm_runner(size_t N, size_t low_bits_to_clear, size_t high_bits_to_clear)
|
||||
{
|
||||
|
|
@ -1762,6 +1788,116 @@ TEST(crypto, msm)
|
|||
}
|
||||
|
||||
|
||||
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::ge_precomp v)
|
||||
{
|
||||
o << "{{";
|
||||
|
||||
for(size_t i = 0; i < 9; ++i)
|
||||
o << v.yplusx[i] << ", ";
|
||||
|
||||
o << v.yplusx[9] << "}, {";
|
||||
|
||||
for(size_t i = 0; i < 9; ++i)
|
||||
o << v.yminusx[i] << ", ";
|
||||
|
||||
o << v.yminusx[9] << "}, {";
|
||||
|
||||
for(size_t i = 0; i < 9; ++i)
|
||||
o << v.xy2d[i] << ", ";
|
||||
|
||||
o << v.xy2d[9] << "}}";
|
||||
return o;
|
||||
}
|
||||
|
||||
bool calc_and_print_generator_precomp(const point_pc_t& generator, const char* generator_var_name)
|
||||
{
|
||||
precomp_data_t precomp_data = {};
|
||||
construct_precomp_data(precomp_data, generator);
|
||||
|
||||
std::cout << " const precomp_data_t " << generator_var_name << "_precomp_data = {" << ENDL;
|
||||
|
||||
for(size_t i = 0; i < 32; ++i)
|
||||
{
|
||||
std::cout << " {" << ENDL;
|
||||
for(size_t j = 0; j < 8; ++j)
|
||||
std::cout << " " << precomp_data[i][j] << (j != 7 ? "," : "" ) << ENDL;
|
||||
std::cout << " }" << (i != 31 ? "," : "" ) << ENDL;
|
||||
}
|
||||
|
||||
std::cout << " };" << ENDL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(print, generators_precomp)
|
||||
{
|
||||
#define CALC_PRECOMP(G) calc_and_print_generator_precomp(G, #G)
|
||||
|
||||
CALC_PRECOMP(c_point_H);
|
||||
CALC_PRECOMP(c_point_H2);
|
||||
CALC_PRECOMP(c_point_U);
|
||||
CALC_PRECOMP(c_point_X);
|
||||
CALC_PRECOMP(c_point_H_plus_G);
|
||||
CALC_PRECOMP(c_point_H_minus_G);
|
||||
return true;
|
||||
|
||||
#undef CALC_PRECOMP
|
||||
}
|
||||
|
||||
bool check_generator_precomp(const point_pc_t& generator, const char* generator_var_name)
|
||||
{
|
||||
point_t generator_pt = generator; // to avoid using precomputed data in scalar multiplications
|
||||
point_t random_point = hash_helper_t::hp(scalar_t::random());
|
||||
|
||||
point_t A = generator_pt;
|
||||
for(size_t i = 0; i < 32; ++i)
|
||||
{
|
||||
point_t B = c_point_0;
|
||||
for(size_t j = 0; j < 8; ++j)
|
||||
{
|
||||
B += A;
|
||||
|
||||
// restore ge_p3 from ge_precomp using native NaCl functions...
|
||||
point_t restored_pt{};
|
||||
ge_p1p1 p1p1{};
|
||||
ge_madd(&p1p1, &random_point.m_p3, &((*generator.m_precomp_data_p)[i][j]));
|
||||
ge_p1p1_to_p3(&restored_pt.m_p3, &p1p1);
|
||||
restored_pt -= random_point;
|
||||
|
||||
// ...and compare it with the calculated one
|
||||
if (B != restored_pt)
|
||||
{
|
||||
std::cout << "ERROR: " << generator_var_name << ", i: " << i << ", j: " << j << ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (i != 31)
|
||||
A.modify_mul_pow_2(8);
|
||||
}
|
||||
|
||||
std::cout << " " << std::left << std::setw(32) << generator_var_name << " OK" << ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(crypto, generators_precomp)
|
||||
{
|
||||
#define CHECK_PRECOMP(G) ASSERT_TRUE(check_generator_precomp(G, #G))
|
||||
|
||||
CHECK_PRECOMP(c_point_H);
|
||||
CHECK_PRECOMP(c_point_H2);
|
||||
CHECK_PRECOMP(c_point_U);
|
||||
CHECK_PRECOMP(c_point_X);
|
||||
CHECK_PRECOMP(c_point_H_plus_G);
|
||||
CHECK_PRECOMP(c_point_H_minus_G);
|
||||
|
||||
return true;
|
||||
|
||||
#undef CHECK_PRECOMP
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// test's runner
|
||||
//
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// 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>
|
||||
|
||||
uint64_t get_bits_v1(const scalar_t& s, uint8_t bit_index_first, uint8_t bits_count)
|
||||
{
|
||||
|
|
@ -20,27 +20,42 @@ uint64_t get_bits_v1(const scalar_t& s, uint8_t bit_index_first, uint8_t bits_co
|
|||
}
|
||||
|
||||
|
||||
inline std::ostream &operator <<(std::ostream &o, const crypto::ge_precomp v)
|
||||
TEST(crypto, ge_precomp)
|
||||
{
|
||||
o << "{{";
|
||||
|
||||
for(size_t i = 0; i < 9; ++i)
|
||||
o << v.yplusx[i] << ", ";
|
||||
//precomp_data_t G_precomp = {};
|
||||
//construct_precomp_data(G_precomp, c_point_G);
|
||||
//std::cout << "size of G_precomp: " << sizeof G_precomp << " bytes" << ENDL;
|
||||
//for(size_t i = 0; i < 32; ++i)
|
||||
// for(size_t j = 0; j < 8; ++j)
|
||||
// std::cout << "i: " << i << ", j: " << j << ", precomp: " << ENDL << G_precomp[i][j] << ENDL;
|
||||
|
||||
o << v.yplusx[9] << "},\n {";
|
||||
|
||||
for(size_t i = 0; i < 9; ++i)
|
||||
o << v.yminusx[i] << ", ";
|
||||
|
||||
o << v.yminusx[9] << "},\n {";
|
||||
|
||||
for(size_t i = 0; i < 9; ++i)
|
||||
o << v.xy2d[i] << ", ";
|
||||
|
||||
o << v.xy2d[9] << "}}\n";
|
||||
return o;
|
||||
precomp_data_t H_precomp = {};
|
||||
construct_precomp_data(H_precomp, c_point_H);
|
||||
|
||||
auto check_for_x = [&](const scalar_t& x) -> bool {
|
||||
point_t P;
|
||||
ge_scalarmult_precomp_vartime(&P.m_p3, H_precomp, x.m_s);
|
||||
return P == x * c_point_H;
|
||||
};
|
||||
|
||||
ASSERT_TRUE(check_for_x(c_scalar_0));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_1));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_1div8));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_Lm1));
|
||||
ASSERT_TRUE(check_for_x(c_scalar_L));
|
||||
|
||||
for(size_t i = 0; i < 1000; ++i)
|
||||
{
|
||||
scalar_t x = scalar_t::random();
|
||||
ASSERT_TRUE(check_for_x(x));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
TEST(perf, primitives)
|
||||
{
|
||||
struct helper
|
||||
|
|
@ -315,7 +330,7 @@ TEST(perf, primitives)
|
|||
return HASH_64_VEC(points_cached);
|
||||
});
|
||||
|
||||
run("ge_add(p3 + p3)", 50000, [](timer_t& t, size_t rounds) {
|
||||
run("ge_add(p1p1 = p3 + cached)", 50000, [](timer_t& t, size_t rounds) {
|
||||
std::vector<size_t> rnd_indecies;
|
||||
helper::make_rnd_indicies(rnd_indecies, rounds);
|
||||
std::vector<ge_cached> points_cached(rounds);
|
||||
|
|
@ -530,7 +545,7 @@ TEST(perf, primitives)
|
|||
return HASH_64_VEC(points_p3);
|
||||
});
|
||||
|
||||
run("ge_scalarmult_base()", 5000, [](timer_t& t, size_t rounds) {
|
||||
run("ge_scalarmult_base()", 10000, [](timer_t& t, size_t rounds) {
|
||||
std::vector<size_t> rnd_indecies;
|
||||
helper::make_rnd_indicies(rnd_indecies, rounds);
|
||||
|
||||
|
|
@ -555,6 +570,87 @@ TEST(perf, primitives)
|
|||
return HASH_64_VEC(points_p3);
|
||||
});
|
||||
|
||||
run("construct_precomp_data()", 300, [](timer_t& t, size_t rounds) {
|
||||
std::vector<size_t> rnd_indecies;
|
||||
helper::make_rnd_indicies(rnd_indecies, rounds);
|
||||
|
||||
unsigned char s[32] = {};
|
||||
std::vector<point_t> random_points(rounds);
|
||||
for (size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
s[0] = i;
|
||||
ge_p2 p2;
|
||||
ge_fromfe_frombytes_vartime(&p2, s);
|
||||
ge_p2_to_p3(&random_points[i].m_p3, &p2);
|
||||
}
|
||||
|
||||
std::vector<ge_p3> points_p3(rounds);
|
||||
precomp_data_t precomp_data;
|
||||
uint64_t result = 0;
|
||||
t.start();
|
||||
for (size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
construct_precomp_data(precomp_data, random_points[rnd_indecies[i]]);
|
||||
result ^= (precomp_data[1][1].xy2d[1] + precomp_data[31][7].xy2d[9]);
|
||||
}
|
||||
t.stop();
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
run("ge_scalarmult_precomp_vartime()", 10000, [](timer_t& t, size_t rounds) {
|
||||
std::vector<size_t> rnd_indecies;
|
||||
helper::make_rnd_indicies(rnd_indecies, rounds);
|
||||
|
||||
scalar_t x;
|
||||
x.make_random();
|
||||
|
||||
std::vector<crypto::ec_scalar> scalars(rounds);
|
||||
for (size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
scalar_t x = x + x + x;
|
||||
memcpy(&scalars[i].data, x.data(), 32);
|
||||
}
|
||||
|
||||
precomp_data_t precomp_data;
|
||||
construct_precomp_data(precomp_data, x * c_point_X);
|
||||
|
||||
std::vector<ge_p3> points_p3(rounds);
|
||||
t.start();
|
||||
for (size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
ge_scalarmult_precomp_vartime(&points_p3[i], precomp_data, (const unsigned char*)&scalars[rnd_indecies[i]]);
|
||||
}
|
||||
t.stop();
|
||||
|
||||
return HASH_64_VEC(points_p3);
|
||||
});
|
||||
|
||||
run("ge_scalarmult_base_vartime()", 10000, [](timer_t& t, size_t rounds) {
|
||||
std::vector<size_t> rnd_indecies;
|
||||
helper::make_rnd_indicies(rnd_indecies, rounds);
|
||||
|
||||
scalar_t x;
|
||||
x.make_random();
|
||||
|
||||
std::vector<crypto::ec_scalar> scalars(rounds);
|
||||
for (size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
scalar_t x = x + x + x;
|
||||
memcpy(&scalars[i].data, x.data(), 32);
|
||||
}
|
||||
|
||||
std::vector<ge_p3> points_p3(rounds);
|
||||
t.start();
|
||||
for (size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
ge_scalarmult_base_vartime(&points_p3[i], (const unsigned char*)&scalars[rnd_indecies[i]]);
|
||||
}
|
||||
t.stop();
|
||||
|
||||
return HASH_64_VEC(points_p3);
|
||||
});
|
||||
|
||||
run("ge_mul8_p3()", 5000, [](timer_t& t, size_t rounds) {
|
||||
std::vector<size_t> rnd_indecies;
|
||||
helper::make_rnd_indicies(rnd_indecies, rounds);
|
||||
|
|
@ -738,5 +834,402 @@ TEST(perf, primitives)
|
|||
return HASH_64_VEC(result);
|
||||
});
|
||||
|
||||
run("get_bits x 10", 20000, [](timer_t& t, size_t rounds) {
|
||||
std::vector<size_t> rnd_indecies;
|
||||
helper::make_rnd_indicies(rnd_indecies, rounds);
|
||||
|
||||
scalar_vec_t data;
|
||||
data.resize_and_make_random(rounds);
|
||||
|
||||
std::vector<uint64_t> result(rounds);
|
||||
t.start();
|
||||
for (size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
auto& x = data[rnd_indecies[i]];
|
||||
result[i] =
|
||||
x.get_bits(x.m_s[11], x.m_s[21] % 65) ^
|
||||
x.get_bits(x.m_s[12], x.m_s[22] % 65) ^
|
||||
x.get_bits(x.m_s[13], x.m_s[23] % 65) ^
|
||||
x.get_bits(x.m_s[14], x.m_s[24] % 65) ^
|
||||
x.get_bits(x.m_s[15], x.m_s[25] % 65) ^
|
||||
x.get_bits(x.m_s[16], x.m_s[26] % 65) ^
|
||||
x.get_bits(x.m_s[17], x.m_s[27] % 65) ^
|
||||
x.get_bits(x.m_s[18], x.m_s[28] % 65) ^
|
||||
x.get_bits(x.m_s[19], x.m_s[29] % 65) ^
|
||||
x.get_bits(x.m_s[20], x.m_s[30] % 65);
|
||||
}
|
||||
t.stop();
|
||||
|
||||
return HASH_64_VEC(result);
|
||||
});
|
||||
|
||||
return true;
|
||||
} // TEST
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////// v3
|
||||
|
||||
|
||||
|
||||
///////////////// v4
|
||||
|
||||
|
||||
template<typename CT>
|
||||
bool msm_and_check_zero_pippenger_v4(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand, size_t c)
|
||||
{
|
||||
// TODO: with c = 8 and with direct access got much worse result than with c = 7 and get_bits(), consider checking again for bigger datasets (N>256)
|
||||
CHECK_AND_ASSERT_MES(g_scalars.size() <= CT::c_bpp_mn_max, false, "g_scalars oversized");
|
||||
CHECK_AND_ASSERT_MES(h_scalars.size() <= CT::c_bpp_mn_max, false, "h_scalars oversized");
|
||||
CHECK_AND_ASSERT_MES(c < 10, false, "c is too big");
|
||||
|
||||
size_t C = 1ull << c;
|
||||
|
||||
// k_max * c + (c-1) >= max_bit_idx
|
||||
//
|
||||
// max_bit_idx - (c - 1) max_bit_idx - (c - 1) + (c - 1) max_bit_idx
|
||||
// k_max = ceil ( --------------------- ) = floor ( ------------------------------ ) = floor ( ----------- )
|
||||
// c c c
|
||||
const size_t b = 253; // the maximum number of bits in x https://eprint.iacr.org/2022/999.pdf TODO: we may also scan for maximum bit used in all the scalars if all the scalars are small
|
||||
const size_t max_bit_idx = b - 1;
|
||||
const size_t k_max = max_bit_idx / c;
|
||||
const size_t K = k_max + 1;
|
||||
|
||||
std::unique_ptr<point_t[]> buckets( new point_t[C * K] );
|
||||
std::vector<bool> buckets_inited(C * K);
|
||||
|
||||
// first loop, calculate partial bucket sums
|
||||
for (size_t n = 0; n < g_scalars.size(); ++n)
|
||||
{
|
||||
for (size_t k = 0; k < K; ++k)
|
||||
{
|
||||
uint64_t l = g_scalars[n].get_bits(k * c, c); // l in [0; 2^c-1]
|
||||
if (l != 0)
|
||||
{
|
||||
size_t bucket_id = l * K + k;
|
||||
if (buckets_inited[bucket_id])
|
||||
buckets[bucket_id] += CT::get_generator(false, n);
|
||||
else
|
||||
{
|
||||
buckets[bucket_id] = CT::get_generator(false, n);
|
||||
buckets_inited[bucket_id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < h_scalars.size(); ++n)
|
||||
{
|
||||
for (size_t k = 0; k < K; ++k)
|
||||
{
|
||||
uint64_t l = h_scalars[n].get_bits(k * c, c); // l in [0; 2^c-1]
|
||||
if (l != 0)
|
||||
{
|
||||
size_t bucket_id = l * K + k;
|
||||
if (buckets_inited[bucket_id])
|
||||
buckets[bucket_id] += CT::get_generator(true, n);
|
||||
else
|
||||
{
|
||||
buckets[bucket_id] = CT::get_generator(true, n);
|
||||
buckets_inited[bucket_id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the second loop
|
||||
// S[l, k] = S[l-1, k] + B[l, k]
|
||||
// G[k] = sum{1..C-1} S[l, k]
|
||||
std::unique_ptr<point_t[]> Sk( new point_t[K] );
|
||||
std::vector<bool> Sk_inited(K);
|
||||
std::unique_ptr<point_t[]> Gk( new point_t[K] );
|
||||
std::vector<bool> Gk_inited(K);
|
||||
for (size_t l = C - 1; l > 0; --l)
|
||||
{
|
||||
for (size_t k = 0; k < K; ++k)
|
||||
{
|
||||
size_t bucket_id = l * K + k;
|
||||
if (buckets_inited[bucket_id])
|
||||
{
|
||||
if (Sk_inited[k])
|
||||
Sk[k] += buckets[bucket_id];
|
||||
else
|
||||
{
|
||||
Sk[k] = buckets[bucket_id];
|
||||
Sk_inited[k] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Sk_inited[k])
|
||||
{
|
||||
if (Gk_inited[k])
|
||||
Gk[k] += Sk[k];
|
||||
else
|
||||
{
|
||||
Gk[k] = Sk[k];
|
||||
Gk_inited[k] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the third loop: Horner’s rule
|
||||
point_t result = Gk_inited[K - 1] ? Gk[K - 1] : c_point_0;
|
||||
for (size_t k = K - 2; k != SIZE_MAX; --k)
|
||||
{
|
||||
result.modify_mul_pow_2(c);
|
||||
if (Gk_inited[k])
|
||||
result += Gk[k];
|
||||
}
|
||||
|
||||
result += summand;
|
||||
|
||||
if (!result.is_zero())
|
||||
{
|
||||
LOG_PRINT_L0("msm result is non zero: " << result);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//template<typename CT>
|
||||
//struct mes_msm_and_check_zero_pippenger_v1
|
||||
//{
|
||||
// static bool msm_and_check_zero(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand, size_t c)
|
||||
// {
|
||||
// return msm_and_check_zero_pippenger_v1<CT>(g_scalars, h_scalars, summand, c);
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//template<typename CT>
|
||||
//struct mes_msm_and_check_zero_pippenger_v2
|
||||
//{
|
||||
// static bool msm_and_check_zero(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand, size_t c)
|
||||
// {
|
||||
// return msm_and_check_zero_pippenger_v2<CT>(g_scalars, h_scalars, summand, c);
|
||||
// }
|
||||
//};
|
||||
|
||||
template<typename CT>
|
||||
struct mes_msm_and_check_zero_pippenger_v3
|
||||
{
|
||||
static bool msm_and_check_zero(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand, size_t c)
|
||||
{
|
||||
return msm_and_check_zero_pippenger_v3<CT>(g_scalars, h_scalars, summand, c);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CT>
|
||||
struct mes_msm_and_check_zero_pippenger_v4
|
||||
{
|
||||
static bool msm_and_check_zero(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand, size_t c)
|
||||
{
|
||||
return msm_and_check_zero_pippenger_v4<CT>(g_scalars, h_scalars, summand, c);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct pme_runner_i
|
||||
{
|
||||
virtual ~pme_runner_i() {}
|
||||
virtual bool iteration(bool warmup) = 0;
|
||||
};
|
||||
|
||||
template<size_t N, typename CT, template<typename> typename selector_t>
|
||||
struct pme_runner_t : public pme_runner_i
|
||||
{
|
||||
pme_runner_t(const char* testname_, size_t pip_partition_bits_c)
|
||||
: testname(testname_)
|
||||
, pip_partition_bits_c(pip_partition_bits_c)
|
||||
{
|
||||
testname += std::string(", ") + std::string(typeid(selector_t<CT>).name()).erase(0, 11) + std::string(", c = ") + epee::string_tools::num_to_string_fast(pip_partition_bits_c);
|
||||
std::cout << testname << ENDL;
|
||||
}
|
||||
virtual ~pme_runner_t()
|
||||
{
|
||||
if (timings.empty())
|
||||
return;
|
||||
|
||||
uint64_t median = 0;
|
||||
auto median_it = timings.begin() + timings.size() / 2;
|
||||
std::nth_element(timings.begin(), median_it, timings.end());
|
||||
median = *median_it;
|
||||
if (timings.size() % 2 == 0)
|
||||
{
|
||||
auto max_it = std::max_element(timings.begin(), median_it);
|
||||
median = (median + *max_it) / 2;
|
||||
}
|
||||
|
||||
uint64_t total_time = std::accumulate(timings.begin(), timings.end(), 0);
|
||||
std::cout << std::left << std::setw(100) << testname << " : " << std::setw(5) << median << " (median), " << std::setw(5) << total_time / timings.size() << " (avg), mcs" << ENDL;
|
||||
}
|
||||
|
||||
virtual bool iteration(bool warmup)
|
||||
{
|
||||
scalar_vec_t g_scalars, h_scalars;
|
||||
g_scalars.resize_and_make_random(N);
|
||||
g_scalars[0] = c_scalar_Lm1;
|
||||
//std::cout << "bit 251: " << g_scalars[0].get_bit(251) << ", bit 252: " << g_scalars[0].get_bit(252) << ENDL;
|
||||
h_scalars.resize_and_make_random(N);
|
||||
point_t sum = c_point_0;
|
||||
for(size_t i = 0; i < N; ++i)
|
||||
{
|
||||
//g_scalars[i].m_u64[3] = 0;
|
||||
//h_scalars[i].m_u64[3] = 0;
|
||||
//g_scalars[i].m_s[31] = 0;
|
||||
//h_scalars[i].m_s[31] = 0;
|
||||
sum += g_scalars[i] * CT::get_generator(false, i) + h_scalars[i] * CT::get_generator(true, i);
|
||||
}
|
||||
|
||||
TIME_MEASURE_START(t);
|
||||
bool r = selector_t<CT>::msm_and_check_zero(g_scalars, h_scalars, -sum, pip_partition_bits_c);
|
||||
TIME_MEASURE_FINISH(t);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
if (!warmup)
|
||||
timings.push_back(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> timings;
|
||||
std::string testname;
|
||||
size_t pip_partition_bits_c;
|
||||
};
|
||||
|
||||
|
||||
TEST(perf, msm)
|
||||
{
|
||||
bool r = false;
|
||||
|
||||
std::deque<std::unique_ptr<pme_runner_i>> runners;
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 1));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 2));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 3));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 4));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 5));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 6));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 7));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 8));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 9));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 1));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 2));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 3));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 4));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 5));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 6));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 7));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 8));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 9));
|
||||
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 1));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 2));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 3));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 4));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 5));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 6));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 7));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 8));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v2> >("Zarcanum, BPPE, 128", 9));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 1));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 2));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 3));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 4));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 5));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 6));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 7));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 8));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v2> >("ZC out, BPP, 256", 9));
|
||||
|
||||
|
||||
runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v3> >("Zarcanum, BPPE, 128 +++++++++++", 7));
|
||||
runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v3> >("ZC out, BPP, 256 +++++++++++", 7));
|
||||
|
||||
runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v4> >("Zarcanum, BPPE, 128 ###########", 7));
|
||||
runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v4> >("ZC out, BPP, 256 ###########", 7));
|
||||
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<128, bpp_crypto_trait_Zarcanum, mes_msm_and_check_zero_pippenger_v1> >("Zarcanum, BPPE, 128", 7));
|
||||
//runners.emplace_front(std::make_unique< pme_runner_t<256, bpp_crypto_trait_ZC_out, mes_msm_and_check_zero_pippenger_v1> >("ZC out, BPP, 256", 7));
|
||||
|
||||
|
||||
std::cout << "warm up..." << ENDL;
|
||||
size_t runs_count = 30;
|
||||
for(size_t k = 0; k < runs_count; ++k)
|
||||
{
|
||||
for(auto& runner : runners)
|
||||
ASSERT_TRUE(runner->iteration(true));
|
||||
}
|
||||
|
||||
runs_count = 200;
|
||||
for(size_t k = 0; k < runs_count; ++k)
|
||||
{
|
||||
for(auto& runner : runners)
|
||||
ASSERT_TRUE(runner->iteration(false));
|
||||
|
||||
size_t done_percent = 100 * k / runs_count;
|
||||
if (100 * (k + 1) / runs_count > done_percent && done_percent % 5 == 0)
|
||||
std::cout << done_percent << " %" << ENDL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool perf_generators_runner(const T& generator, const char* title)
|
||||
{
|
||||
const size_t warmup_rounds = 20;
|
||||
const size_t rounds = 500;
|
||||
const size_t inner_rounds = 128;
|
||||
uint64_t h = 0;
|
||||
std::vector<uint64_t> timings;
|
||||
|
||||
size_t N = 1024;
|
||||
scalar_vec_t scalars;
|
||||
scalars.resize_and_make_random(N);
|
||||
std::vector<point_t> points(N);
|
||||
|
||||
for(size_t i = 0; i < warmup_rounds; ++i)
|
||||
for(size_t j = 0; j < inner_rounds; ++j)
|
||||
points[(i + j) % N] = scalars[(i + j) % N] * generator;
|
||||
|
||||
h = hash_64(points.data(), points.size() * sizeof(point_t));
|
||||
|
||||
for(size_t i = 0; i < rounds; ++i)
|
||||
{
|
||||
TIME_MEASURE_START(t);
|
||||
for(size_t j = 0; j < inner_rounds; ++j)
|
||||
points[(i + j) % N] = scalars[(i + j) % N] * generator;
|
||||
TIME_MEASURE_FINISH(t);
|
||||
timings.push_back(t);
|
||||
}
|
||||
|
||||
h ^= hash_64(points.data(), points.size() * sizeof(point_t));
|
||||
|
||||
std::cout << std::left << std::setw(20) << title << " : " << std::setw(5) << std::fixed << std::setprecision(1) << (double)epee::misc_utils::median(timings) / inner_rounds << " mcs, hash = " << h << ENDL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(perf, generators)
|
||||
{
|
||||
#define TEST_GENERATOR(G) ASSERT_TRUE(perf_generators_runner(G, #G))
|
||||
|
||||
TEST_GENERATOR(c_point_0);
|
||||
TEST_GENERATOR(c_point_G);
|
||||
TEST_GENERATOR(c_point_H);
|
||||
TEST_GENERATOR(c_point_H2);
|
||||
TEST_GENERATOR(c_point_U);
|
||||
TEST_GENERATOR(c_point_X);
|
||||
TEST_GENERATOR(c_point_H_plus_G);
|
||||
TEST_GENERATOR(c_point_H_minus_G);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue