Path: blob/master/algo/timetravel.c
1306 views
#include <miner.h>12#include <stdlib.h>3#include <stdint.h>4#include <string.h>5#include <stdio.h>67#include <sha3/sph_blake.h>8#include <sha3/sph_bmw.h>9#include <sha3/sph_groestl.h>10#include <sha3/sph_jh.h>11#include <sha3/sph_keccak.h>12#include <sha3/sph_skein.h>13#include <sha3/sph_luffa.h>14#include <sha3/sph_cubehash.h>1516// Machinecoin Genesis Timestamp17#define HASH_FUNC_BASE_TIMESTAMP 13890408651819#define HASH_FUNC_COUNT 820#define HASH_FUNC_COUNT_PERMUTATIONS 403202122static __thread uint32_t s_ntime = UINT32_MAX;23static __thread int permutation[HASH_FUNC_COUNT] = { 0 };2425// helpers26static void swap(int *a, int *b) {27int c = *a;28*a = *b;29*b = c;30}3132static void reverse(int *pbegin, int *pend) {33while ( (pbegin != pend) && (pbegin != --pend) )34swap(pbegin++, pend);35}3637static void next_permutation(int *pbegin, int *pend) {38if (pbegin == pend)39return;4041int *i = pbegin;42++i;43if (i == pend)44return;4546i = pend;47--i;4849while (1) {50int *j = i;51--i;5253if (*i < *j) {54int *k = pend;5556while (!(*i < *--k))57/* pass */;5859swap(i, k);60reverse(j, pend);61return; // true62}6364if (i == pbegin) {65reverse(pbegin, pend);66return; // false67}68}69}7071void timetravel_hash(void *output, const void *input)72{73uint32_t _ALIGN(64) hash[16 * HASH_FUNC_COUNT];74uint32_t *hashA, *hashB;75uint32_t dataLen = 64;76uint32_t *work_data = (uint32_t *)input;77const uint32_t timestamp = work_data[17];7879sph_blake512_context ctx_blake;80sph_bmw512_context ctx_bmw;81sph_groestl512_context ctx_groestl;82sph_skein512_context ctx_skein;83sph_jh512_context ctx_jh;84sph_keccak512_context ctx_keccak;85sph_luffa512_context ctx_luffa;86sph_cubehash512_context ctx_cubehash;8788// We want to permute algorithms. To get started we89// initialize an array with a sorted sequence of unique90// integers where every integer represents its own algorithm.91if (timestamp != s_ntime) {92int steps = (int) (timestamp - HASH_FUNC_BASE_TIMESTAMP) % HASH_FUNC_COUNT_PERMUTATIONS;93for (int i = 0; i < HASH_FUNC_COUNT; i++) {94permutation[i] = i;95}96for (int i = 0; i < steps; i++) {97next_permutation(permutation, permutation + HASH_FUNC_COUNT);98}99s_ntime = timestamp;100}101102for (int i = 0; i < HASH_FUNC_COUNT; i++) {103if (i == 0) {104dataLen = 80;105hashA = work_data;106} else {107dataLen = 64;108hashA = &hash[16 * (i - 1)];109}110hashB = &hash[16 * i];111112switch(permutation[i]) {113case 0:114sph_blake512_init(&ctx_blake);115sph_blake512(&ctx_blake, hashA, dataLen);116sph_blake512_close(&ctx_blake, hashB);117break;118case 1:119sph_bmw512_init(&ctx_bmw);120sph_bmw512 (&ctx_bmw, hashA, dataLen);121sph_bmw512_close(&ctx_bmw, hashB);122break;123case 2:124sph_groestl512_init(&ctx_groestl);125sph_groestl512 (&ctx_groestl, hashA, dataLen);126sph_groestl512_close(&ctx_groestl, hashB);127break;128case 3:129sph_skein512_init(&ctx_skein);130sph_skein512 (&ctx_skein, hashA, dataLen);131sph_skein512_close(&ctx_skein, hashB);132break;133case 4:134sph_jh512_init(&ctx_jh);135sph_jh512 (&ctx_jh, hashA, dataLen);136sph_jh512_close(&ctx_jh, hashB);137break;138case 5:139sph_keccak512_init(&ctx_keccak);140sph_keccak512 (&ctx_keccak, hashA, dataLen);141sph_keccak512_close(&ctx_keccak, hashB);142break;143case 6:144sph_luffa512_init(&ctx_luffa);145sph_luffa512 (&ctx_luffa, hashA, dataLen);146sph_luffa512_close(&ctx_luffa, hashB);147break;148case 7:149sph_cubehash512_init(&ctx_cubehash);150sph_cubehash512 (&ctx_cubehash, hashA, dataLen);151sph_cubehash512_close(&ctx_cubehash, hashB);152break;153default:154break;155}156}157158memcpy(output, &hash[16 * (HASH_FUNC_COUNT - 1)], 32);159}160161int scanhash_timetravel(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)162{163uint32_t _ALIGN(64) hash[8];164uint32_t _ALIGN(64) endiandata[20];165uint32_t *pdata = work->data;166uint32_t *ptarget = work->target;167168const uint32_t Htarg = ptarget[7];169const uint32_t first_nonce = pdata[19];170uint32_t nonce = first_nonce;171volatile uint8_t *restart = &(work_restart[thr_id].restart);172173if (opt_benchmark)174ptarget[7] = 0x0cff;175176for (int k=0; k < 19; k++)177be32enc(&endiandata[k], pdata[k]);178179do {180be32enc(&endiandata[19], nonce);181timetravel_hash(hash, endiandata);182183if (hash[7] <= Htarg && fulltest(hash, ptarget)) {184work_set_target_ratio(work, hash);185pdata[19] = nonce;186*hashes_done = pdata[19] - first_nonce;187return 1;188}189nonce++;190191} while (nonce < max_nonce && !(*restart));192193pdata[19] = nonce;194*hashes_done = pdata[19] - first_nonce + 1;195return 0;196}197198199