Skip to content

Commit

Permalink
xmr: code cleanup, heap fragmentations fixes
Browse files Browse the repository at this point in the history
Squashed commits:
[d2ac2eb6] xmr: addr cleanup
[7e4c1a9c] xmr: code cleanup, heap fragmentations fixes
  • Loading branch information
ph4r05 committed Sep 17, 2018
1 parent 93af8af commit a75ef32
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 143 deletions.
38 changes: 24 additions & 14 deletions src/apps/monero/protocol/tsx_sign_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,13 @@ def _build_key(self, secret, discriminator=None, index: int = None) -> bytes:
offset += len(discriminator)

if index is not None:
from apps.monero.xmr.serialize.int_serialize import dump_uvarint_b_into

dump_uvarint_b_into(index, key_buff, offset)
# dump_uvarint_b_into, saving import
shifted = True
while shifted:
shifted = index >> 7
key_buff[offset] = (index & 0x7F) | (0x80 if shifted else 0x00)
offset += 1
index = shifted

return crypto.keccak_2hash(key_buff)

Expand Down Expand Up @@ -497,19 +501,26 @@ def process_payment_id(self, tsx_data):
tsx_data.payment_id, view_key_pub, self.r
)

extra_nonce = tsx_helper.set_encrypted_payment_id_to_tx_extra_nonce(
payment_id_encr
)
extra_nonce = payment_id_encr
extra_prefix = 1

elif len(tsx_data.payment_id) == 32:
extra_nonce = tsx_helper.set_payment_id_to_tx_extra_nonce(
tsx_data.payment_id
)
extra_nonce = tsx_data.payment_id
extra_prefix = 0

else:
raise ValueError("Payment ID size invalid")

self.tx.extra = tsx_helper.add_extra_nonce_to_tx_extra(b"", extra_nonce)
lextra = len(extra_nonce)
if lextra >= 255:
raise ValueError("Nonce could be 255 bytes max")

extra_buff = bytearray(3 + lextra)
extra_buff[0] = 2
extra_buff[1] = lextra + 1
extra_buff[2] = extra_prefix
utils.memcpy(extra_buff, 3, extra_nonce, 0, lextra)
self.tx.extra = extra_buff

async def compute_sec_keys(self, tsx_data):
"""
Expand Down Expand Up @@ -596,16 +607,15 @@ async def set_input(self, src_entr):
# Construct tx.vin
ki_real = src_entr.multisig_kLRki.ki if self.multi_sig else ki
vini = TxinToKey(amount=src_entr.amount, k_image=crypto.encodepoint(ki_real))
vini.key_offsets = [x.idx for x in src_entr.outputs]
vini.key_offsets = tsx_helper.absolute_output_offsets_to_relative(
vini.key_offsets
[x.idx for x in src_entr.outputs]
)

if src_entr.rct:
vini.amount = 0

# Serialize with variant code for TxinToKey
vini_bin = misc.dump_msg(vini, preallocate=68, prefix=b"\x02")
vini_bin = misc.dump_msg(vini, preallocate=64, prefix=b"\x02")
self._mem_trace(2, True)

if self.in_memory():
Expand Down Expand Up @@ -896,7 +906,7 @@ def _check_bproof(self, batch_size, rsig, masks):

for i in range(batch_size):
C = crypto.decodepoint(rsig.V[i])
C = crypto.point_mul8(C)
crypto.point_mul8_into(C, C)
self._check_out_commitment(self.output_amounts[i], masks[i], C)

def _return_rsig_data(self, rsig):
Expand Down
32 changes: 9 additions & 23 deletions src/apps/monero/xmr/sub/addr.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,28 +64,16 @@ def classify_subaddresses(tx_dests, change_addr):
def addr_eq(a, b):
"""
Address comparisson. Allocation free.
:param a:
:param b:
:return:
"""
return pub_eq(a.spend_public_key, b.spend_public_key) and pub_eq(
a.view_public_key, b.view_public_key
return (
a.spend_public_key == b.spend_public_key
and a.view_public_key == b.view_public_key
)


def pub_eq(a, b):
"""
Simple non-constant time public key compare
"""
if a == b:
return True
if (a is None and b is not None) or (a is not None and b is None):
return False
if len(a) != len(b):
return False
for i in range(len(a)):
if a[i] != b[i]:
return False
return True


def get_change_addr_idx(outputs, change_dts):
"""
Returns ID of the change output from the change_dts and outputs
Expand All @@ -94,13 +82,11 @@ def get_change_addr_idx(outputs, change_dts):
return None

