Merge pull request #256 from wowario/SHA-3

switch to SHA-3 PoW
This commit is contained in:
jw 2020-05-18 15:03:57 -07:00 committed by GitHub
commit 3b1c27db69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 89 additions and 23 deletions

View file

@ -42,6 +42,7 @@ set(crypto_sources
hmac-keccak.c
jh.c
keccak.c
sha3.c
oaes_lib.c
random.c
skein.c

View file

@ -85,6 +85,7 @@ void hash_extra_blake(const void *data, size_t length, char *hash);
void hash_extra_groestl(const void *data, size_t length, char *hash);
void hash_extra_jh(const void *data, size_t length, char *hash);
void hash_extra_skein(const void *data, size_t length, char *hash);
void sha3(const void *data, size_t length, char *hash);
void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash);

View file

@ -73,6 +73,10 @@ namespace crypto {
inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/, height);
}
inline void sha3(const void *data, std::size_t length, hash &hash) {
sha3(data, length, reinterpret_cast<char *>(&hash));
}
inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/, height);

29
src/crypto/sha3.c Normal file
View file

@ -0,0 +1,29 @@
#include <stddef.h>
#include <openssl/evp.h>
void handleErrors(void) {
printf("sha3 error, wow is ded\n");
exit(1);
}
void sha3(const void *data, size_t length, char *hash)
{
EVP_MD_CTX *mdctx;
if((mdctx = EVP_MD_CTX_new()) == NULL) {
handleErrors();
}
if(1 != EVP_DigestInit_ex(mdctx, EVP_sha3_256(), NULL)) {
handleErrors();
}
if(1 != EVP_DigestUpdate(mdctx, data, length)) {
handleErrors();
}
/* the digest context ctx is automatically cleaned up. */
if(1 != EVP_DigestFinal(mdctx, (unsigned char*)hash, NULL)) {
handleErrors();
}
}

View file

@ -449,14 +449,26 @@ namespace cryptonote
uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
uint64_t timestamp;
crypto::hash prev_id;
uint32_t nonce;
uint64_t nonce;
BEGIN_SERIALIZE()
VARINT_FIELD(major_version)
VARINT_FIELD(minor_version)
VARINT_FIELD(timestamp)
FIELD(prev_id)
FIELD(nonce)
if (major_version >= HF_VERSION_SHA3_POW)
{
FIELD(nonce)
}
else
{
uint32_t nonce32;
if (typename Archive<W>::is_saving())
nonce32 = (uint32_t)nonce;
FIELD_N("nonce", nonce32);
if (!typename Archive<W>::is_saving())
nonce = nonce32;
}
END_SERIALIZE()
};

View file

