For the input to the PoW hash function you can use the monerod daemon's RPC getblock
function which returns a blob (that was used as the input for the PoW) for any arbitrary block on the blockchain. I could be wrong though (please correct me).
Alternatively, simply use an existing correct implementation of cryptonight and validate your output against the correct output. See slow-hash.c for the official Monero version.
As for testing blake, groestl et al, you could, using trial-and-error, try as many inputs as needed until you have test cases for each one. To do this add printf
to the respective hash functions shown below to find what inputs resulted in what hash being used. See call to extra_hashes
here.
static void do_blake_hash(const void* input, size_t len, char* output) {
blake256_hash((uint8_t*)output, input, len);
}
void do_groestl_hash(const void* input, size_t len, char* output) {
groestl(input, len * 8, (uint8_t*)output);
}
static void do_jh_hash(const void* input, size_t len, char* output) {
int r = jh_hash(HASH_SIZE * 8, input, 8 * len, (uint8_t*)output);
}
static void do_skein_hash(const void* input, size_t len, char* output) {
int r = skein_hash(8 * HASH_SIZE, input, 8 * len, (uint8_t*)output);
}
static void (* const extra_hashes[4])(const void *, size_t, char *) = {
do_blake_hash,
do_groestl_hash,
do_jh_hash,
do_skein_hash
};
Now you can easily modify the above by replacing do_blake_hash, do_groestl et al with function pointers to your implementation(s). For testing, use assertions to compare corresponding outputs with the known correct implementations.
Note: If your intention for rolling-your-own hashes is for performance, I'd suggest rather seeing how you can optimize "memory-hard" portion of the PoW function. In particular, whether analyzing cache-misses for reading/writing to the scratchpad and improving memory-latency.