4

I can verify transactions ids with version 1 using the normal Keccak256 hash just fine. I seem to be having trouble with version 2.

For example, this transaction: https://explorer.xmr.my/tx/be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843/1

I've calculated Keccak256 on the entire transaction which yields: 190c94b59a9d90e8e6ec4ed69092161e82413c121ae0db84f3e859d2eccb9a80

Obviously, this is not be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843

The TransactionPrefix portion is correctly hashed by Keccak256 to be 1bbfda600fa6affc80dae05b1124bf05ed0e20890aa42601441dbe0f6fa81f4b

I noticed that rctOps.cpp has its own cn_fast_hash which seems to be maybe different than crypto/crypto-ops.cpp's cn_fast_hash. What's the difference if that's what I'm missing?

Jimmy Song
  • 333
  • 1
  • 7

1 Answers1

5

It turns out that for version 2, the hash is computed by combining 3 other hashes and then computing the hash of the aggregate.

To be specific, the tx hash turns out to be:

H(H(prefix) || H(RingCTBase) || H(RingCTPrunable))

Where H is the Keccak256 hashing function, prefix is the Transaction Prefix serialized, RingCTBase is the RingCTBase serialized and RingCTPrunable is the RingCTPrunable serialized.

The details can be found in src/cryptonote_basic/cryptonote_format_utils.cpp's calculate_transaction_hash.

https://github.com/monero-project/monero/blob/master/src/cryptonote_basic/cryptonote_format_utils.cpp#L604

Jimmy Song
  • 333
  • 1
  • 7