Skip to content

Commit

Permalink
xmr: minor code cleanup
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ph4r05 committed Sep 14, 2018
1 parent cf62047 commit ee97ef9
Show file tree
Hide file tree
Showing 31 changed files with 86 additions and 562 deletions.
36 changes: 31 additions & 5 deletions src/apps/monero/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,23 @@ Signs a Monero transaction on the TREZOR.
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.
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

Expand Down Expand Up @@ -169,7 +182,8 @@ dedicated class so the memory consumption is minimal between round trips.

### `MoneroTransactionInitRequest`:

- Contains basic construction data for the transaction, e.g., transaction destinations, fee, mixin level.
- 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.
Expand All @@ -195,12 +209,24 @@ This message caries permutation on the key images so they are sorted in the desi
- 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.
- Mainly 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 can carry 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).
- 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.

### `MoneroTransactionRangeSigRequest`

TREZOR computes data related to transaction output, e.g., range proofs, ECDH info for the receiver, output public key.
- Optional protocol message that supports more complicated, several round-trips range proof offloading proposals as described in the [monero-doc].
- Not used with the basic range proof offloading where the whole range proof is computed on the host.

### `MoneroTransactionAllOutSetRequest`

Expand Down
47 changes: 3 additions & 44 deletions src/apps/monero/controller/iface.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Dusan Klinec, ph4r05, 2018


