1
0
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:
Dusan Klinec 2022-06-20 19:45:52 +02:00 committed by matejcik
parent 892f3e348d
commit 2d36c4e8f3
4 changed files with 64 additions and 14 deletions

View File

@ -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

View File

@ -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

View File

@ -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}"

View File

@ -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()