Proxy miner signature support (WIP)

This commit is contained in:
SChernykh 2021-06-17 16:58:18 +02:00
parent bc63b63a2a
commit ebe299902c
9 changed files with 71 additions and 22 deletions

View file

@ -81,6 +81,7 @@ set(HEADERS_BASE
src/base/tools/cryptonote/Signatures.h
src/base/tools/cryptonote/WalletAddress.h
src/base/tools/cryptonote/crypto-ops.h
src/base/tools/cryptonote/umul128.h
)
set(SOURCES_BASE

View file

@ -267,24 +267,6 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
}
m_blockhashingblob = Json::getString(params, "blockhashing_blob");
if (m_apiVersion == API_DERO) {
const uint64_t offset = Json::getUint64(params, "reserved_offset");
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
}
if (pool_coin.isValid()) {
job.setAlgorithm(pool_coin.algorithm(m_blocktemplate.major_version));
}
if (!job.setBlob(m_blockhashingblob)) {
*code = 3;
return false;
}
job.setSeedHash(Json::getString(params, "seed_hash"));
job.setHeight(Json::getUint64(params, kHeight));
job.setDiff(Json::getUint64(params, "difficulty"));
job.setId(blocktemplate.data() + blocktemplate.size() - 32);
if (m_blocktemplate.has_miner_signature) {
if (m_pool.spendSecretKey().isEmpty()) {
@ -324,6 +306,29 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
}
uint8_t derivation[32];
# ifdef XMRIG_PROXY_PROJECT
// Generate unique keys for miner transaction
// TODO: make it unique for each connection
{
uint8_t* eph_public_key = m_blocktemplate.raw_blob.data() + m_blocktemplate.eph_public_key_index;
uint8_t* txkey_pub = m_blocktemplate.raw_blob.data() + m_blocktemplate.tx_pubkey_index;
uint8_t txkey_sec[32];
generate_keys(txkey_pub, txkey_sec);
generate_key_derivation(public_viewkey, txkey_sec, derivation);
derive_public_key(derivation, 0, public_spendkey, eph_public_key);
Cvt::toHex(blocktemplate.data() + m_blocktemplate.eph_public_key_index * 2, 64, eph_public_key, 32);
Cvt::toHex(blocktemplate.data() + m_blocktemplate.tx_pubkey_index * 2, 64, txkey_pub, 32);
m_blocktemplate.UpdateMinerTxHash();
m_blocktemplate.GenerateHashingBlob();
Cvt::toHex(m_blockhashingblob.data() + m_blocktemplate.miner_tx_prefix_begin_index * 2, 64, m_blocktemplate.root_hash, 32);
}
# endif
if (!generate_key_derivation(m_blocktemplate.raw_blob.data() + m_blocktemplate.tx_pubkey_index, secret_viewkey, derivation)) {
LOG_ERR("Failed to generate key derivation for miner signature.");
*code = 9;
@ -356,6 +361,26 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
job.setTimestamp(m_blocktemplate.timestamp);
}
if (m_apiVersion == API_DERO) {
const uint64_t offset = Json::getUint64(params, "reserved_offset");
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
}
if (pool_coin.isValid()) {
job.setAlgorithm(pool_coin.algorithm(m_blocktemplate.major_version));
}
if (!job.setBlob(m_blockhashingblob)) {
*code = 3;
return false;
}
job.setSeedHash(Json::getString(params, "seed_hash"));
job.setHeight(Json::getUint64(params, kHeight));
job.setDiff(Json::getUint64(params, "difficulty"));
job.setId(blocktemplate.data() + blocktemplate.size() - 32);
m_job = std::move(job);
m_blocktemplateStr = std::move(blocktemplate);
m_prevHash = Json::getString(params, "prev_hash");

View file

@ -80,7 +80,6 @@ struct BlockTemplate
bool Init(const String& blockTemplate, Coin coin);
private:
void CalculateMinerTxHash(uint8_t* hash);
void CalculateMerkleTreeHash();
void UpdateMinerTxHash();

View file

@ -167,6 +167,30 @@ void derive_secret_key(const uint8_t* derivation, size_t output_index, const uin
}
bool derive_public_key(const uint8_t* derivation, size_t output_index, const uint8_t* base, uint8_t* derived_key)
{
ec_scalar scalar;
ge_p3 point1;
ge_p3 point2;
ge_cached point3;
ge_p1p1 point4;
ge_p2 point5;
if (ge_frombytes_vartime(&point1, base) != 0) {
return false;
}
derivation_to_scalar(derivation, output_index, scalar);
ge_scalarmult_base(&point2, (uint8_t*) &scalar);
ge_p3_to_cached(&point3, &point2);
ge_add(&point4, &point1, &point3);
ge_p1p1_to_p2(&point5, &point4);
ge_tobytes(derived_key, &point5);
return true;
}
void derive_view_secret_key(const uint8_t* spend_secret_key, uint8_t* view_secret_key)
{
keccak(spend_secret_key, 32, view_secret_key, 32);

View file

@ -33,6 +33,7 @@ bool check_signature(const uint8_t* prefix_hash, const uint8_t* pub, const uint8
bool generate_key_derivation(const uint8_t* key1, const uint8_t* key2, uint8_t* derivation);
void derive_secret_key(const uint8_t* derivation, size_t output_index, const uint8_t* base, uint8_t* derived_key);
bool derive_public_key(const uint8_t* derivation, size_t output_index, const uint8_t* base, uint8_t* derived_key);
void derive_view_secret_key(const uint8_t* spend_secret_key, uint8_t* view_secret_key);

View file

@ -22,8 +22,8 @@
#include "base/crypto/keccak.h"
#include "base/tools/cryptonote/BlobReader.h"
#include "base/tools/cryptonote/WalletAddress.h"
#include "base/tools/cryptonote/umul128.h"
#include "base/tools/Buffer.h"
#include "crypto/cn/umul128.h"
#include <array>

View file

@ -0,0 +1,68 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with OpenSSL (or a modified version of that library), containing parts
* covered by the terms of OpenSSL License and SSLeay License, the licensors
* of this Program grant you additional permission to convey the resulting work.
*
*/
#pragma once
#include <cstdint>
#ifdef XMRIG_64_BIT
# ifdef _MSC_VER
# include <intrin.h>
# pragma intrinsic(_umul128)
# define __umul128 _umul128
# elif defined __GNUC__
static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi)
{
unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b;
*hi = r >> 64;
return (uint64_t) r;
}
# define __umul128 _umul128
# endif
#else
static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) {
// multiplier = ab = a * 2^32 + b
// multiplicand = cd = c * 2^32 + d
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
uint64_t a = multiplier >> 32;
uint64_t b = multiplier & 0xFFFFFFFF;
uint64_t c = multiplicand >> 32;
uint64_t d = multiplicand & 0xFFFFFFFF;
//uint64_t ac = a * c;
uint64_t ad = a * d;
//uint64_t bc = b * c;
uint64_t bd = b * d;
uint64_t adbc = ad + (b * c);
uint64_t adbc_carry = adbc < ad ? 1 : 0;
// multiplier * multiplicand = product_hi * 2^64 + product_lo
uint64_t product_lo = bd + (adbc << 32);
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
*product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
return product_lo;
}
#endif