Skip to content

Commit

Permalink
xmr: protocol: simplification - require change address to equal the m…
Browse files Browse the repository at this point in the history
…ain address
  • Loading branch information
ph4r05 committed Aug 15, 2018
1 parent 1a3416e commit f334d8a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/apps/monero/controller/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)


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


class StdObj(object):
def __init__(self, **kwargs):
for kw in kwargs:
Expand Down
33 changes: 30 additions & 3 deletions src/apps/monero/protocol/tsx_sign_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __init__(self, trezor=None, creds=None, state=None, **kwargs):
self.output_change = None
self.mixin = 0
self.fee = 0
self.account_idx = 0

self.additional_tx_private_keys = []
self.additional_tx_public_keys = []
Expand Down Expand Up @@ -179,9 +180,25 @@ def gen_r(self, use_r=None):
self.r = crypto.random_scalar() if use_r is None else use_r
self.r_pub = crypto.scalarmult_base(self.r)

def get_primary_change_address(self):
"""
Computes primary change address for the current account index
:return:
"""
D, C = monero.generate_sub_address_keys(
self.creds.view_key_private,
self.creds.spend_key_public,
self.account_idx,
0,
)
return misc.StdObj(
view_public_key=crypto.encodepoint(C),
spend_public_key=crypto.encodepoint(D),
)

def check_change(self, outputs):
"""
Checks if the change address is among tx outputs.
Checks if the change address is among tx outputs and it is equal to our address.
:param outputs:
:return:
"""
Expand All @@ -191,11 +208,20 @@ def check_change(self, outputs):
if change_addr is None:
return

found = False
for out in outputs:
if addr_eq(out.addr, change_addr):
return True
found = True
break

if not found:
raise misc.TrezorChangeAddressError("Change address not found in outputs")

my_addr = self.get_primary_change_address()
if not addr_eq(my_addr, change_addr):
raise misc.TrezorChangeAddressError("Change address differs from ours")

raise ValueError("Change address not found in outputs")
return True

def in_memory(self):
"""
Expand Down Expand Up @@ -453,6 +479,7 @@ async def init_transaction(self, tsx_data, tsx_ctr):
self.output_change = misc.dst_entry_to_stdobj(tsx_data.change_dts)
self.mixin = tsx_data.mixin
self.fee = tsx_data.fee
self.account_idx = tsx_data.account
self.use_simple_rct = self.input_count > 1
self.use_bulletproof = tsx_data.is_bulletproof
self.multi_sig = tsx_data.is_multisig
Expand Down
1 change: 1 addition & 0 deletions src/apps/monero/protocol/tsx_sign_state_holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(self, **kwargs):
self.output_change = None
self.mixin = 0
self.fee = 0
self.account_idx = 0

self.additional_tx_private_keys = []
self.additional_tx_public_keys = []
Expand Down
19 changes: 19 additions & 0 deletions src/apps/monero/xmr/monero.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,22 @@ def generate_monero_keys(seed):
hash = crypto.cn_fast_hash(crypto.encodeint(spend_sec))
view_sec, view_pub = generate_keys(crypto.decodeint(hash))
return spend_sec, spend_pub, view_sec, view_pub


def generate_sub_address_keys(view_sec, spend_pub, major, minor):
"""
Computes generic public sub-address
:param view_sec:
:param spend_pub:
:param major:
:param minor:
:return: spend public, view public
"""
if major == 0 and minor == 0: # special case, Monero-defined
return spend_pub, crypto.scalarmult_base(view_sec)

m = get_subaddress_secret_key(view_sec, major=major, minor=minor)
M = crypto.scalarmult_base(m)
D = crypto.point_add(spend_pub, M)
C = crypto.ge_scalarmult(view_sec, D)
return D, C

0 comments on commit f334d8a

Please sign in to comment.