1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-15 12:08:59 +00:00
trezor-firmware/core/src/apps/monero/README.md

322 lines
15 KiB
Markdown
Raw Normal View History

xmr: master merging commit templates: build style: correct math in comment [260130c1] xmr: show address fix [abd27e6c] xmr: reorganize module structure [cd9e5a5d] xmr: simplify layout code [a5b56f17] xmr: monero.crypto test fix [60bc30ec] xmr: minor fixes [f82bd9c0] xmr: use trezor.utils.ensure [adf119ac] xmr: get rid of xmr.common module [3531a42f] pipenv: temporary fix attempt for travis - until pipenv bug is resolved [d172f86f] xmr: protob messages refactored [e83085ea] trezor-common version bump & messages regenerated xmr: mlsag_hasher simplified [feb5f1c6] xmr: simplify key_image_sync workflow [d4cb0084] xmr: tiny note in README and typo [62411cde] xmr: readme updates [ff15b46e] xmr: rename and order mlsag functions [3fb57dab] xmr: mlsag notes [c27ae90b] xmr: output index check added in step6 [973c457b] xmr: grouping is mandatory [684c7e19] xmr: range sig grouping check added [012ca766] xmr: small refactor in borromean range proof [1ba72b65] xmr: move range signatures to seperate file; rename mlsag2 to mlsag [a89f3ab0] xmr: fix wrong annotation in modtrezorcrypto [8303b42f] xmr: state's use_simple_rct and use_bulletproof modified to enums [276712a9] xmr: re-export most of functions in apps.monero.xmr.crypto [74165457] xmr: out_pk_masks changed to out_pk_commitments [1e186727] xmr: state comments [3c69a2e1] xmr: TrezorTxPrefixHashNotMatchingError note removed only concerns multisig [5af0feae] xmr: master merging commit xmr: step 10 review [d8e99375] xmr: step 09 review [a510150d] travis: workaround form 6a0ea22b6eb3bdc9bce62d7c88fb8841ef8fdb0c [03d27115] mocks: regenerate [bd24bb35] mocks: add support for entering the global scope [f75c1902] mocks: regenerate [bce85968] modtrezorcrypto: define mock package [7c077521] mocks: support package definition [b3f1017b] xmr: step 05 and 06 masks and range proofs review Masks are now always generated in step 5 and stored in state. Range proofs were reviewed only in a high-level manner and will be reviewed later. [67f391cd] xmr: step 08 review [673bf01f] xmr: steps 04, 05, 06 (almost) and 07 review _range_proof in step 06 is still to be reviewed [24c52517] xmr: simplify serialization, remove Archive [896cdebf] xmr: redundant exception removed [cb3813aa] xmr: serializer simplified [471213b4] xmr: serializer flake8 fix [9d4df17f] xmr: aescbc not needed [52dd8b3b] xmr: serializer - erefs kicked out [9e3be78f] xmr: sign cleanup, comments - state cleanup, comments added, unused code removed [164a7d6a] xmr: sign step 09 - fix in_memory artifact, dead branch [8fa4066d] xmr: sign step 03 - permutation length check added [55a593aa] xmr: multisig removed from protocol and functions [6470678d] xmr: black styling [02664401] xmr: step 03 review [daf7b7d6] xmr: step 02 review xmr: adding agent tests to travis [c752866f] xmr: unused imports removed [85115fd9] xmr: serializer test fixed - removed unsupported messages after serialization simplification [60874751] xmr: sign step 06 - comment on bulletproof hashing - hash_bp(bp) != hash(serialize(bp)) because hash does not contain array lengths [4abb5473] xmr: sign protocol - multisig logic removed [813cb3a0] xmr: lite protocol removed - backup left in xmr-total-full-with-lite branch [e5f5b5bd] xmr: serialization slimming - base types reduced, not needed for now - some int serialization methods not used now [fb515aaf] xmr: serialization - archive simplified - simple parameter passing, no kwargs - unused methods removed - reader/writer passing removed for archive methods [ec4c4adb] xmr: KeccakXmrArchive simplified, no archive used - getting rid of container_size. We dont use containers with fixed size so this special case can be abandoned. - KeccakXmrArchive is lighweight without need to touch main serialization [90065bd4] xmr: serialization - serialize_archive removed - custom serialization routine is not required at this moment [b98c2f89] xmr: extra serialization refactored, manual serialization - extra is serialized manually to reduce serialization overhead - extra contains simple structures now: - payment ID = already serialized manually - tx pub key = easy to serialize manually - tx additional pub keys = serialized manually with little effort, more efficient memory usage [8ce28a54] xmr: state 6 - provided tx keys removed - needed only in the multisig scenario which is pruned now [8d827f46] xmr: PreMlsagHasher pseudo out hashing fix [49e552da] xmr: redundant import removed [4199943d] xmr: KeccakXmrArchive simplified [69bbf5fa] xmr: PreMlsagHasher - KeyV import removed, comment added [9a194fa2] xmr: step7 - manual hashing of Extra [d8a09283] xmr: PreMlsagHasher state load/save removed - not needed, state not serialized anymore [d5f43fa4] xmr: serialize reimport removed - complex types are not surviving protocol boundary anymore, no need to fix hierarchy problems due to unimporting [3b045612] xmr: serialize - TupleType removed [b9a56981] xmr: serialization schemes simplified [a59dbb8d] xmr: HashWrapper removed [d0d1f05b] xmr: step 01 cleanup and comments [8f7a7782] xmr: isort, black, flake8 fixes [14265eb2] xmr: getting rid of CtKey from the state - only lightweight objects are kept in the state. CtKey is import heavy object. Each set_out call locally imports a new own version of the Ctkey which causes a memory leak. [c0cfc203] xmr: set_out minor function call fix [c11c4686] xmr: sign_tx unimport optimization to reduce fragmentation [df0a1dfc] xmr: range_sig allocation reordering, large chunks first [63cddd5f] xmr: remove misc.StdObj [8c8e3f33] xmr: proper memory usage in workflow [9be1e0ac] xmr: typos and renames [87f718b5] xmr: back to flat workflow [64751339] xmr: refactor builder to seperate steps - lot of work to be done, but the general idea will probably stay - the messages workflow works, but the signed tx was not accepted by daemon, so there is a bug somewhere - additional cleanup/refactoring is defintely needed [14b0a851] xmr: iface modified to layout [27d568e1] xmr: extmod refactoring - *_into removed, replaced by generic methods - point_add, point_sub added - code cleanup (+1 squashed commit) Squashed commits: [fbe39496] monero support added Squashed commits: xmr: hmac/enc keys removed from builder [41028dff] xmr: unused function removed [358573e3] xmr: PR comments fixes [4abf9dc9] xmr: test fixes after refactoring [192785ad] template rebuilt [57a1f25e] xmr: wrapper protocol messages removed [6f40ce17] xmr: trezor-common version bump & sync [03e71de2] xmr: check input permutation [6fc8b0ec] xmr: code cleanup, refactoring [85ecc151] xmr: crypto code cleanup [20b4113c] xmr: chunked bulletproof vectors - workaround for the heap fragmentation problems [66786f9d] tools: enable to reset class level indentation for mocks gen [dc6f84a9] xmr: extmod-monero comments added, for mocks [b1d4ab11] xmr: code cleanup [447a8625] xmr: tsx confirmation raises exception on cancellation [00dd8f6c] xmr: protocol optimizations removed, flow unified - in_memory optimization stored tx.vin parts in the memory which enabled to skip roundtrips with permutations and hash_vini. Optimizations was removed so the protocol flow is unified among inputs, independent of the tx specs - many_inputs: optimization stored spending keys for UTXO in memory, now it is offloaded in the encrypted form. [ea69c7ad] vendor: trezor-common version bump & pb sync [5d81c2a8] xmr: manual BP serialization - more memory effective as the memory is critical in the range proof section [d64bda7c] xmr: range_proof C-impl deprecated - using now partitioned implementation in Python, which is also quite fast and easier to maintain due to allocations and buffers. [18604e0f] xmr: borromean range sig generated by partitions - overcomes heap fragmentation problem [65a5116b] xmr: comments removed [ca2bd0cc] xmr: auto-generated intelliJ param comments removed [a75ef32e] xmr: code cleanup, heap fragmentations fixes Squashed commits: [d2ac2eb6] xmr: addr cleanup [7e4c1a9c] xmr: code cleanup, heap fragmentations fixes [93af8afb] xmr: refactoring, typing, comments [28df8662] xmr: comment fix [8b4f4d9c] xmr: serializer test fix (+34 squashed commits) Squashed commits: [823ee192] xmr: crypto comment cleanup [6debfb6b] xmr: ring_ct cleanup [759f52bf] xmr: tsx signer code style, hintins [0b175bc9] xmr: tsx builder external state removed [fee4a5ad] xmr: builder state fix [92736fa7] xmr: sign_tx unimport [a570ecb9] xmr: misc code cleanup [4a496bb7] xmr: hash wrapper not needed in writer [fefdb834] xmr: signer serialization improved [8fa6eec9] xmr: signer mem clean [66c53fe5] xmr: isort [6996bd90] xmr: black [59915a85] xmr: tsx input serialization refactored [326af131] xmr: msg dump with prefix [6e39801d] xmr: manual serialization of tx prefix [9e5e047a] xmr: manual serialization improvements [d07cee60] xmr: manual serialization of txout elements [8d56c80e] xmr: TxOut custom serialization optimized II [c19ba122] xmr: TxOut custom serialization optimized [ce0d9b0b] xmr: TxOut manual serialization [44e38342] xmr: sing_tx unimport [61ac61be] xmr: lite log trace rename [176b4275] xmr: de-async overhaul [89ae3bad] xmr: diag style [5ccb2fbb] xmr: wrappers cleanup [aa86fb19] xmr: py3 only inheritance [8031b1b0] xmr: builder, log_trace -> mem_trace for clarity [25bf70d7] xmr: debugging logging only in debug mode [c7c8d3c8] xmr: iface cleanup [b0373396] xmr: lite debug only [b1f6ce04] xmr: diag only in debug [de7d718b] xmr: tsx counter removed [76729beb] xmr: tsx_sign removed [c6e6ffa8] Merge commit 'ba500bf4ec1ef9cd953bdf5a47888c5226db8d0b' into xmr [ee97ef9f] xmr: minor code cleanup xmr: black xmr: minor code cleanup [bae3ecac] xmr: bp comments [5e812e6f] xmr: sign - mem_trace, pydoc [7216a8c6] xmr: pydoc removed [e87365f4] xmr: layout cleanup [8d21d82e] xmr: redundant constructors removed [9aa82bed] xmr: redundant comments removed [9b926d6c] xmr: preludes removed [bc9e77f1] xmr: readme update [cf62047a] xmr: aggregated bulletproofs + rsig offloading xmr: change idx fix xmr: iface refactoring, integrated address (+5 squashed commits) xmr: layout pagination refactoring xmr: addr - integrated address pb: sync vendor: trezor-common version bump xmr: style fixes xmr: handle sweep tsx correctly - handle dummy change address correctly xmr: integrated address generation build: fix after trezor-crypto version bump xmr: new protocol dispatch handlers xmr: slip0010 [43cf4c3c] xmr: comment fix xmr: extmod pointer aritm fix xmr: _into api unified, result is the first parameter xmr: bp cleanup xmr: scalar nullity test fix xmr: msg registration improved - lite protocol optional - diag protocol optional xmr: unused imports (+33 squashed commits) [b4d045ae] xmr: bp - noqa flake8 false positive [2c79d4be] xmr: isort [8b9d2835] xmr: code cleanup [eb7496e9] xmr: iface - shorter timeouts for faster tests [59520b63] xmr: ringct comment [6b16088e] xmr: signer - comment fixes [a08958e2] xmr: simple and bulletproof condition fix [4e0289a9] vendor: trezor-common version bump [de472e5a] xmr: black [234d2249] xmr: lightening, fixes, KeccakXmrArchive - builder keys - unload mods before memory intensive operation [abdec665] xmr: sign_tx logging [989d8687] xmr: serialize lightening [7d61f056] xmr: tsx sign refactoring, lightening - wake_up state restore - minimize import weight [3a0daa8b] xmr: serialize thinning [65ad1d2e] xmr: serialize thinning [501221d5] xmr: bp - thinning [3d980377] xmr: bp - generalization with proof_v8 [10d11d60] xmr: extended rsig - offloading protocol [a8f5caa2] xmr: crypto - rsig params fix [f5e130b8] xmr: crypto - inv8 [dbc3f9d8] xmr: rsig pb sync [5748a13e] xmr: bp - data for bp4 fix (+18 squashed commits) Squashed commits: [5bcd54e3] xmr: bp - black [e93e97dd] xmr: bp refactoring, large memory optimizations - memoryview in __getitem__ requires new memory allocation so the refactored version uses to(), read() methods that can operate directly on buffers without need to create memory views. [c30745ae] xmr: bp - black [f5c40699] xmr: bp - tests extended [8dae75de] xmr: bp - get_exponent optim [3e59ff80] xmr: bp - precomputations for 4 statements [d1d2e29c] xmr: bp - gc.collect [1bb6b5ba] xmr: bp - optimizations, streamlining [2a2b0cb7] xmr: bp - verification in log(MN) memory for 1 proof - not allocating MN vectors - sequential multiexec added for memory efficient verification - bulletproofs: maintain -z4, -z5, and -y0 to avoid subtractions [8276d25] - bulletproofs: merge multiexps as per sarang's new python code [acd64d2b] [75aa7dee] xmr: bp - memory optimization [a10d05a9] xmr: bp - deterministic mask generation init [5060d6a7] xmr: bp optimizations [dd69eb1b] xmr: bp - black [19f0f64b] xmr: bp - optimizations, power key vector [2ba63f8c] xmr: bp - minor cleanup, optimizations, scalarmultH [31c9ca2d] xmr: bp - mem clean [3fc2c793] xmr: bp - memory save [5b16c9cc] bp: black [f1040c97] xmr: crypto - memory leak fix [ff863510] xmr: iface - flake [6ebf69c2] xmr: lite - flake8, black [eee55d62] xmr: bp - memory diag [2767009b] xmr: bulletproofs upgrade, mainnet version, cleaning [be6ebbd5] xmr: lite protocol [d603e96d] xmr: pb sync [5da15da9] vendor: trezor-common fix [0373b97e] xmr: iface - output confirmation split, subaddr fix [2cf32176] xmr: monero - subaddress fixed for index (0, 0) [3bb8f08b] xmr: enc.aescbc added - for lite protocol (+1 squashed commit) Squashed commits: [011dbaab] TMP: trezor-common on master, crypto on ph4 - trezor-crypto on ph4r04 fork as it has all required stuff - Lite protocol not merged in master, thus does not work in the PR [795b34e1] xmr: get_address fix [2d39c90c] xmr: bp - import fix (squashed commit) Squashed commits: [2d5c6cee] extmod: monero - reduce32 and ge25519_norm removed (squashed commit) - not needed in trezor-core (+4 squashed commits) Squashed commits: [90e6b5c5] xmr: bp optimization [4fda0d22] xmr: redundant ge_ functions removed [68903767] xmr: crypto - sc_reduce32 not needed [c8a6c807] xmr: test for inversion added (+12 squashed commits) Squashed commits: [378928db] xmr: adapting to new trezor-crypto [8f4ff8c1] protob sync [82dff70a] vendor: trezor-common version bump [fabc67b3] extmod: monero - inversion mod curve order optimized a bit [4f29fe4c] xmr: import fix [f6f8e300] xmr: bp - code cleanup [d54b4f3b] xmr: bp - memory cleaning [1065abc3] xmr: tsx_signer - bulletproofs fixes [9f8a700f] xmr: bp key vector iterator fix [49c25977] xmr.serialize: bulletproof fix [1ee77378] xmr: monero - format [cf0a7104] xmr: bp last mask fix (+20 squashed commits) Squashed commits: [fa1c3623] xmr: black [3f3e31f3] xmr: bulletproofs added to signer [d23d9284] xmr: protocol.tsx_sign_builder - logger collects [a28eb55f] xmr: bp - memory optimizations [d2fcb23a] xmr: tests for bulletproofs added [82eef146] xmr: bp - gc (+14 squashed commits) Squashed commits: [4cf70d97] xmr: bp - gc [42877b05] xmr: bp - minor memory optimization [2c612e45] xmr: bp - use sc_inv_into [d7e9dab4] xmr: bp - KeyVEval fix [1523f400] xmr: bp - blacked [b264a65b] xmr: bp - KeyVEval - caching current element, avoid allocations [83ba7a65] xmr: bp - memory view optimized [b517906c] xmr: bp - gc() during inversion [92d37c88] xmr: bp - gc.collect() after expensive inversion [e7fad558] xmr: bp - hashing memory optimization [4c278152] xmr: bp - deterministic masks optimization, prove_s1 optim [cbf74a70] xmr: bp - detect which modular inversion is usable [8ea1ec43] xmr: better memory tracing for bulletproofs [2f4dd552] xmr: bulletproofs added [1928e2d3] xmr: crypto - sc_inv_into added (+2 squashed commits) Squashed commits: [f895fa6e] xmr: crypto - hash to existing buffer [b76c6b09] xmr: crypto - in-place crypto functions added - required for Bulletproof to minimize the heap fragmentation [cab4366e] extmod: monero - modular inversion mod curve order added (+2 squashed commits) Squashed commits: [52a6e487] extmod: monero - hash into buffer added [695a3827] extmod: monero module - muladd256_modm added - required for Bulletproof [3f4498d7] xmr: crypto tests added - basic unit tests for crypto, tests monero module and underlying trezor-crypto + basic address manipulation [820d012d] pb sync [49eeddd1] vendor: trezor-common version bump [30382440] xmr: crypto - point norm not needed [89701c41] tests: xmr - serializer tests added [bfee46db] tests: support async unit tests, assertListEqual added [55c14487] xmr: serialize - serialization logic cleaned, refactored [4b771638] xmr: simplification, do not ask to confirm change tx output - change address checked to match main address in the builder [f334d8ad] xmr: protocol: simplification - require change address to equal the main address [1a3416eb] xmr: unpack256_modm_noreduce added - 32B array to integer mod curve order, without modular reduction after conversion - required for bulletproofs [1c94b5d4] xmr: readme added [3cc9f9fa] extmod/monero: mul256_modm added, required for BP [5cf77a4c] xmr: monero support added [for review] depends on PRs: https://github.com/trezor/trezor-crypto/pull/162 https://github.com/trezor/trezor-core/pull/286
2018-08-06 12:07:14 +00:00
# Monero
MAINTAINER = ...
AUTHOR = Dusan Klinec <dusan.klinec@gmail.com>
REVIEWER = Tomas Susanka <tomas.susanka@satoshilabs.com>,
Jan Pochyla <jan.pochyla@satoshilabs.com>,
Ondrej Vejpustek <ondrej.vejpustek@satoshilabs.com>
-----
This Monero implementation was implemented from scratch originally for TREZOR by porting Monero C++ code to the Python codebase.
The implementation heavily relies on the [trezor-crypto] Monero functionality which implements basic crypto primitives and
other Monero related functionality (e.g., monero base58, accelerated and optimized Borromean range signatures)
A general high level description of the integration proposal is described in the documentation: [monero-doc].
## Features
The implementation provides the following features:
### Transaction signature
Signs a Monero transaction on the TREZOR.
- Designed so number of UTXO is practically unlimited (hundreds to thousands)
- Maximal number of outputs per transaction is 8 (usually there are only 2)
- Supports 8 B encrypted payment ID and 32 B unencrypted payment ID.
### Key Image sync
Key Image is computed with the spend key which is stored on the TREZOR.
In order to detect if the UTXO has been already spent (thus computing balance due to change transactions)
and correct spending UTXOs the key images are required. Without the key images the Monero view only
wallet incorrectly computes balance as it sees all ever received transactions as unspent.
Key image sync is a protocol that allows to compute key images for incoming transfers by TREZOR.
Example: 20 XMR in the single UTXO is received, thus real balance is 20. 1 XMR is sent to a different
address and remaining 19 are sent back with a change transaction. Correct balance is 19 but without
correct key image the view only wallet shows balance 39. Without knowing which UTXO is spent
the newly constructed spending transactions can pick already spent input. Such transaction is
rejected by a Monero daemon as a double spending transaction.
Normally, the Key image sync is not needed as the key image computation is done by
the transaction signing algorithm. However, if the wallet file is somehow corrupted
or the wallet is used on a new host / restored from the TREZOR the key
image sync is required for correct function of the wallet. It recomputes key images
for all received transaction inputs.
## Integration rationale
The Monero codebase already contains cold wallet support. I.e., wallet not connected to the Internet, which should provide
better security guarantees as it minimizes attack surface compared to the hot wallet - always connected wallet.
As the cold wallet is not connected to the Internet and does not have access nor to the blockchain neither to the monero
full node the all information for transaction construction have to be prepared by the hot wallet.
When using the cold wallet, hot wallet is watch-only. It has only the view-key so it can scan blockchain for incoming
transactions but is not able to spend any transaction.
Transaction signature with cold wallet works like this:
- Create transaction construction data on hot wallet. `transfer <address> <amount>`. Works similar to the normal wallet operation
but instead of the signed transaction, the watch-only hot wallet generates `unsigned_txset` file which contains
transaction construction data.
- Cold wallet opens `unsigned_txset`, verifies the signature on the transaction construction data and creates Monero transaction
using the data. Cold wallet creates `signed_txset`
- Hot wallet opens `signed_txset`, verifies the transaction and asks user whether to submit transaction to the full node.
### Cold wallet protocols
As cold wallet support is already present in Monero codebase, the protocols were well designed and analyzed.
We decided to reuse the cold wallet approach when signing the transaction as the TREZOR pretty much behaves as the cold wallet,
i.e., does not have access to the blockchain or full Monero node. The whole transaction is built in the TREZOR thus
the integration has security properties of the cold wallet (which is belevied to be secure). This integration approach
makes security analysis easier and enables to use existing codebase and protocols. This makes merging TREZOR support to
the Monero codebase easier.
We believe that by choosing a bit more high-level approach in the protocol design we could easily add more advanced features,
TREZOR implements cold wallet protocols in this integration scheme.
## Description
Main high level protocol logic is implemented in `apps/monero/protocol/` directory.
### Serialization
The serialization in `apps/monero/xmr/serialize` is the cryptonote serialization format used to serialize data to blockchain.
The serialization was ported from Monero C++. Source comes from the library [monero-serialize].
Serialization scheme was inspired by protobuf serialization scheme.
Fields are specified as a classmethod which is easier to `gc.collect()` after serialization is done.
```python
@classmethod
def f_specs(cls):
return (("size", SizeT),)
```
Serialization is synchronous.
### Protocols
Transaction signing and Key Image (KI) sync are multi-step stateful protocols.
The protocol have several roundtrips.
In the signing protocol the connected host mainly serves as a dumb storage providing values to the TREZOR when needed,
mainly due to memory constrains on TREZOR. The offloaded data can be in plaintext. In this case data is HMACed with unique HMAC
key to avoid data tampering, reordering, replay, reuse, etc... Some data are offloaded as protected, encrypted and authenticated
with Chacha20Poly1305 with unique key (derived from the protocol step, message, purpose, counter, master secret).
TREZOR builds the signed Monero transaction incrementally, i.e., one UTXO per round trip, one transaction output per roundtrip.
### Protocol workflow
Key image sync and transaction signing protocols are stateful.
Both protocols implement custom workflow managing the protocol state and state transitions explicitly.
Entry to the protocol workflow is passed on the initial protocol message, i.e., only the initial protocol message
is registered via `wire.add()`. The workflow internally manages receiving / sending protocol messages.
Each finished protocol step specifies the next expected message set which helps to govern protocol state transitions,
i.e., exception is thrown if another message is received as expected.
As the protocols implement custom workflow the general package unimport in `wire` is not called which
could lead to memory problems as locally imported packages are not freed from memory on `gc.collect()`.
Thus protocols call unimport manually after processing the protocol messages.
Protobuf messages are following the convention `MoneroXRequest`, `MoneroXAck`.
## Key Image sync work flow
In the KI sync cold wallet protocol KIs are generated by the cold wallet. For each KI there is a ring signature
generated by the cold wallet (KI proof).
KI sync is mainly needed to recover from some problem or when using a new hot-wallet (corruption of a wallet file or
using TREZOR on a different host).
The KI protocol has 3 steps.
### Init step
- `MoneroKeyImageExportInitRequest`
- Contains commitment to all KIs we are going to compute (hash of all UTXOs).
- User can confirm / reject the KI sync in this step. Init message contains number of KIs for computation.
### Sync
- `MoneroKeyImageSyncStepRequest`
- Computes N KIs in this step. N = 10 for now.
- Returns encrypted result, `MoneroExportedKeyImage`
### Finalization
- `MoneroKeyImageSyncFinalRequest`
- When commitment on all KIs is correct (i.e, number of UTXOs matches, hashes match) the encryption key is released
to the agent/hot-wallet so it can decrypt computed KIs and import it
## Transaction signing
For detailed description and rationale please refer to the [monero-doc].
- The protocol workflow `apps/monero/sign_tx.py`
- The protocol is implemented in `apps/monero/protocol/signing/`
### `MoneroTransactionInitRequest`:
- Contains basic construction data for the transaction, e.g., transaction destinations, fee, mixin level,
range proof details (type of the range proof, batching scheme).
After receiving this message:
- The TREZOR prompts user for verification of the destination addresses and amounts.
- Commitments are computed thus later potential deviations from transaction destinations are detected and signing aborts.
- Secrets for HMACs / encryption are computed, TX key is computed.
- Precomputes required sub-addresses (init message indicates which sub-addresses are needed).
### `MoneroTransactionSetInputRequest`
- Sends one UTXO to the TREZOR for processing, encoded as `MoneroTransactionSourceEntry`.
- Contains construction data needed for signing the transaction, computing spending key for UTXO.
TREZOR computes spending keys, `TxinToKey`, `pseudo_out`, HMACs for offloaded data
### `MoneroTransactionInputsPermutationRequest`
UTXOs have to be sorted by the key image in the valid blockchain transaction.
This message caries permutation on the key images so they are sorted in the desired way.
### `MoneroTransactionInputViniRequest`
- Step needed to correctly hash all transaction inputs, in the right order (permutation computed in the previous step).
- Contains `MoneroTransactionSourceEntry` and `TxinToKey` computed in the previous step.
- TREZOR Computes `tx_prefix_hash` is part of the signed data.
### `MoneroTransactionAllInputsSetRequest`
- Sent after all inputs have been processed.
- Used in the range proof offloading to the host. E.g., in case of batched Bulletproofs with more than 2 transaction outputs.
The message response contains TREZOR-generated commitment masks so host can compute range proof correctly.
### `MoneroTransactionSetOutputRequest`
- Sends transaction output, `MoneroTransactionDestinationEntry`, one per message.
- HMAC prevents tampering with previously accepted data (in the init step).
- TREZOR computes data related to transaction output, e.g., range proofs, ECDH info for the receiver, output public key.
- In case offloaded range proof is used the request can carry computed range proof.
### `MoneroTransactionAllOutSetRequest`
Sent after all transaction outputs have been sent to the TREZOR for processing.
Request is empty, the response contains computed `extra` field (may contain additional public keys if sub-addresses are used),
computed `tx_prefix_hash` and basis for the final transaction signature `MoneroRingCtSig` (fee, transaction type).
### `MoneroTransactionMlsagDoneRequest`
Message sent to ask TREZOR to compute pre-MLSAG hash required for the signature.
Hash is computed incrementally by TREZOR since the init message and can be finalized in this step.
Request is empty, response contains message hash, required for the signature.
### `MoneroTransactionSignInputRequest`
- Caries `MoneroTransactionSourceEntry`, similarly as previous messages `MoneroTransactionSetInputRequest`, `MoneroTransactionInputViniRequest`.
- Caries computed transaction inputs, pseudo outputs, HMACs, encrypted spending keys and alpha masks
- TREZOR generates MLSAG for this UTXO, returns the signature.
- Code returns also `cout` value if the multisig mode is active - not fully implemented, will be needed later when implementing multisigs.
### `MoneroTransactionFinalRequest`
- Sent when all UTXOs have been signed properly
- Finalizes transaction signature
- Returns encrypted transaction private keys which are needed later, e.g. for TX proof. As TREZOR cannot store aux data
for all signed transactions its offloaded encrypted to the wallet. Later when TX proof is implemented in the TREZOR it
will load encrypted TX keys, decrypt it and generate the proof.
## Implementation notes
Few notes on design / implementation.
### Cryptography
Operation with Ed25519 points and scalars are implemented in [trezor-crypto] so the underlying cryptography layer
is fast, secure and constant-time.
Ed Point coordinates are Extended Edwards, using type `ge25519` with coordinates `(x, y, z, t)`. Functions in Monero code
in the [trezor-crypto] use the `ge25519` for points (no other different point formats).
Functions like `op256_modm` (e.g., `add256_modm`) operate on scalar values, i.e., 256 bit integers modulo curve order
`2**252 + 3*610042537739*15158679415041928064055629`.
Functions `curve25519_*` operate on 256 bit integers modulo `2**255 - 19`, the coordinates of the point.
These are used mainly internally (e.g., for `hash_to_point()`) and not exported to the [trezor-core].
[trezor-crypto] contains also some Monero-specific functions, such as
`xmr_hash_to_scalar`, `xmr_hash_to_ec`, `xmr_generate_key_derivation`. Those are used in [trezor-core] where more high
level operations are implemented, such as MLSAG.
#### Crypto API
API bridging [trezor-crypto] and [trezor-core]: `embed/extmod/modtrezorcrypto/modtrezorcrypto-monero.h`
It encapsulates Ed25519 points and scalars in corresponding Python classes which have memory-wiping destructor.
API provides basic functions for work with scalars and points and Monero specific functions.
The API is designed in such a way it is easy to work with Ed25519 as there is only one point format which is always
normed to avoid complications when chaining operations such as `scalarmult`s.
### Range signatures
Borromean range signatures were optimized and ported to [trezor-crypto].
Range signatures xmr_gen_range_sig are CPU intensive and memory intensive operations which were originally implemented
in python (trezor-core) but it was not feasible to run on the Trezor device due to a small amount of RAM and long
computation times. It was needed to optimize the algorithm and port it to C so it is feasible to run it on the real hardware and run it fast.
Range signature is a well-contained problem with no allocations needed, simple API.
For memory and timing reasons its implemented directly in trezor-crypto (as it brings real benefit to the user).
On the other hand, MLASG and other ring signatures are built from building blocks in python for easier development,
code readability, maintenance and debugging. Porting to C is not that straightforward and I don't see any benefit here.
The memory and CPU is not the problem as in the case of range signatures so I think it is fine to have it in Python.
Porting to C would also increase complexity of trezor-crypto and could lead to bugs.
Using small and easily auditable & testable building blocks, such as ge25519_add (fast, in C) to build more complex
schemes in high level language is, in my opinion, a scalable and secure way to build the system.
Porting all Monero crypto schemes to C would be very time consuming and prone to errors.
Having access to low-level features also speeds up development of new features, such as multisigs.
MLSAG may need to be slightly changed when implementing multisigs
(some preparations have been made already but we will see after this phase starts).
Bulletproof generation and verification is implemented, however the device can handle maximum 2 batched outputs
in the bulletproof due to high memory requirements (more on that in [monero-doc]). If number of outputs is larger
than 2 the offloading to host is required. In such case, the bulletproofs are first computed at the host and sent to
Trezor for verification.
Bulletproof implementation is covered by unit tests, the proofs in unittest were generated by the Monero C++
implementation.
[trezor-crypto]: https://github.com/trezor/trezor-crypto
[trezor-core]: https://github.com/trezor/trezor-core
[monero-doc]: https://github.com/ph4r05/monero-trezor-doc
[monero-serialize]: https://github.com/ph4r05/monero-serialize