Skip to content

Commit

Permalink
Timetravel hash function from Machinecoin project
Browse files Browse the repository at this point in the history
note tpruvot: nice commit, proper...  Waaaaahhhh ^^
  • Loading branch information
madzebra authored and tpruvot committed Jan 23, 2017
1 parent e867845 commit 87a2e10
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ cpuminer_SOURCES = \
algo/skein.c \
algo/skein2.c \
algo/s3.c \
algo/timetravel.c \
algo/veltor.c \
algo/x11evo.c \
algo/x11.c \
Expand Down
215 changes: 215 additions & 0 deletions algo/timetravel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#include <miner.h>

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include <sha3/sph_blake.h>
#include <sha3/sph_bmw.h>
#include <sha3/sph_groestl.h>
#include <sha3/sph_jh.h>
#include <sha3/sph_keccak.h>
#include <sha3/sph_skein.h>
#include <sha3/sph_luffa.h>
#include <sha3/sph_cubehash.h>
#include <sha3/sph_shavite.h>
#include <sha3/sph_simd.h>
#include <sha3/sph_echo.h>

#define HASH_FUNC_BASE_TIMESTAMP 1389040865 // Machinecoin: Genesis Timestamp
#define HASH_FUNC_COUNT 8 // Machinecoin: HASH_FUNC_COUNT of 11
#define HASH_FUNC_COUNT_PERMUTATIONS 40320 // Machinecoin: HASH_FUNC_COUNT!

// helpers
void swap(int *a, int *b) {
int c = *a;
*a = *b;
*b = c;
}

void reverse(int *pbegin, int *pend) {
while ( (pbegin != pend) && (pbegin != --pend) )
swap(pbegin++, pend);
}

void next_permutation(int *pbegin, int *pend) {
if (pbegin == pend)
return;

int *i = pbegin;
++i;
if (i == pend)
return;

i = pend;
--i;

while (1) {
int *j = i;
--i;

if (*i < *j) {
int *k = pend;

while (!(*i < *--k))
/* pass */;

swap(i, k);
reverse(j, pend);
return; // true
}

if (i == pbegin) {
reverse(pbegin, pend);
return; // false
}
}
}
// helpers

void timetravel_hash(void *output, const void *input)
{
uint32_t _ALIGN(64) hash[128]; // 16 bytes * HASH_FUNC_COUNT
uint32_t *hashA, *hashB;
uint32_t dataLen = 64;
uint32_t *work_data = (uint32_t *)input;
const uint32_t timestamp = work_data[17];


sph_blake512_context ctx_blake;
sph_bmw512_context ctx_bmw;
sph_groestl512_context ctx_groestl;
sph_skein512_context ctx_skein;
sph_jh512_context ctx_jh;
sph_keccak512_context ctx_keccak;
sph_luffa512_context ctx_luffa;
sph_cubehash512_context ctx_cubehash;
sph_shavite512_context ctx_shavite;
sph_simd512_context ctx_simd;
sph_echo512_context ctx_echo;

// We want to permute algorithms. To get started we
// initialize an array with a sorted sequence of unique
// integers where every integer represents its own algorithm.
uint32_t permutation[HASH_FUNC_COUNT];
for (uint32_t i = 0; i < HASH_FUNC_COUNT; i++) {
permutation[i]=i;
}

// Compute the next permuation
uint32_t steps = (timestamp - HASH_FUNC_BASE_TIMESTAMP)%HASH_FUNC_COUNT_PERMUTATIONS;
for (uint32_t i = 0; i < steps; i++) {
next_permutation(permutation, permutation + HASH_FUNC_COUNT);
}

for (uint32_t i = 0; i < HASH_FUNC_COUNT; i++) {
if (i == 0) {
dataLen = 80;
hashA = work_data;
} else {
dataLen = 64;
hashA = &hash[16 * (i - 1)];
}
hashB = &hash[16 * i];

switch(permutation[i]) {
case 0:
sph_blake512_init(&ctx_blake);
sph_blake512(&ctx_blake, hashA, dataLen);
sph_blake512_close(&ctx_blake, hashB);
break;
case 1:
sph_bmw512_init(&ctx_bmw);
sph_bmw512 (&ctx_bmw, hashA, dataLen);
sph_bmw512_close(&ctx_bmw, hashB);
break;
case 2:
sph_groestl512_init(&ctx_groestl);
sph_groestl512 (&ctx_groestl, hashA, dataLen);
sph_groestl512_close(&ctx_groestl, hashB);
break;
case 3:
sph_skein512_init(&ctx_skein);
sph_skein512 (&ctx_skein, hashA, dataLen);
sph_skein512_close(&ctx_skein, hashB);
break;
case 4:
sph_jh512_init(&ctx_jh);
sph_jh512 (&ctx_jh, hashA, dataLen);
sph_jh512_close(&ctx_jh, hashB);
break;
case 5:
sph_keccak512_init(&ctx_keccak);
sph_keccak512 (&ctx_keccak, hashA, dataLen);
sph_keccak512_close(&ctx_keccak, hashB);
break;
case 6:
sph_luffa512_init(&ctx_luffa);
sph_luffa512 (&ctx_luffa, hashA, dataLen);
sph_luffa512_close(&ctx_luffa, hashB);
break;
case 7:
sph_cubehash512_init(&ctx_cubehash);
sph_cubehash512 (&ctx_cubehash, hashA, dataLen);
sph_cubehash512_close(&ctx_cubehash, hashB);
break;
case 8:
sph_shavite512_init(&ctx_shavite);
sph_shavite512(&ctx_shavite, hashA, dataLen);
sph_shavite512_close(&ctx_shavite, hashB);
break;
case 9:
sph_simd512_init(&ctx_simd);
sph_simd512 (&ctx_simd, hashA, dataLen);
sph_simd512_close(&ctx_simd, hashB);
break;
case 10:
sph_echo512_init(&ctx_echo);
sph_echo512 (&ctx_echo, hashA, dataLen);
sph_echo512_close(&ctx_echo, hashB);
break;
default:
break;
}
}

memcpy(output, &hash[16 * (HASH_FUNC_COUNT - 1)], 32);
}