class TrezorInterface(object):
def __init__(self, ctx=None):
self.ctx = ctx
Expand Down Expand Up @@ -39,9 +34,6 @@ async def confirm_out(
async def confirm_payment_id(self, payment_id, ctx=None):
"""
Confirm payment ID
:param payment_id:
:param ctx:
:return:
"""
if payment_id is None:
return
Expand All @@ -53,10 +45,6 @@ async def confirm_payment_id(self, payment_id, ctx=None):
async def confirm_transaction(self, tsx_data, creds=None, ctx=None):
"""
Ask for confirmation from user
:param tsx_data:
:param creds:
:param ctx:
:return:
"""
from apps.monero.xmr.sub.addr import get_change_addr_idx

Expand Down Expand Up @@ -121,10 +109,6 @@ async def confirm_transaction(self, tsx_data, creds=None, ctx=None):
return True

async def transaction_error(self, *args, **kwargs):
"""
Transaction error
:return:
"""
from trezor import ui
from trezor.ui.text import Text
from apps.monero import layout
Expand All @@ -138,13 +122,11 @@ async def transaction_error(self, *args, **kwargs):
async def transaction_signed(self, ctx=None):
"""
Notifies the transaction was completely signed
:return:
"""

async def transaction_finished(self, ctx=None):
"""
Notifies the transaction has been completed (all data were sent)
:return:
"""
from trezor import ui
from trezor.ui.text import Text
Expand All @@ -157,13 +139,6 @@ async def transaction_finished(self, ctx=None):
await self.restore_default()

async def transaction_step(self, step, sub_step=None, sub_step_total=None):
"""
Transaction progress
:param step:
:param sub_step:
:param sub_step_total:
:return:
"""
from trezor import ui
from trezor.ui.text import Text
from apps.monero import layout
Expand Down Expand Up @@ -196,35 +171,19 @@ async def transaction_step(self, step, sub_step=None, sub_step_total=None):
await layout.simple_text(text, tm=10 * 1000)

async def confirm_ki_sync(self, init_msg, ctx=None):
"""
Ask confirmation on key image sync
:param init_msg:
:return:
"""
from apps.monero import layout

await layout.require_confirm_keyimage_sync(self.gctx(ctx))
return True

async def ki_error(self, e, ctx=None):
"""
Key image sync error
:param e:
:return:
"""
pass

async def ki_step(self, i, ctx=None):
"""
Key image sync step
:param i:
:return:
"""
pass

async def ki_finished(self, ctx=None):
"""
Ki sync finished
:return:
"""
pass


def get_iface(ctx=None):
Expand Down
14 changes: 3 additions & 11 deletions src/apps/monero/controller/misc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Dusan Klinec, ph4r05, 2018


class TrezorError(Exception):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand All @@ -11,18 +6,15 @@ def __init__(self, *args, **kwargs):


class TrezorSecurityError(TrezorError):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
pass


class TrezorTxPrefixHashNotMatchingError(TrezorError):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
pass


class TrezorChangeAddressError(TrezorError):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
pass


class StdObj(object):
Expand Down
9 changes: 0 additions & 9 deletions src/apps/monero/controller/wrapper.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Dusan Klinec, ph4r05, 2018


async def monero_get_creds(ctx, address_n=None, network_type=None):
from apps.common import seed
from apps.monero.xmr import crypto
Expand Down Expand Up @@ -30,7 +25,3 @@ def get_interface(ctx):
from apps.monero.controller import iface

return iface.get_iface(ctx)


def exc2str(e):
return str(e)
4 changes: 0 additions & 4 deletions src/apps/monero/diag.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Dusan Klinec, ph4r05, 2018

import gc
import micropython
import sys
Expand Down
4 changes: 0 additions & 4 deletions src/apps/monero/key_image_sync.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Dusan Klinec, ph4r05, 2018

import gc
import micropython

Expand Down
69 changes: 18 additions & 51 deletions src/apps/monero/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,6 @@
from apps.common.confirm import require_confirm, require_hold_to_confirm


async def require_confirm_watchkey(ctx):
content = Text("Confirm export", ui.ICON_SEND, icon_color=ui.GREEN)
content.normal(*["Do you really want to", "export watch-only", "credentials?"])
return await require_confirm(ctx, content, ButtonRequestType.SignTx)


async def require_confirm_keyimage_sync(ctx):
content = Text("Confirm ki sync", ui.ICON_SEND, icon_color=ui.GREEN)
content.normal(*["Do you really want to", "sync key images?"])
return await require_confirm(ctx, content, ButtonRequestType.SignTx)


async def require_confirm_tx_plain(ctx, to, value, is_change=False):
content = Text(
"Confirm " + ("sending" if not is_change else "change"),
ui.ICON_SEND,
icon_color=ui.GREEN,
)
content.bold(format_amount(value))
content.normal("to")
content.mono(*split_address(to))
return await require_confirm(ctx, content, code=ButtonRequestType.SignTx)


def paginate_lines(lines, lines_per_page=5):
pages = []
cpage = []
Expand Down Expand Up @@ -117,7 +93,6 @@ async def naive_pagination(
content = Text("%s %s" % (title, paging), icon, icon_color=icon_color)
content.normal(*text)

# render_scrollbar(cur_step, npages)
reaction = await tx_dialog(
ctx,
code,
Expand All @@ -141,6 +116,18 @@ async def naive_pagination(
cur_step += 1


async def require_confirm_watchkey(ctx):
content = Text("Confirm export", ui.ICON_SEND, icon_color=ui.GREEN)
content.normal(*["Do you really want to", "export watch-only", "credentials?"])
return await require_confirm(ctx, content, ButtonRequestType.SignTx)


async def require_confirm_keyimage_sync(ctx):
content = Text("Confirm ki sync", ui.ICON_SEND, icon_color=ui.GREEN)
content.normal(*["Do you really want to", "sync key images?"])
return await require_confirm(ctx, content, ButtonRequestType.SignTx)


async def require_confirm_payment_id(ctx, payment_id):
from ubinascii import hexlify
from trezor import wire
Expand All @@ -156,19 +143,13 @@ async def require_confirm_payment_id(ctx, payment_id):


async def require_confirm_tx(ctx, to, value, is_change=False):
len_addr = (len(to) + 15) // 16
if len_addr <= 2:
return await require_confirm_tx_plain(ctx, to, value, is_change)

else:
to_chunks = list(split_address(to))
from trezor import wire

text = [ui.BOLD, format_amount(value), ui.MONO] + to_chunks
from trezor import wire

conf_text = "Confirm send" if not is_change else "Con. change"
if not await naive_pagination(ctx, text, conf_text, ui.ICON_SEND, ui.GREEN, 4):
raise wire.ActionCancelled("Cancelled")
to_chunks = list(split_address(to))
text = [ui.BOLD, format_amount(value), ui.MONO] + to_chunks
conf_text = "Confirm send" if not is_change else "Con. change"
if not await naive_pagination(ctx, text, conf_text, ui.ICON_SEND, ui.GREEN, 4):
raise wire.ActionCancelled("Cancelled")


async def require_confirm_fee(ctx, fee):
Expand All @@ -177,20 +158,6 @@ async def require_confirm_fee(ctx, fee):
await require_hold_to_confirm(ctx, content, ButtonRequestType.ConfirmOutput)


@ui.layout
async def simple_wait(tm):
from trezor import loop

await loop.sleep(tm)


async def light_on():
from trezor import loop

slide = await ui.backlight_slide(ui.BACKLIGHT_NORMAL, delay=0)
loop.schedule(slide)


@ui.layout
async def ui_text(text, tm=None) -> None:
from trezor import loop
Expand Down
4 changes: 0 additions & 4 deletions src/apps/monero/lite_protocol.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Dusan Klinec, ph4r05, 2018

import gc

from trezor import log
Expand Down
4 changes: 0 additions & 4 deletions src/apps/monero/protocol/key_image_sync.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Dusan Klinec, ph4r05, 2018

from trezor import log

from apps.monero.controller import wrapper as twrap
Expand Down
Loading

0 comments on commit ee97ef9

Please sign in to comment.