Added checks for tx keys

This commit is contained in:
SChernykh 2021-08-31 17:23:20 +02:00
parent 0558cdb9cc
commit 780afd84a2
9 changed files with 66 additions and 16 deletions

View file

@ -628,7 +628,9 @@ bool BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Min
}
else {
hash eph_public_key;
shares[i].m_wallet->get_eph_public_key(m_txkeySec, i, eph_public_key);
if (!shares[i].m_wallet->get_eph_public_key(m_txkeySec, i, eph_public_key)) {
LOGERR(1, "get_eph_public_key failed at index " << i);
}
m_minerTx.insert(m_minerTx.end(), eph_public_key.h, eph_public_key.h + HASH_SIZE);
m_poolBlockTemplate->m_outputs.emplace_back(m_rewards[i], eph_public_key);
}

View file

@ -84,10 +84,7 @@ void generate_keys(hash& pub, hash& sec)
static constexpr uint8_t limit[32] = { 0xe3, 0x6a, 0x67, 0x72, 0x8b, 0xce, 0x13, 0x29, 0x8f, 0x30, 0x82, 0x8c, 0x0b, 0xa4, 0x10, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 };
do {
randomBytes(sec.h);
if (!less32(sec.h, limit)) {
continue;
}
do { randomBytes(sec.h); } while (!less32(sec.h, limit));
sc_reduce32(sec.h);
} while (!sc_isnonzero(sec.h));
@ -96,6 +93,22 @@ void generate_keys(hash& pub, hash& sec)
ge_p3_tobytes(pub.h, &point);
}
bool check_keys(const hash& pub, const hash& sec)
{
// From ge_scalarmult_base's comment: "preconditions a[31] <= 127"
if (sec.h[HASH_SIZE - 1] > 127) {
return false;
}
ge_p3 point;
ge_scalarmult_base(&point, sec.h);
hash pub_check;
ge_p3_tobytes(pub_check.h, &point);
return pub == pub_check;
}
bool generate_key_derivation(const hash& key1, const hash& key2, hash& derivation)
{
ge_p3 point;

View file

@ -20,6 +20,7 @@
namespace p2pool {
void generate_keys(hash& pub, hash& sec);
bool check_keys(const hash& pub, const hash& sec);
bool generate_key_derivation(const hash& key1, const hash& key2, hash& derivation);
bool derive_public_key(const hash& derivation, size_t output_index, const hash& base, hash& derived_key);

View file

@ -721,7 +721,7 @@ bool P2PServer::P2PClient::on_connect()
// server->m_clientsListLock is already locked here
for (P2PClient* client = static_cast<P2PClient*>(server->m_connectedClientsList->m_next); client != server->m_connectedClientsList; client = static_cast<P2PClient*>(client->m_next)) {
if ((client != this) && (client->m_addr == m_addr)) {
LOGWARN(5, "peer " << static_cast<char*>(m_addrString) << " is already connected as " << static_cast<char*>(client->m_addrString));
LOGINFO(5, "peer " << static_cast<char*>(m_addrString) << " is already connected as " << static_cast<char*>(client->m_addrString));
return false;
}
}

View file

@ -20,6 +20,7 @@
#include "keccak.h"
#include "side_chain.h"
#include "pow_hash.h"
#include "crypto.h"
static constexpr char log_category_prefix[] = "PoolBlock ";

View file

@ -233,9 +233,16 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, SideChain& sidechai
hash view_pub_key;
READ_BUF(spend_pub_key.h, HASH_SIZE);
READ_BUF(view_pub_key.h, HASH_SIZE);
m_minerWallet.assign(spend_pub_key, view_pub_key);
if (!m_minerWallet.assign(spend_pub_key, view_pub_key, sidechain.network_type())) {
return __LINE__;
}
READ_BUF(m_txkeySec.h, HASH_SIZE);
if (!check_keys(m_txkeyPub, m_txkeySec)) {
return __LINE__;
}
READ_BUF(m_parent.h, HASH_SIZE);
uint64_t num_uncles;

View file

@ -550,7 +550,9 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
blob.emplace_back(TXOUT_TO_KEY);
shares[i].m_wallet->get_eph_public_key(block->m_txkeySec, i, eph_public_key);
if (!shares[i].m_wallet->get_eph_public_key(block->m_txkeySec, i, eph_public_key)) {
LOGWARN(6, "get_eph_public_key failed at index " << i);
}
blob.insert(blob.end(), eph_public_key.h, eph_public_key.h + HASH_SIZE);
block->m_outputs.emplace_back(rewards[i], eph_public_key);
@ -1146,7 +1148,14 @@ void SideChain::verify(PoolBlock* block)
}
hash eph_public_key;
shares[i].m_wallet->get_eph_public_key(block->m_txkeySec, i, eph_public_key);
if (!shares[i].m_wallet->get_eph_public_key(block->m_txkeySec, i, eph_public_key)) {
LOGWARN(3, "block at height = " << block->m_sidechainHeight <<
", id = " << block->m_sidechainId <<
", mainchain height = " << block->m_txinGenHeight <<
" failed to eph_public_key at index " << i);
block->m_invalid = true;
return;
}
if (eph_public_key != block->m_outputs[i].m_ephPublicKey) {
LOGWARN(3, "block at height = " << block->m_sidechainHeight <<

View file

@ -24,6 +24,10 @@
#include "crypto.h"
#include <array>
extern "C" {
#include "crypto-ops.h"
}
static constexpr char log_category_prefix[] = "Wallet ";
namespace {
@ -189,8 +193,13 @@ bool Wallet::decode(const char* address)
return valid();
}
void Wallet::assign(const hash& spend_pub_key, const hash& view_pub_key)
bool Wallet::assign(const hash& spend_pub_key, const hash& view_pub_key, NetworkType type)
{
ge_p3 point;
if ((ge_frombytes_vartime(&point, spend_pub_key.h) != 0) || (ge_frombytes_vartime(&point, view_pub_key.h) != 0)) {
return false;
}
MutexLock lock(m_lock);
m_prefix = 0;
@ -198,15 +207,17 @@ void Wallet::assign(const hash& spend_pub_key, const hash& view_pub_key)
m_viewPublicKey = view_pub_key;
m_checksum = 0;
m_type = NetworkType::Mainnet;
m_type = type;
m_txkeySec = {};
m_outputIndex = std::numeric_limits<size_t>::max();
m_derivation = {};
m_ephPublicKey = {};
return true;
}
void Wallet::get_eph_public_key(const hash& txkey_sec, size_t output_index, hash& eph_public_key)
bool Wallet::get_eph_public_key(const hash& txkey_sec, size_t output_index, hash& eph_public_key)
{
MutexLock lock(m_lock);
@ -217,7 +228,9 @@ void Wallet::get_eph_public_key(const hash& txkey_sec, size_t output_index, hash
derivation = m_derivation;
}
else {
generate_key_derivation(m_viewPublicKey, txkey_sec, derivation);
if (!generate_key_derivation(m_viewPublicKey, txkey_sec, derivation)) {
return false;
}
m_derivation = derivation;
m_txkeySec = txkey_sec;
derivation_changed = true;
@ -227,10 +240,14 @@ void Wallet::get_eph_public_key(const hash& txkey_sec, size_t output_index, hash
eph_public_key = m_ephPublicKey;
}
else {
derive_public_key(derivation, output_index, m_spendPublicKey, eph_public_key);
if (!derive_public_key(derivation, output_index, m_spendPublicKey, eph_public_key)) {
return false;
}
m_outputIndex = output_index;
m_ephPublicKey = eph_public_key;
}
return true;
}
} // namespace p2pool

View file

@ -34,12 +34,12 @@ public:
FORCEINLINE NetworkType type() const { return m_type; }
bool decode(const char* address);
void assign(const hash& spend_pub_key, const hash& view_pub_key);
bool assign(const hash& spend_pub_key, const hash& view_pub_key, NetworkType type);
FORCEINLINE const hash& spend_public_key() const { return m_spendPublicKey; }
FORCEINLINE const hash& view_public_key() const { return m_viewPublicKey; }
void get_eph_public_key(const hash& txkey_sec, size_t output_index, hash& eph_public_key);
bool get_eph_public_key(const hash& txkey_sec, size_t output_index, hash& eph_public_key);
FORCEINLINE bool operator<(const Wallet& w) const { return m_spendPublicKey < w.m_spendPublicKey; }
FORCEINLINE bool operator==(const Wallet& w) const { return m_spendPublicKey == w.m_spendPublicKey; }