Thanks to great answers to this question I managed to improve my output recognition code, however I still have issues with some payments. The amounts are garbled, which means the xor mask is probably not computed correctly.
I guess I'm missing something very simple or external libraries I'm using have some glitch.
Here's my Python code snippet sprinkled with full debug.
print(" secret view key: {:s}".format(binascii.hexlify(svk).decode()))
print("checking tx: {:s}".format(self.txid))
print("tx has {:3d} outputs".format(len(self.outputs)))
print("tx has {:3d} keys".format(len(self.tx_keys)))
for output in self.outputs:
print("checking output {:d}".format(oidx))
keyidx = -1
for tx_key in self.tx_keys:
keyidx += 1
print(
" checking key {:d}: {:s}".format(
keyidx, binascii.hexlify(tx_key).decode()
)
)
hsdata = b"".join(
[
ed25519.encodepoint(
ed25519.scalarmult(
ed25519.decodepoint(tx_key), ed25519.decodeint(svk) * 8
)
),
varint.encode(oidx),
]
)
Hs_ur = sha3.keccak_256(hsdata).digest()
# sc_reduce32:
Hsint_ur = ed25519.decodeint(Hs_ur)
Hmul = Hsint_ur / ed25519.l # info value only
Hsint = Hsint_ur % ed25519.l
Hs = ed25519.encodeint(Hsint)
#
k = ed25519.encodepoint(
ed25519.edwards_add(
ed25519.scalarmult_B(Hsint), ed25519.decodepoint(psk),
)
)
if k != output.key:
print(" no match")
continue
print(" Hs_ur = {:s}".format(binascii.hexlify(Hs_ur).decode()))
print(" Hs = {:s}".format(binascii.hexlify(Hs).decode()))
print(" Hint_ur = {:d}".format(Hsint_ur))
print(" Hint = {:d}".format(Hsint))
print(" Hmul = {:.2f}".format(Hmul))
amount_hs = sha3.keccak_256(b"amount" + Hs).digest()
print(
" amount_hs = {:s}".format(
binascii.hexlify(amount_hs).decode()
)
)
print(
" enc_amount = {:s}".format(
binascii.hexlify(output.encamount).decode()
)
)
xormask = amount_hs[: len(output.encamount)]
print(
" xormask = {:s}".format(binascii.hexlify(xormask).decode())
)
dec_amount = bytes(a ^ b for a, b in zip(output.encamount, xormask))
print(
" dec_amount = {:s}".format(
binascii.hexlify(dec_amount).decode()
)
)
int_amount = int.from_bytes(
dec_amount, byteorder="little", signed=False
)
print(" int_amount = {:d}".format(int_amount))
amount = monero.numbers.from_atomic(int_amount)
print(" amount = {:.12f}".format(amount))
amounts.append((oidx, amount))
break
oidx += 1
The failing examples are on stagenet wallet 56eDKfprZtQGfB4y6gVLZx5naKVHw6KEKLDoq2WWtLng9ANuBvsw67wfqyhQECoLmjQN4cKAdvMp2WsC5fnw9seKLcCSfjj
.
First, the amount should be 1.1 XMR
. Receiving address is 76F1zQpev8aKYiZa4RiykvMgpbpavDVHNCJhYa71zB88MquS8vmjPytLSC2nDoBoHX5WpXLR5SyS6ExGbSMVV1nkT6rfZTd
with (major, minor) = (0, 3)
.
secret view key: e507923516f52389eae889b6edc182ada82bb9354fb405abedbe0772a15aea0a
checking tx: 050679bd5717cd4c3d0ed1db7dac4aa7e8a222ffc7661b249e5a595a3af37d3c
tx has 3 outputs
tx has 4 keys
checking output 0
[...]
checking output 2
checking key 0: 32f30dc0fe0c0ecb7918ba654fcc73b8d74b2d8653ffbbd284475ef3a3dcbea0
no match
checking key 1: 7b2c2aadfbfd0b3cbcca0b09e6d445410caf0ea8beb3b66c5573f1eb86515943
no match
checking key 2: b16f348827c34bb9620efc65291ca1fb994ab01db5c103aeb9435e6e50d89854
no match
checking key 3: e7b4e99f8c3eb19a7a6bcbf205e9441acb5e0193186fae5add2c3394e0e8fc33
Hs_ur = b38365a00459da5926204ae221a39ed0032c9a6214c127eea3a182e525c6a6df
Hs = aac0e9e7ad50ebe04329b79bd3f24bc1022c9a6214c127eea3a182e525c6a60f
Hint_ur = 101160429414286561058410493824695951988207185202632588040406292122661588140979
Hint = 7079356908967152276759068505137026857064672530693789162380929924950682878122
Hmul = 13.98
amount_hs = 78121283ad4069dc1918842b5935ad12aaec9110e87728961dd63a32e8e7fdcb
enc_amount = 58f647750234eeda
xormask = 78121283ad4069dc
dec_amount = 20e455f6af748706
int_amount = 470472985184429088
amount = 470472.985184429088
Second, where 1.0 XMR
is expected. Address is 797WaaL2Tm4CKQcKjLCdtx9Mg6wVuLQcYe68Ljb17euvEMNQDBqXAXN7eHFNy4uSgwJk2hicLnvWY6p4fbAqcfaVEiox2rd
of index (0,1)
.
secret view key: e507923516f52389eae889b6edc182ada82bb9354fb405abedbe0772a15aea0a
checking tx: 9e1650ef843c028b1b5f880e6e7ec6562441e9f723d4cfc515207c507e2c752f
tx has 7 outputs
tx has 8 keys
checking output 0
[...]
checking output 5
checking key 0: 7f499f5f06de78e6b7399a91b36050e88292f5f62e5681e7845fd54b415358c5
no match
checking key 1: 73b8efdba4f3c0e2c9a372105cca4fc94f62599ab99d1d75e0893d4160a2d824
no match
checking key 2: 9f7d69600d357bef31163ef770bebe2f35898ddbcb2cfb3f17433dc65a20acee
no match
checking key 3: be503a4ad8186a587cd08c6abb74ea5c58119f6a38e504a423eed563a84e3720
no match
checking key 4: dae9c26ff80dbddb2f4fdbcb2dc42e106598988214e5acfeed60084ff71e7ca2
no match
checking key 5: ce4692824aec372b248e0aa3b61f08d082d698e80b2b0d71f5b89485c6098287
no match
checking key 6: 470cb29c97e354bb987b2e4abd5f321981f1d97feda32ed0101375efb62e1506
Hs_ur = 1d49aae57466ecf912a94503731effc61a5b9d1d5293b8f96969087e43341d8b
Hs = b5a9fbfda14d593960c288eb7d4f07201a5b9d1d5293b8f96969087e43341d0b
Hint_ur = 62923085228351870090926105142326278992011507504216180910171871531129174116637
Hint = 5027040609693772379140612637982325065154576629176920062156264024845540108725
Hmul = 8.69
amount_hs = e89bf8f4d6e281ec2fd24b102526d7d754b5294cdeead73450a16c46827a0350
enc_amount = 1609fc1cf655d9ad
xormask = e89bf8f4d6e281ec
dec_amount = fe9204e820b75841
int_amount = 4708714762375303934
amount = 4708714.762375303934
checking output 6
[...]
And third. This one has 3 outputs belonging to a single wallet's subaddress. One of them fails, with expected value of 0.2 XMR
. The receiving address is 7AAMoYytsGDGwVyCrLo3rU1vKwbDM9qHzEapbqUz596HhBEBj2aF4a9dmqaNaAd9LYcQHXTGaZe8KGBZHKi4k1FQSnJB3fa
of index (0,5)
.
secret view key: e507923516f52389eae889b6edc182ada82bb9354fb405abedbe0772a15aea0a
checking tx: e2871c4203e29433257219bc20fa58c68dc12efed8f05a86d59921969a2b97cc
tx has 4 outputs
tx has 1 keys
checking output 0
checking key 0: 2105e965fe7529abaa9fc3c3518781589b9a55f8394aea8349c08f259d21a011
Hs_ur = b5d32c1b921dbc8ba9eb87858ffa322db856195f4662ab7f881c85d375267bc7
Hs = 99e4a6bf5578df6a9d91ece11f44bf32b756195f4662ab7f881c85d375267b07
Hint_ur = 90227844499988343076557049979814408693606878134973414102304889890092333454261
Hint = 3383777572001196508878811223298477803321481822414522830281478630666882442393
Hmul = 12.47
amount_hs = d825027477697301c41799884d1c85c21f16424ad77772303f03a0a21cb668df
enc_amount = d8cd743c60697301
xormask = d825027477697301
dec_amount = 00e8764817000000
int_amount = 100000000000
amount = 0.100000000000
checking output 1
checking key 0: 2105e965fe7529abaa9fc3c3518781589b9a55f8394aea8349c08f259d21a011
no match
checking output 2
checking key 0: 2105e965fe7529abaa9fc3c3518781589b9a55f8394aea8349c08f259d21a011
Hs_ur = 07b71d3af42a786d69779c30713d8a28573611bc5b64ca8d125aeb0d28d362dd
Hs = fef3a1819d2289f4868009ea228d3719563611bc5b64ca8d125aeb0d28d3620d
Hint_ur = 100135747897593070915110917150315415114983223372346125091948185109869432256263
Hint = 6054675392273662133459491830756489983840710700407326213922822912158526993406
Hmul = 13.84
amount_hs = af9a2a62843a4e60a0ce1b9e1d8015e3078891b9cfa990d1bbab3a01e6657129
enc_amount = af224ebbc13a4e60
xormask = af9a2a62843a4e60
dec_amount = 00b864d945000000
int_amount = 300000000000
amount = 0.300000000000
checking output 3
checking key 0: 2105e965fe7529abaa9fc3c3518781589b9a55f8394aea8349c08f259d21a011
Hs_ur = 81493a64f4b36e2f8ff465fc2fb14d478cfe2b4bc87585cc2d3c462953ba35da
Hs = 7886beab9dab7fb6acfdd2b5e100fb378bfe2b4bc87585cc2d3c462953ba350a
Hint_ur = 98699129852428100445151195285318558098375685193814448536205178562327051127169
Hint = 4618057347108691663499769965759632967233172521875649658179816364616145864312
Hmul = 13.64
amount_hs = c4bd91f8fea5c96250ae1494039fcd97ba0cadf3b71fce420b3a789d766920b3
enc_amount = b4547ae104c58adf
xormask = c4bd91f8fea5c962
dec_amount = 70e9eb19fa6043bd
int_amount = 13637850723900975472
amount = 13637850.723900975472
8aR
. Nevertheless, I also triedscalarmult(scalarmult(key, svk), 8)
andscalarmult(scalarmult(key, 8), svk)
but the results are ursurprisingly the same. – emesik Feb 14 '20 at 11:2943b16f348827c34bb9620efc65291ca1fb994ab01db5c103aeb9435e6e50d898
which is an invalid ed25519 public key, so now I'm wondering if I'm reading the txextra wrong myself. – knaccc Feb 14 '20 at 13:39050679bd5717cd4c3d0ed1db7dac4aa7e8a222ffc7661b249e5a595a3af37d3c
are:32f30dc0fe0c0ecb7918ba654fcc73b8d74b2d8653ffbbd284475ef3a3dcbea0
,7b2c2aadfbfd0b3cbcca0b09e6d445410caf0ea8beb3b66c5573f1eb86515943
,b16f348827c34bb9620efc65291ca1fb994ab01db5c103aeb9435e6e50d89854
ande7b4e99f8c3eb19a7a6bcbf205e9441acb5e0193186fae5add2c3394e0e8fc33
– emesik Feb 14 '20 at 14:34f8b71657486142c2
with decryption keyf85784325f6042c2
and a second output of value 1.1xmr for encrypted amount78ea099ead4169dc
with decryption key78121283ad4069dc
. These don't match what you're written. – knaccc Feb 14 '20 at 15:020506..
. are:32f3...
,7b2c...
,b16f...
ande7b4...
" <- Is incorrect. The tx 0506... has 3 output keys,f923...
,07f8...
andad66...
with one tx pub key (R):32f3...
. – jtgrassie Feb 14 '20 at 22:32