Path: blob/master/algo/scrypt-jane.c
1299 views
#include "miner.h"12#include <stdlib.h>3#include <string.h>4#include "inttypes.h"56/* Hard-coded scrypt parameteres r and p - mikaelh */7#define SCRYPT_R 18#define SCRYPT_P 1910/* Only the instrinsics versions are optimized for hard-coded values - mikaelh */11#define CPU_X86_FORCE_INTRINSICS1213#undef SCRYPT_KECCAK51214#undef SCRYPT_CHACHA15#undef SCRYPT_CHOOSE_COMPILETIME16#define SCRYPT_KECCAK51217#define SCRYPT_CHACHA18#define SCRYPT_CHOOSE_COMPILETIME1920//#include "scrypt-jane.h"21#include "../scryptjane/scrypt-jane-portable.h"22#include "../scryptjane/scrypt-jane-hash.h"23#include "../scryptjane/scrypt-jane-romix.h"24#include "../scryptjane/scrypt-jane-test-vectors.h"252627#define scrypt_maxN 30 /* (1 << (30 + 1)) = ~2 billion */28#if (SCRYPT_BLOCK_BYTES == 64)29#define scrypt_r_32kb 8 /* (1 << 8) = 256 * 2 blocks in a chunk * 64 bytes = Max of 32kb in a chunk */30#elif (SCRYPT_BLOCK_BYTES == 128)31#define scrypt_r_32kb 7 /* (1 << 7) = 128 * 2 blocks in a chunk * 128 bytes = Max of 32kb in a chunk */32#elif (SCRYPT_BLOCK_BYTES == 256)33#define scrypt_r_32kb 6 /* (1 << 6) = 64 * 2 blocks in a chunk * 256 bytes = Max of 32kb in a chunk */34#elif (SCRYPT_BLOCK_BYTES == 512)35#define scrypt_r_32kb 5 /* (1 << 5) = 32 * 2 blocks in a chunk * 512 bytes = Max of 32kb in a chunk */36#endif37#define scrypt_maxr scrypt_r_32kb /* 32kb */38#define scrypt_maxp 25 /* (1 << 25) = ~33 million */3940typedef struct scrypt_aligned_alloc_t {41uint8_t *mem, *ptr;42} scrypt_aligned_alloc;4344static int45scrypt_alloc(uint64_t size, scrypt_aligned_alloc *aa) {46static const size_t max_alloc = (size_t)-1;47size += (SCRYPT_BLOCK_BYTES - 1);48if (size > max_alloc)49return 0; // scrypt_fatal_error("scrypt: not enough address space on this CPU to allocate required memory");50aa->mem = (uint8_t *)malloc((size_t)size);51aa->ptr = (uint8_t *)(((size_t)aa->mem + (SCRYPT_BLOCK_BYTES - 1)) & ~(SCRYPT_BLOCK_BYTES - 1));52if (!aa->mem)53return 0; // scrypt_fatal_error("scrypt: out of memory");54return 1;55}5657static void58scrypt_free(scrypt_aligned_alloc *aa) {59free(aa->mem);60}6162void63scrypt_N_1_1(const uint8_t *password, size_t password_len, const uint8_t *salt, size_t salt_len, uint32_t N, uint8_t *out, size_t bytes, uint8_t *X, uint8_t *Y, uint8_t *V) {64uint32_t chunk_bytes, i;65const uint32_t r = SCRYPT_R;66const uint32_t p = SCRYPT_P;6768#if !defined(SCRYPT_CHOOSE_COMPILETIME)69scrypt_ROMixfn scrypt_ROMix = scrypt_getROMix();70#endif7172chunk_bytes = SCRYPT_BLOCK_BYTES * r * 2;7374/* 1: X = PBKDF2(password, salt) */75scrypt_pbkdf2_1(password, password_len, salt, salt_len, X, chunk_bytes * p);7677/* 2: X = ROMix(X) */78for (i = 0; i < p; i++)79scrypt_ROMix_1((scrypt_mix_word_t *)(X + (chunk_bytes * i)), (scrypt_mix_word_t *)Y, (scrypt_mix_word_t *)V, N);8081/* 3: Out = PBKDF2(password, X) */82scrypt_pbkdf2_1(password, password_len, X, chunk_bytes * p, out, bytes);8384#ifdef SCRYPT_PREVENT_STATE_LEAK85/* This is an unnecessary security feature - mikaelh */86scrypt_ensure_zero(Y, (p + 1) * chunk_bytes);87#endif88}899091// increasing Nfactor gradually92const unsigned char minNfactor = 4;93const unsigned char maxNfactor = 30;9495unsigned char GetNfactor(unsigned int nTimestamp, unsigned int ntime) {96int l = 0;97unsigned long int s;98int n;99unsigned char N;100101if (nTimestamp <= ntime)102return 4;103104s = nTimestamp - ntime;105while ((s >> 1) > 3) {106l += 1;107s >>= 1;108}109110s &= 3;111112n = (l * 170 + s * 25 - 2320) / 100;113114if (n < 0) n = 0;115116if (n > 255) {117n = 255;118// printf("GetNfactor(%d) - something wrong(n == %d)\n", nTimestamp, n);119}120121N = (unsigned char)n;122//printf("GetNfactor: %d -> %d %d : %d / %d\n", nTimestamp - nChainStartTime, l, s, n, min(max(N, minNfactor), maxNfactor));123124if (N<minNfactor) return minNfactor;125if (N>maxNfactor) return maxNfactor;126return N;127}128129130int scanhash_scryptjane(int Nfactor, int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)131{132scrypt_aligned_alloc YX, V;133uint8_t *X, *Y;134uint32_t N, chunk_bytes;135const uint32_t r = SCRYPT_R;136const uint32_t p = SCRYPT_P;137138uint32_t *pdata = work->data;139uint32_t *ptarget = work->target;140uint32_t _ALIGN(64) endiandata[20];141const uint32_t first_nonce = pdata[19];142uint32_t nonce = first_nonce;143144if (opt_benchmark)145ptarget[7] = 0x00ff;146147for (int k = 0; k < 20; k++)148be32enc(&endiandata[k], pdata[k]);149150//Nfactor = GetNfactor(data[17], ntime);151//if (Nfactor > scrypt_maxN) {152// return 1;153// //scrypt_fatal_error("scrypt: N out of range");154//}155156N = (1 << (Nfactor + 1));157158chunk_bytes = SCRYPT_BLOCK_BYTES * r * 2;159if (!scrypt_alloc((uint64_t)N * chunk_bytes, &V)) return 1;160if (!scrypt_alloc((p + 1) * chunk_bytes, &YX)) {161scrypt_free(&V);162return 1;163}164165Y = YX.ptr;166X = Y + chunk_bytes;167168do {169const uint32_t Htarg = ptarget[7];170uint32_t hash[8];171be32enc(&endiandata[19], nonce);172173scrypt_N_1_1((unsigned char *)endiandata, 80,174(unsigned char *)endiandata, 80,175N, (unsigned char *)hash, 32, X, Y, V.ptr);176177if (hash[7] <= Htarg && fulltest(hash, ptarget)) {178pdata[19] = nonce;179*hashes_done = pdata[19] - first_nonce;180scrypt_free(&V);181scrypt_free(&YX);182return 1;183}184nonce++;185186} while (nonce < max_nonce && !work_restart[thr_id].restart);187188pdata[19] = nonce;189*hashes_done = pdata[19] - first_nonce + 1;190191scrypt_free(&V);192scrypt_free(&YX);193return 0;194}195196/* simple cpu test (util.c) */197void scryptjanehash(void *output, const void *input, uint32_t Nfactor)198{199scrypt_aligned_alloc YX, V;200uint8_t *X, *Y;201uint32_t chunk_bytes;202uint32_t N = (1 << (Nfactor + 1));203const uint32_t r = SCRYPT_R;204const uint32_t p = SCRYPT_P;205206memset(output, 0, 32);207208chunk_bytes = SCRYPT_BLOCK_BYTES * r * 2;209if (!scrypt_alloc((uint64_t)N * chunk_bytes, &V)) return;210if (!scrypt_alloc((p + 1) * chunk_bytes, &YX)) {211scrypt_free(&V);212return;213}214215Y = YX.ptr;216X = Y + chunk_bytes;217218scrypt_N_1_1((unsigned char*)input, 80, (unsigned char*)input, 80,219N, (unsigned char*)output, 32, X, Y, V.ptr);220221scrypt_free(&V);222scrypt_free(&YX);223}224225226