|
|
@ -1,15 +1,12 @@ |
|
|
|
// Equihash solver
|
|
|
|
// Copyright (c) 2016-2016 John Tromp
|
|
|
|
// Copyright (c) 2016-2016 John Tromp, The Zcash developers
|
|
|
|
|
|
|
|
#include "blake/blake2.h" |
|
|
|
#include "sodium.h" |
|
|
|
#ifdef __APPLE__ |
|
|
|
#include "osx_barrier.h" |
|
|
|
#include <machine/endian.h> |
|
|
|
#include <libkern/OSByteOrder.h> |
|
|
|
#define htole32(x) OSSwapHostToLittleInt32(x) |
|
|
|
#else |
|
|
|
#include <endian.h> |
|
|
|
#include "pow/tromp/osx_barrier.h" |
|
|
|
#endif |
|
|
|
#include "compat/endian.h" |
|
|
|
|
|
|
|
#include <stdint.h> // for types uint32_t,uint64_t |
|
|
|
#include <string.h> // for functions memset |
|
|
|
#include <stdlib.h> // for function qsort |
|
|
@ -38,46 +35,20 @@ static const u32 HASHOUT = HASHESPERBLAKE*WN/8; |
|
|
|
|
|
|
|
typedef u32 proof[PROOFSIZE]; |
|
|
|
|
|
|
|
void setheader(blake2b_state *ctx, const char *header, const u32 headerlen, u32 nce) { |
|
|
|
uint32_t le_N = htole32(WN); |
|
|
|
uint32_t le_K = htole32(WK); |
|
|
|
uchar personal[] = "ZcashPoW01230123"; |
|
|
|
memcpy(personal+8, &le_N, 4); |
|
|
|
memcpy(personal+12, &le_K, 4); |
|
|
|
blake2b_param P[1]; |
|
|
|
P->digest_length = HASHOUT; |
|
|
|
P->key_length = 0; |
|
|
|
P->fanout = 1; |
|
|
|
P->depth = 1; |
|
|
|
P->leaf_length = 0; |
|
|
|
P->node_offset = 0; |
|
|
|
P->node_depth = 0; |
|
|
|
P->inner_length = 0; |
|
|
|
memset(P->reserved, 0, sizeof(P->reserved)); |
|
|
|
memset(P->salt, 0, sizeof(P->salt)); |
|
|
|
memcpy(P->personal, (const uint8_t *)personal, 16); |
|
|
|
blake2b_init_param(ctx, P); |
|
|
|
blake2b_update(ctx, (const uchar *)header, headerlen); |
|
|
|
uchar nonce[32]; |
|
|
|
memset(nonce, 0, 32); |
|
|
|
uint32_t le_nonce = htole32(nce); |
|
|
|
memcpy(nonce, &le_nonce, 4); |
|
|
|
blake2b_update(ctx, nonce, 32); |
|
|
|
} |
|
|
|
|
|
|
|
enum verify_code { POW_OK, POW_DUPLICATE, POW_OUT_OF_ORDER, POW_NONZERO_XOR }; |
|
|
|
const char *errstr[] = { "OK", "duplicate index", "indices out of order", "nonzero xor" }; |
|
|
|
|
|
|
|
void genhash(blake2b_state *ctx, u32 idx, uchar *hash) { |
|
|
|
blake2b_state state = *ctx; |
|
|
|
void genhash(const crypto_generichash_blake2b_state *ctx, u32 idx, uchar *hash) { |
|
|
|
crypto_generichash_blake2b_state state = *ctx; |
|
|
|
u32 leb = htole32(idx / HASHESPERBLAKE); |
|
|
|
blake2b_update(&state, (uchar *)&leb, sizeof(u32)); |
|
|
|
crypto_generichash_blake2b_update(&state, (uchar *)&leb, sizeof(u32)); |
|
|
|
uchar blakehash[HASHOUT]; |
|
|
|
blake2b_final(&state, blakehash, HASHOUT); |
|
|
|
crypto_generichash_blake2b_final(&state, blakehash, HASHOUT); |
|
|
|
memcpy(hash, blakehash + (idx % HASHESPERBLAKE) * WN/8, WN/8); |
|
|
|
} |
|
|
|
|
|
|
|
int verifyrec(blake2b_state *ctx, u32 *indices, uchar *hash, int r) { |
|
|
|
int verifyrec(const crypto_generichash_blake2b_state *ctx, u32 *indices, uchar *hash, int r) { |
|
|
|
if (r == 0) { |
|
|
|
genhash(ctx, *indices, hash); |
|
|
|
return POW_OK; |
|
|
@ -119,11 +90,9 @@ bool duped(proof prf) { |
|
|
|
} |
|
|
|
|
|
|
|
// verify Wagner conditions
|
|
|
|
int verify(u32 indices[PROOFSIZE], const char *header, const u32 headerlen, const u32 nonce) { |
|
|
|
int verify(u32 indices[PROOFSIZE], const crypto_generichash_blake2b_state *ctx) { |
|
|
|
if (duped(indices)) |
|
|
|
return POW_DUPLICATE; |
|
|
|
blake2b_state ctx; |
|
|
|
setheader(&ctx, header, headerlen, nonce); |
|
|
|
uchar hash[WN/8]; |
|
|
|
return verifyrec(&ctx, indices, hash, WK); |
|
|
|
return verifyrec(ctx, indices, hash, WK); |
|
|
|
} |
|
|
|