4

I'm interested in cobbling together my own implementation, but in order to validate it, I need to find some valid inputs/outputs (4 minimum, i.e. one that goes through the groestl path, one that goes through the blake path, one that goes through the jh path, and one that goes through the skein path). Does anyone have any to share?

Failing that, how can I get the PoW input and hash from looking in the block explorer?

Edit: and if I can't figure those out from looking in the block explorer, where can I figure them out?

2 Answers 2

4

There's a test code for hash functions (https://github.com/monero-project/monero/tree/master/tests/hash) where the expected values are in the txt files.

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.