crypto: fixed generators with precomputed data improved (data made static) + more tests

This commit is contained in:
sowle 2023-12-27 02:04:59 +01:00
parent 4200669f5b
commit e239389768
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
6 changed files with 2084 additions and 53 deletions

View file

@ -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 *);
@ -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);

View file

@ -113,6 +113,7 @@ 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 *);

File diff suppressed because it is too large Load diff

View file

@ -936,16 +936,17 @@ namespace crypto
//
struct point_pc_t : public point_t
{
explicit point_pc_t(const int32_t(&v)[40])
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);
//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, &lhs.m_s[0]);
ge_scalarmult_precomp_vartime(&result.m_p3, *self.m_precomp_data_p, &lhs.m_s[0]);
return result;
}
@ -954,14 +955,14 @@ namespace crypto
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, &reciprocal.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");
precomp_data_t m_precomp_data;
}; // struct point_g_t
const precomp_data_t* m_precomp_data_p;
}; // struct point_pc_t
//
@ -1121,26 +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 }};
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 };
extern const point_pc_t c_point_H;
extern const point_pc_t c_point_H2;
extern const point_pc_t c_point_U;
extern const point_pc_t c_point_X;
extern const point_pc_t c_point_H_plus_G;
extern const point_pc_t c_point_H_minus_G;
//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 }};
//
// hash functions' helper
//

View file

@ -1788,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
//

View file

@ -20,27 +20,6 @@ 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)
{
o << "{{";
for(size_t i = 0; i < 9; ++i)
o << v.yplusx[i] << ", ";
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;
}
TEST(crypto, ge_precomp)
{
//precomp_data_t G_precomp = {};