void sha256_process(sha256_context *ctx, const void *Data, size_t Size) { const byte *Src=(const byte *)Data; size_t BufPos = (uint)ctx->Count & 0x3f; ctx->Count+=Size; while (Size > 0) { size_t BufSpace=sizeof(ctx->Buffer)-BufPos; size_t CopySize=Size>BufSpace ? BufSpace:Size; if (CopySize == 64) ctx->Data=Src; // Point to source data instead of copying it to buffer. else { ctx->Data=ctx->Buffer; memcpy(ctx->Buffer+BufPos,Src,CopySize); } Src+=CopySize; BufPos+=CopySize; Size-=CopySize; if (BufPos == 64) { BufPos = 0; sha256_transform(ctx); } } sha256_transform(NULL); }
void sha256_done(sha256_context *ctx, byte *Digest) { ctx->Data = ctx->Buffer; uint64 BitLength = ctx->Count * 8; uint BufPos = (uint)ctx->Count & 0x3f; ctx->Buffer[BufPos++] = 0x80; // Padding the message with "1" bit. while (BufPos != 56) // We need 56 bytes block followed by 8 byte length. { BufPos &= 0x3f; if (BufPos == 0) sha256_transform(ctx); ctx->Buffer[BufPos++] = 0; } for (uint i = 0; i < 8; i++) // Store bit length of entire message. { ctx->Buffer[BufPos++] = (byte)(BitLength >> 56); BitLength <<= 8; } sha256_transform(ctx); for (uint i = 0; i < 32; i++) Digest[i] = byte(ctx->H[i / 4] >> ((3 - i % 4) * 8)); sha256_init(ctx); sha256_transform(NULL); cleandata(ctx->Buffer, sizeof(ctx->Buffer)); }
static inline void HMAC_SHA256_80_init(const uint32_t *key, uint32_t *tstate, uint32_t *ostate) { uint32_t ihash[8]; uint32_t pad[16]; int i; /* tstate is assumed to contain the midstate of key */ memcpy(pad, key + 16, 16); memcpy(pad + 4, keypad, 48); sha256_transform(tstate, pad, 0); memcpy(ihash, tstate, 32); sha256_init(ostate); for (i = 0; i < 8; i++) pad[i] = ihash[i] ^ 0x5c5c5c5c; for (; i < 16; i++) pad[i] = 0x5c5c5c5c; sha256_transform(ostate, pad, 0); sha256_init(tstate); for (i = 0; i < 8; i++) pad[i] = ihash[i] ^ 0x36363636; for (; i < 16; i++) pad[i] = 0x36363636; sha256_transform(tstate, pad, 0); }
int sha256_process(sha256_state * md, const unsigned char *in, unsigned long inlen) { unsigned long n; int block_size = sizeof(md->buf); if (md->curlen > block_size) return FALSE; while (inlen > 0) { if (md->curlen == 0 && inlen >= block_size) { sha256_transform(md->state, (unsigned char *)in); md->length += block_size * 8; in += block_size; inlen -= block_size; } else { n = MIN(inlen, (block_size - md->curlen)); memcpy(md->buf + md->curlen, in, (size_t)n); md->curlen += n; in += n; inlen -= n; if (md->curlen == block_size) { sha256_transform(md->state, md->buf); md->length += block_size * 8; md->curlen = 0; } } } return TRUE; }
void akmos_sha2_256_update(akmos_sha2_256_t *ctx, const uint8_t *input, size_t len) { size_t nb, new_len, rem_len, tmp_len; const uint8_t *sfi; tmp_len = AKMOS_SHA2_256_BLKLEN - ctx->len; rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], input, rem_len); if(ctx->len + len < AKMOS_SHA2_256_BLKLEN) { ctx->len += len; return; } new_len = len - rem_len; nb = new_len / AKMOS_SHA2_256_BLKLEN; sfi = input + rem_len; sha256_transform(ctx->h, ctx->w, ctx->block, 1 & SIZE_T_MAX); sha256_transform(ctx->h, ctx->w, sfi, nb); rem_len = new_len % AKMOS_SHA2_256_BLKLEN; memcpy(ctx->block, &sfi[nb * 64], rem_len); ctx->len = rem_len; ctx->total += (nb + 1); }
static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate, const uint32_t *ostate, const uint32_t *salt, uint32_t *output) { uint32_t istate[8], ostate2[8]; uint32_t ibuf[16], obuf[16]; int i, j; memcpy(istate, tstate, 32); sha256_transform(istate, salt, 0); memcpy(ibuf, salt + 16, 16); memcpy(ibuf + 5, innerpad, 44); memcpy(obuf + 8, outerpad, 32); for (i = 0; i < 4; i++) { memcpy(obuf, istate, 32); ibuf[4] = i + 1; sha256_transform(obuf, ibuf, 0); memcpy(ostate2, ostate, 32); sha256_transform(ostate2, obuf, 0); for (j = 0; j < 8; j++) output[8 * i + j] = swab32(ostate2[j]); } }
void sha256d_80_swap(uint32_t *hash, const uint32_t *data) { uint32_t S[16]; int i; sha256_init(S); sha256_transform(S, data, 0); sha256_transform(S, data + 16, 0); memcpy(S + 8, sha256d_hash1 + 8, 32); sha256_init(hash); sha256_transform(hash, S, 0); for (i = 0; i < 8; i++) hash[i] = swab32(hash[i]); }
void sha256func(unsigned char *hash, const unsigned char *data, int len) { uint32_t S[16], T[16]; int i, r; sha256_init(S); for (r = len; r > -9; r -= 64) { if (r < 64) memset(T, 0, 64); memcpy(T, data + len - r, r > 64 ? 64 : (r < 0 ? 0 : r)); if (r >= 0 && r < 64) ((unsigned char *)T)[r] = 0x80; for (i = 0; i < 16; i++) T[i] = be32dec(T + i); if (r < 56) T[15] = 8 * len; sha256_transform(S, T, 0); } /* memcpy(S + 8, sha256d_hash1 + 8, 32); sha256_init(T); sha256_transform(T, S, 0); */ for (i = 0; i < 8; i++) be32enc((uint32_t *)hash + i, T[i]); }
static int sha256_update(struct shash_desc *desc, const u8 *data, unsigned int len) { struct sha256_state *sctx = shash_desc_ctx(desc); unsigned int partial, done; const u8 *src; partial = sctx->count & 0x3f; sctx->count += len; done = 0; src = data; if ((partial + len) > 63) { if (partial) { done = -partial; memcpy(sctx->buf + partial, data, done + 64); src = sctx->buf; } do { sha256_transform(sctx->state, src); done += 64; src = data + done; } while (done + 63 < len); partial = 0; } memcpy(sctx->buf + partial, src, len - done); return 0; }
void sha256(unsigned char input[32], int rounds, unsigned char output[32]) { GET_UINT32_BE( W[0], input, 0 ); GET_UINT32_BE( W[1], input, 4 ); GET_UINT32_BE( W[2], input, 8 ); GET_UINT32_BE( W[3], input, 12 ); GET_UINT32_BE( W[4], input, 16 ); GET_UINT32_BE( W[5], input, 20 ); GET_UINT32_BE( W[6], input, 24 ); GET_UINT32_BE( W[7], input, 28 ); int i; for(i=0;i<rounds;++i) sha256_transform(); PUT_UINT32_BE( W[0], output, 0 ); PUT_UINT32_BE( W[1], output, 4 ); PUT_UINT32_BE( W[2], output, 8 ); PUT_UINT32_BE( W[3], output, 12 ); PUT_UINT32_BE( W[4], output, 16 ); PUT_UINT32_BE( W[5], output, 20 ); PUT_UINT32_BE( W[6], output, 24 ); PUT_UINT32_BE( W[7], output, 28 ); }
void fio_sha256_update(struct fio_sha256_ctx *sctx, const uint8_t *data, unsigned int len) { unsigned int partial, done; const uint8_t *src; partial = sctx->count & 0x3f; sctx->count += len; done = 0; src = data; if ((partial + len) > 63) { if (partial) { done = -partial; memcpy(sctx->buf + partial, data, done + 64); src = sctx->buf; } do { sha256_transform(sctx->state, src); done += 64; src = data + done; } while (done + 63 < len); partial = 0; } memcpy(sctx->buf + partial, src, len - done); }
static inline void PBKDF2_SHA256_128_32(uint32_t *tstate, uint32_t *ostate, const uint32_t *salt, uint32_t *output) { uint32_t buf[16]; int i; sha256_transform(tstate, salt, 1); sha256_transform(tstate, salt + 16, 1); sha256_transform(tstate, finalblk, 0); memcpy(buf, tstate, 32); memcpy(buf + 8, outerpad, 32); sha256_transform(ostate, buf, 0); for (i = 0; i < 8; i++) output[i] = swab32(ostate[i]); }
int scanhash_scrypt(int thr_id, uint32_t *pdata, unsigned char *scratchbuf, const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done) { uint32_t data[SCRYPT_MAX_WAYS * 20], hash[SCRYPT_MAX_WAYS * 8]; uint32_t midstate[8]; uint32_t n = pdata[19] - 1; const uint32_t Htarg = ptarget[7]; int throughput = scrypt_best_throughput(); int i; #ifdef HAVE_SHA256_4WAY if (sha256_use_4way()) throughput *= 4; #endif for (i = 0; i < throughput; i++) memcpy(data + i * 20, pdata, 80); sha256_init(midstate); sha256_transform(midstate, data, 0); do { for (i = 0; i < throughput; i++) data[i * 20 + 19] = ++n; #if defined(HAVE_SHA256_4WAY) if (throughput == 4) scrypt_1024_1_1_256_4way(data, hash, midstate, scratchbuf); else #endif #if defined(HAVE_SCRYPT_3WAY) && defined(HAVE_SHA256_4WAY) if (throughput == 12) scrypt_1024_1_1_256_12way(data, hash, midstate, scratchbuf); else #endif #if defined(HAVE_SCRYPT_3WAY) if (throughput == 3) scrypt_1024_1_1_256_3way(data, hash, midstate, scratchbuf); else #endif scrypt_1024_1_1_256(data, hash, midstate, scratchbuf); for (i = 0; i < throughput; i++) { if (hash[i * 8 + 7] <= Htarg && fulltest(hash + i * 8, ptarget)) { *hashes_done = n - pdata[19] + 1; pdata[19] = data[i * 20 + 19]; return 1; } } } while (n < max_nonce && !work_restart[thr_id].restart); *hashes_done = n - pdata[19] + 1; pdata[19] = n; return 0; }
static inline int scanhash_sha256d_4way(int thr_id, uint32_t *pdata, const uint32_t *ptarget, uint32_t max_nonce, struct timeval *tv_start, struct timeval *tv_end, unsigned long *hashes_done) { gettimeofday(tv_start, NULL); uint32_t data[4 * 64] __attribute__((aligned(128))); uint32_t hash[4 * 8] __attribute__((aligned(32))); uint32_t midstate[4 * 8] __attribute__((aligned(32))); uint32_t prehash[4 * 8] __attribute__((aligned(32))); uint32_t n = pdata[19] - 1; const uint32_t first_nonce = pdata[19]; const uint32_t Htarg = ptarget[7]; int i, j; memcpy(data, pdata + 16, 64); sha256d_preextend(data); for (i = 31; i >= 0; i--) for (j = 0; j < 4; j++) data[i * 4 + j] = data[i]; sha256_init(midstate); sha256_transform(midstate, pdata, 0); memcpy(prehash, midstate, 32); sha256d_prehash(prehash, pdata + 16); for (i = 7; i >= 0; i--) { for (j = 0; j < 4; j++) { midstate[i * 4 + j] = midstate[i]; prehash[i * 4 + j] = prehash[i]; } } do { for (i = 0; i < 4; i++) data[4 * 3 + i] = ++n; sha256d_ms_4way(hash, data, midstate, prehash); for (i = 0; i < 4; i++) { if (swab32(hash[4 * 7 + i]) <= Htarg) { pdata[19] = data[4 * 3 + i]; sha256d_80_swap(hash, pdata); if (fulltest(hash, ptarget)) { *hashes_done = n - first_nonce + 1; gettimeofday(&tv_end, NULL); return 1; } } } } while (n < max_nonce && !scan_abort_flag && !work_restart[thr_id].restart); *hashes_done = n - first_nonce + 1; pdata[19] = n; gettimeofday(&tv_end, NULL); return 0; }
int sha256_done(sha256_state * md, unsigned char *out) { int i; if (md->curlen >= sizeof(md->buf)) return FALSE; /* increase the length of the message */ md->length += md->curlen * 8; /* append the '1' bit */ md->buf[md->curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->curlen > 56) { while (md->curlen < 64) { md->buf[md->curlen++] = (unsigned char)0; } sha256_transform(md->state, md->buf); md->curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->curlen < 56) { md->buf[md->curlen++] = (unsigned char)0; } /* store length */ SILC_PUT64_MSB(md->length, md->buf + 56); sha256_transform(md->state, md->buf); /* copy output */ for (i = 0; i < 8; i += 2) { SILC_PUT32_MSB(md->state[i], out + (4 * i)); SILC_PUT32_MSB(md->state[i + 1], out + (4 * (i + 1))); } return TRUE; }
static inline int scanhash_sha256d_8way(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done) { uint32_t *pdata = work->data; uint32_t *ptarget = work->target; uint32_t _ALIGN(128) data[8 * 64]; uint32_t _ALIGN(32) hash[8 * 8]; uint32_t _ALIGN(32) midstate[8 * 8]; uint32_t _ALIGN(32) prehash[8 * 8]; uint32_t n = pdata[19] - 1; const uint32_t first_nonce = pdata[19]; const uint32_t Htarg = ptarget[7]; int i, j; memcpy(data, pdata + 16, 64); sha256d_preextend(data); for (i = 31; i >= 0; i--) for (j = 0; j < 8; j++) data[i * 8 + j] = data[i]; sha256_init(midstate); sha256_transform(midstate, pdata, 0); memcpy(prehash, midstate, 32); sha256d_prehash(prehash, pdata + 16); for (i = 7; i >= 0; i--) { for (j = 0; j < 8; j++) { midstate[i * 8 + j] = midstate[i]; prehash[i * 8 + j] = prehash[i]; } } do { for (i = 0; i < 8; i++) data[8 * 3 + i] = ++n; sha256d_ms_8way(hash, data, midstate, prehash); for (i = 0; i < 8; i++) { if (swab32(hash[8 * 7 + i]) <= Htarg) { pdata[19] = data[8 * 3 + i]; sha256d_80_swap(hash, pdata); if (fulltest(hash, ptarget)) { *hashes_done = n - first_nonce + 1; return 1; } } } } while (n < max_nonce && !work_restart[thr_id].restart); *hashes_done = n - first_nonce + 1; pdata[19] = n; return 0; }
PRIVATE static void sha256_write_byte_block(sha256_t *p) { uint32_t data32[16]; unsigned i; for (i = 0; i < 16; i++) data32[i] = ((uint32_t)(p->buffer[i * 4 ]) << 24) + ((uint32_t)(p->buffer[i * 4 + 1]) << 16) + ((uint32_t)(p->buffer[i * 4 + 2]) << 8) + ((uint32_t)(p->buffer[i * 4 + 3])); sha256_transform(p->state, data32); }
int scanhash_sha256d(int thr_id, uint32_t *pdata, const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done) { uint32_t data[64] __attribute__((aligned(128))); uint32_t hash[8] __attribute__((aligned(32))); uint32_t midstate[8] __attribute__((aligned(32))); uint32_t prehash[8] __attribute__((aligned(32))); uint32_t n = pdata[19] - 1; const uint32_t first_nonce = pdata[19]; const uint32_t Htarg = ptarget[7]; #ifdef HAVE_SHA256_16WAY if (sha256_use_16way()) return scanhash_sha256d_16way(thr_id, pdata, ptarget, max_nonce, hashes_done); #endif #ifdef HAVE_SHA256_8WAY if (sha256_use_8way()) return scanhash_sha256d_8way(thr_id, pdata, ptarget, max_nonce, hashes_done); #endif #ifdef HAVE_SHA256_4WAY if (sha256_use_4way()) return scanhash_sha256d_4way(thr_id, pdata, ptarget, max_nonce, hashes_done); #endif memcpy(data, pdata + 16, 64); sha256d_preextend(data); sha256_init(midstate); sha256_transform(midstate, pdata, 0); memcpy(prehash, midstate, 32); sha256d_prehash(prehash, pdata + 16); do { data[3] = ++n; sha256d_ms(hash, data, midstate, prehash); if (swab32(hash[7]) <= Htarg) { pdata[19] = data[3]; sha256d_80_swap(hash, pdata); if (fulltest(hash, ptarget)) { *hashes_done = n - first_nonce + 1; return 1; } } } while (n < max_nonce && !work_restart[thr_id].restart); *hashes_done = n - first_nonce + 1; pdata[19] = n; return 0; }
static inline int scanhash_sha256d_16way(int thr_id, uint32_t *pdata, const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done) { uint32_t data[16 * 64] __attribute__((aligned(128))); uint32_t hash[16 * 8] __attribute__((aligned(64))); uint32_t midstate[16 * 8] __attribute__((aligned(64))); uint32_t prehash[16 * 8] __attribute__((aligned(64))); uint32_t n = pdata[19] - 1; const uint32_t first_nonce = pdata[19]; const uint32_t Htarg = ptarget[7]; int i, j; memcpy(data, pdata + 16, 64); sha256d_preextend(data); for (i = 63; i >= 0; i--) for (j = 0; j < 16; j++) data[i * 16 + j] = data[i]; sha256_init(midstate); sha256_transform(midstate, pdata, 0); memcpy(prehash, midstate, 32); sha256d_prehash(prehash, pdata + 16); for (i = 7; i >= 0; i--) { for (j = 0; j < 16; j++) { midstate[i * 16 + j] = midstate[i]; prehash[i * 16 + j] = prehash[i]; } } do { for (i = 0; i < 16; i++) data[16 * 3 + i] = ++n; sha256d_ms_16way(hash, data, midstate, prehash); for (i = 0; i < 16; i++) { if (swab32(hash[16 * 7 + i]) <= Htarg) { pdata[19] = data[16 * 3 + i]; sha256d_80_swap(hash, pdata); if (fulltest(hash, ptarget)) { *hashes_done = n - first_nonce + 1; return 1; } } } } while (n < max_nonce && !work_restart[thr_id].restart); *hashes_done = n - first_nonce + 1; pdata[19] = n; return 0; }
int scanhash_sha256d(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done) { uint32_t *pdata = work->data; uint32_t *ptarget = work->target; uint32_t _ALIGN(128) data[64]; uint32_t _ALIGN(32) hash[8]; uint32_t _ALIGN(32) midstate[8]; uint32_t _ALIGN(32) prehash[8]; uint32_t n = pdata[19] - 1; const uint32_t first_nonce = pdata[19]; const uint32_t Htarg = ptarget[7]; #ifdef HAVE_SHA256_8WAY if (sha256_use_8way()) return scanhash_sha256d_8way(thr_id, work, max_nonce, hashes_done); #endif #ifdef HAVE_SHA256_4WAY if (sha256_use_4way()) return scanhash_sha256d_4way(thr_id, work, max_nonce, hashes_done); #endif memcpy(data, pdata + 16, 64); sha256d_preextend(data); sha256_init(midstate); sha256_transform(midstate, pdata, 0); memcpy(prehash, midstate, 32); sha256d_prehash(prehash, pdata + 16); do { data[3] = ++n; sha256d_ms(hash, data, midstate, prehash); if (unlikely(swab32(hash[7]) <= Htarg)) { pdata[19] = data[3]; sha256d_80_swap(hash, pdata); if (fulltest(hash, ptarget)) { *hashes_done = n - first_nonce + 1; return 1; } } } while (likely(n < max_nonce && !work_restart[thr_id].restart)); *hashes_done = n - first_nonce + 1; pdata[19] = n; return 0; }
// Update hash with the remaining portion of the message and finalise it. // Total length of the entire message must be provided, as it will be appended // at the end according to the specification. // Input: hash[8] is the accumulated internal state in native byte order. // Output: hash[8] is the resulting hash that can be considered a byte sequence // (i.e. in big endian). void sha256_finish(uint32_t hash[8], const uint8_t *data, int len, int total) { union { uint8_t b[SHA256_BLOCK_SIZE]; // 64 bytes uint32_t w[SHA256_BLOCK_SIZE / 4]; } buf; int i; for (i = 0; i + (int) sizeof buf <= len; i += sizeof buf) { memcpy(buf.b, data + i, sizeof buf); sha256_transform(hash, buf.w); } int l = len - i; memcpy(buf.b, data + i, l); buf.b[l]=0x80; if (l > 55) { for (i = l + 1; i != sizeof buf; i++) buf.b[i]=0; sha256_transform(hash, buf.w); l = 0; buf.b[l] = 0; } for (i = l + 1; i <= 55; i++) buf.b[i]=0; buf.w[14] = 0; // high 4 bytes of bit length buf.w[15] = cpu_to_be32(total * 8); // bit length sha256_transform(hash, buf.w); #if __BYTE_ORDER == __LITTLE_ENDIAN for (i = 0; i < 8; i++) hash[i] = cpu_to_be32(hash[i]); #endif }
void akmos_sha2_256_done(akmos_sha2_256_t *ctx, uint8_t *digest) { size_t i, nb, pm_len; uint64_t len_b; nb = (1 + ((AKMOS_SHA2_256_BLKLEN - 9) < (ctx->len % AKMOS_SHA2_256_BLKLEN))); len_b = ((ctx->total * 64) + ctx->len) * 8; pm_len = nb * 64; memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; UNPACK64LE(ctx->block + pm_len - 8, len_b); if(nb > 0) sha256_transform(ctx->h, ctx->w, ctx->block, nb); for(i = 0; i < ctx->diglen / (sizeof(uint32_t)); i++) UNPACK32LE(digest + (i * sizeof(uint32_t)), ctx->h[i]); }
uint32_t* run_cpu_new(bc_work_t work, uint64_t nscrypt){ uint32_t word_per_scrypt = 20; uint32_t word_per_hash = 8; //get starting nonce from the data. (last 4 bytes in data) uint32_t* data_32bit = (uint32_t*) work.result.data; uint32_t start_nonce = data_32bit[word_per_scrypt-1]; uint32_t midstate[8]; sha256_init(midstate); sha256_transform(midstate, data_32bit, 0); //Initialise input and outputs - 80 bytes per scrypt for inputs, 32bytes outputs uint32_t *input = calloc(nscrypt, word_per_scrypt*sizeof(uint32_t)); uint32_t *output = calloc(nscrypt, word_per_hash*sizeof(uint32_t)); if(NULL == input || NULL == output){ LOG_FATAL("Cannot allocate memory for input/output buffers.\n"); } for(uint32_t i = 0; i < nscrypt; i++){ uint64_t index = i*word_per_scrypt; memcpy(input + index, data_32bit, sizeof(uint32_t)*word_per_scrypt); } for(uint32_t i = 0; i < nscrypt; i++){ uint64_t index = i*word_per_scrypt; input[index+word_per_scrypt-1] = start_nonce + i; } dfescrypt_cpu(nscrypt, input, output, midstate); free(input); return output; }
/** * \brief Prepare the data and run the Scrypt kernel. * \param work data received from getwork. * \return boolean - if nonce has been found. */ void scrypt_prepare_run(scrypt_worker_t *worker, bc_work_t work){ uint32_t word_per_scrypt = 20; uint32_t start_nonce = 0; //get starting nonce from the data. (last 4 bytes in data) uint32_t* data_32bit = (uint32_t*) work.result.data; uint32_t nscrypt = dfe_get_num_scrypt(worker->dfe); uint32_t midstate[8]; sha256_init(midstate); sha256_transform(midstate, data_32bit, 0); uint32_t *input = calloc(nscrypt, word_per_scrypt*sizeof(uint32_t)); for(uint32_t i = 0; i < nscrypt; i++){ uint64_t index = i*word_per_scrypt; memcpy(input + index, data_32bit, sizeof(uint32_t)*word_per_scrypt); } for(uint32_t i = 0; i < nscrypt; i++){ uint64_t index = i*word_per_scrypt; input[index+word_per_scrypt-1] = start_nonce + i; } uint32_t* X = worker->dfe_buffer; uint32_t* tstates = worker->tstate_buffer; uint32_t* ostates = worker->ostate_buffer; #pragma omp parallel for for (int64_t i = 0; i < (int64_t)nscrypt; i++) { memcpy(&tstates[i*8], midstate, 32); SHA256_before(&tstates[i*8], &ostates[i*8], &input[20*i], &X[i*32]); } free(input); }
void *subchain_hash_thread(void *pthread_arg) { /* * subchain_hash_thread() * Given a hash value and its position (index) in the chain, determine * the corresponding final hash. This is then used to find a candidate * chain in the main table */ PthreadData *mydata; mydata = (PthreadData*)pthread_arg; // TableHeader *header = mydata->header; TableEntry *entry = mydata->entry; uint thread_idx = mydata->entry_idx; uint8_t M[64]; // Initial string - zero padded and length in bits appended uint32_t W[64]; // Expanded Key Schedule uint32_t H[8]; // Hash int i = 0; // working index uint64_t l = 0; // length of message uint8_t B[64]; // store initial and working passwords here to protect original data uint8_t *in,*out; int reduction_idx,count; if(thread_idx<LINKS) { // set up a pointer to input_hash & final_hash TableEntry *data = entry + thread_idx; // move target hash to H for(i=0;i<8;i++) H[i] = data->input_hash[i]; reduction_idx = thread_idx; count = LINKS - thread_idx - 1; while(count > 0) { // Reduce hash to zero terminated password in B reduce_hash(H,B,reduction_idx); // copy zero terminated string from B to M and note length in = B; out = M; i=0; l=0; while(in[i] != 0x00) { out[i] = in[i]; i++; l++; } out[i++] = 0x80; // zero fill while(i < 56) out[i++]=0x00; /* * The hash algorithm uses 32 bit (4 byte words). * On little endian machines (Intel) the constants * are stored lsb->msb internally. To match this the WORDS * of the input message are subject to endian swap. */ uint8_t *x = M; int y; for(y=0; y<14; y++) { // long swap *(x+3) ^= *x; *x ^= *(x+3); *(x+3) ^= *x; // short swap *(x+2) ^= *(x+1); *(x+1) ^= *(x+2); *(x+2) ^= *(x+1); // move pointer up x += 4; } // need a 32 bit pointer to store length as 2 words l*=8; //length in bits uint32_t *p = (uint32_t*)&l; uint32_t *q = (uint32_t*)&out[i]; *q = *(p+1); *(q+1) = *p; // The 64 bytes in the message block can now be used // to initialise the 64 4-byte words in the message schedule W[64] // REUSE i uint8_t *r = (uint8_t*)M; uint8_t *s = (uint8_t*)W; for(i=0;i<64;i++) s[i] = r[i]; for(i=16;i<64;i++) W[i] = SIG1(W[i-2]) + W[i-7] + SIG0(W[i-15]) + W[i-16]; // set initial hash values initHash(H); // Now calc the hash sha256_transform(W,H); // update the counters reduction_idx += 1; count -= 1; } // while(count>0) // copy comp_hash to final hash for(i=0;i<8;i++) data->final_hash[i] = H[i]; data->sublinks = thread_idx; } // if(thread_idx<LINKS) void *void_ptr=NULL; return(void_ptr); } // hash_calculate
bool BlockMine2(MinerClient &client, WorkBlob &work) { uint32_t data[SCRYPT_MAX_WAYS * 20]; uint32_t hash[SCRYPT_MAX_WAYS * 8]; uint32_t midstate[8]; unsigned char* ScratchPad = (unsigned char *)malloc(1024 * SCRYPT_MAX_WAYS * 128 + 63); uint32_t shareCompare = work.ShareTarget.data[7]; //shareCompare = Helpers::BigEndian32Decode(&shareCompare); uint32_t nonce = 0; for (int i = 0; i < 20; i++) //Weird endian adjustment needed for pooler's code { ((int*)work.Blob)[i] = Helpers::BigEndian32Decode(&((int*)work.Blob)[i]); } int throughput = scrypt_best_throughput(); if (sha256_use_4way()) throughput *= 4; //throughput = 1; for (int i = 0; i < throughput; i++) { memcpy(data + i * 20, work.Blob, 80); } sha256_init(midstate); sha256_transform(midstate, data, 0); for (uint32_t t = 0; t<32768; t++) { if (client.CurrentProtocol == Stratum) { if (client.CurrentJob.Id != work.Id) { free(ScratchPad); return true; } } if (!client.Connected || !client.LoggedIn) { free(ScratchPad); return false; } for (uint32_t x = 0; x<4096; x++) { for (int i = 0; i < throughput; i++) data[i * 20 + 19] = nonce++; if (throughput == 4) scrypt_1024_1_1_256_4way(data, hash, midstate, ScratchPad, 1024); else if (throughput == 12) scrypt_1024_1_1_256_12way(data, hash, midstate, ScratchPad, 1024); if (throughput == 24) scrypt_1024_1_1_256_24way(data, hash, midstate, ScratchPad, 1024); else if (throughput == 3) scrypt_1024_1_1_256_3way(data, hash, midstate, ScratchPad, 1024); else scrypt_1024_1_1_256(data, hash, midstate, ScratchPad, 1024); for (int i = 0; i < throughput; i++) { if (hash[i * 8 + 7] <= shareCompare) { printf("We found a share submitting!\n"); if (client.CurrentProtocol == Stratum) { StratumShare share; //Helpers::BigEndian32Encode(share.Nonce, data[i * 20 + 19]); //Helpers::BigEndian32Encode(share.Ntime, *work.NtimePointer); //Helpers::BigEndian32Encode(share.ENonce2, *work.ENonce2); memcpy(share.Nonce, &(data[i * 20 + 19]), 4); memcpy(share.Ntime, work.NtimePointer, 4); memcpy(share.ENonce2, work.ENonce2, 4); share.Id = work.Id; StratumProtocol::AddShares( share, client); } } } client.TotalHashCount+=throughput; } } free(ScratchPad); return true; }
bool __SseSearch(unsigned int *round1State, unsigned char *round1Block2, unsigned __int32 *round2State, unsigned char *round2Block1, unsigned __int32 *nonce_, sseCheckFunc check) { // starting nonce unsigned int nonce = 0; // vector containing input round1 state __m128i round1State_m128i[8]; for (int i = 0; i < 8; i++) round1State_m128i[i] = _mm_set1_epi32(round1State[i]); // vector containing input round 1 block 2, contains the nonce field __m128i round1Block2_m128i[16]; for (int i = 0; i < 16; i++) round1Block2_m128i[i] = _mm_set1_epi32(((unsigned __int32*)round1Block2)[i]); // vector containing input round 2 state, initialized __m128i round2State_m128i[8]; for (int i = 0; i < 8; i++) round2State_m128i[i] = _mm_set1_epi32(round2State[i]); // vector containing round 2 block, to which the state from round 1 should be output __m128i round2Block1_m128i[16]; for (int i = 0; i < 16; i++) round2Block1_m128i[i] = _mm_set1_epi32(((unsigned __int32*)round2Block1)[i]); // vector containing the final output from round 2 __m128i round2State2_m128i[8]; // initial nonce vector __m128i nonce_inc_m128i = _mm_set_epi32(0, 1, 2, 3); for (;;) { // set nonce in blocks round1Block2_m128i[3] = _mm_add_epi32(_mm_set1_epi32(nonce), nonce_inc_m128i); // transform variable second half of block using saved state from first block, into pre-padded round 2 block (end of first hash) sha256_transform(round1State_m128i, round1Block2_m128i, round2Block1_m128i); // transform round 2 block into round 2 state (second hash) sha256_transform(round2State_m128i, round2Block1_m128i, round2State2_m128i); // isolate 0x00000000, segment to uint64 for easier testing __m128i p = _mm_cmpeq_epi32(round2State2_m128i[7], _mm_setzero_si128()); unsigned __int64 *p64 = (unsigned __int64*)&p; // one of the two sides of the vector has values if ((p64[0] != 0) | (p64[1] != 0)) { // first result if (_mm_extract_epi16(p, 0) != 0) { *nonce_ = endian_swap(nonce + 3); return true; } // second result if (_mm_extract_epi16(p, 2) != 0) { *nonce_ = endian_swap(nonce + 2); return true; } // third result if (_mm_extract_epi16(p, 4) != 0) { *nonce_ = endian_swap(nonce + 1); return true; } // fourth result if (_mm_extract_epi16(p, 6) != 0) { *nonce_ = endian_swap(nonce + 0); return true; } } // report progress, or check overflow if ((nonce += 4) % 65536 == 0) if (!check(65536) || nonce < 4) break; } return false; }
static void runhash(void *state, const void *input, const void *init) { memcpy(state, init, 32); sha256_transform((u32*)state, (const u8*)input); }