int scanhash_timetravel(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)
{
uint32_t _ALIGN(64) hash[8];
uint32_t _ALIGN(64) endiandata[20];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;

const uint32_t Htarg = ptarget[7];
const uint32_t first_nonce = pdata[19];
uint32_t nonce = first_nonce;
volatile uint8_t *restart = &(work_restart[thr_id].restart);

if (opt_benchmark)
ptarget[7] = 0x0cff;

for (int k=0; k < 19; k++)
be32enc(&endiandata[k], pdata[k]);

do {
be32enc(&endiandata[19], nonce);
timetravel_hash(hash, endiandata);

if (hash[7] <= Htarg && fulltest(hash, ptarget)) {
work_set_target_ratio(work, hash);
pdata[19] = nonce;
*hashes_done = pdata[19] - first_nonce;
return 1;
}
nonce++;

} while (nonce < max_nonce && !(*restart));

pdata[19] = nonce;
*hashes_done = pdata[19] - first_nonce + 1;
return 0;
}
8 changes: 8 additions & 0 deletions cpu-miner.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ enum algos {
ALGO_SKEIN, /* Skein */
ALGO_SKEIN2, /* Double skein (Woodcoin) */
ALGO_S3, /* S3 */
ALGO_TIMETRAVEL, /* Timetravel (Machinecoin) */
ALGO_VANILLA, /* Vanilla (Blake256 8-rounds - double sha256) */
ALGO_VELTOR, /* Skein Shavite Shabal Streebog */
ALGO_X11EVO, /* Permuted X11 */
Expand Down Expand Up @@ -164,6 +165,7 @@ static const char *algo_names[] = {
"skein",
"skein2",
"s3",
"timetravel",
"vanilla",
"veltor",
"x11evo",
Expand Down Expand Up @@ -314,6 +316,7 @@ Options:\n\
skein Skein+Sha (Skeincoin)\n\
skein2 Double Skein (Woodcoin)\n\
s3 S3\n\
timetravel Timetravel (Machinecoin)\n\
vanilla Blake-256 8-rounds\n\
x11evo Permuted x11\n\
x11 X11\n\
Expand Down Expand Up @@ -1782,6 +1785,7 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
case ALGO_GROESTL:
case ALGO_LBRY:
case ALGO_LYRA2REV2:
case ALGO_TIMETRAVEL:
case ALGO_XEVAN:
work_set_target(work, sctx->job.diff / (256.0 * opt_diff_factor));
break;
Expand Down Expand Up @@ -2105,6 +2109,7 @@ static void *miner_thread(void *userdata)
break;
case ALGO_LYRA2:
case ALGO_LYRA2REV2:
case ALGO_TIMETRAVEL:
case ALGO_XEVAN:
max64 = 0xffff;
break;
Expand Down Expand Up @@ -2268,6 +2273,9 @@ static void *miner_thread(void *userdata)
case ALGO_S3:
rc = scanhash_s3(thr_id, &work, max_nonce, &hashes_done);
break;
case ALGO_TIMETRAVEL:
rc = scanhash_timetravel(thr_id, &work, max_nonce, &hashes_done);
break;
case ALGO_VANILLA:
rc = scanhash_blakecoin(thr_id, &work, max_nonce, &hashes_done);
break;
Expand Down
1 change: 1 addition & 0 deletions cpuminer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@
<ClCompile Include="algo\sibcoin.c" />
<ClCompile Include="algo\skein.c" />
<ClCompile Include="algo\skein2.c" />
<ClCompile Include="algo\timetravel.c" />
<ClCompile Include="algo\veltor.c" />
<ClCompile Include="algo\x11evo.c" />
<ClCompile Include="algo\x11.c" />
Expand Down
3 changes: 3 additions & 0 deletions cpuminer.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@
<ClCompile Include="algo\skein.c">
<Filter>algo</Filter>
</ClCompile>
<ClCompile Include="algo\timetravel.c">
<Filter>algo</Filter>
</ClCompile>
<ClCompile Include="algo\veltor.c">
<Filter>algo</Filter>
</ClCompile>
Expand Down
2 changes: 2 additions & 0 deletions miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ int scanhash_sib(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *ha
int scanhash_skein(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done);
int scanhash_skein2(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done);
int scanhash_s3(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done);
int scanhash_timetravel(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done);
int scanhash_veltor(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done);
int scanhash_x11evo(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done);
int scanhash_x11(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done);
Expand Down Expand Up @@ -518,6 +519,7 @@ void sibhash(void *output, const void *input);
void skeinhash(void *state, const void *input);
void skein2hash(void *state, const void *input);
void s3hash(void *output, const void *input);
void timetravel_hash(void *output, const void *input);
void veltor_hash(void *output, const void *input);
void xevan_hash(void *output, const void *input);
void x11evo_hash(void *output, const void *input);
Expand Down
3 changes: 3 additions & 0 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -2423,6 +2423,9 @@ void print_hash_tests(void)
s3hash(&hash[0], &buf[0]);
printpfx("s3", hash);

timetravel_hash(&hash[0], &buf[0]);
printpfx("timetravel", hash);

veltor_hash(&hash[0], &buf[0]);
printpfx("veltor", hash);

Expand Down

0 comments on commit 87a2e10

Please sign in to comment.