The cryptonote whitepaper says

First, the input is hashed using Keccak [KECCAK] with parameters b = 1600 and c = 512. [..]

That's nothing else as hashing the input with SHA3. The size of a SHA3 hash is 512 bit = 64 byte. The paper continues

[..] The bytes 64..191 are extracted from the Keccak final state and split into 8 blocks of 16 bytes each.

How can I extract the bytes from 64 to 191 when the size of the hash is only 64 byte?

Edit: Does Keccak final state refer to the internal state of the SHA3 algorithm and not to the output? If yes that leads to the question how can I get this value when I use a normal SHA3 hashing function that just returns the output. Or - oh my gosh - do I need to implement SHA3 by my own?

1 Answer 1


Keccak has a 200 bytes internal state.

For SHA3, the produced hash is only a part of the final Keccak internal state (e.g. the first 64 bytes).

However, the scratchpad initialization function of CryptoNight uses data from almost all the final internal Keccak state. The first 32 bytes are used as an AES-256 key and the 128 bytes from byte 64 to byte 191 are used as initial data. The initial data is then encrypted with AES rounds to make the first 128 bytes of the scratchpad.

Therefore, you can't get all the required data from the 64 byte output of the official SHA3/512 hash function.

EDIT: The function used by Monero is not based on SHA3 with a 64 bytes output, but on the original Keccak with a 32 byte output (the message paddings of SHA3 and Keccak are not the same).

  • Does it perform also the Squeezing Keccak part? Because using github.com/monero-project/mininero/blob/master/Keccak.py I get the correct "result" printed as "Value after absorption" as if the squeezing was not even done in the monero's src/crypto/keccak.c code.
    – Marki555
    Jul 16, 2018 at 20:10
  • Indeed the "squeezing phase" of Keccak.py is not used in monero's keccak.c.
    – glv
    Jul 17, 2018 at 7:59
  • Thanks, but then why there are also 2 invocations of keccakf(st,KECCAK_ROUNDS) in keccak.c?
    – Marki555
    Jul 17, 2018 at 8:25
  • 1
    In monero's keccak.c, most of the message is hashed in the for loop (first keccakf), then the remaining bytes of the message are padded and hashed (second keccakf). In mininero's Keccak.py, the message is padded first, then the padded message is hashed completely (first keccakf in the for loop). The second keccakf (in the "squeezing phase") will never be called given the parameters used for monero (n = 256, r = 1088).
    – glv
    Jul 17, 2018 at 8:43
  • Thanks, now it makes sense :) If you want you can write it as an answer to my question monero.stackexchange.com/q/9802/2978
    – Marki555
    Jul 17, 2018 at 11:38

Your Answer

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

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