mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +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";
|
sha256 = "02s3qkb6kz3ndyx7rfndjbvp4vlwiqc42fxypn3g6jnc0v5jyz95";
|
||||||
}) { };
|
}) { };
|
||||||
moneroTests = nixpkgs.fetchurl {
|
moneroTests = nixpkgs.fetchurl {
|
||||||
url = "https://github.com/ph4r05/monero/releases/download/v0.17.3.2-dev-tests-u18.04-02/trezor_tests";
|
url = "https://github.com/ph4r05/monero/releases/download/v0.17.3.2-dev-tests-u18.04-03/trezor_tests";
|
||||||
sha256 = "f790ad7485cbbad92fbea673a75935028f61d42f64627a7c55f850f6742cf93a";
|
sha256 = "3280aeef795baf2fc46687c07ac4131e5a18767ecdd3af83cf17823ebb2d1007";
|
||||||
};
|
};
|
||||||
moneroTestsPatched = nixpkgs.runCommandCC "monero_trezor_tests" {} ''
|
moneroTestsPatched = nixpkgs.runCommandCC "monero_trezor_tests" {} ''
|
||||||
cp ${moneroTests} $out
|
cp ${moneroTests} $out
|
||||||
|
@ -60,7 +60,7 @@ async def set_output(
|
|||||||
state.mem_trace(5, True)
|
state.mem_trace(5, True)
|
||||||
|
|
||||||
# Compute tx keys and masks if applicable
|
# 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)
|
utils.unimport_end(mods)
|
||||||
state.mem_trace(6, True)
|
state.mem_trace(6, True)
|
||||||
|
|
||||||
@ -76,7 +76,13 @@ async def set_output(
|
|||||||
return MoneroTransactionSetOutputAck()
|
return MoneroTransactionSetOutputAck()
|
||||||
|
|
||||||
# Tx header prefix hashing, hmac dst_entr
|
# 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)
|
state.mem_trace(11, True)
|
||||||
|
|
||||||
out_pk_dest, out_pk_commitment, ecdh_info_bin = _get_ecdh_info_and_out_pk(
|
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(
|
def _compute_tx_keys(
|
||||||
state: State, dst_entr: MoneroTransactionDestinationEntry
|
state: State, dst_entr: MoneroTransactionDestinationEntry
|
||||||
) -> tuple[crypto.Point, crypto.Scalar]:
|
) -> tuple[crypto.Point, crypto.Scalar, crypto.Point]:
|
||||||
"""Computes tx_out_key, amount_key"""
|
"""Computes tx_out_key, amount_key"""
|
||||||
|
|
||||||
if state.is_processing_offloaded:
|
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 tx key if applicable
|
||||||
additional_txkey_priv = _set_out_additional_keys(state, dst_entr)
|
additional_txkey_priv = _set_out_additional_keys(state, dst_entr)
|
||||||
@ -192,26 +198,36 @@ def _compute_tx_keys(
|
|||||||
state.current_output_index,
|
state.current_output_index,
|
||||||
crypto_helpers.decodepoint(dst_entr.addr.spend_public_key),
|
crypto_helpers.decodepoint(dst_entr.addr.spend_public_key),
|
||||||
)
|
)
|
||||||
del (derivation, additional_txkey_priv)
|
del (additional_txkey_priv,)
|
||||||
|
|
||||||
from apps.monero.xmr import monero
|
from apps.monero.xmr import monero
|
||||||
|
|
||||||
mask = monero.commitment_mask(crypto_helpers.encodeint(amount_key))
|
mask = monero.commitment_mask(crypto_helpers.encodeint(amount_key))
|
||||||
state.output_masks.append(mask)
|
state.output_masks.append(mask)
|
||||||
return tx_out_key, amount_key
|
return tx_out_key, amount_key, derivation
|
||||||
|
|
||||||
|
|
||||||
def _set_out_tx_out(
|
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]:
|
) -> tuple[bytes, bytes]:
|
||||||
"""
|
"""
|
||||||
Manually serializes TxOut(0, TxoutToKey(key)) and calculates hmac.
|
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[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)
|
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
|
# Tx header prefix hashing
|
||||||
state.tx_prefix_hasher.buffer(tx_out_bin)
|
state.tx_prefix_hasher.buffer(tx_out_bin)
|
||||||
@ -569,6 +585,28 @@ def _set_out_derivation(
|
|||||||
return 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:
|
def _is_last_in_batch(state: State, idx: int, bidx: int) -> bool:
|
||||||
"""
|
"""
|
||||||
Returns true if the current output is last in the rsig batch
|
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.
|
# When updating URL and sha256sum also update the URL in ci/shell.nix.
|
||||||
error=1
|
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_URL:=https://github.com/ph4r05/monero/releases/download/v0.17.3.2-dev-tests-u18.04-03/trezor_tests}"
|
||||||
: "${TREZOR_MONERO_TESTS_SHA256SUM:=f790ad7485cbbad92fbea673a75935028f61d42f64627a7c55f850f6742cf93a}"
|
: "${TREZOR_MONERO_TESTS_SHA256SUM:=3280aeef795baf2fc46687c07ac4131e5a18767ecdd3af83cf17823ebb2d1007}"
|
||||||
: "${TREZOR_MONERO_TESTS_PATH:=$CORE_DIR/tests/trezor_monero_tests}"
|
: "${TREZOR_MONERO_TESTS_PATH:=$CORE_DIR/tests/trezor_monero_tests}"
|
||||||
: "${TREZOR_MONERO_TESTS_LOG:=$CORE_DIR/tests/trezor_monero_tests.log}"
|
: "${TREZOR_MONERO_TESTS_LOG:=$CORE_DIR/tests/trezor_monero_tests.log}"
|
||||||
: "${TREZOR_MONERO_TESTS_CHAIN:=$CORE_DIR/tests/trezor_monero_tests.chain}"
|
: "${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))
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user