5

Checked this link: https://moneroblocks.info/api/get_transaction_data/4adb55cde1ffcc0ea639b6718355c48c0e574000306d95ef857e55d91ddabcf2

I could not find the encrypted mask value.

I believe the encrypted amount is in the ecdh part:

     "ecdhInfo": [
        {
          "amount": "f350bbedb3a4a93b"
        },
        {
          "amount": "c2005984b560da47"
        },
        {
          "amount": "6a2a649c8322d6e1"
        },
        {
          "amount": "0e0c6e72d16779c7"
        }
      ],
WeCanBeFriends
  • 660
  • 3
  • 7

1 Answers1

6

As of the March 2019 hard fork, commitment masks are deterministically derived from the per-output shared secret. This means the ECDHinfo part of the transaction will no longer store the encrypted mask.

See the commit here: https://github.com/monero-project/monero/commit/7d375981584e5ddac4ea6ad8879e2211d465b79d

Therefore, to determine the commitment mask, calculate:

commitment mask = Hs("commitment_mask" || Hs(8aR||i))

To reduce the storage requirement for the amount from 32 bytes to 8 bytes, the 8 byte amount is now XOR encrypted using an 8 byte key deterministically derived from the shared secret.

To encrypt the amount, calculate:

encrypted amount = 8 byte amount XOR first 8 bytes of keccak("amount" || Hs(8rA||i))

To decrypt the amount, calculate:

amount = 8 byte encrypted amount XOR first 8 bytes of keccak("amount" || Hs(8aR||i))

knaccc
  • 8,468
  • 16
  • 22
  • TBC: a is the public view key, i is the index of the output in the transaction – WeCanBeFriends May 26 '19 at 21:11
  • 1
    a is the private view key, not public. – jtgrassie May 26 '19 at 22:10
  • Oh right, 8aR is the public view key – WeCanBeFriends May 26 '19 at 22:24
  • 1
    8aR is not "the public view key" either. R is the tx public key (the shared part of the shared secret), a is the receivers private view key and i is the output index. – jtgrassie May 27 '19 at 00:24
  • Ahh thanks for the correction. I am now a bit confused as to why the G variable is there now. We could just send the scalar Hs("commitment_mask" || Hs(8aR||i)). Unless I'm missing something – WeCanBeFriends May 27 '19 at 00:41
  • 1
    @WeCanBeFriends You're right, I've fixed the error in my answer. The shared secret is Hs(8aR||i) and not Hs(8aR||i)G. From a cryptographic point of view, it would also have worked to have chosen to directly use (8aR||i) instead of Hs(8aR||i) (inside these hashed constructions only), but since the code already calculates Hs(8aR||i) for use elsewhere, we just re-use it for simplicity. – knaccc May 27 '19 at 04:23
  • @knacc Ahh makes sense, you've also answered my follow-up question about 8aR||i – WeCanBeFriends May 27 '19 at 11:28