src/uint256.h \
src/kernel.h \
src/scrypt.h \
- src/pbkdf2.h \
src/serialize.h \
src/strlcpy.h \
src/main.h \
src/noui.cpp \
src/kernel.cpp \
src/scrypt.cpp \
- src/pbkdf2.cpp \
src/qt/multisigaddressentry.cpp \
src/qt/multisiginputentry.cpp \
src/qt/multisigdialog.cpp
{ "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 },
if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "scaninput" && n > 1) ConvertTo<int>(params[1]);
+ if (strMethod == "scaninput" && n > 2) ConvertTo<double>(params[2]);
+ if (strMethod == "scaninput" && n > 3) ConvertTo<int>(params[3]);
+
if (strMethod == "sendalert" && n > 2) ConvertTo<boost::int64_t>(params[2]);
if (strMethod == "sendalert" && n > 3) ConvertTo<boost::int64_t>(params[3]);
if (strMethod == "sendalert" && n > 4) ConvertTo<boost::int64_t>(params[4]);
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);
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<nCurrentSearchInterval && fCoinsDataActual && !fShutdown; n++)
return false;
}
+// Scan given input for kernel solution
+bool ScanInputForStakeKernelHash(CTransaction &tx, uint32_t nOut, uint32_t nBits, uint32_t nSearchInterval, std::pair<uint256, uint32_t> &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<nTime+nSearchInterval && !fShutdown; nTimeTx++)
+ {
+ // Complete first hashing iteration
+ uint256 hash1;
+ SHA256_Update(&ctxCurrent, (unsigned char*)&nTimeTx, 4);
+ SHA256_Final((unsigned char*)&hash1, &ctxCurrent);
+
+ // Restore old context
+ ctxCurrent = ctxCopy;
+
+ // Finally, calculate kernel hash
+ uint256 hashProofOfStake;
+ SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
+
+ // Skip if hash doesn't satisfy the maximum target
+ if (hashProofOfStake > 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)
{
// 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<uint256, uint32_t> &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);
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
- obj/pbkdf2.o \
obj/scrypt.o
all: novacoind
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
- obj/pbkdf2.o \
obj/scrypt.o
all: novacoind.exe
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
- obj/pbkdf2.o \
obj/scrypt.o
all: novacoind.exe
obj/wallet.o \
obj/walletdb.o \
obj/noui.o \
- obj/pbkdf2.o \
obj/kernel.o \
obj/scrypt.o
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
- obj/pbkdf2.o \
obj/scrypt.o
all: novacoind
+++ /dev/null
-// Copyright (c) 2013 NovaCoin Developers
-
-#include <string.h>
-#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));
-}
-
+++ /dev/null
-// Copyright (c) 2013 NovaCoin Developers
-
-#ifndef PBKDF2_H
-#define PBKDF2_H
-
-#include <openssl/sha.h>
-#include <stdint.h>
-
-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
#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)
return obj;
}
+Value scaninput(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 4 || params.size() < 2)
+ throw runtime_error(
+ "scaninput <txid> <nout> [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<uint256, uint32_t> 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)
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
-#include "pbkdf2.h"
+#include <openssl/evp.h>
#include <emmintrin.h>
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;
}
#include <stdlib.h>
+#include <openssl/evp.h>
#include "scrypt.h"
-#include "pbkdf2.h"
#include "util.h"
#include "net.h"
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];
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;
}
uint256 scrypt_blockhash(const uint8_t* input)
{
return scrypt_blockhash_detected(input);
-}
\ No newline at end of file
+}