Merge branch 'plowsof-master' into viewtags

viewtags
Michał Sałaban 2 years ago
commit a9cf78d294

@ -140,16 +140,30 @@ class Transaction(object):
already generated. already generated.
""" """
def _scan_pubkeys(svk, psk, stealth_address, amount, encamount, commitment): def _scan_pubkeys(
svk, psk, stealth_address, amount, encamount, commitment, on_chain_vt
):
for keyidx, tx_key in enumerate(self.pubkeys): for keyidx, tx_key in enumerate(self.pubkeys):
# precompute # precompute
svk_2 = ed25519.scalar_add(svk, svk) svk_2 = ed25519.scalar_add(svk, svk)
svk_4 = ed25519.scalar_add(svk_2, svk_2) svk_4 = ed25519.scalar_add(svk_2, svk_2)
svk_8 = ed25519.scalar_add(svk_4, svk_4) svk_8 = ed25519.scalar_add(svk_4, svk_4)
# #
shared_secret = ed25519.scalarmult(svk_8, tx_key)
if on_chain_vt:
vt_hsdata = b"".join(
[b"view_tag", shared_secret, varint.encode(idx)]
)
vt_full = keccak_256(vt_hsdata).digest()
vt = vt_full[0:1]
if vt != on_chain_vt:
# short-circuit so it doesn't have to do the rest of this for ~99.6% of outputs
# the view tag check yields false positives 1/256 times, because it's just 1 byte
continue
hsdata = b"".join( hsdata = b"".join(
[ [
ed25519.scalarmult(svk_8, tx_key), shared_secret,
varint.encode(idx), varint.encode(idx),
] ]
) )
@ -207,9 +221,43 @@ class Transaction(object):
*map(operator.methodcaller("addresses"), wallet.accounts) *map(operator.methodcaller("addresses"), wallet.accounts)
) )
) )
"""
pre hard fork:
{
"target": {
"key": "ea3f..."
}
}
post hard fork:
{
"target": {
"tagged_key": {
"key": "ea3f...",
"view_tag": "a1"
}
}
}
"""
outs = [] outs = []
for idx, vout in enumerate(self.json["vout"]): for idx, vout in enumerate(self.json["vout"]):
stealth_address = binascii.unhexlify(vout["target"]["key"]) # see if post hard fork json structure present:
try:
if vout["target"]["tagged_key"]:
# post fork transaction
stealth_address = binascii.unhexlify(
vout["target"]["tagged_key"]["key"]
)
orig_stealth_address = vout["target"]["tagged_key"]["key"]
on_chain_vt = binascii.unhexlify(
vout["target"]["tagged_key"]["view_tag"]
)
except:
# pre fork transaction
stealth_address = binascii.unhexlify(vout["target"]["key"])
orig_stealth_address = vout["target"]["key"]
on_chain_vt = False
pass
encamount = None encamount = None
commitment = None commitment = None
if self.version == 2 and not self.is_coinbase: if self.version == 2 and not self.is_coinbase:
@ -229,13 +277,19 @@ class Transaction(object):
for addridx, addr in enumerate(addresses): for addridx, addr in enumerate(addresses):
psk = binascii.unhexlify(addr.spend_key()) psk = binascii.unhexlify(addr.spend_key())
payment = _scan_pubkeys( payment = _scan_pubkeys(
svk, psk, stealth_address, amount, encamount, commitment svk,
psk,
stealth_address,
amount,
encamount,
commitment,
on_chain_vt,
) )
if payment: if payment:
break break
outs.append( outs.append(
Output( Output(
stealth_address=vout["target"]["key"], stealth_address=orig_stealth_address,
amount=payment.amount if payment else amount, amount=payment.amount if payment else amount,
index=self.output_indices[idx] if self.output_indices else None, index=self.output_indices[idx] if self.output_indices else None,
transaction=self, transaction=self,

Loading…
Cancel
Save