From: CryptoManiac Date: Wed, 1 Apr 2015 20:37:59 +0000 (+0300) Subject: Merge pull request #191 from novacoin-project/scaninput X-Git-Tag: nvc-v0.5.3~52 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=0068ce8ee8d23110a8d892f3213fe7335bf98813;hp=28fdb061d3af424edea93c095219a5862fffba7c Merge pull request #191 from novacoin-project/scaninput Scaninput --- diff --git a/novacoin-qt.pro b/novacoin-qt.pro index 585782d..de9d411 100644 --- a/novacoin-qt.pro +++ b/novacoin-qt.pro @@ -212,7 +212,6 @@ HEADERS += src/qt/bitcoingui.h \ src/uint256.h \ src/kernel.h \ src/scrypt.h \ - src/pbkdf2.h \ src/serialize.h \ src/strlcpy.h \ src/main.h \ @@ -343,7 +342,6 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/noui.cpp \ src/kernel.cpp \ src/scrypt.cpp \ - src/pbkdf2.cpp \ src/qt/multisigaddressentry.cpp \ src/qt/multisiginputentry.cpp \ src/qt/multisigdialog.cpp diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 03bd10e..8433d86 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -250,6 +250,7 @@ static const CRPCCommand vRPCCommands[] = { "getinfo", &getinfo, true, false }, { "getsubsidy", &getsubsidy, true, false }, { "getmininginfo", &getmininginfo, true, false }, + { "scaninput", &scaninput, true, true }, { "getnewaddress", &getnewaddress, true, false }, { "getnettotals", &getnettotals, true, true }, { "getaccountaddress", &getaccountaddress, true, false }, @@ -1211,6 +1212,10 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 0) ConvertTo(params[0]); if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "scaninput" && n > 1) ConvertTo(params[1]); + if (strMethod == "scaninput" && n > 2) ConvertTo(params[2]); + if (strMethod == "scaninput" && n > 3) ConvertTo(params[3]); + if (strMethod == "sendalert" && n > 2) ConvertTo(params[2]); if (strMethod == "sendalert" && n > 3) ConvertTo(params[3]); if (strMethod == "sendalert" && n > 4) ConvertTo(params[4]); diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 9ec5c9e..83e8eed 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -161,6 +161,7 @@ extern json_spirit::Value sendalert(const json_spirit::Array& params, bool fHelp extern json_spirit::Value getsubsidy(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value scaninput(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); diff --git a/src/kernel.cpp b/src/kernel.cpp index c9d3f49..a3ec598 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -469,7 +469,7 @@ bool ScanForStakeKernelHash(MetaMap &mapMeta, uint32_t nBits, uint32_t nTime, ui bnTargetPerCoinDay.SetCompact(nBits); int64_t nValueIn = pcoin.first->vout[pcoin.second].nValue; - // Search backward in time from the given timestamp + // Search backward in time from the given timestamp // Search nSearchInterval seconds back up to nMaxStakeSearchInterval // Stopping search in case of shutting down or cache invalidation for (unsigned int n=0; n &solution) +{ + CTxDB txdb("r"); + + CBlock block; + CTxIndex txindex; + + // Load transaction index item + if (!txdb.ReadTxIndex(tx.GetHash(), txindex)) + return false; + + // Read block header + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + return false; + + uint64_t nStakeModifier = 0; + if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier)) + return false; + + uint32_t nTime = GetTime(); + // Only count coins meeting min age requirement + if (nStakeMinAge + block.nTime > nTime) + nTime += (nStakeMinAge + block.nTime - nTime); + + // Transaction offset inside block + uint32_t nTxOffset = txindex.pos.nTxPos - txindex.pos.nBlockPos; + int64_t nValueIn = tx.vout[nOut].nValue; + + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + + // Get maximum possible target to filter out the majority of obviously insufficient hashes + CBigNum bnMaxTargetPerCoinDay = bnTargetPerCoinDay * CBigNum(nValueIn) * nStakeMaxAge / COIN / (24 * 60 * 60); + uint256 maxTarget = bnMaxTargetPerCoinDay.getuint256(); + + + // Build static part of kernel + CDataStream ssKernel(SER_GETHASH, 0); + ssKernel << nStakeModifier; + ssKernel << block.nTime << nTxOffset << tx.nTime << nOut; + CDataStream::const_iterator it = ssKernel.begin(); + + // Init sha256 context and update it + // with first 16 bytes of kernel + SHA256_CTX ctxCurrent; + SHA256_Init(&ctxCurrent); + SHA256_Update(&ctxCurrent, (unsigned char*)&it[0], 8 + 16); + SHA256_CTX ctxCopy = ctxCurrent; + + // Search forward in time from the given timestamp + // Stopping search in case of shutting down + for (uint32_t nTimeTx=nTime; nTimeTx maxTarget) + continue; + + CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)tx.nTime, (int64_t)nTimeTx) / COIN / (24 * 60 * 60); + CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay; + + if (bnTargetProofOfStake >= CBigNum(hashProofOfStake)) + { + solution.first = hashProofOfStake; + solution.second = nTimeTx; + + return true; + } + } + + return false; +} + // Check kernel hash target and coinstake signature bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake) { diff --git a/src/kernel.h b/src/kernel.h index 1b639a6..9772782 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -36,6 +36,8 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, uint32_t // Scan given coins set for kernel solution bool ScanForStakeKernelHash(MetaMap &mapMeta, uint32_t nBits, uint32_t nTime, uint32_t nSearchInterval, CoinsSet::value_type &kernelcoin, uint32_t &nTimeTx, uint32_t &nBlockTime, uint64_t &nKernelsTried, uint64_t &nCoinDaysTried); +bool ScanInputForStakeKernelHash(CTransaction &tx, uint32_t nOut, uint32_t nBits, uint32_t nSearchInterval, std::pair &solution); + // Check kernel hash target and coinstake signature // Sets hashProofOfStake on success return bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake); diff --git a/src/makefile.bsd b/src/makefile.bsd index 27f8187..5035b19 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -128,7 +128,6 @@ OBJS= \ obj/walletdb.o \ obj/noui.o \ obj/kernel.o \ - obj/pbkdf2.o \ obj/scrypt.o all: novacoind diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 26a8eb8..e71d542 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -104,7 +104,6 @@ OBJS= \ obj/walletdb.o \ obj/noui.o \ obj/kernel.o \ - obj/pbkdf2.o \ obj/scrypt.o all: novacoind.exe diff --git a/src/makefile.mingw b/src/makefile.mingw index 1d36b42..a621c9d 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -93,7 +93,6 @@ OBJS= \ obj/walletdb.o \ obj/noui.o \ obj/kernel.o \ - obj/pbkdf2.o \ obj/scrypt.o all: novacoind.exe diff --git a/src/makefile.osx b/src/makefile.osx index 3a4a80c..937a825 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -93,7 +93,6 @@ OBJS= \ obj/wallet.o \ obj/walletdb.o \ obj/noui.o \ - obj/pbkdf2.o \ obj/kernel.o \ obj/scrypt.o diff --git a/src/makefile.unix b/src/makefile.unix index 4ef89d5..9bc4067 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -135,7 +135,6 @@ OBJS= \ obj/walletdb.o \ obj/noui.o \ obj/kernel.o \ - obj/pbkdf2.o \ obj/scrypt.o all: novacoind diff --git a/src/pbkdf2.cpp b/src/pbkdf2.cpp deleted file mode 100644 index 6d3f3dc..0000000 --- a/src/pbkdf2.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2013 NovaCoin Developers - -#include -#include "pbkdf2.h" - -static inline uint32_t -be32dec(const void *pp) -{ - const uint8_t *p = (uint8_t const *)pp; - - return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + - ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); -} - -static inline void -be32enc(void *pp, uint32_t x) -{ - uint8_t * p = (uint8_t *)pp; - - p[3] = x & 0xff; - p[2] = (x >> 8) & 0xff; - p[1] = (x >> 16) & 0xff; - p[0] = (x >> 24) & 0xff; -} - - - -/* Initialize an HMAC-SHA256 operation with the given key. */ -void -HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) -{ - unsigned char pad[64]; - unsigned char khash[32]; - const unsigned char * K = (const unsigned char *)_K; - size_t i; - - /* If Klen > 64, the key is really SHA256(K). */ - if (Klen > 64) { - SHA256_Init(&ctx->ictx); - SHA256_Update(&ctx->ictx, K, Klen); - SHA256_Final(khash, &ctx->ictx); - K = khash; - Klen = 32; - } - - /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ - SHA256_Init(&ctx->ictx); - memset(pad, 0x36, 64); - for (i = 0; i < Klen; i++) - pad[i] ^= K[i]; - SHA256_Update(&ctx->ictx, pad, 64); - - /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ - SHA256_Init(&ctx->octx); - memset(pad, 0x5c, 64); - for (i = 0; i < Klen; i++) - pad[i] ^= K[i]; - SHA256_Update(&ctx->octx, pad, 64); - - /* Clean the stack. */ - memset(khash, 0, 32); -} - -/* Add bytes to the HMAC-SHA256 operation. */ -void -HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len) -{ - - /* Feed data to the inner SHA256 operation. */ - SHA256_Update(&ctx->ictx, in, len); -} - -/* Finish an HMAC-SHA256 operation. */ -void -HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx) -{ - unsigned char ihash[32]; - - /* Finish the inner SHA256 operation. */ - SHA256_Final(ihash, &ctx->ictx); - - /* Feed the inner hash to the outer SHA256 operation. */ - SHA256_Update(&ctx->octx, ihash, 32); - - /* Finish the outer SHA256 operation. */ - SHA256_Final(digest, &ctx->octx); - - /* Clean the stack. */ - memset(ihash, 0, 32); -} - -/** - * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): - * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and - * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). - */ -void -PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, - size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) -{ - HMAC_SHA256_CTX PShctx, hctx; - size_t i; - uint8_t ivec[4]; - uint8_t U[32]; - uint8_t T[32]; - uint64_t j; - int k; - size_t clen; - - /* Compute HMAC state after processing P and S. */ - HMAC_SHA256_Init(&PShctx, passwd, passwdlen); - HMAC_SHA256_Update(&PShctx, salt, saltlen); - - /* Iterate through the blocks. */ - for (i = 0; i * 32 < dkLen; i++) { - /* Generate INT(i + 1). */ - be32enc(ivec, (uint32_t)(i + 1)); - - /* Compute U_1 = PRF(P, S || INT(i)). */ - memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); - HMAC_SHA256_Update(&hctx, ivec, 4); - HMAC_SHA256_Final(U, &hctx); - - /* T_i = U_1 ... */ - memcpy(T, U, 32); - - for (j = 2; j <= c; j++) { - /* Compute U_j. */ - HMAC_SHA256_Init(&hctx, passwd, passwdlen); - HMAC_SHA256_Update(&hctx, U, 32); - HMAC_SHA256_Final(U, &hctx); - - /* ... xor U_j ... */ - for (k = 0; k < 32; k++) - T[k] ^= U[k]; - } - - /* Copy as many bytes as necessary into buf. */ - clen = dkLen - i * 32; - if (clen > 32) - clen = 32; - memcpy(&buf[i * 32], T, clen); - } - - /* Clean PShctx, since we never called _Final on it. */ - memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX)); -} - diff --git a/src/pbkdf2.h b/src/pbkdf2.h deleted file mode 100644 index 4c55fd9..0000000 --- a/src/pbkdf2.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2013 NovaCoin Developers - -#ifndef PBKDF2_H -#define PBKDF2_H - -#include -#include - -typedef struct HMAC_SHA256Context { - SHA256_CTX ictx; - SHA256_CTX octx; -} HMAC_SHA256_CTX; - -void -HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen); - -void -HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len); - -void -HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx); - -void -PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, - size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen); - -#endif // PBKDF2_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index e73e441..8f02836 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -8,11 +8,14 @@ #include "txdb.h" #include "init.h" #include "miner.h" +#include "kernel.h" #include "bitcoinrpc.h" using namespace json_spirit; using namespace std; +extern uint256 nPoWBase; + Value getsubsidy(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) @@ -70,6 +73,55 @@ Value getmininginfo(const Array& params, bool fHelp) return obj; } +Value scaninput(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 4 || params.size() < 2) + throw runtime_error( + "scaninput [difficulty] [days]\n" + "Scan specified input for suitable kernel solutions.\n" + " [difficulty] - upper limit for difficulty, current difficulty by default;\n" + " [days] - time window, 365 days by default.\n" + ); + + + uint256 hash; + hash.SetHex(params[0].get_str()); + + uint32_t nOut = params[1].get_int(), nBits = GetNextTargetRequired(pindexBest, true), nDays = 365; + + if (params.size() > 2) + { + CBigNum bnTarget(nPoWBase); + bnTarget *= 1000; + bnTarget /= (int) (params[2].get_real() * 1000); + nBits = bnTarget.GetCompact(); + } + + if (params.size() > 3) + { + nDays = params[3].get_int(); + } + + CTransaction tx; + uint256 hashBlock = 0; + if (GetTransaction(hash, tx, hashBlock)) + { + std::pair solution; + if (ScanInputForStakeKernelHash(tx, nOut, nBits, nDays * 86400, solution)) + { + Object r; + r.push_back(Pair("hash", solution.first.GetHex())); + r.push_back(Pair("time", DateTimeStrFormat(solution.second))); + + return r; + } + } + else + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + + return Value::null; +} + Value getworkex(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) diff --git a/src/scrypt-sse2.cpp b/src/scrypt-sse2.cpp index ef6ffb0..94987a6 100644 --- a/src/scrypt-sse2.cpp +++ b/src/scrypt-sse2.cpp @@ -31,7 +31,7 @@ #include #include #include -#include "pbkdf2.h" +#include #include @@ -53,104 +53,104 @@ static inline void le32enc(void *pp, uint32_t x) static inline void xor_salsa8_sse2(__m128i B[4], const __m128i Bx[4]) { - __m128i X0, X1, X2, X3; - __m128i T; - int i; - - X0 = B[0] = _mm_xor_si128(B[0], Bx[0]); - X1 = B[1] = _mm_xor_si128(B[1], Bx[1]); - X2 = B[2] = _mm_xor_si128(B[2], Bx[2]); - X3 = B[3] = _mm_xor_si128(B[3], Bx[3]); - - for (i = 0; i < 8; i += 2) { - /* Operate on "columns". */ - T = _mm_add_epi32(X0, X3); - X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7)); - X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25)); - T = _mm_add_epi32(X1, X0); - X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); - X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); - T = _mm_add_epi32(X2, X1); - X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13)); - X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19)); - T = _mm_add_epi32(X3, X2); - X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); - X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); - - /* Rearrange data. */ - X1 = _mm_shuffle_epi32(X1, 0x93); - X2 = _mm_shuffle_epi32(X2, 0x4E); - X3 = _mm_shuffle_epi32(X3, 0x39); - - /* Operate on "rows". */ - T = _mm_add_epi32(X0, X1); - X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7)); - X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25)); - T = _mm_add_epi32(X3, X0); - X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); - X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); - T = _mm_add_epi32(X2, X3); - X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13)); - X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19)); - T = _mm_add_epi32(X1, X2); - X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); - X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); - - /* Rearrange data. */ - X1 = _mm_shuffle_epi32(X1, 0x39); - X2 = _mm_shuffle_epi32(X2, 0x4E); - X3 = _mm_shuffle_epi32(X3, 0x93); - } - - B[0] = _mm_add_epi32(B[0], X0); - B[1] = _mm_add_epi32(B[1], X1); - B[2] = _mm_add_epi32(B[2], X2); - B[3] = _mm_add_epi32(B[3], X3); + __m128i X0, X1, X2, X3; + __m128i T; + int i; + + X0 = B[0] = _mm_xor_si128(B[0], Bx[0]); + X1 = B[1] = _mm_xor_si128(B[1], Bx[1]); + X2 = B[2] = _mm_xor_si128(B[2], Bx[2]); + X3 = B[3] = _mm_xor_si128(B[3], Bx[3]); + + for (i = 0; i < 8; i += 2) { + /* Operate on "columns". */ + T = _mm_add_epi32(X0, X3); + X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7)); + X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25)); + T = _mm_add_epi32(X1, X0); + X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); + X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); + T = _mm_add_epi32(X2, X1); + X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13)); + X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19)); + T = _mm_add_epi32(X3, X2); + X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); + X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); + + /* Rearrange data. */ + X1 = _mm_shuffle_epi32(X1, 0x93); + X2 = _mm_shuffle_epi32(X2, 0x4E); + X3 = _mm_shuffle_epi32(X3, 0x39); + + /* Operate on "rows". */ + T = _mm_add_epi32(X0, X1); + X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7)); + X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25)); + T = _mm_add_epi32(X3, X0); + X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); + X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); + T = _mm_add_epi32(X2, X3); + X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13)); + X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19)); + T = _mm_add_epi32(X1, X2); + X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); + X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); + + /* Rearrange data. */ + X1 = _mm_shuffle_epi32(X1, 0x39); + X2 = _mm_shuffle_epi32(X2, 0x4E); + X3 = _mm_shuffle_epi32(X3, 0x93); + } + + B[0] = _mm_add_epi32(B[0], X0); + B[1] = _mm_add_epi32(B[1], X1); + B[2] = _mm_add_epi32(B[2], X2); + B[3] = _mm_add_epi32(B[3], X3); } uint256 scrypt_blockhash__sse2(const uint8_t* input) { uint256 result = 0; uint8_t scratchpad[SCRYPT_BUFFER_SIZE]; - uint8_t B[128]; - union { - __m128i i128[8]; - uint32_t u32[32]; - } X; - __m128i *V; - uint32_t i, j, k; - - V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); - - PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128); - - for (k = 0; k < 2; k++) { - for (i = 0; i < 16; i++) { - X.u32[k * 16 + i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]); - } - } - - for (i = 0; i < 1024; i++) { - for (k = 0; k < 8; k++) - V[i * 8 + k] = X.i128[k]; - xor_salsa8_sse2(&X.i128[0], &X.i128[4]); - xor_salsa8_sse2(&X.i128[4], &X.i128[0]); - } - for (i = 0; i < 1024; i++) { - j = 8 * (X.u32[16] & 1023); - for (k = 0; k < 8; k++) - X.i128[k] = _mm_xor_si128(X.i128[k], V[j + k]); - xor_salsa8_sse2(&X.i128[0], &X.i128[4]); - xor_salsa8_sse2(&X.i128[4], &X.i128[0]); - } - - for (k = 0; k < 2; k++) { - for (i = 0; i < 16; i++) { - le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X.u32[k * 16 + i]); - } - } - - PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)&result, 32); + uint8_t B[128]; + union { + __m128i i128[8]; + uint32_t u32[32]; + } X; + __m128i *V; + uint32_t i, j, k; + + V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + PKCS5_PBKDF2_HMAC((const int8_t *)input, 80, (const int8_t *)input, 80, 1, EVP_sha256(), 128, B); + + for (k = 0; k < 2; k++) { + for (i = 0; i < 16; i++) { + X.u32[k * 16 + i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]); + } + } + + for (i = 0; i < 1024; i++) { + for (k = 0; k < 8; k++) + V[i * 8 + k] = X.i128[k]; + xor_salsa8_sse2(&X.i128[0], &X.i128[4]); + xor_salsa8_sse2(&X.i128[4], &X.i128[0]); + } + for (i = 0; i < 1024; i++) { + j = 8 * (X.u32[16] & 1023); + for (k = 0; k < 8; k++) + X.i128[k] = _mm_xor_si128(X.i128[k], V[j + k]); + xor_salsa8_sse2(&X.i128[0], &X.i128[4]); + xor_salsa8_sse2(&X.i128[4], &X.i128[0]); + } + + for (k = 0; k < 2; k++) { + for (i = 0; i < 16; i++) { + le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X.u32[k * 16 + i]); + } + } + + PKCS5_PBKDF2_HMAC((const int8_t *)input, 80, B, 128, 1, EVP_sha256(), 32, (int8_t*)&result); return result; } diff --git a/src/scrypt.cpp b/src/scrypt.cpp index 32eea96..e7cfbda 100644 --- a/src/scrypt.cpp +++ b/src/scrypt.cpp @@ -1,7 +1,7 @@ #include +#include #include "scrypt.h" -#include "pbkdf2.h" #include "util.h" #include "net.h" @@ -24,7 +24,6 @@ extern uint256 scrypt_blockhash__sse2(const uint8_t* input); scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes r = 1, p = 1, N = 1024 */ - uint256 scrypt_blockhash_generic(const uint8_t* input) { uint8_t scratchpad[SCRYPT_BUFFER_SIZE]; @@ -33,9 +32,9 @@ uint256 scrypt_blockhash_generic(const uint8_t* input) uint32_t *V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); - PBKDF2_SHA256(input, 80, input, 80, 1, (uint8_t *)X, 128); + PKCS5_PBKDF2_HMAC((const char*)input, 80, input, 80, 1, EVP_sha256(), 128, (unsigned char *)X); scrypt_core(X, V); - PBKDF2_SHA256(input, 80, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32); + PKCS5_PBKDF2_HMAC((const char*)input, 80, (const unsigned char*)X, 128, 1, EVP_sha256(), 32, (unsigned char*)&result); return result; } @@ -75,4 +74,4 @@ void scrypt_detect_sse2() uint256 scrypt_blockhash(const uint8_t* input) { return scrypt_blockhash_detected(input); -} \ No newline at end of file +}