mirror of
https://github.com/monero-project/monero.git
synced 2026-07-28 14:47:15 -07:00
crypto: torsion clearing for FCMP++
This commit is contained in:
@@ -83,6 +83,7 @@ monero_add_library(version SOURCES ${CMAKE_BINARY_DIR}/version.cpp DEPENDS genve
|
|||||||
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
add_subdirectory(crypto)
|
add_subdirectory(crypto)
|
||||||
|
add_subdirectory(fcmp_pp)
|
||||||
add_subdirectory(ringct)
|
add_subdirectory(ringct)
|
||||||
add_subdirectory(checkpoints)
|
add_subdirectory(checkpoints)
|
||||||
add_subdirectory(cryptonote_basic)
|
add_subdirectory(cryptonote_basic)
|
||||||
|
|||||||
@@ -320,6 +320,9 @@ namespace crypto {
|
|||||||
inline std::ostream &operator <<(std::ostream &o, const crypto::view_tag &v) {
|
inline std::ostream &operator <<(std::ostream &o, const crypto::view_tag &v) {
|
||||||
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
|
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
|
||||||
}
|
}
|
||||||
|
inline std::ostream &operator <<(std::ostream &o, const crypto::ec_point &v) {
|
||||||
|
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
|
||||||
|
}
|
||||||
|
|
||||||
const extern crypto::public_key null_pkey;
|
const extern crypto::public_key null_pkey;
|
||||||
const extern crypto::secret_key null_skey;
|
const extern crypto::secret_key null_skey;
|
||||||
@@ -336,6 +339,7 @@ inline const unsigned char* to_bytes(const crypto::ec_scalar &scalar) { return &
|
|||||||
inline unsigned char* to_bytes(crypto::ec_point &point) { return &reinterpret_cast<unsigned char&>(point); }
|
inline unsigned char* to_bytes(crypto::ec_point &point) { return &reinterpret_cast<unsigned char&>(point); }
|
||||||
inline const unsigned char* to_bytes(const crypto::ec_point &point) { return &reinterpret_cast<const unsigned char&>(point); }
|
inline const unsigned char* to_bytes(const crypto::ec_point &point) { return &reinterpret_cast<const unsigned char&>(point); }
|
||||||
|
|
||||||
|
CRYPTO_MAKE_HASHABLE(ec_point)
|
||||||
CRYPTO_MAKE_HASHABLE(public_key)
|
CRYPTO_MAKE_HASHABLE(public_key)
|
||||||
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(secret_key)
|
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(secret_key)
|
||||||
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(public_key_memsafe)
|
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(public_key_memsafe)
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Copyright (c) 2024, The Monero Project
|
||||||
|
#
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
# permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
# conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
# of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
# materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software without specific
|
||||||
|
# prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
set(fcmp_pp_sources
|
||||||
|
fcmp_pp_crypto.cpp)
|
||||||
|
|
||||||
|
monero_find_all_headers(fcmp_pp_headers "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
|
monero_add_library(fcmp_pp
|
||||||
|
${fcmp_pp_sources}
|
||||||
|
${fcmp_pp_headers})
|
||||||
|
|
||||||
|
target_link_libraries(fcmp_pp
|
||||||
|
PUBLIC
|
||||||
|
cncrypto
|
||||||
|
PRIVATE
|
||||||
|
${EXTRA_LIBRARIES})
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) 2024, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "fcmp_pp_crypto.h"
|
||||||
|
|
||||||
|
namespace fcmp_pp
|
||||||
|
{
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool mul8_is_identity_vartime(const ge_p3 &point) {
|
||||||
|
ge_p2 point_ge_p2;
|
||||||
|
ge_p3_to_p2(&point_ge_p2, &point);
|
||||||
|
ge_p1p1 point_mul8;
|
||||||
|
ge_mul8(&point_mul8, &point_ge_p2);
|
||||||
|
ge_p3 point_mul8_p3;
|
||||||
|
ge_p1p1_to_p3(&point_mul8_p3, &point_mul8);
|
||||||
|
return ge_p3_is_point_at_infinity_vartime(&point_mul8_p3);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
crypto::ec_point clear_torsion_vartime(const ge_p3 &point) {
|
||||||
|
// mul by inv 8, then mul by 8
|
||||||
|
ge_p2 point_inv_8;
|
||||||
|
ge_scalarmult(&point_inv_8, to_bytes(EC_INV_EIGHT), &point);
|
||||||
|
ge_p1p1 point_inv_8_mul_8;
|
||||||
|
ge_mul8(&point_inv_8_mul_8, &point_inv_8);
|
||||||
|
ge_p3 torsion_cleared_point;
|
||||||
|
ge_p1p1_to_p3(&torsion_cleared_point, &point_inv_8_mul_8);
|
||||||
|
crypto::ec_point k_out;
|
||||||
|
ge_p3_tobytes(to_bytes(k_out), &torsion_cleared_point);
|
||||||
|
return k_out;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool get_valid_torsion_cleared_point_vartime(const crypto::ec_point &point, crypto::ec_point &torsion_cleared_out) {
|
||||||
|
ge_p3 p3;
|
||||||
|
if (ge_frombytes_vartime(&p3, to_bytes(point)) != 0)
|
||||||
|
return false;
|
||||||
|
torsion_cleared_out = fcmp_pp::clear_torsion_vartime(p3);
|
||||||
|
if (torsion_cleared_out == EC_I)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
}//namespace fcmp_pp
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) 2024, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include "crypto/crypto-ops.h"
|
||||||
|
}
|
||||||
|
#include "crypto/crypto.h"
|
||||||
|
|
||||||
|
namespace fcmp_pp
|
||||||
|
{
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
static const crypto::ec_point EC_I = {1};
|
||||||
|
|
||||||
|
static const crypto::ec_scalar EC_INV_EIGHT = {{
|
||||||
|
static_cast<char>(static_cast<signed char>(121)), static_cast<char>(static_cast<signed char>(47)),
|
||||||
|
static_cast<char>(static_cast<signed char>(-36)), static_cast<char>(static_cast<signed char>(-30)),
|
||||||
|
static_cast<char>(static_cast<signed char>(41)), static_cast<char>(static_cast<signed char>(-27)),
|
||||||
|
static_cast<char>(static_cast<signed char>(6)), static_cast<char>(static_cast<signed char>(97)),
|
||||||
|
static_cast<char>(static_cast<signed char>(-48)), static_cast<char>(static_cast<signed char>(-38)),
|
||||||
|
static_cast<char>(static_cast<signed char>(28)), static_cast<char>(static_cast<signed char>(125)),
|
||||||
|
static_cast<char>(static_cast<signed char>(-77)), static_cast<char>(static_cast<signed char>(-99)),
|
||||||
|
static_cast<char>(static_cast<signed char>(-45)), static_cast<char>(static_cast<signed char>(7)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(0)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(0)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(0)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(0)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(0)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(0)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(0)),
|
||||||
|
static_cast<char>(static_cast<signed char>(0)), static_cast<char>(static_cast<signed char>(6))
|
||||||
|
}};
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
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);
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
}//namespace fcmp_pp
|
||||||
@@ -70,6 +70,7 @@ target_link_libraries(ringct
|
|||||||
common
|
common
|
||||||
cncrypto
|
cncrypto
|
||||||
device
|
device
|
||||||
|
fcmp_pp
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
${EXTRA_LIBRARIES})
|
${EXTRA_LIBRARIES})
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "rctSigs.h"
|
#include "rctSigs.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include "misc_log_ex.h"
|
#include "misc_log_ex.h"
|
||||||
#include "misc_language.h"
|
#include "misc_language.h"
|
||||||
#include "common/perf_timer.h"
|
#include "common/perf_timer.h"
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
#include "bulletproofs_plus.h"
|
#include "bulletproofs_plus.h"
|
||||||
#include "cryptonote_config.h"
|
#include "cryptonote_config.h"
|
||||||
#include "device/device.hpp"
|
#include "device/device.hpp"
|
||||||
|
#include "fcmp_pp/fcmp_pp_crypto.h"
|
||||||
#include "serialization/crypto.h"
|
#include "serialization/crypto.h"
|
||||||
|
|
||||||
using namespace crypto;
|
using namespace crypto;
|
||||||
@@ -1574,4 +1577,33 @@ namespace rct {
|
|||||||
key mask;
|
key mask;
|
||||||
return decodeRct(rv, sk, i, mask, hwdev);
|
return decodeRct(rv, sk, i, mask, hwdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool verPointsForTorsion(const std::vector<key> & pts) {
|
||||||
|
if (pts.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
|
||||||
|
tools::threadpool::waiter waiter(tpool);
|
||||||
|
|
||||||
|
std::atomic<bool> all_valid{true};
|
||||||
|
for (std::size_t i = 0; i < pts.size(); ++i)
|
||||||
|
{
|
||||||
|
tpool.submit(&waiter, [&pts, &all_valid, i]
|
||||||
|
{
|
||||||
|
const crypto::ec_point &point = rct::rct2pt(pts[i]);
|
||||||
|
crypto::ec_point torsion_cleared_point;
|
||||||
|
if (fcmp_pp::get_valid_torsion_cleared_point_vartime(point, torsion_cleared_point)
|
||||||
|
&& point == torsion_cleared_point)
|
||||||
|
{
|
||||||
|
// Point is torsion free if it's equal to itself after clearing torsion
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
all_valid.store(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_AND_ASSERT_MES(waiter.wait(), false, "threadpool waiter failed in torsion check");
|
||||||
|
CHECK_AND_ASSERT_MES(all_valid.load(), false, "Torsion check failed");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,9 @@ namespace rct {
|
|||||||
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask, hw::device &hwdev);
|
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask, hw::device &hwdev);
|
||||||
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, hw::device &hwdev);
|
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, hw::device &hwdev);
|
||||||
key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev);
|
key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev);
|
||||||
|
|
||||||
|
// Make sure points are valid points, don't have torsion, and are not equal to identity
|
||||||
|
bool verPointsForTorsion(const std::vector<key> & pts);
|
||||||
}
|
}
|
||||||
#endif /* RCTSIGS_H */
|
#endif /* RCTSIGS_H */
|
||||||
|
|
||||||
|
|||||||
@@ -741,10 +741,12 @@ namespace rct {
|
|||||||
static inline const rct::key &sk2rct(const crypto::secret_key &sk) { return (const rct::key&)sk; }
|
static inline const rct::key &sk2rct(const crypto::secret_key &sk) { return (const rct::key&)sk; }
|
||||||
static inline const rct::key &ki2rct(const crypto::key_image &ki) { return (const rct::key&)ki; }
|
static inline const rct::key &ki2rct(const crypto::key_image &ki) { return (const rct::key&)ki; }
|
||||||
static inline const rct::key &hash2rct(const crypto::hash &h) { return (const rct::key&)h; }
|
static inline const rct::key &hash2rct(const crypto::hash &h) { return (const rct::key&)h; }
|
||||||
|
static inline const rct::key &pt2rct(const crypto::ec_point &pt) { return (const rct::key&)pt; }
|
||||||
static inline const crypto::public_key &rct2pk(const rct::key &k) { return (const crypto::public_key&)k; }
|
static inline const crypto::public_key &rct2pk(const rct::key &k) { return (const crypto::public_key&)k; }
|
||||||
static inline const crypto::secret_key &rct2sk(const rct::key &k) { return (const crypto::secret_key&)k; }
|
static inline const crypto::secret_key &rct2sk(const rct::key &k) { return (const crypto::secret_key&)k; }
|
||||||
static inline const crypto::key_image &rct2ki(const rct::key &k) { return (const crypto::key_image&)k; }
|
static inline const crypto::key_image &rct2ki(const rct::key &k) { return (const crypto::key_image&)k; }
|
||||||
static inline const crypto::hash &rct2hash(const rct::key &k) { return (const crypto::hash&)k; }
|
static inline const crypto::hash &rct2hash(const rct::key &k) { return (const crypto::hash&)k; }
|
||||||
|
static inline const crypto::ec_point &rct2pt(const rct::key &k) { return (const crypto::ec_point&)k; }
|
||||||
static inline bool operator==(const rct::key &k0, const crypto::public_key &k1) { return !crypto_verify_32(k0.bytes, (const unsigned char*)&k1); }
|
static inline bool operator==(const rct::key &k0, const crypto::public_key &k1) { return !crypto_verify_32(k0.bytes, (const unsigned char*)&k1); }
|
||||||
static inline bool operator!=(const rct::key &k0, const crypto::public_key &k1) { return crypto_verify_32(k0.bytes, (const unsigned char*)&k1); }
|
static inline bool operator!=(const rct::key &k0, const crypto::public_key &k1) { return crypto_verify_32(k0.bytes, (const unsigned char*)&k1); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,6 @@ bool operator !=(const ec_scalar &a, const ec_scalar &b) {
|
|||||||
return 0 != memcmp(&a, &b, sizeof(ec_scalar));
|
return 0 != memcmp(&a, &b, sizeof(ec_scalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(const ec_point &a, const ec_point &b) {
|
|
||||||
return 0 != memcmp(&a, &b, sizeof(ec_point));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator !=(const key_derivation &a, const key_derivation &b) {
|
bool operator !=(const key_derivation &a, const key_derivation &b) {
|
||||||
return 0 != memcmp(&a, &b, sizeof(key_derivation));
|
return 0 != memcmp(&a, &b, sizeof(key_derivation));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ target_link_libraries(unit_tests
|
|||||||
daemon_messages
|
daemon_messages
|
||||||
daemon_rpc_server
|
daemon_rpc_server
|
||||||
blockchain_db
|
blockchain_db
|
||||||
|
fcmp_pp
|
||||||
lmdb_lib
|
lmdb_lib
|
||||||
rpc
|
rpc
|
||||||
net
|
net
|
||||||
|
|||||||
@@ -39,8 +39,11 @@ extern "C"
|
|||||||
}
|
}
|
||||||
#include "crypto/generators.h"
|
#include "crypto/generators.h"
|
||||||
#include "cryptonote_basic/merge_mining.h"
|
#include "cryptonote_basic/merge_mining.h"
|
||||||
|
#include "fcmp_pp/fcmp_pp_crypto.h"
|
||||||
#include "ringct/rctOps.h"
|
#include "ringct/rctOps.h"
|
||||||
|
#include "ringct/rctSigs.h"
|
||||||
#include "ringct/rctTypes.h"
|
#include "ringct/rctTypes.h"
|
||||||
|
#include "string_tools.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -429,3 +432,92 @@ TEST(Crypto, fe_equals)
|
|||||||
ASSERT_NE(memcmp(fe_d2_reduced, fe_d2, sizeof(fe)), 0);
|
ASSERT_NE(memcmp(fe_d2_reduced, fe_d2, sizeof(fe)), 0);
|
||||||
ASSERT_EQ(fe_equals(fe_d2_reduced, fe_d2), 1);
|
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