change_idx = None
change_coord = change_dts.amount, change_dts.addr
for idx, dst in enumerate(outputs):
if (
change_coord
and change_coord[0]
and change_coord[0] == dst.amount
and addr_eq(change_coord[1], dst.addr)
change_dts.amount
and change_dts.amount == dst.amount
and addr_eq(change_dts.addr, dst.addr)
):
change_idx = idx
return change_idx
110 changes: 4 additions & 106 deletions src/apps/monero/xmr/sub/tsx_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,85 +9,17 @@
)


def parse_extra_fields(extra_buff):
"""
Parses extra buffer to the extra fields vector
"""
extras = []
rw = MemoryReaderWriter(extra_buff)
ar2 = xmrserialize.Archive(rw, False)
while len(rw.get_buffer()) > 0:
extras.append(ar2.variant(elem_type=TxExtraField))
return extras


def find_tx_extra_field_by_type(extra_fields, msg, idx=0):
"""
Finds given message type in the extra array, or returns None if not found
"""
cur_idx = 0
for x in extra_fields:
if isinstance(x, msg):
if cur_idx == idx:
return x
cur_idx += 1
return None


def has_encrypted_payment_id(extra_nonce):
"""
Returns true if encrypted payment id is present
"""
return len(extra_nonce) == 9 and extra_nonce[0] == 1


def has_payment_id(extra_nonce):
"""
Returns true if payment id is present
"""
return len(extra_nonce) == 33 and extra_nonce[0] == 0


def get_payment_id_from_tx_extra_nonce(extra_nonce):
"""
Extracts encrypted payment id from extra
"""
if 33 != len(extra_nonce):
raise ValueError("Nonce size mismatch")
if 0x0 != extra_nonce[0]:
raise ValueError("Nonce payment type invalid")
return extra_nonce[1:]


def get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce):
"""
Extracts encrypted payment id from extra
"""
if 9 != len(extra_nonce):
raise ValueError("Nonce size mismatch")
if 0x1 != extra_nonce[0]:
raise ValueError("Nonce payment type invalid")
return extra_nonce[1:]


def set_payment_id_to_tx_extra_nonce(payment_id):
"""
Sets payment ID to the extra
"""
return b"\x00" + payment_id


def absolute_output_offsets_to_relative(off):
"""
Relative offsets, prev + cur = next.
Helps with varint encoding size.
"""
if len(off) == 0:
return off
res = sorted(off)
off.sort()
for i in range(len(off) - 1, 0, -1):
res[i] -= res[i - 1]
return res
off[i] -= off[i - 1]
return off


def get_destination_view_key_pub(destinations, change_addr=None):
Expand Down Expand Up @@ -130,40 +62,6 @@ def encrypt_payment_id(payment_id, public_key, secret_key):
return pm_copy


def set_encrypted_payment_id_to_tx_extra_nonce(payment_id):
return b"\x01" + payment_id


def remove_field_from_tx_extra(extra, mtype):
"""
Removes extra field of fiven type from the buffer
Reserializes with skipping the given mtype.
"""
if len(extra) == 0:
return []

reader = MemoryReaderWriter(extra)
writer = MemoryReaderWriter()
ar_read = xmrserialize.Archive(reader, False)
ar_write = xmrserialize.Archive(writer, True)
while len(reader.get_buffer()) > 0:
c_extras = ar_read.variant(elem_type=TxExtraField)
if not isinstance(c_extras, mtype):
ar_write.variant(c_extras, elem_type=TxExtraField)

return writer.get_buffer()


def add_extra_nonce_to_tx_extra(extra, extra_nonce):
"""
Appends nonce extra to the extra buffer
"""
if len(extra_nonce) > 255:
raise ValueError("Nonce could be 255 bytes max")
extra += b"\x02" + len(extra_nonce).to_bytes(1, "big") + extra_nonce
return extra


def add_tx_pub_key_to_extra(tx_extra, pub_key):
"""
Adds public key to the extra
Expand Down Expand Up @@ -191,5 +89,5 @@ def add_additional_tx_pub_keys_to_extra(

# format: variant_tag (0x4) | array len varint | 32B | 32B | ...
ar.variant(pubs_msg, TxExtraField)
tx_extra += bytes(rw.get_buffer())
tx_extra += rw.get_buffer()
return tx_extra

0 comments on commit a75ef32

Please sign in to comment.