@ -144,7 +144,7 @@ namespace cryptonote
m_height = height;
m_block_reward = block_reward;
++m_template_no;
m_starter_nonce = crypto::rand<uint32_t>();
m_starter_nonce = crypto::rand<uint64_t>();
return true;
}
//-----------------------------------------------------------------------------------------------------
@ -375,7 +375,7 @@ namespace cryptonote
m_threads_autodetect.push_back({epee::misc_utils::get_ns_count(), m_total_hashes});
m_threads_total = 1;
}
m_starter_nonce = crypto::rand<uint32_t>();
m_starter_nonce = crypto::rand<uint64_t>();
CRITICAL_REGION_LOCAL(m_threads_lock);
if(is_mining())
{
@ -473,7 +473,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------------
bool miner::find_nonce_for_given_block(const get_block_hash_t &gbh, block& bl, const difficulty_type& diffic, uint64_t height)
{
for(; bl.nonce != std::numeric_limits<uint32_t>::max(); bl.nonce++)
for(; bl.nonce != std::numeric_limits<uint64_t>::max(); bl.nonce++)
{
crypto::hash h;
gbh(bl, height, diffic <= 100 ? 0 : tools::get_max_concurrency(), h);
@ -524,7 +524,7 @@ namespace cryptonote
uint32_t th_local_index = boost::interprocess::ipcdetail::atomic_inc32(&m_thread_index);
MLOG_SET_THREAD_NAME(std::string("[miner ") + std::to_string(th_local_index) + "]");
MGINFO("Miner thread was started ["<< th_local_index << "]");
uint32_t nonce = m_starter_nonce + th_local_index;
uint64_t nonce = m_starter_nonce + th_local_index;
uint64_t height = 0;
difficulty_type local_diff = 0;
uint32_t local_template_ver = 0;

View file

@ -123,7 +123,7 @@ namespace cryptonote
epee::critical_section m_template_lock;
block m_template;
std::atomic<uint32_t> m_template_no;
std::atomic<uint32_t> m_starter_nonce;
std::atomic<uint64_t> m_starter_nonce;
difficulty_type m_diffic;
uint64_t m_height;
volatile uint32_t m_thread_index;

View file

@ -178,6 +178,7 @@
#define HF_VERSION_REJECT_SIGS_IN_COINBASE 15
#define HF_VERSION_ENFORCE_MIN_AGE 15
#define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY 15
#define HF_VERSION_SHA3_POW 16 // Block 288,888 ~8 February 2021
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8

View file

@ -1761,7 +1761,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");
crypto::hash proof_of_work;
memset(proof_of_work.data, 0xff, sizeof(proof_of_work.data));
if (b.major_version >= RX_BLOCK_VERSION)
if (b.major_version >= RX_BLOCK_VERSION && b.major_version < HF_VERSION_SHA3_POW)
{
crypto::hash seedhash = null_hash;
uint64_t seedheight = rx_seedheight(bei.height);

View file

@ -681,7 +681,11 @@ namespace cryptonote
bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const int miners)
{
blobdata bd = get_block_hashing_blob(b);
if (b.major_version >= RX_BLOCK_VERSION)
if (b.major_version >= HF_VERSION_SHA3_POW)
{
crypto::sha3(bd.data(), bd.size(), res);
}
else if (b.major_version >= RX_BLOCK_VERSION && b.major_version < HF_VERSION_SHA3_POW)
{
uint64_t seed_height, main_height;
crypto::hash hash;

View file

@ -41,6 +41,7 @@ const hardfork_t mainnet_hard_forks[] = {
{ 13, 114969, 0, 1559292691 },
{ 14, 115257, 0, 1559292774 },
{ 15, 160777, 0, 1573280497 },
{ 16, 288888, 0, 1589210508 },
};
const size_t num_mainnet_hard_forks = sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]);

View file

@ -1261,7 +1261,7 @@ namespace cryptonote
if (lMiner.is_mining() || lMiner.get_is_background_mining_enabled())
res.address = get_account_address_as_str(nettype(), false, lMiningAdr);
const uint8_t major_version = m_core.get_blockchain_storage().get_current_hard_fork_version();
const unsigned variant = major_version >= 13 ? 6 : major_version >= 11 && major_version <= 12 ? 4 : 2;
const unsigned variant = major_version >= HF_VERSION_SHA3_POW ? 7 : major_version >= 13 && major_version < HF_VERSION_SHA3_POW ? 6 : major_version >= 11 && major_version <= 12 ? 4 : 2;
switch (variant)
{
case 0: res.pow_algorithm = "Cryptonight"; break;
@ -1269,6 +1269,7 @@ namespace cryptonote
case 2: case 3: res.pow_algorithm = "CNv2 (Cryptonight variant 2)"; break;
case 4: case 5: res.pow_algorithm = "CN/WOW"; break;
case 6: res.pow_algorithm = "RandomWOW"; break;
case 7: res.pow_algorithm = "SHA-3"; break;
default: res.pow_algorithm = "I'm not sure actually"; break;
}
if (res.is_background_mining_enabled)
@ -1621,7 +1622,7 @@ namespace cryptonote
return false;
}
if (b.major_version >= RX_BLOCK_VERSION)
if (b.major_version >= RX_BLOCK_VERSION && b.major_version < HF_VERSION_SHA3_POW)
{
uint64_t next_height;
crypto::rx_seedheights(height, &seed_height, &next_height);
@ -1736,7 +1737,7 @@ namespace cryptonote
crypto::hash seed_hash, next_seed_hash;
if (!get_block_template(info.address, req.prev_block.empty() ? NULL : &prev_block, blob_reserve, reserved_offset, wdiff, res.height, res.expected_reward, b, res.seed_height, seed_hash, next_seed_hash, error_resp))
return false;
if (b.major_version >= RX_BLOCK_VERSION)
if (b.major_version >= RX_BLOCK_VERSION && b.major_version < HF_VERSION_SHA3_POW)
{
res.seed_hash = string_tools::pod_to_hex(seed_hash);
if (seed_hash != next_seed_hash)
@ -3017,7 +3018,7 @@ namespace cryptonote
}
res.hashing_blob = epee::string_tools::buff_to_hex_nodelimer(hashing_blob);
res.top_hash = epee::string_tools::pod_to_hex(top_hash);
if (hashing_blob[0] >= RX_BLOCK_VERSION)
if (hashing_blob[0] >= RX_BLOCK_VERSION && hashing_blob[0] < HF_VERSION_SHA3_POW)
{
res.seed_hash = string_tools::pod_to_hex(seed_hash);
if (seed_hash != next_seed_hash)

View file

@ -984,7 +984,7 @@ namespace cryptonote
uint8_t minor_version;
uint64_t timestamp;
std::string prev_hash;
uint32_t nonce;
uint64_t nonce;
bool orphan_status;
uint64_t height;
uint64_t depth;
@ -1008,7 +1008,19 @@ namespace cryptonote
KV_SERIALIZE(minor_version)
KV_SERIALIZE(timestamp)
KV_SERIALIZE(prev_hash)
KV_SERIALIZE(nonce)
if (this_ref.major_version >= HF_VERSION_SHA3_POW)
{
KV_SERIALIZE(nonce)
}
else
{
uint32_t nonce32;
if (is_store)
nonce32 = (uint32_t)this_ref.nonce;
epee::serialization::selector<is_store>::serialize(nonce32, stg, hparent_section, "nonce");
if (!is_store)
const_cast<uint64_t &>(this_ref.nonce) = nonce32;
}
KV_SERIALIZE(orphan_status)
KV_SERIALIZE(height)
KV_SERIALIZE(depth)
@ -2350,7 +2362,7 @@ namespace cryptonote
{
struct request_t: public rpc_access_request_base
{
uint32_t nonce;
uint64_t nonce;
uint32_t cookie;
BEGIN_KV_SERIALIZE_MAP()

View file

@ -163,7 +163,7 @@ namespace rpc
uint64_t minor_version;
uint64_t timestamp;
crypto::hash prev_id;
uint32_t nonce;
uint64_t nonce;
uint64_t height;
uint64_t depth;
crypto::hash hash;

View file

@ -178,7 +178,7 @@ namespace cryptonote
return true;
}
bool rpc_payment::submit_nonce(const crypto::public_key &client, uint32_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale)
bool rpc_payment::submit_nonce(const crypto::public_key &client, uint64_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale)
{
client_info &info = m_client_info[client]; // creates if not found
if (cookie != info.cookie && cookie != info.cookie - 1)
@ -231,7 +231,7 @@ namespace cryptonote
block = is_current ? info.block : info.previous_block;
*(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(nonce);
if (block.major_version >= RX_BLOCK_VERSION)
if (block.major_version >= RX_BLOCK_VERSION && block.major_version < HF_VERSION_SHA3_POW)
{
const uint64_t seed_height = is_current ? info.seed_height : info.previous_seed_height;
const crypto::hash &seed_hash = is_current ? info.seed_hash : info.previous_seed_hash;

View file

@ -102,7 +102,7 @@ namespace cryptonote
uint64_t balance(const crypto::public_key &client, int64_t delta = 0);
bool pay(const crypto::public_key &client, uint64_t ts, uint64_t payment, const std::string &rpc, bool same_ts, uint64_t &credits);
bool get_info(const crypto::public_key &client, const std::function<bool(const cryptonote::blobdata&, cryptonote::block&, uint64_t &seed_height, crypto::hash &seed_hash)> &get_block_template, cryptonote::blobdata &hashing_blob, uint64_t &seed_height, crypto::hash &seed_hash, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie);
bool submit_nonce(const crypto::public_key &client, uint32_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale);
bool submit_nonce(const crypto::public_key &client, uint64_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale);
const cryptonote::account_public_address &get_payment_address() const { return m_address; }
bool foreach(const std::function<bool(const crypto::public_key &client, const client_info &info)> &f) const;
unsigned int flush_by_age(time_t seconds = 0);

View file

@ -1276,7 +1276,7 @@ private:
bool get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &hashing_blob, uint64_t &height, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie);
bool daemon_requires_payment();
bool make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance);
bool make_rpc_payment(uint64_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance);
bool search_for_rpc_payment(uint64_t credits_target, const std::function<bool(uint64_t, uint64_t)> &startfunc, const std::function<bool(unsigned)> &contfunc, const std::function<bool(uint64_t)> &foundfunc = NULL, const std::function<void(const std::string&)> &errorfunc = NULL);
template<typename T> void handle_payment_changes(const T &res, std::true_type) {
if (res.status == CORE_RPC_STATUS_OK || res.status == CORE_RPC_STATUS_PAYMENT_REQUIRED)

View file

@ -75,7 +75,7 @@ bool wallet2::daemon_requires_payment()
return get_rpc_payment_info(false, payment_required, credits, diff, credits_per_hash_found, blob, height, seed_height, seed_hash, next_seed_hash, cookie) && payment_required;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance)
bool wallet2::make_rpc_payment(uint64_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance)
{
cryptonote::COMMAND_RPC_ACCESS_SUBMIT_NONCE::request req = AUTO_VAL_INIT(req);
cryptonote::COMMAND_RPC_ACCESS_SUBMIT_NONCE::response res = AUTO_VAL_INIT(res);
@ -143,7 +143,7 @@ bool wallet2::search_for_rpc_payment(uint64_t credits_target, const std::functio
const uint32_t local_nonce = nonce++; // wrapping's OK
*(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(local_nonce);
const uint8_t major_version = hashing_blob[0];
if (major_version >= RX_BLOCK_VERSION)
if (major_version >= RX_BLOCK_VERSION && major_version < HF_VERSION_SHA3_POW)
{
const int miners = 1;
crypto::rx_slow_hash(height, seed_height, seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash.data, miners, 0);