// (C) 2018 The Verus Developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. /* This provides the PoW hash function for Verus, enabling CPU mining. */ #ifndef VERUS_HASH_H_ #define VERUS_HASH_H_ #include #include #include extern "C" { #include "crypto/haraka.h" #include "crypto/haraka_portable.h" } class CVerusHash { public: static void Hash(void *result, const void *data, size_t len); static void (*haraka512Function)(unsigned char *out, const unsigned char *in); static void init(); CVerusHash() { } CVerusHash &Write(const unsigned char *data, size_t len); CVerusHash &Reset() { curBuf = buf1; result = buf2; curPos = 0; std::fill(buf1, buf1 + sizeof(buf1), 0); return *this; } int64_t *ExtraI64Ptr() { return (int64_t *)(curBuf + 32); } void ClearExtra() { if (curPos) { std::fill(curBuf + 32 + curPos, curBuf + 64, 0); } } void ExtraHash(unsigned char hash[32]) { (*haraka512Function)(hash, curBuf); } void Finalize(unsigned char hash[32]) { if (curPos) { std::fill(curBuf + 32 + curPos, curBuf + 64, 0); (*haraka512Function)(hash, curBuf); } else std::memcpy(hash, curBuf, 32); } private: // only buf1, the first source, needs to be zero initialized unsigned char buf1[64] = {0}, buf2[64]; unsigned char *curBuf = buf1, *result = buf2; size_t curPos = 0; }; class CVerusHashV2 { public: static void Hash(void *result, const void *data, size_t len); static void (*haraka512Function)(unsigned char *out, const unsigned char *in); static void init(); CVerusHashV2() {} CVerusHashV2 &Write(const unsigned char *data, size_t len); CVerusHashV2 &Reset() { curBuf = buf1; result = buf2; curPos = 0; std::fill(buf1, buf1 + sizeof(buf1), 0); } int64_t *ExtraI64Ptr() { return (int64_t *)(curBuf + 32); } void ClearExtra() { if (curPos) { std::fill(curBuf + 32 + curPos, curBuf + 64, 0); } } void ExtraHash(unsigned char hash[32]) { (*haraka512Function)(hash, curBuf); } void Finalize(unsigned char hash[32]) { if (curPos) { std::fill(curBuf + 32 + curPos, curBuf + 64, 0); (*haraka512Function)(hash, curBuf); } else std::memcpy(hash, curBuf, 32); } private: // only buf1, the first source, needs to be zero initialized unsigned char buf1[64] = {0}, buf2[64]; unsigned char *curBuf = buf1, *result = buf2; size_t curPos = 0; }; extern void verus_hash(void *result, const void *data, size_t len); extern void verus_hash_v2(void *result, const void *data, size_t len); inline bool IsCPUVerusOptimized() { unsigned int eax,ebx,ecx,edx; if (!__get_cpuid(1,&eax,&ebx,&ecx,&edx)) { return false; } return ((ecx & (bit_AVX | bit_AES)) == (bit_AVX | bit_AES)); }; #endif