mirror of
https://github.com/monero-project/monero.git
synced 2026-07-28 22:51:07 -07:00
crypto: torsion clearing for FCMP++
This commit is contained in:
@@ -39,8 +39,11 @@ extern "C"
|
||||
}
|
||||
#include "crypto/generators.h"
|
||||
#include "cryptonote_basic/merge_mining.h"
|
||||
#include "fcmp_pp/fcmp_pp_crypto.h"
|
||||
#include "ringct/rctOps.h"
|
||||
#include "ringct/rctSigs.h"
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "string_tools.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -429,3 +432,92 @@ TEST(Crypto, fe_equals)
|
||||
ASSERT_NE(memcmp(fe_d2_reduced, fe_d2, sizeof(fe)), 0);
|
||||
ASSERT_EQ(fe_equals(fe_d2_reduced, fe_d2), 1);
|
||||
}
|
||||
|
||||
TEST(Crypto, ec_constants_rct_parity)
|
||||
{
|
||||
ASSERT_TRUE(memcmp(&fcmp_pp::EC_I, &rct::I, 32) == 0);
|
||||
ASSERT_TRUE(memcmp(&fcmp_pp::EC_INV_EIGHT, &rct::INV_EIGHT, 32) == 0);
|
||||
}
|
||||
|
||||
#define CHECK_CLEARED(k, cleared) \
|
||||
crypto::ec_point cleared2; \
|
||||
const bool r = fcmp_pp::get_valid_torsion_cleared_point_vartime(rct::rct2pt(k), cleared2); \
|
||||
ASSERT_TRUE(r); \
|
||||
ASSERT_EQ(cleared, cleared2);
|
||||
|
||||
TEST(Crypto, torsion_check_pass_random)
|
||||
{
|
||||
std::vector<rct::key> pts;
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
const rct::key pk = rct::pkGen();
|
||||
ge_p3 x;
|
||||
ASSERT_EQ(ge_frombytes_vartime(&x, pk.bytes), 0);
|
||||
ASSERT_TRUE(rct::isInMainSubgroup(pk));
|
||||
ASSERT_FALSE(fcmp_pp::mul8_is_identity_vartime(x));
|
||||
const crypto::ec_point cleared = fcmp_pp::clear_torsion_vartime(x);
|
||||
ASSERT_EQ(rct::rct2pt(pk), cleared);
|
||||
CHECK_CLEARED(pk, cleared);
|
||||
pts.emplace_back(pk);
|
||||
}
|
||||
ASSERT_TRUE(rct::verPointsForTorsion(pts));
|
||||
}
|
||||
|
||||
TEST(Crypto, torsion_check_hardcoded)
|
||||
{
|
||||
struct TorsionTestPoints { std::string point; bool torsion_free; };
|
||||
static const std::vector<TorsionTestPoints> torsion_test_points = {
|
||||
{"b10ba13e303cbe9abf7d5d44f1d417727abcc14903a74e071abd652ce1bf76dd", false},
|
||||
{"9b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd088071", false}, // genesis (see config::GENESIS_TX)
|
||||
{"785eda585dca4f3d27976106008ccfbca13146c8b21b8c7e4909032639a776e1", true},
|
||||
{"9a7b10563aa266032cd075f4e347f348a3841ae4f41572633351a97dd44066b4", true},
|
||||
};
|
||||
|
||||
std::vector<rct::key> all_pts, torsion_free_pts, torsioned_pts, torsion_cleared_pts;
|
||||
for (const auto &point : torsion_test_points)
|
||||
{
|
||||
rct::key k;
|
||||
epee::string_tools::hex_to_pod(point.point, k);
|
||||
ge_p3 x;
|
||||
ASSERT_EQ(ge_frombytes_vartime(&x, k.bytes), 0);
|
||||
ASSERT_EQ(rct::isInMainSubgroup(k), point.torsion_free);
|
||||
ASSERT_FALSE(fcmp_pp::mul8_is_identity_vartime(x));
|
||||
const crypto::ec_point cleared = fcmp_pp::clear_torsion_vartime(x);
|
||||
if (point.torsion_free)
|
||||
{
|
||||
ASSERT_EQ(rct::rct2pt(k), cleared);
|
||||
torsion_free_pts.push_back(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_NE(rct::rct2pt(k), cleared);
|
||||
torsioned_pts.push_back(k);
|
||||
}
|
||||
CHECK_CLEARED(k, cleared);
|
||||
all_pts.emplace_back(k);
|
||||
torsion_cleared_pts.emplace_back(rct::pt2rct(cleared));
|
||||
}
|
||||
|
||||
ASSERT_TRUE(rct::verPointsForTorsion(torsion_free_pts));
|
||||
ASSERT_FALSE(rct::verPointsForTorsion(torsioned_pts));
|
||||
ASSERT_FALSE(rct::verPointsForTorsion(all_pts));
|
||||
ASSERT_TRUE(rct::verPointsForTorsion(torsion_cleared_pts));
|
||||
}
|
||||
|
||||
TEST(Crypto, mul8_is_identity_vartime)
|
||||
{
|
||||
static const std::vector<rct::key> mul8_identity_points = {
|
||||
rct::I,
|
||||
rct::Z
|
||||
};
|
||||
|
||||
for (const auto &point : mul8_identity_points)
|
||||
{
|
||||
ge_p3 x;
|
||||
ASSERT_EQ(ge_frombytes_vartime(&x, point.bytes), 0);
|
||||
ASSERT_TRUE(fcmp_pp::mul8_is_identity_vartime(x));
|
||||
|
||||
crypto::ec_point _;
|
||||
ASSERT_FALSE(fcmp_pp::get_valid_torsion_cleared_point_vartime(rct::rct2pt(point), _));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user