mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-21 23:18:13 +00:00
fix(core/monero): add missing view_tags to hf15
This commit is contained in:
parent
892f3e348d
commit
2d36c4e8f3
@ -19,8 +19,8 @@ let
|
||||
sha256 = "02s3qkb6kz3ndyx7rfndjbvp4vlwiqc42fxypn3g6jnc0v5jyz95";
|
||||
}) { };
|
||||
moneroTests = nixpkgs.fetchurl {
|
||||
url = "https://github.com/ph4r05/monero/releases/download/v0.17.3.2-dev-tests-u18.04-02/trezor_tests";
|
||||
sha256 = "f790ad7485cbbad92fbea673a75935028f61d42f64627a7c55f850f6742cf93a";
|
||||
url = "https://github.com/ph4r05/monero/releases/download/v0.17.3.2-dev-tests-u18.04-03/trezor_tests";
|
||||
sha256 = "3280aeef795baf2fc46687c07ac4131e5a18767ecdd3af83cf17823ebb2d1007";
|
||||
};
|
||||
moneroTestsPatched = nixpkgs.runCommandCC "monero_trezor_tests" {} ''
|
||||
cp ${moneroTests} $out
|
||||
|
@ -60,7 +60,7 @@ async def set_output(
|
||||
state.mem_trace(5, True)
|
||||
|
||||
# Compute tx keys and masks if applicable
|
||||
tx_out_key, amount_key = _compute_tx_keys(state, dst_entr)
|
||||
tx_out_key, amount_key, derivation = _compute_tx_keys(state, dst_entr)
|
||||
utils.unimport_end(mods)
|
||||
state.mem_trace(6, True)
|
||||
|
||||
@ -76,7 +76,13 @@ async def set_output(
|
||||
return MoneroTransactionSetOutputAck()
|
||||
|
||||
# Tx header prefix hashing, hmac dst_entr
|
||||
tx_out_bin, hmac_vouti = _set_out_tx_out(state, dst_entr, tx_out_key)
|
||||
tx_out_bin, hmac_vouti = _set_out_tx_out(
|
||||
state,
|
||||
dst_entr,
|
||||
tx_out_key,
|
||||
derivation,
|
||||
)
|
||||
del (derivation,)
|
||||
state.mem_trace(11, True)
|
||||
|
||||
out_pk_dest, out_pk_commitment, ecdh_info_bin = _get_ecdh_info_and_out_pk(
|
||||
@ -172,11 +178,11 @@ def _validate(
|
||||
|
||||
def _compute_tx_keys(
|
||||
state: State, dst_entr: MoneroTransactionDestinationEntry
|
||||
) -> tuple[crypto.Point, crypto.Scalar]:
|
||||
) -> tuple[crypto.Point, crypto.Scalar, crypto.Point]:
|
||||
"""Computes tx_out_key, amount_key"""
|
||||
|
||||
if state.is_processing_offloaded:
|
||||
return None, None # no need to recompute
|
||||
return None, None, None # no need to recompute
|
||||
|
||||
# additional tx key if applicable
|
||||
additional_txkey_priv = _set_out_additional_keys(state, dst_entr)
|
||||
@ -192,26 +198,36 @@ def _compute_tx_keys(
|
||||
state.current_output_index,
|
||||
crypto_helpers.decodepoint(dst_entr.addr.spend_public_key),
|
||||
)
|
||||
del (derivation, additional_txkey_priv)
|
||||
del (additional_txkey_priv,)
|
||||
|
||||
from apps.monero.xmr import monero
|
||||
|
||||
mask = monero.commitment_mask(crypto_helpers.encodeint(amount_key))
|
||||
state.output_masks.append(mask)
|
||||
return tx_out_key, amount_key
|
||||
return tx_out_key, amount_key, derivation
|
||||
|
||||
|
||||
def _set_out_tx_out(
|
||||
state: State, dst_entr: MoneroTransactionDestinationEntry, tx_out_key: crypto.Point
|
||||
state: State,
|
||||
dst_entr: MoneroTransactionDestinationEntry,
|
||||
tx_out_key: crypto.Point,
|
||||
derivation: crypto.Point,
|
||||
) -> tuple[bytes, bytes]:
|
||||
"""
|
||||
Manually serializes TxOut(0, TxoutToKey(key)) and calculates hmac.
|
||||
"""
|
||||
tx_out_bin = bytearray(34)
|
||||
use_tags = state.hard_fork >= 15
|
||||
tx_out_bin = bytearray(35 if use_tags else 34)
|
||||
tx_out_bin[0] = 0 # amount varint
|
||||
tx_out_bin[1] = 2 # variant code TxoutToKey
|
||||
tx_out_bin[1] = (
|
||||
3 if use_tags else 2
|
||||
) # variant code txout_to_tagged_key or txout_to_key
|
||||
crypto.encodepoint_into(tx_out_bin, tx_out_key, 2)
|
||||
state.mem_trace(8)
|
||||
if use_tags:
|
||||
view_tag = _derive_view_tags(derivation, state.current_output_index)
|
||||
tx_out_bin[-1] = view_tag[0]
|
||||
|
||||
state.mem_trace(8, True)
|
||||
|
||||
# Tx header prefix hashing
|
||||
state.tx_prefix_hasher.buffer(tx_out_bin)
|
||||
@ -569,6 +585,28 @@ def _set_out_derivation(
|
||||
return derivation
|
||||
|
||||
|
||||
def _derive_view_tags(derivation: crypto.Point, output_index: int) -> bytes:
|
||||
"""
|
||||
Computes view tags for tx output - speeds up blockchain scanning for wallets
|
||||
view_tag_full = H["view_tag"|derivation|output_index]
|
||||
"""
|
||||
buff = bytearray(32)
|
||||
ctx = crypto_helpers.get_keccak()
|
||||
ctx.update(b"view_tag")
|
||||
crypto.encodepoint_into(buff, derivation)
|
||||
ctx.update(buff)
|
||||
|
||||
# Correct way of serializing output_index is calling dump_uvarint_b_into, but we
|
||||
# know that output_index is always lower than 127 so we save imports and calls.
|
||||
if output_index > 127:
|
||||
raise ValueError("Output index too big")
|
||||
|
||||
buff[0] = output_index
|
||||
ctx.update(buff[:1])
|
||||
full_tag = ctx.digest()
|
||||
return full_tag[:1]
|
||||
|
||||
|
||||
def _is_last_in_batch(state: State, idx: int, bidx: int) -> bool:
|
||||
"""
|
||||
Returns true if the current output is last in the rsig batch
|
||||
|
@ -23,8 +23,8 @@ fi
|
||||
|
||||
# When updating URL and sha256sum also update the URL in ci/shell.nix.
|
||||
error=1
|
||||
: "${TREZOR_MONERO_TESTS_URL:=https://github.com/ph4r05/monero/releases/download/v0.17.3.2-dev-tests-u18.04-02/trezor_tests}"
|
||||
: "${TREZOR_MONERO_TESTS_SHA256SUM:=f790ad7485cbbad92fbea673a75935028f61d42f64627a7c55f850f6742cf93a}"
|
||||
: "${TREZOR_MONERO_TESTS_URL:=https://github.com/ph4r05/monero/releases/download/v0.17.3.2-dev-tests-u18.04-03/trezor_tests}"
|
||||
: "${TREZOR_MONERO_TESTS_SHA256SUM:=3280aeef795baf2fc46687c07ac4131e5a18767ecdd3af83cf17823ebb2d1007}"
|
||||
: "${TREZOR_MONERO_TESTS_PATH:=$CORE_DIR/tests/trezor_monero_tests}"
|
||||
: "${TREZOR_MONERO_TESTS_LOG:=$CORE_DIR/tests/trezor_monero_tests.log}"
|
||||
: "${TREZOR_MONERO_TESTS_CHAIN:=$CORE_DIR/tests/trezor_monero_tests.chain}"
|
||||
|
@ -236,6 +236,18 @@ class TestMoneroCrypto(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(pkey_ex, crypto_helpers.encodepoint(pkey_comp))
|
||||
|
||||
def test_view_tags(self):
|
||||
from apps.monero.signing.step_06_set_output import _derive_view_tags
|
||||
|
||||
test_vectors = [
|
||||
(b'0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97', 0, b'\x76'),
|
||||
(b'fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0', 15, b'\xeb'),
|
||||
(b'ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d', 13, b'\x42'),
|
||||
]
|
||||
|
||||
for key, idx, exp in test_vectors:
|
||||
self.assertEqual(_derive_view_tags(crypto_helpers.decodepoint(unhexlify(key)), idx), exp)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user