mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-05 08:29:13 +00:00
style: apply black/isort
This commit is contained in:
parent
e336f578af
commit
3d3e9b67b4
@ -2,7 +2,7 @@
|
||||
# modified for Python 3 by Jochen Hoenicke <hoenicke@gmail.com>
|
||||
|
||||
import hashlib
|
||||
from typing import Tuple, NewType
|
||||
from typing import NewType, Tuple
|
||||
|
||||
Point = NewType("Point", Tuple[int, int])
|
||||
|
||||
@ -17,7 +17,7 @@ def H(m: bytes) -> bytes:
|
||||
|
||||
def expmod(b: int, e: int, m: int) -> int:
|
||||
if e < 0:
|
||||
raise ValueError('negative exponent')
|
||||
raise ValueError("negative exponent")
|
||||
if e == 0:
|
||||
return 1
|
||||
t = expmod(b, e >> 1, m) ** 2 % m
|
||||
@ -123,18 +123,18 @@ def decodepoint(s: bytes) -> Point:
|
||||
x = q - x
|
||||
P = Point((x, y))
|
||||
if not isoncurve(P):
|
||||
raise ValueError('decoding point that is not on curve')
|
||||
raise ValueError("decoding point that is not on curve")
|
||||
return P
|
||||
|
||||
|
||||
def checkvalid(s: bytes, m: bytes, pk: bytes) -> None:
|
||||
if len(s) != b >> 2:
|
||||
raise ValueError('signature length is wrong')
|
||||
raise ValueError("signature length is wrong")
|
||||
if len(pk) != b >> 3:
|
||||
raise ValueError('public-key length is wrong')
|
||||
raise ValueError("public-key length is wrong")
|
||||
R = decodepoint(s[0 : b >> 3])
|
||||
A = decodepoint(pk)
|
||||
S = decodeint(s[b >> 3 : b >> 2])
|
||||
h = Hint(encodepoint(R) + pk + m)
|
||||
if scalarmult(B, S) != edwards(R, scalarmult(A, h)):
|
||||
raise ValueError('signature does not pass verification')
|
||||
raise ValueError("signature does not pass verification")
|
||||
|
@ -1,37 +1,91 @@
|
||||
from . import messages as proto
|
||||
from .tools import expect, CallException, normalize_nfc, session
|
||||
from .tools import CallException, expect, normalize_nfc, session
|
||||
|
||||
|
||||
@expect(proto.PublicKey)
|
||||
def get_public_node(client, n, ecdsa_curve_name=None, show_display=False, coin_name=None):
|
||||
return client.call(proto.GetPublicKey(address_n=n, ecdsa_curve_name=ecdsa_curve_name, show_display=show_display, coin_name=coin_name))
|
||||
def get_public_node(
|
||||
client, n, ecdsa_curve_name=None, show_display=False, coin_name=None
|
||||
):
|
||||
return client.call(
|
||||
proto.GetPublicKey(
|
||||
address_n=n,
|
||||
ecdsa_curve_name=ecdsa_curve_name,
|
||||
show_display=show_display,
|
||||
coin_name=coin_name,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@expect(proto.Address, field="address")
|
||||
def get_address(client, coin_name, n, show_display=False, multisig=None, script_type=proto.InputScriptType.SPENDADDRESS):
|
||||
def get_address(
|
||||
client,
|
||||
coin_name,
|
||||
n,
|
||||
show_display=False,
|
||||
multisig=None,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
):
|
||||
if multisig:
|
||||
return client.call(proto.GetAddress(address_n=n, coin_name=coin_name, show_display=show_display, multisig=multisig, script_type=script_type))
|
||||
return client.call(
|
||||
proto.GetAddress(
|
||||
address_n=n,
|
||||
coin_name=coin_name,
|
||||
show_display=show_display,
|
||||
multisig=multisig,
|
||||
script_type=script_type,
|
||||
)
|
||||
)
|
||||
else:
|
||||
return client.call(proto.GetAddress(address_n=n, coin_name=coin_name, show_display=show_display, script_type=script_type))
|
||||
return client.call(
|
||||
proto.GetAddress(
|
||||
address_n=n,
|
||||
coin_name=coin_name,
|
||||
show_display=show_display,
|
||||
script_type=script_type,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@expect(proto.MessageSignature)
|
||||
def sign_message(client, coin_name, n, message, script_type=proto.InputScriptType.SPENDADDRESS):
|
||||
def sign_message(
|
||||
client, coin_name, n, message, script_type=proto.InputScriptType.SPENDADDRESS
|
||||
):
|
||||
message = normalize_nfc(message)
|
||||
return client.call(proto.SignMessage(coin_name=coin_name, address_n=n, message=message, script_type=script_type))
|
||||
return client.call(
|
||||
proto.SignMessage(
|
||||
coin_name=coin_name, address_n=n, message=message, script_type=script_type
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def verify_message(client, coin_name, address, signature, message):
|
||||
message = normalize_nfc(message)
|
||||
try:
|
||||
resp = client.call(proto.VerifyMessage(address=address, signature=signature, message=message, coin_name=coin_name))
|
||||
resp = client.call(
|
||||
proto.VerifyMessage(
|
||||
address=address,
|
||||
signature=signature,
|
||||
message=message,
|
||||
coin_name=coin_name,
|
||||
)
|
||||
)
|
||||
except CallException as e:
|
||||
resp = e
|
||||
return isinstance(resp, proto.Success)
|
||||
|
||||
|
||||
@session
|
||||
def sign_tx(client, coin_name, inputs, outputs, version=None, lock_time=None, expiry=None, overwintered=None, debug_processor=None):
|
||||
def sign_tx(
|
||||
client,
|
||||
coin_name,
|
||||
inputs,
|
||||
outputs,
|
||||
version=None,
|
||||
lock_time=None,
|
||||
expiry=None,
|
||||
overwintered=None,
|
||||
debug_processor=None,
|
||||
):
|
||||
# start = time.time()
|
||||
txes = client._prepare_sign_tx(inputs, outputs)
|
||||
|
||||
@ -52,7 +106,7 @@ def sign_tx(client, coin_name, inputs, outputs, version=None, lock_time=None, ex
|
||||
|
||||
# Prepare structure for signatures
|
||||
signatures = [None] * len(inputs)
|
||||
serialized_tx = b''
|
||||
serialized_tx = b""
|
||||
|
||||
counter = 0
|
||||
while True:
|
||||
@ -71,7 +125,10 @@ def sign_tx(client, coin_name, inputs, outputs, version=None, lock_time=None, ex
|
||||
|
||||
if res.serialized and res.serialized.signature_index is not None:
|
||||
if signatures[res.serialized.signature_index] is not None:
|
||||
raise ValueError("Signature for index %d already filled" % res.serialized.signature_index)
|
||||
raise ValueError(
|
||||
"Signature for index %d already filled"
|
||||
% res.serialized.signature_index
|
||||
)
|
||||
signatures[res.serialized.signature_index] = res.serialized.signature
|
||||
|
||||
if res.request_type == proto.RequestType.TXFINISHED:
|
||||
@ -93,7 +150,9 @@ def sign_tx(client, coin_name, inputs, outputs, version=None, lock_time=None, ex
|
||||
msg.outputs_cnt = len(current_tx.bin_outputs)
|
||||
else:
|
||||
msg.outputs_cnt = len(current_tx.outputs)
|
||||
msg.extra_data_len = len(current_tx.extra_data) if current_tx.extra_data else 0
|
||||
msg.extra_data_len = (
|
||||
len(current_tx.extra_data) if current_tx.extra_data else 0
|
||||
)
|
||||
res = client.call(proto.TxAck(tx=msg))
|
||||
continue
|
||||
|
||||
@ -104,6 +163,7 @@ def sign_tx(client, coin_name, inputs, outputs, version=None, lock_time=None, ex
|
||||
# msg needs to be deep copied so when it's modified
|
||||
# the other messages stay intact
|
||||
from copy import deepcopy
|
||||
|
||||
msg = deepcopy(msg)
|
||||
# If debug_processor function is provided,
|
||||
# pass thru it the request and prepared response.
|
||||
@ -124,6 +184,7 @@ def sign_tx(client, coin_name, inputs, outputs, version=None, lock_time=None, ex
|
||||
# msg needs to be deep copied so when it's modified
|
||||
# the other messages stay intact
|
||||
from copy import deepcopy
|
||||
|
||||
msg = deepcopy(msg)
|
||||
# If debug_processor function is provided,
|
||||
# pass thru it the request and prepared response.
|
||||
|
@ -16,6 +16,6 @@
|
||||
|
||||
import warnings
|
||||
|
||||
warnings.warn("ckd_public module is deprecated and will be removed", DeprecationWarning)
|
||||
|
||||
from .tests.support.ckd_public import * # noqa
|
||||
|
||||
warnings.warn("ckd_public module is deprecated and will be removed", DeprecationWarning)
|
||||
|
@ -14,22 +14,32 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import binascii
|
||||
import functools
|
||||
import getpass
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import binascii
|
||||
import getpass
|
||||
import warnings
|
||||
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
from . import messages as proto
|
||||
from . import btc, cosi, device, ethereum, firmware, lisk, misc, nem, stellar
|
||||
from . import mapping
|
||||
from . import tools
|
||||
from . import debuglink
|
||||
from . import (
|
||||
btc,
|
||||
cosi,
|
||||
debuglink,
|
||||
device,
|
||||
ethereum,
|
||||
firmware,
|
||||
lisk,
|
||||
mapping,
|
||||
messages as proto,
|
||||
misc,
|
||||
nem,
|
||||
stellar,
|
||||
tools,
|
||||
)
|
||||
|
||||
if sys.version_info.major < 3:
|
||||
raise Exception("Trezorlib does not support Python 2 anymore.")
|
||||
@ -42,6 +52,7 @@ LOG = logging.getLogger(__name__)
|
||||
try:
|
||||
import termios
|
||||
import tty
|
||||
|
||||
# POSIX system. Create and return a getch that manipulates the tty.
|
||||
# On Windows, termios will fail to import.
|
||||
|
||||
@ -55,6 +66,7 @@ try:
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
||||
return ch
|
||||
|
||||
|
||||
except ImportError:
|
||||
# Windows system.
|
||||
# Use msvcrt's getch function.
|
||||
@ -67,12 +79,16 @@ except ImportError:
|
||||
# skip special keys: read the scancode and repeat
|
||||
msvcrt.getch()
|
||||
continue
|
||||
return key.decode('latin1')
|
||||
return key.decode("latin1")
|
||||
|
||||
|
||||
def get_buttonrequest_value(code):
|
||||
# Converts integer code to its string representation of ButtonRequestType
|
||||
return [k for k in dir(proto.ButtonRequestType) if getattr(proto.ButtonRequestType, k) == code][0]
|
||||
return [
|
||||
k
|
||||
for k in dir(proto.ButtonRequestType)
|
||||
if getattr(proto.ButtonRequestType, k) == code
|
||||
][0]
|
||||
|
||||
|
||||
class PinException(tools.CallException):
|
||||
@ -81,13 +97,18 @@ class PinException(tools.CallException):
|
||||
|
||||
class MovedTo:
|
||||
"""Deprecation redirector for methods that were formerly part of TrezorClient"""
|
||||
|
||||
def __init__(self, where):
|
||||
self.where = where
|
||||
self.name = where.__module__ + '.' + where.__name__
|
||||
self.name = where.__module__ + "." + where.__name__
|
||||
|
||||
def _deprecated_redirect(self, client, *args, **kwargs):
|
||||
"""Redirector for a deprecated method on TrezorClient"""
|
||||
warnings.warn("Function has been moved to %s" % self.name, DeprecationWarning, stacklevel=2)
|
||||
warnings.warn(
|
||||
"Function has been moved to %s" % self.name,
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self.where(client, *args, **kwargs)
|
||||
|
||||
def __get__(self, instance, cls):
|
||||
@ -113,7 +134,7 @@ class BaseClient(object):
|
||||
|
||||
@tools.session
|
||||
def call_raw(self, msg):
|
||||
__tracebackhide__ = True # pytest traceback hiding - this function won't appear in tracebacks
|
||||
__tracebackhide__ = True # for pytest # pylint: disable=W0612
|
||||
self.transport.write(msg)
|
||||
return self.transport.read()
|
||||
|
||||
@ -126,20 +147,25 @@ class BaseClient(object):
|
||||
if handler is not None:
|
||||
msg = handler(resp)
|
||||
if msg is None:
|
||||
raise ValueError("Callback %s must return protobuf message, not None" % handler)
|
||||
raise ValueError(
|
||||
"Callback %s must return protobuf message, not None" % handler
|
||||
)
|
||||
resp = self.call(msg)
|
||||
|
||||
return resp
|
||||
|
||||
def callback_Failure(self, msg):
|
||||
if msg.code in (proto.FailureType.PinInvalid,
|
||||
proto.FailureType.PinCancelled, proto.FailureType.PinExpected):
|
||||
if msg.code in (
|
||||
proto.FailureType.PinInvalid,
|
||||
proto.FailureType.PinCancelled,
|
||||
proto.FailureType.PinExpected,
|
||||
):
|
||||
raise PinException(msg.code, msg.message)
|
||||
|
||||
raise tools.CallException(msg.code, msg.message)
|
||||
|
||||
def register_message(self, msg):
|
||||
'''Allow application to register custom protobuf message type'''
|
||||
"""Allow application to register custom protobuf message type"""
|
||||
mapping.register_message(msg)
|
||||
|
||||
|
||||
@ -164,21 +190,27 @@ class TextUIMixin(object):
|
||||
def callback_RecoveryMatrix(self, msg):
|
||||
if self.recovery_matrix_first_pass:
|
||||
self.recovery_matrix_first_pass = False
|
||||
self.print("Use the numeric keypad to describe positions. For the word list use only left and right keys.")
|
||||
self.print(
|
||||
"Use the numeric keypad to describe positions. For the word list use only left and right keys."
|
||||
)
|
||||
self.print("Use backspace to correct an entry. The keypad layout is:")
|
||||
self.print(" 7 8 9 7 | 9")
|
||||
self.print(" 4 5 6 4 | 6")
|
||||
self.print(" 1 2 3 1 | 3")
|
||||
while True:
|
||||
character = getch()
|
||||
if character in ('\x03', '\x04'):
|
||||
if character in ("\x03", "\x04"):
|
||||
return proto.Cancel()
|
||||
|
||||
if character in ('\x08', '\x7f'):
|
||||
return proto.WordAck(word='\x08')
|
||||
if character in ("\x08", "\x7f"):
|
||||
return proto.WordAck(word="\x08")
|
||||
|
||||
# ignore middle column if only 6 keys requested.
|
||||
if msg.type == proto.WordRequestType.Matrix6 and character in ('2', '5', '8'):
|
||||
if msg.type == proto.WordRequestType.Matrix6 and character in (
|
||||
"2",
|
||||
"5",
|
||||
"8",
|
||||
):
|
||||
continue
|
||||
|
||||
if character.isdigit():
|
||||
@ -186,22 +218,24 @@ class TextUIMixin(object):
|
||||
|
||||
def callback_PinMatrixRequest(self, msg):
|
||||
if msg.type == proto.PinMatrixRequestType.Current:
|
||||
desc = 'current PIN'
|
||||
desc = "current PIN"
|
||||
elif msg.type == proto.PinMatrixRequestType.NewFirst:
|
||||
desc = 'new PIN'
|
||||
desc = "new PIN"
|
||||
elif msg.type == proto.PinMatrixRequestType.NewSecond:
|
||||
desc = 'new PIN again'
|
||||
desc = "new PIN again"
|
||||
else:
|
||||
desc = 'PIN'
|
||||
desc = "PIN"
|
||||
|
||||
self.print("Use the numeric keypad to describe number positions. The layout is:")
|
||||
self.print(
|
||||
"Use the numeric keypad to describe number positions. The layout is:"
|
||||
)
|
||||
self.print(" 7 8 9")
|
||||
self.print(" 4 5 6")
|
||||
self.print(" 1 2 3")
|
||||
self.print("Please enter %s: " % desc)
|
||||
pin = getpass.getpass('')
|
||||
pin = getpass.getpass("")
|
||||
if not pin.isdigit():
|
||||
raise ValueError('Non-numerical PIN provided')
|
||||
raise ValueError("Non-numerical PIN provided")
|
||||
return proto.PinMatrixAck(pin=pin)
|
||||
|
||||
def callback_PassphraseRequest(self, msg):
|
||||
@ -214,9 +248,9 @@ class TextUIMixin(object):
|
||||
return proto.PassphraseAck(passphrase=passphrase)
|
||||
|
||||
self.print("Passphrase required: ")
|
||||
passphrase = getpass.getpass('')
|
||||
passphrase = getpass.getpass("")
|
||||
self.print("Confirm your Passphrase: ")
|
||||
if passphrase == getpass.getpass(''):
|
||||
if passphrase == getpass.getpass(""):
|
||||
passphrase = Mnemonic.normalize_string(passphrase)
|
||||
return proto.PassphraseAck(passphrase=passphrase)
|
||||
else:
|
||||
@ -227,8 +261,7 @@ class TextUIMixin(object):
|
||||
return proto.PassphraseStateAck()
|
||||
|
||||
def callback_WordRequest(self, msg):
|
||||
if msg.type in (proto.WordRequestType.Matrix9,
|
||||
proto.WordRequestType.Matrix6):
|
||||
if msg.type in (proto.WordRequestType.Matrix9, proto.WordRequestType.Matrix6):
|
||||
return self.callback_RecoveryMatrix(msg)
|
||||
self.print("Enter one word of mnemonic: ")
|
||||
word = input()
|
||||
@ -247,7 +280,7 @@ class DebugLinkMixin(object):
|
||||
# of unit testing, because it will fail to work
|
||||
# without special DebugLink interface provided
|
||||
# by the device.
|
||||
DEBUG = LOG.getChild('debug_link').debug
|
||||
DEBUG = LOG.getChild("debug_link").debug
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DebugLinkMixin, self).__init__(*args, **kwargs)
|
||||
@ -263,7 +296,7 @@ class DebugLinkMixin(object):
|
||||
self.expected_responses = None
|
||||
|
||||
# Use blank passphrase
|
||||
self.set_passphrase('')
|
||||
self.set_passphrase("")
|
||||
|
||||
def close(self):
|
||||
super(DebugLinkMixin, self).close()
|
||||
@ -291,8 +324,10 @@ class DebugLinkMixin(object):
|
||||
# return isinstance(value, TypeError)
|
||||
# Evaluate missed responses in 'with' statement
|
||||
if self.expected_responses is not None and len(self.expected_responses):
|
||||
raise RuntimeError("Some of expected responses didn't come from device: %s" %
|
||||
[repr(x) for x in self.expected_responses])
|
||||
raise RuntimeError(
|
||||
"Some of expected responses didn't come from device: %s"
|
||||
% [repr(x) for x in self.expected_responses]
|
||||
)
|
||||
|
||||
# Cleanup
|
||||
self.expected_responses = None
|
||||
@ -311,13 +346,14 @@ class DebugLinkMixin(object):
|
||||
self.passphrase = Mnemonic.normalize_string(passphrase)
|
||||
|
||||
def set_mnemonic(self, mnemonic):
|
||||
self.mnemonic = Mnemonic.normalize_string(mnemonic).split(' ')
|
||||
self.mnemonic = Mnemonic.normalize_string(mnemonic).split(" ")
|
||||
|
||||
def call_raw(self, msg):
|
||||
__tracebackhide__ = True # pytest traceback hiding - this function won't appear in tracebacks
|
||||
__tracebackhide__ = True # for pytest # pylint: disable=W0612
|
||||
|
||||
if SCREENSHOT and self.debug:
|
||||
from PIL import Image
|
||||
|
||||
layout = self.debug.read_layout()
|
||||
im = Image.new("RGB", (128, 64))
|
||||
pix = im.load()
|
||||
@ -326,7 +362,7 @@ class DebugLinkMixin(object):
|
||||
rx, ry = 127 - x, 63 - y
|
||||
if (ord(layout[rx + (ry / 8) * 128]) & (1 << (ry % 8))) > 0:
|
||||
pix[x, y] = (255, 255, 255)
|
||||
im.save('scr%05d.png' % self.screenshot_id)
|
||||
im.save("scr%05d.png" % self.screenshot_id)
|
||||
self.screenshot_id += 1
|
||||
|
||||
resp = super(DebugLinkMixin, self).call_raw(msg)
|
||||
@ -334,25 +370,31 @@ class DebugLinkMixin(object):
|
||||
return resp
|
||||
|
||||
def _check_request(self, msg):
|
||||
__tracebackhide__ = True # pytest traceback hiding - this function won't appear in tracebacks
|
||||
__tracebackhide__ = True # for pytest # pylint: disable=W0612
|
||||
|
||||
if self.expected_responses is not None:
|
||||
try:
|
||||
expected = self.expected_responses.pop(0)
|
||||
except IndexError:
|
||||
raise AssertionError(proto.FailureType.UnexpectedMessage,
|
||||
"Got %s, but no message has been expected" % repr(msg))
|
||||
raise AssertionError(
|
||||
proto.FailureType.UnexpectedMessage,
|
||||
"Got %s, but no message has been expected" % repr(msg),
|
||||
)
|
||||
|
||||
if msg.__class__ != expected.__class__:
|
||||
raise AssertionError(proto.FailureType.UnexpectedMessage,
|
||||
"Expected %s, got %s" % (repr(expected), repr(msg)))
|
||||
raise AssertionError(
|
||||
proto.FailureType.UnexpectedMessage,
|
||||
"Expected %s, got %s" % (repr(expected), repr(msg)),
|
||||
)
|
||||
|
||||
for field, value in expected.__dict__.items():
|
||||
if value is None or value == []:
|
||||
continue
|
||||
if getattr(msg, field) != value:
|
||||
raise AssertionError(proto.FailureType.UnexpectedMessage,
|
||||
"Expected %s, got %s" % (repr(expected), repr(msg)))
|
||||
raise AssertionError(
|
||||
proto.FailureType.UnexpectedMessage,
|
||||
"Expected %s, got %s" % (repr(expected), repr(msg)),
|
||||
)
|
||||
|
||||
def callback_ButtonRequest(self, msg):
|
||||
self.DEBUG("ButtonRequest code: " + get_buttonrequest_value(msg.code))
|
||||
@ -368,7 +410,7 @@ class DebugLinkMixin(object):
|
||||
if self.pin_correct:
|
||||
pin = self.debug.read_pin_encoded()
|
||||
else:
|
||||
pin = '444222'
|
||||
pin = "444222"
|
||||
return proto.PinMatrixAck(pin=pin)
|
||||
|
||||
def callback_PassphraseRequest(self, msg):
|
||||
@ -380,7 +422,7 @@ class DebugLinkMixin(object):
|
||||
|
||||
def callback_WordRequest(self, msg):
|
||||
(word, pos) = self.debug.read_recovery_word()
|
||||
if word != '':
|
||||
if word != "":
|
||||
return proto.WordAck(word=word)
|
||||
if pos != 0:
|
||||
return proto.WordAck(word=self.mnemonic[pos - 1])
|
||||
@ -389,7 +431,7 @@ class DebugLinkMixin(object):
|
||||
|
||||
|
||||
class ProtocolMixin(object):
|
||||
VENDORS = ('bitcointrezor.com', 'trezor.io')
|
||||
VENDORS = ("bitcointrezor.com", "trezor.io")
|
||||
|
||||
def __init__(self, state=None, *args, **kwargs):
|
||||
super(ProtocolMixin, self).__init__(*args, **kwargs)
|
||||
@ -410,15 +452,27 @@ class ProtocolMixin(object):
|
||||
|
||||
@staticmethod
|
||||
def expand_path(n):
|
||||
warnings.warn('expand_path is deprecated, use tools.parse_path', DeprecationWarning, stacklevel=2)
|
||||
warnings.warn(
|
||||
"expand_path is deprecated, use tools.parse_path",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return tools.parse_path(n)
|
||||
|
||||
@tools.expect(proto.Success, field="message")
|
||||
def ping(self, msg, button_protection=False, pin_protection=False, passphrase_protection=False):
|
||||
msg = proto.Ping(message=msg,
|
||||
def ping(
|
||||
self,
|
||||
msg,
|
||||
button_protection=False,
|
||||
pin_protection=False,
|
||||
passphrase_protection=False,
|
||||
):
|
||||
msg = proto.Ping(
|
||||
message=msg,
|
||||
button_protection=button_protection,
|
||||
pin_protection=pin_protection,
|
||||
passphrase_protection=passphrase_protection)
|
||||
passphrase_protection=passphrase_protection,
|
||||
)
|
||||
return self.call(msg)
|
||||
|
||||
def get_device_id(self):
|
||||
@ -435,14 +489,18 @@ class ProtocolMixin(object):
|
||||
if inp.prev_hash in txes:
|
||||
continue
|
||||
|
||||
if inp.script_type in (proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
proto.InputScriptType.SPENDWITNESS):
|
||||
if inp.script_type in (
|
||||
proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
proto.InputScriptType.SPENDWITNESS,
|
||||
):
|
||||
continue
|
||||
|
||||
if not self.tx_api:
|
||||
raise RuntimeError('TX_API not defined')
|
||||
raise RuntimeError("TX_API not defined")
|
||||
|
||||
prev_tx = self.tx_api.get_tx(binascii.hexlify(inp.prev_hash).decode('utf-8'))
|
||||
prev_tx = self.tx_api.get_tx(
|
||||
binascii.hexlify(inp.prev_hash).decode("utf-8")
|
||||
)
|
||||
txes[inp.prev_hash] = prev_tx
|
||||
|
||||
return txes
|
||||
|
@ -14,12 +14,12 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import os.path
|
||||
import json
|
||||
import os.path
|
||||
|
||||
from .tx_api import TxApiInsight
|
||||
|
||||
COINS_JSON = os.path.join(os.path.dirname(__file__), 'coins.json')
|
||||
COINS_JSON = os.path.join(os.path.dirname(__file__), "coins.json")
|
||||
|
||||
|
||||
def _load_coins_json():
|
||||
@ -35,24 +35,26 @@ def _load_coins_json():
|
||||
|
||||
|
||||
def _insight_for_coin(coin):
|
||||
url = next(iter(coin['blockbook'] + coin['bitcore']), None)
|
||||
url = next(iter(coin["blockbook"] + coin["bitcore"]), None)
|
||||
if not url:
|
||||
return None
|
||||
zcash = coin['coin_name'].lower().startswith('zcash')
|
||||
bip115 = coin['bip115']
|
||||
network = 'insight_{}'.format(coin['coin_name'].lower().replace(' ', '_'))
|
||||
zcash = coin["coin_name"].lower().startswith("zcash")
|
||||
bip115 = coin["bip115"]
|
||||
network = "insight_{}".format(coin["coin_name"].lower().replace(" ", "_"))
|
||||
return TxApiInsight(network=network, url=url, zcash=zcash, bip115=bip115)
|
||||
|
||||
|
||||
# exported variables
|
||||
__all__ = ['by_name', 'slip44', 'tx_api']
|
||||
__all__ = ["by_name", "slip44", "tx_api"]
|
||||
|
||||
try:
|
||||
by_name = _load_coins_json()
|
||||
except Exception as e:
|
||||
raise ImportError("Failed to load coins.json. Check your installation.") from e
|
||||
|
||||
slip44 = {name: coin['slip44'] for name, coin in by_name.items()}
|
||||
tx_api = {name: _insight_for_coin(coin)
|
||||
slip44 = {name: coin["slip44"] for name, coin in by_name.items()}
|
||||
tx_api = {
|
||||
name: _insight_for_coin(coin)
|
||||
for name, coin in by_name.items()
|
||||
if coin["blockbook"] or coin["bitcore"]}
|
||||
if coin["blockbook"] or coin["bitcore"]
|
||||
}
|
||||
|
@ -14,15 +14,13 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from functools import reduce
|
||||
import binascii
|
||||
from functools import reduce
|
||||
from typing import Iterable, Tuple
|
||||
|
||||
from . import messages
|
||||
from . import _ed25519, messages
|
||||
from .tools import expect
|
||||
|
||||
from . import _ed25519
|
||||
|
||||
# XXX, these could be NewType's, but that would infect users of the cosi module with these types as well.
|
||||
# Unsure if we want that.
|
||||
Ed25519PrivateKey = bytes
|
||||
@ -37,7 +35,9 @@ def combine_keys(pks: Iterable[Ed25519PublicPoint]) -> Ed25519PublicPoint:
|
||||
return Ed25519PublicPoint(_ed25519.encodepoint(combine))
|
||||
|
||||
|
||||
def combine_sig(global_R: Ed25519PublicPoint, sigs: Iterable[Ed25519Signature]) -> Ed25519Signature:
|
||||
def combine_sig(
|
||||
global_R: Ed25519PublicPoint, sigs: Iterable[Ed25519Signature]
|
||||
) -> Ed25519Signature:
|
||||
"""Combine a list of signatures into a single CoSi signature."""
|
||||
S = [_ed25519.decodeint(si) for si in sigs]
|
||||
s = sum(S) % _ed25519.l
|
||||
@ -45,7 +45,9 @@ def combine_sig(global_R: Ed25519PublicPoint, sigs: Iterable[Ed25519Signature])
|
||||
return Ed25519Signature(sig)
|
||||
|
||||
|
||||
def get_nonce(sk: Ed25519PrivateKey, data: bytes, ctr: int = 0) -> Tuple[int, Ed25519PublicPoint]:
|
||||
def get_nonce(
|
||||
sk: Ed25519PrivateKey, data: bytes, ctr: int = 0
|
||||
) -> Tuple[int, Ed25519PublicPoint]:
|
||||
"""Calculate CoSi nonces for given data.
|
||||
These differ from Ed25519 deterministic nonces in that there is a counter appended at end.
|
||||
|
||||
@ -58,12 +60,18 @@ def get_nonce(sk: Ed25519PrivateKey, data: bytes, ctr: int = 0) -> Tuple[int, Ed
|
||||
"""
|
||||
h = _ed25519.H(sk)
|
||||
b = _ed25519.b
|
||||
r = _ed25519.Hint(bytes([h[i] for i in range(b >> 3, b >> 2)]) + data + binascii.unhexlify('%08x' % ctr))
|
||||
r = _ed25519.Hint(
|
||||
bytes([h[i] for i in range(b >> 3, b >> 2)])
|
||||
+ data
|
||||
+ binascii.unhexlify("%08x" % ctr)
|
||||
)
|
||||
R = _ed25519.scalarmult(_ed25519.B, r)
|
||||
return r, Ed25519PublicPoint(_ed25519.encodepoint(R))
|
||||
|
||||
|
||||
def verify(signature: Ed25519Signature, digest: bytes, pub_key: Ed25519PublicPoint) -> None:
|
||||
def verify(
|
||||
signature: Ed25519Signature, digest: bytes, pub_key: Ed25519PublicPoint
|
||||
) -> None:
|
||||
"""Verify Ed25519 signature. Raise exception if the signature is invalid."""
|
||||
# XXX this *might* change to bool function
|
||||
_ed25519.checkvalid(signature, digest, pub_key)
|
||||
@ -76,10 +84,13 @@ def pubkey_from_privkey(privkey: Ed25519PrivateKey) -> Ed25519PublicPoint:
|
||||
return Ed25519PublicPoint(_ed25519.publickey(privkey))
|
||||
|
||||
|
||||
def sign_with_privkey(digest: bytes, privkey: Ed25519PrivateKey,
|
||||
def sign_with_privkey(
|
||||
digest: bytes,
|
||||
privkey: Ed25519PrivateKey,
|
||||
global_pubkey: Ed25519PublicPoint,
|
||||
nonce: int,
|
||||
global_commit: Ed25519PublicPoint) -> Ed25519Signature:
|
||||
global_commit: Ed25519PublicPoint,
|
||||
) -> Ed25519Signature:
|
||||
"""Create a CoSi signature of `digest` with the supplied private key.
|
||||
This function needs to know the global public key and global commitment.
|
||||
"""
|
||||
@ -100,4 +111,11 @@ def commit(client, n, data):
|
||||
|
||||
@expect(messages.CosiSignature)
|
||||
def sign(client, n, data, global_commitment, global_pubkey):
|
||||
return client.call(messages.CosiSign(address_n=n, data=data, global_commitment=global_commitment, global_pubkey=global_pubkey))
|
||||
return client.call(
|
||||
messages.CosiSign(
|
||||
address_n=n,
|
||||
data=data,
|
||||
global_commitment=global_commitment,
|
||||
global_pubkey=global_pubkey,
|
||||
)
|
||||
)
|
||||
|
@ -18,8 +18,7 @@ import binascii
|
||||
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
from . import messages as proto
|
||||
from . import tools
|
||||
from . import messages as proto, tools
|
||||
from .tools import expect
|
||||
|
||||
|
||||
@ -69,7 +68,7 @@ class DebugLink(object):
|
||||
# We have to encode that into encoded pin,
|
||||
# because application must send back positions
|
||||
# on keypad, not a real PIN.
|
||||
pin_encoded = ''.join([str(matrix.index(p) + 1) for p in pin])
|
||||
pin_encoded = "".join([str(matrix.index(p) + 1) for p in pin])
|
||||
|
||||
print("Encoded PIN:", pin_encoded)
|
||||
return pin_encoded
|
||||
@ -138,21 +137,33 @@ class DebugLink(object):
|
||||
return obj.memory
|
||||
|
||||
def memory_write(self, address, memory, flash=False):
|
||||
self._call(proto.DebugLinkMemoryWrite(address=address, memory=memory, flash=flash), nowait=True)
|
||||
self._call(
|
||||
proto.DebugLinkMemoryWrite(address=address, memory=memory, flash=flash),
|
||||
nowait=True,
|
||||
)
|
||||
|
||||
def flash_erase(self, sector):
|
||||
self._call(proto.DebugLinkFlashErase(sector=sector), nowait=True)
|
||||
|
||||
|
||||
@expect(proto.Success, field="message")
|
||||
def load_device_by_mnemonic(client, mnemonic, pin, passphrase_protection, label, language='english', skip_checksum=False, expand=False):
|
||||
def load_device_by_mnemonic(
|
||||
client,
|
||||
mnemonic,
|
||||
pin,
|
||||
passphrase_protection,
|
||||
label,
|
||||
language="english",
|
||||
skip_checksum=False,
|
||||
expand=False,
|
||||
):
|
||||
# Convert mnemonic to UTF8 NKFD
|
||||
mnemonic = Mnemonic.normalize_string(mnemonic)
|
||||
|
||||
# Convert mnemonic to ASCII stream
|
||||
mnemonic = mnemonic.encode('utf-8')
|
||||
mnemonic = mnemonic.encode("utf-8")
|
||||
|
||||
m = Mnemonic('english')
|
||||
m = Mnemonic("english")
|
||||
|
||||
if expand:
|
||||
mnemonic = m.expand(mnemonic)
|
||||
@ -161,13 +172,20 @@ def load_device_by_mnemonic(client, mnemonic, pin, passphrase_protection, label,
|
||||
raise ValueError("Invalid mnemonic checksum")
|
||||
|
||||
if client.features.initialized:
|
||||
raise RuntimeError("Device is initialized already. Call wipe_device() and try again.")
|
||||
raise RuntimeError(
|
||||
"Device is initialized already. Call wipe_device() and try again."
|
||||
)
|
||||
|
||||
resp = client.call(proto.LoadDevice(mnemonic=mnemonic, pin=pin,
|
||||
resp = client.call(
|
||||
proto.LoadDevice(
|
||||
mnemonic=mnemonic,
|
||||
pin=pin,
|
||||
passphrase_protection=passphrase_protection,
|
||||
language=language,
|
||||
label=label,
|
||||
skip_checksum=skip_checksum))
|
||||
skip_checksum=skip_checksum,
|
||||
)
|
||||
)
|
||||
client.init_device()
|
||||
return resp
|
||||
|
||||
@ -175,9 +193,11 @@ def load_device_by_mnemonic(client, mnemonic, pin, passphrase_protection, label,
|
||||
@expect(proto.Success, field="message")
|
||||
def load_device_by_xprv(client, xprv, pin, passphrase_protection, label, language):
|
||||
if client.features.initialized:
|
||||
raise RuntimeError("Device is initialized already. Call wipe_device() and try again.")
|
||||
raise RuntimeError(
|
||||
"Device is initialized already. Call wipe_device() and try again."
|
||||
)
|
||||
|
||||
if xprv[0:4] not in ('xprv', 'tprv'):
|
||||
if xprv[0:4] not in ("xprv", "tprv"):
|
||||
raise ValueError("Unknown type of xprv")
|
||||
|
||||
if not 100 < len(xprv) < 112: # yes this is correct in Python
|
||||
@ -186,7 +206,7 @@ def load_device_by_xprv(client, xprv, pin, passphrase_protection, label, languag
|
||||
node = proto.HDNodeType()
|
||||
data = binascii.hexlify(tools.b58decode(xprv, None))
|
||||
|
||||
if data[90:92] != b'00':
|
||||
if data[90:92] != b"00":
|
||||
raise ValueError("Contain invalid private key")
|
||||
|
||||
checksum = binascii.hexlify(tools.btc_hash(binascii.unhexlify(data[:156]))[:4])
|
||||
@ -207,11 +227,15 @@ def load_device_by_xprv(client, xprv, pin, passphrase_protection, label, languag
|
||||
node.chain_code = binascii.unhexlify(data[26:90])
|
||||
node.private_key = binascii.unhexlify(data[92:156]) # skip 0x00 indicating privkey
|
||||
|
||||
resp = client.call(proto.LoadDevice(node=node,
|
||||
resp = client.call(
|
||||
proto.LoadDevice(
|
||||
node=node,
|
||||
pin=pin,
|
||||
passphrase_protection=passphrase_protection,
|
||||
language=language,
|
||||
label=label))
|
||||
label=label,
|
||||
)
|
||||
)
|
||||
client.init_device()
|
||||
return resp
|
||||
|
||||
@ -221,4 +245,8 @@ def self_test(client):
|
||||
if client.features.bootloader_mode is not True:
|
||||
raise RuntimeError("Device must be in bootloader mode")
|
||||
|
||||
return client.call(proto.SelfTest(payload=b'\x00\xFF\x55\xAA\x66\x99\x33\xCCABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\x00\xFF\x55\xAA\x66\x99\x33\xCC'))
|
||||
return client.call(
|
||||
proto.SelfTest(
|
||||
payload=b"\x00\xFF\x55\xAA\x66\x99\x33\xCCABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\x00\xFF\x55\xAA\x66\x99\x33\xCC"
|
||||
)
|
||||
)
|
||||
|
@ -16,34 +16,42 @@
|
||||
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
from . import messages as proto
|
||||
from .tools import expect, session
|
||||
|
||||
from .transport import enumerate_devices, get_transport
|
||||
|
||||
|
||||
class TrezorDevice:
|
||||
'''
|
||||
"""
|
||||
This class is deprecated. (There is no reason for it to exist in the first
|
||||
place, it is nothing but a collection of two functions.)
|
||||
Instead, please use functions from the ``trezorlib.transport`` module.
|
||||
'''
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def enumerate(cls):
|
||||
warnings.warn('TrezorDevice is deprecated.', DeprecationWarning)
|
||||
warnings.warn("TrezorDevice is deprecated.", DeprecationWarning)
|
||||
return enumerate_devices()
|
||||
|
||||
@classmethod
|
||||
def find_by_path(cls, path):
|
||||
warnings.warn('TrezorDevice is deprecated.', DeprecationWarning)
|
||||
warnings.warn("TrezorDevice is deprecated.", DeprecationWarning)
|
||||
return get_transport(path, prefix_search=False)
|
||||
|
||||
|
||||
@expect(proto.Success, field="message")
|
||||
def apply_settings(client, label=None, language=None, use_passphrase=None, homescreen=None, passphrase_source=None, auto_lock_delay_ms=None):
|
||||
def apply_settings(
|
||||
client,
|
||||
label=None,
|
||||
language=None,
|
||||
use_passphrase=None,
|
||||
homescreen=None,
|
||||
passphrase_source=None,
|
||||
auto_lock_delay_ms=None,
|
||||
):
|
||||
settings = proto.ApplySettings()
|
||||
if label is not None:
|
||||
settings.label = label
|
||||
@ -91,9 +99,21 @@ def wipe(client):
|
||||
|
||||
|
||||
@expect(proto.Success, field="message")
|
||||
def recover(client, word_count, passphrase_protection, pin_protection, label, language, type=proto.RecoveryDeviceType.ScrambledWords, expand=False, dry_run=False):
|
||||
def recover(
|
||||
client,
|
||||
word_count,
|
||||
passphrase_protection,
|
||||
pin_protection,
|
||||
label,
|
||||
language,
|
||||
type=proto.RecoveryDeviceType.ScrambledWords,
|
||||
expand=False,
|
||||
dry_run=False,
|
||||
):
|
||||
if client.features.initialized and not dry_run:
|
||||
raise RuntimeError("Device is initialized already. Call wipe_device() and try again.")
|
||||
raise RuntimeError(
|
||||
"Device is initialized already. Call wipe_device() and try again."
|
||||
)
|
||||
|
||||
if word_count not in (12, 18, 24):
|
||||
raise ValueError("Invalid word count. Use 12/18/24")
|
||||
@ -103,9 +123,10 @@ def recover(client, word_count, passphrase_protection, pin_protection, label, la
|
||||
client.expand = expand
|
||||
if client.expand:
|
||||
# optimization to load the wordlist once, instead of for each recovery word
|
||||
client.mnemonic_wordlist = Mnemonic('english')
|
||||
client.mnemonic_wordlist = Mnemonic("english")
|
||||
|
||||
res = client.call(proto.RecoveryDevice(
|
||||
res = client.call(
|
||||
proto.RecoveryDevice(
|
||||
word_count=int(word_count),
|
||||
passphrase_protection=bool(passphrase_protection),
|
||||
pin_protection=bool(pin_protection),
|
||||
@ -113,7 +134,9 @@ def recover(client, word_count, passphrase_protection, pin_protection, label, la
|
||||
language=language,
|
||||
enforce_wordlist=True,
|
||||
type=type,
|
||||
dry_run=dry_run))
|
||||
dry_run=dry_run,
|
||||
)
|
||||
)
|
||||
|
||||
client.init_device()
|
||||
return res
|
||||
@ -121,19 +144,33 @@ def recover(client, word_count, passphrase_protection, pin_protection, label, la
|
||||
|
||||
@expect(proto.Success, field="message")
|
||||
@session
|
||||
def reset(client, display_random, strength, passphrase_protection, pin_protection, label, language, u2f_counter=0, skip_backup=False):
|
||||
def reset(
|
||||
client,
|
||||
display_random,
|
||||
strength,
|
||||
passphrase_protection,
|
||||
pin_protection,
|
||||
label,
|
||||
language,
|
||||
u2f_counter=0,
|
||||
skip_backup=False,
|
||||
):
|
||||
if client.features.initialized:
|
||||
raise RuntimeError("Device is initialized already. Call wipe_device() and try again.")
|
||||
raise RuntimeError(
|
||||
"Device is initialized already. Call wipe_device() and try again."
|
||||
)
|
||||
|
||||
# Begin with device reset workflow
|
||||
msg = proto.ResetDevice(display_random=display_random,
|
||||
msg = proto.ResetDevice(
|
||||
display_random=display_random,
|
||||
strength=strength,
|
||||
passphrase_protection=bool(passphrase_protection),
|
||||
pin_protection=bool(pin_protection),
|
||||
language=language,
|
||||
label=label,
|
||||
u2f_counter=u2f_counter,
|
||||
skip_backup=bool(skip_backup))
|
||||
skip_backup=bool(skip_backup),
|
||||
)
|
||||
|
||||
resp = client.call(msg)
|
||||
if not isinstance(resp, proto.EntropyRequest):
|
||||
|
@ -1,9 +1,9 @@
|
||||
from . import messages as proto
|
||||
from .tools import expect, CallException, normalize_nfc, session
|
||||
from .tools import CallException, expect, normalize_nfc, session
|
||||
|
||||
|
||||
def int_to_big_endian(value):
|
||||
return value.to_bytes((value.bit_length() + 7) // 8, 'big')
|
||||
return value.to_bytes((value.bit_length() + 7) // 8, "big")
|
||||
|
||||
|
||||
# ====== Client functions ====== #
|
||||
@ -15,13 +15,25 @@ def get_address(client, n, show_display=False, multisig=None):
|
||||
|
||||
|
||||
@session
|
||||
def sign_tx(client, n, nonce, gas_price, gas_limit, to, value, data=None, chain_id=None, tx_type=None):
|
||||
def sign_tx(
|
||||
client,
|
||||
n,
|
||||
nonce,
|
||||
gas_price,
|
||||
gas_limit,
|
||||
to,
|
||||
value,
|
||||
data=None,
|
||||
chain_id=None,
|
||||
tx_type=None,
|
||||
):
|
||||
msg = proto.EthereumSignTx(
|
||||
address_n=n,
|
||||
nonce=int_to_big_endian(nonce),
|
||||
gas_price=int_to_big_endian(gas_price),
|
||||
gas_limit=int_to_big_endian(gas_limit),
|
||||
value=int_to_big_endian(value))
|
||||
value=int_to_big_endian(value),
|
||||
)
|
||||
|
||||
if to:
|
||||
msg.to = to
|
||||
@ -56,7 +68,11 @@ def sign_message(client, n, message):
|
||||
def verify_message(client, address, signature, message):
|
||||
message = normalize_nfc(message)
|
||||
try:
|
||||
resp = client.call(proto.EthereumVerifyMessage(address=address, signature=signature, message=message))
|
||||
resp = client.call(
|
||||
proto.EthereumVerifyMessage(
|
||||
address=address, signature=signature, message=message
|
||||
)
|
||||
)
|
||||
except CallException as e:
|
||||
resp = e
|
||||
if isinstance(resp, proto.Success):
|
||||
|
@ -1,12 +1,16 @@
|
||||
import binascii
|
||||
|
||||
import construct as c
|
||||
import pyblake2
|
||||
|
||||
from . import cosi
|
||||
from . import messages as proto
|
||||
from . import tools
|
||||
from . import cosi, messages as proto, tools
|
||||
|
||||
|
||||
def bytes_not(data):
|
||||
return bytes(~b & 0xff for b in data)
|
||||
|
||||
|
||||
# fmt: off
|
||||
Toif = c.Struct(
|
||||
"magic" / c.Const(b"TOI"),
|
||||
"format" / c.Enum(c.Byte, full_color=b"f", grayscale=b"g"),
|
||||
@ -16,10 +20,6 @@ Toif = c.Struct(
|
||||
)
|
||||
|
||||
|
||||
def bytes_not(data):
|
||||
return bytes(~b & 0xff for b in data)
|
||||
|
||||
|
||||
VendorTrust = c.Transformed(c.BitStruct(
|
||||
"reserved" / c.Padding(9),
|
||||
"show_vendor_string" / c.Flag,
|
||||
@ -87,7 +87,10 @@ FirmwareHeader = c.Struct(
|
||||
"signature" / c.Bytes(64),
|
||||
|
||||
"_end_offset" / c.Tell,
|
||||
"header_len" / c.Pointer(c.this._start_offset + 4, c.Rebuild(c.Int32ul, c.this._end_offset - c.this._start_offset)),
|
||||
"header_len" / c.Pointer(
|
||||
c.this._start_offset + 4,
|
||||
c.Rebuild(c.Int32ul, c.this._end_offset - c.this._start_offset)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@ -97,12 +100,13 @@ Firmware = c.Struct(
|
||||
"code" / c.Bytes(c.this.firmware_header.code_length),
|
||||
c.Terminated,
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
def validate_firmware(filename):
|
||||
with open(filename, "rb") as f:
|
||||
data = f.read()
|
||||
if data[:6] == b'54525a':
|
||||
if data[:6] == b"54525a":
|
||||
data = binascii.unhexlify(data)
|
||||
|
||||
try:
|
||||
@ -113,19 +117,29 @@ def validate_firmware(filename):
|
||||
vendor = fw.vendor_header
|
||||
header = fw.firmware_header
|
||||
|
||||
print("Vendor header from {}, version {}.{}".format(vendor.vendor_string, vendor.version.major, vendor.version.minor))
|
||||
print("Firmware version {v.major}.{v.minor}.{v.patch} build {v.build}".format(v=header.version))
|
||||
print(
|
||||
"Vendor header from {}, version {}.{}".format(
|
||||
vendor.vendor_string, vendor.version.major, vendor.version.minor
|
||||
)
|
||||
)
|
||||
print(
|
||||
"Firmware version {v.major}.{v.minor}.{v.patch} build {v.build}".format(
|
||||
v=header.version
|
||||
)
|
||||
)
|
||||
|
||||
# rebuild header without signatures
|
||||
stripped_header = header.copy()
|
||||
stripped_header.sigmask = 0
|
||||
stripped_header.signature = b'\0' * 64
|
||||
stripped_header.signature = b"\0" * 64
|
||||
header_bytes = FirmwareHeader.build(stripped_header)
|
||||
digest = pyblake2.blake2s(header_bytes).digest()
|
||||
|
||||
print("Fingerprint: {}".format(binascii.hexlify(digest).decode("ascii")))
|
||||
|
||||
global_pk = cosi.combine_keys(vendor.pubkeys[i] for i in range(8) if header.sigmask & (1 << i))
|
||||
global_pk = cosi.combine_keys(
|
||||
vendor.pubkeys[i] for i in range(8) if header.sigmask & (1 << i)
|
||||
)
|
||||
|
||||
try:
|
||||
cosi.verify(header.signature, digest, global_pk)
|
||||
@ -156,13 +170,17 @@ def update(client, fp):
|
||||
resp = client.call(proto.FirmwareUpload(payload=data))
|
||||
if isinstance(resp, proto.Success):
|
||||
return True
|
||||
elif isinstance(resp, proto.Failure) and resp.code == proto.FailureType.FirmwareError:
|
||||
elif (
|
||||
isinstance(resp, proto.Failure)
|
||||
and resp.code == proto.FailureType.FirmwareError
|
||||
):
|
||||
return False
|
||||
raise RuntimeError("Unexpected result %s" % resp)
|
||||
|
||||
# TREZORv2 method
|
||||
if isinstance(resp, proto.FirmwareRequest):
|
||||
import pyblake2
|
||||
|
||||
while True:
|
||||
payload = data[resp.offset : resp.offset + resp.length]
|
||||
digest = pyblake2.blake2s(payload).digest()
|
||||
@ -171,7 +189,10 @@ def update(client, fp):
|
||||
continue
|
||||
elif isinstance(resp, proto.Success):
|
||||
return True
|
||||
elif isinstance(resp, proto.Failure) and resp.code == proto.FailureType.FirmwareError:
|
||||
elif (
|
||||
isinstance(resp, proto.Failure)
|
||||
and resp.code == proto.FailureType.FirmwareError
|
||||
):
|
||||
return False
|
||||
raise RuntimeError("Unexpected result %s" % resp)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import binascii
|
||||
|
||||
from . import messages as proto
|
||||
from .tools import expect, CallException, normalize_nfc
|
||||
from .tools import CallException, expect, normalize_nfc
|
||||
|
||||
|
||||
@expect(proto.LiskAddress, field="address")
|
||||
@ -23,7 +23,11 @@ def sign_message(client, n, message):
|
||||
def verify_message(client, pubkey, signature, message):
|
||||
message = normalize_nfc(message)
|
||||
try:
|
||||
resp = client.call(proto.LiskVerifyMessage(signature=signature, public_key=pubkey, message=message))
|
||||
resp = client.call(
|
||||
proto.LiskVerifyMessage(
|
||||
signature=signature, public_key=pubkey, message=message
|
||||
)
|
||||
)
|
||||
except CallException as e:
|
||||
resp = e
|
||||
return isinstance(resp, proto.Success)
|
||||
@ -55,7 +59,9 @@ def sign_tx(client, n, transaction):
|
||||
msg = proto.LiskTransactionCommon()
|
||||
|
||||
msg.type = transaction["type"]
|
||||
msg.fee = int(transaction["fee"]) # Lisk use strings for big numbers (javascript issue)
|
||||
msg.fee = int(
|
||||
transaction["fee"]
|
||||
) # Lisk use strings for big numbers (javascript issue)
|
||||
msg.amount = int(transaction["amount"]) # And we convert it back to number
|
||||
msg.timestamp = transaction["timestamp"]
|
||||
|
||||
|
@ -23,14 +23,15 @@ OMITTED_MESSAGES = set() # type: Set[Type[protobuf.MessageType]]
|
||||
|
||||
|
||||
class PrettyProtobufFormatter(logging.Formatter):
|
||||
|
||||
def format(self, record: logging.LogRecord) -> str:
|
||||
time = self.formatTime(record)
|
||||
message = '[{time}] {source} {level}: {msg}'.format(
|
||||
time=time, level=record.levelname.upper(),
|
||||
message = "[{time}] {source} {level}: {msg}".format(
|
||||
time=time,
|
||||
level=record.levelname.upper(),
|
||||
source=record.name,
|
||||
msg=super().format(record))
|
||||
if hasattr(record, 'protobuf'):
|
||||
msg=super().format(record),
|
||||
)
|
||||
if hasattr(record, "protobuf"):
|
||||
if type(record.protobuf) in OMITTED_MESSAGES:
|
||||
message += " ({} bytes)".format(record.protobuf.ByteSize())
|
||||
else:
|
||||
@ -45,6 +46,6 @@ def enable_debug_output(handler: Optional[logging.Handler] = None):
|
||||
formatter = PrettyProtobufFormatter()
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
logger = logging.getLogger('trezorlib')
|
||||
logger = logging.getLogger("trezorlib")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(handler)
|
||||
|
@ -22,24 +22,30 @@ map_class_to_type = {}
|
||||
|
||||
def build_map():
|
||||
for msg_name in dir(messages.MessageType):
|
||||
if msg_name.startswith('__'):
|
||||
if msg_name.startswith("__"):
|
||||
continue
|
||||
|
||||
try:
|
||||
msg_class = getattr(messages, msg_name)
|
||||
except AttributeError:
|
||||
raise ValueError("Implementation of protobuf message '%s' is missing" % msg_name)
|
||||
raise ValueError(
|
||||
"Implementation of protobuf message '%s' is missing" % msg_name
|
||||
)
|
||||
|
||||
if msg_class.MESSAGE_WIRE_TYPE != getattr(messages.MessageType, msg_name):
|
||||
raise ValueError("Inconsistent wire type and MessageType record for '%s'" % msg_class)
|
||||
raise ValueError(
|
||||
"Inconsistent wire type and MessageType record for '%s'" % msg_class
|
||||
)
|
||||
|
||||
register_message(msg_class)
|
||||
|
||||
|
||||
def register_message(msg_class):
|
||||
if msg_class.MESSAGE_WIRE_TYPE in map_type_to_class:
|
||||
raise Exception("Message for wire type %s is already registered by %s" %
|
||||
(msg_class.MESSAGE_WIRE_TYPE, get_class(msg_class.MESSAGE_WIRE_TYPE)))
|
||||
raise Exception(
|
||||
"Message for wire type %s is already registered by %s"
|
||||
% (msg_class.MESSAGE_WIRE_TYPE, get_class(msg_class.MESSAGE_WIRE_TYPE))
|
||||
)
|
||||
|
||||
map_class_to_type[msg_class] = msg_class.MESSAGE_WIRE_TYPE
|
||||
map_type_to_class[msg_class.MESSAGE_WIRE_TYPE] = msg_class
|
||||
|
@ -8,32 +8,59 @@ def get_entropy(client, size):
|
||||
|
||||
|
||||
@expect(proto.SignedIdentity)
|
||||
def sign_identity(client, identity, challenge_hidden, challenge_visual, ecdsa_curve_name=None):
|
||||
return client.call(proto.SignIdentity(identity=identity, challenge_hidden=challenge_hidden, challenge_visual=challenge_visual, ecdsa_curve_name=ecdsa_curve_name))
|
||||
def sign_identity(
|
||||
client, identity, challenge_hidden, challenge_visual, ecdsa_curve_name=None
|
||||
):
|
||||
return client.call(
|
||||
proto.SignIdentity(
|
||||
identity=identity,
|
||||
challenge_hidden=challenge_hidden,
|
||||
challenge_visual=challenge_visual,
|
||||
ecdsa_curve_name=ecdsa_curve_name,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@expect(proto.ECDHSessionKey)
|
||||
def get_ecdh_session_key(client, identity, peer_public_key, ecdsa_curve_name=None):
|
||||
return client.call(proto.GetECDHSessionKey(identity=identity, peer_public_key=peer_public_key, ecdsa_curve_name=ecdsa_curve_name))
|
||||
return client.call(
|
||||
proto.GetECDHSessionKey(
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name=ecdsa_curve_name,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@expect(proto.CipheredKeyValue, field="value")
|
||||
def encrypt_keyvalue(client, n, key, value, ask_on_encrypt=True, ask_on_decrypt=True, iv=b''):
|
||||
return client.call(proto.CipherKeyValue(address_n=n,
|
||||
def encrypt_keyvalue(
|
||||
client, n, key, value, ask_on_encrypt=True, ask_on_decrypt=True, iv=b""
|
||||
):
|
||||
return client.call(
|
||||
proto.CipherKeyValue(
|
||||
address_n=n,
|
||||
key=key,
|
||||
value=value,
|
||||
encrypt=True,
|
||||
ask_on_encrypt=ask_on_encrypt,
|
||||
ask_on_decrypt=ask_on_decrypt,
|
||||
iv=iv))
|
||||
iv=iv,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@expect(proto.CipheredKeyValue, field="value")
|
||||
def decrypt_keyvalue(client, n, key, value, ask_on_encrypt=True, ask_on_decrypt=True, iv=b''):
|
||||
return client.call(proto.CipherKeyValue(address_n=n,
|
||||
def decrypt_keyvalue(
|
||||
client, n, key, value, ask_on_encrypt=True, ask_on_decrypt=True, iv=b""
|
||||
):
|
||||
return client.call(
|
||||
proto.CipherKeyValue(
|
||||
address_n=n,
|
||||
key=key,
|
||||
value=value,
|
||||
encrypt=False,
|
||||
ask_on_encrypt=ask_on_encrypt,
|
||||
ask_on_decrypt=ask_on_decrypt,
|
||||
iv=iv))
|
||||
iv=iv,
|
||||
)
|
||||
)
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
import binascii
|
||||
import json
|
||||
|
||||
from . import messages as proto
|
||||
from .tools import expect, CallException
|
||||
from .tools import CallException, expect
|
||||
|
||||
TYPE_TRANSACTION_TRANSFER = 0x0101
|
||||
TYPE_IMPORTANCE_TRANSFER = 0x0801
|
||||
@ -54,21 +55,27 @@ def create_transfer(transaction):
|
||||
msg.public_key = binascii.unhexlify(transaction["message"]["publicKey"])
|
||||
|
||||
if "mosaics" in transaction:
|
||||
msg.mosaics = [proto.NEMMosaic(
|
||||
msg.mosaics = [
|
||||
proto.NEMMosaic(
|
||||
namespace=mosaic["mosaicId"]["namespaceId"],
|
||||
mosaic=mosaic["mosaicId"]["name"],
|
||||
quantity=mosaic["quantity"],
|
||||
) for mosaic in transaction["mosaics"]]
|
||||
)
|
||||
for mosaic in transaction["mosaics"]
|
||||
]
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
def create_aggregate_modification(transactions):
|
||||
msg = proto.NEMAggregateModification()
|
||||
msg.modifications = [proto.NEMCosignatoryModification(
|
||||
msg.modifications = [
|
||||
proto.NEMCosignatoryModification(
|
||||
type=modification["modificationType"],
|
||||
public_key=binascii.unhexlify(modification["cosignatoryAccount"]),
|
||||
) for modification in transactions["modifications"]]
|
||||
)
|
||||
for modification in transactions["modifications"]
|
||||
]
|
||||
|
||||
if "minCosignatories" in transactions:
|
||||
msg.relative_change = transactions["minCosignatories"]["relativeChange"]
|
||||
@ -141,7 +148,7 @@ def create_importance_transfer(transaction):
|
||||
def create_sign_tx(transaction):
|
||||
msg = proto.NEMSignTx()
|
||||
msg.transaction = create_transaction_common(transaction)
|
||||
msg.cosigning = (transaction["type"] == TYPE_MULTISIG_SIGNATURE)
|
||||
msg.cosigning = transaction["type"] == TYPE_MULTISIG_SIGNATURE
|
||||
|
||||
if transaction["type"] in (TYPE_MULTISIG_SIGNATURE, TYPE_MULTISIG):
|
||||
transaction = transaction["otherTrans"]
|
||||
@ -172,7 +179,9 @@ def create_sign_tx(transaction):
|
||||
|
||||
@expect(proto.NEMAddress, field="address")
|
||||
def get_address(client, n, network, show_display=False):
|
||||
return client.call(proto.NEMGetAddress(address_n=n, network=network, show_display=show_display))
|
||||
return client.call(
|
||||
proto.NEMGetAddress(address_n=n, network=network, show_display=show_display)
|
||||
)
|
||||
|
||||
|
||||
@expect(proto.NEMSignedTx)
|
||||
|
@ -89,6 +89,7 @@ def dump_uvarint(writer, n):
|
||||
# But this is harder in Python because we don't natively know the bit size of the number.
|
||||
# So we have to branch on whether the number is negative.
|
||||
|
||||
|
||||
def sint_to_uint(sint):
|
||||
res = sint << 1
|
||||
if sint < 0:
|
||||
@ -134,8 +135,7 @@ class MessageType:
|
||||
self._fill_missing()
|
||||
|
||||
def __eq__(self, rhs):
|
||||
return (self.__class__ is rhs.__class__ and
|
||||
self.__dict__ == rhs.__dict__)
|
||||
return self.__class__ is rhs.__class__ and self.__dict__ == rhs.__dict__
|
||||
|
||||
def __repr__(self):
|
||||
d = {}
|
||||
@ -143,16 +143,16 @@ class MessageType:
|
||||
if value is None or value == []:
|
||||
continue
|
||||
d[key] = value
|
||||
return '<%s: %s>' % (self.__class__.__name__, d)
|
||||
return "<%s: %s>" % (self.__class__.__name__, d)
|
||||
|
||||
def __iter__(self):
|
||||
return self.__dict__.__iter__()
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr.startswith('_add_'):
|
||||
if attr.startswith("_add_"):
|
||||
return self._additem(attr[5:])
|
||||
|
||||
if attr.startswith('_extend_'):
|
||||
if attr.startswith("_extend_"):
|
||||
return self._extenditem(attr[8:])
|
||||
|
||||
raise AttributeError(attr)
|
||||
@ -208,7 +208,6 @@ class MessageType:
|
||||
|
||||
|
||||
class LimitedReader:
|
||||
|
||||
def __init__(self, reader, limit):
|
||||
self.reader = reader
|
||||
self.limit = limit
|
||||
@ -223,7 +222,6 @@ class LimitedReader:
|
||||
|
||||
|
||||
class CountingWriter:
|
||||
|
||||
def __init__(self):
|
||||
self.size = 0
|
||||
|
||||
@ -331,7 +329,7 @@ def dump_message(writer, msg):
|
||||
|
||||
elif ftype is UnicodeType:
|
||||
if not isinstance(svalue, bytes):
|
||||
svalue = svalue.encode('utf-8')
|
||||
svalue = svalue.encode("utf-8")
|
||||
|
||||
dump_uvarint(writer, len(svalue))
|
||||
writer.write(svalue)
|
||||
@ -346,12 +344,13 @@ def dump_message(writer, msg):
|
||||
raise TypeError
|
||||
|
||||
|
||||
def format_message(pb: MessageType,
|
||||
def format_message(
|
||||
pb: MessageType,
|
||||
indent: int = 0,
|
||||
sep: str = ' ' * 4,
|
||||
sep: str = " " * 4,
|
||||
truncate_after: Optional[int] = 256,
|
||||
truncate_to: Optional[int] = 64) -> str:
|
||||
|
||||
truncate_to: Optional[int] = 64,
|
||||
) -> str:
|
||||
def mostly_printable(bytes):
|
||||
if not bytes:
|
||||
return True
|
||||
@ -369,33 +368,33 @@ def format_message(pb: MessageType,
|
||||
return repr(value)
|
||||
|
||||
# long list, one line per entry
|
||||
lines = ['[', level + ']']
|
||||
lines[1:1] = [leadin + pformat_value(x, indent + 1) + ',' for x in value]
|
||||
return '\n'.join(lines)
|
||||
lines = ["[", level + "]"]
|
||||
lines[1:1] = [leadin + pformat_value(x, indent + 1) + "," for x in value]
|
||||
return "\n".join(lines)
|
||||
if isinstance(value, dict):
|
||||
lines = ['{']
|
||||
lines = ["{"]
|
||||
for key, val in sorted(value.items()):
|
||||
if val is None or val == []:
|
||||
continue
|
||||
lines.append(leadin + key + ': ' + pformat_value(val, indent + 1) + ',')
|
||||
lines.append(level + '}')
|
||||
return '\n'.join(lines)
|
||||
lines.append(leadin + key + ": " + pformat_value(val, indent + 1) + ",")
|
||||
lines.append(level + "}")
|
||||
return "\n".join(lines)
|
||||
if isinstance(value, (bytes, bytearray)):
|
||||
length = len(value)
|
||||
suffix = ''
|
||||
suffix = ""
|
||||
if truncate_after and length > truncate_after:
|
||||
suffix = '...'
|
||||
suffix = "..."
|
||||
value = value[: truncate_to or 0]
|
||||
if mostly_printable(value):
|
||||
output = repr(value)
|
||||
else:
|
||||
output = '0x' + binascii.hexlify(value).decode('ascii')
|
||||
return '{} bytes {}{}'.format(length, output, suffix)
|
||||
output = "0x" + binascii.hexlify(value).decode("ascii")
|
||||
return "{} bytes {}{}".format(length, output, suffix)
|
||||
|
||||
return repr(value)
|
||||
|
||||
return '{name} ({size} bytes) {content}'.format(
|
||||
return "{name} ({size} bytes) {content}".format(
|
||||
name=pb.__class__.__name__,
|
||||
size=pb.ByteSize(),
|
||||
content=pformat_value(pb.__dict__, indent)
|
||||
content=pformat_value(pb.__dict__, indent),
|
||||
)
|
||||
|
@ -14,13 +14,12 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from io import BytesIO
|
||||
import logging
|
||||
import struct
|
||||
from io import BytesIO
|
||||
from typing import Tuple
|
||||
|
||||
from . import mapping
|
||||
from . import protobuf
|
||||
from . import mapping, protobuf
|
||||
from .transport import Transport
|
||||
|
||||
REPLEN = 64
|
||||
@ -29,7 +28,6 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ProtocolV1:
|
||||
|
||||
def session_begin(self, transport: Transport) -> None:
|
||||
pass
|
||||
|
||||
@ -37,8 +35,10 @@ class ProtocolV1:
|
||||
pass
|
||||
|
||||
def write(self, transport: Transport, msg: protobuf.MessageType) -> None:
|
||||
LOG.debug("sending message: {}".format(msg.__class__.__name__),
|
||||
extra={'protobuf': msg})
|
||||
LOG.debug(
|
||||
"sending message: {}".format(msg.__class__.__name__),
|
||||
extra={"protobuf": msg},
|
||||
)
|
||||
data = BytesIO()
|
||||
protobuf.dump_message(data, msg)
|
||||
ser = data.getvalue()
|
||||
@ -47,8 +47,8 @@ class ProtocolV1:
|
||||
|
||||
while data:
|
||||
# Report ID, data padded to 63 bytes
|
||||
chunk = b'?' + data[:REPLEN - 1]
|
||||
chunk = chunk.ljust(REPLEN, b'\x00')
|
||||
chunk = b"?" + data[: REPLEN - 1]
|
||||
chunk = chunk.ljust(REPLEN, b"\x00")
|
||||
transport.write_chunk(chunk)
|
||||
data = data[63:]
|
||||
|
||||
@ -67,23 +67,25 @@ class ProtocolV1:
|
||||
|
||||
# Parse to protobuf
|
||||
msg = protobuf.load_message(data, mapping.get_class(msg_type))
|
||||
LOG.debug("received message: {}".format(msg.__class__.__name__),
|
||||
extra={'protobuf': msg})
|
||||
LOG.debug(
|
||||
"received message: {}".format(msg.__class__.__name__),
|
||||
extra={"protobuf": msg},
|
||||
)
|
||||
return msg
|
||||
|
||||
def parse_first(self, chunk: bytes) -> Tuple[int, int, bytes]:
|
||||
if chunk[:3] != b'?##':
|
||||
raise RuntimeError('Unexpected magic characters')
|
||||
if chunk[:3] != b"?##":
|
||||
raise RuntimeError("Unexpected magic characters")
|
||||
try:
|
||||
headerlen = struct.calcsize('>HL')
|
||||
msg_type, datalen = struct.unpack('>HL', chunk[3:3 + headerlen])
|
||||
headerlen = struct.calcsize(">HL")
|
||||
msg_type, datalen = struct.unpack(">HL", chunk[3 : 3 + headerlen])
|
||||
except Exception:
|
||||
raise RuntimeError('Cannot parse header')
|
||||
raise RuntimeError("Cannot parse header")
|
||||
|
||||
data = chunk[3 + headerlen :]
|
||||
return msg_type, datalen, data
|
||||
|
||||
def parse_next(self, chunk: bytes) -> bytes:
|
||||
if chunk[:1] != b'?':
|
||||
raise RuntimeError('Unexpected magic characters')
|
||||
if chunk[:1] != b"?":
|
||||
raise RuntimeError("Unexpected magic characters")
|
||||
return chunk[1:]
|
||||
|
@ -14,13 +14,12 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from io import BytesIO
|
||||
import logging
|
||||
import struct
|
||||
from io import BytesIO
|
||||
from typing import Tuple
|
||||
|
||||
from . import mapping
|
||||
from . import protobuf
|
||||
from . import mapping, protobuf
|
||||
from .transport import Transport
|
||||
|
||||
REPLEN = 64
|
||||
@ -29,13 +28,12 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ProtocolV2:
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.session = None
|
||||
|
||||
def session_begin(self, transport: Transport) -> None:
|
||||
chunk = struct.pack('>B', 0x03)
|
||||
chunk = chunk.ljust(REPLEN, b'\x00')
|
||||
chunk = struct.pack(">B", 0x03)
|
||||
chunk = chunk.ljust(REPLEN, b"\x00")
|
||||
transport.write_chunk(chunk)
|
||||
resp = transport.read_chunk()
|
||||
self.session = self.parse_session_open(resp)
|
||||
@ -44,46 +42,50 @@ class ProtocolV2:
|
||||
def session_end(self, transport: Transport) -> None:
|
||||
if not self.session:
|
||||
return
|
||||
chunk = struct.pack('>BL', 0x04, self.session)
|
||||
chunk = chunk.ljust(REPLEN, b'\x00')
|
||||
chunk = struct.pack(">BL", 0x04, self.session)
|
||||
chunk = chunk.ljust(REPLEN, b"\x00")
|
||||
transport.write_chunk(chunk)
|
||||
resp = transport.read_chunk()
|
||||
(magic, ) = struct.unpack('>B', resp[:1])
|
||||
(magic,) = struct.unpack(">B", resp[:1])
|
||||
if magic != 0x04:
|
||||
raise RuntimeError('Expected session close')
|
||||
raise RuntimeError("Expected session close")
|
||||
LOG.debug("[session {}] session ended".format(self.session))
|
||||
self.session = None
|
||||
|
||||
def write(self, transport: Transport, msg: protobuf.MessageType) -> None:
|
||||
if not self.session:
|
||||
raise RuntimeError('Missing session for v2 protocol')
|
||||
raise RuntimeError("Missing session for v2 protocol")
|
||||
|
||||
LOG.debug("[session {}] sending message: {}".format(self.session, msg.__class__.__name__),
|
||||
extra={'protobuf': msg})
|
||||
LOG.debug(
|
||||
"[session {}] sending message: {}".format(
|
||||
self.session, msg.__class__.__name__
|
||||
),
|
||||
extra={"protobuf": msg},
|
||||
)
|
||||
# Serialize whole message
|
||||
data = BytesIO()
|
||||
protobuf.dump_message(data, msg)
|
||||
data = data.getvalue()
|
||||
dataheader = struct.pack('>LL', mapping.get_type(msg), len(data))
|
||||
dataheader = struct.pack(">LL", mapping.get_type(msg), len(data))
|
||||
data = dataheader + data
|
||||
seq = -1
|
||||
|
||||
# Write it out
|
||||
while data:
|
||||
if seq < 0:
|
||||
repheader = struct.pack('>BL', 0x01, self.session)
|
||||
repheader = struct.pack(">BL", 0x01, self.session)
|
||||
else:
|
||||
repheader = struct.pack('>BLL', 0x02, self.session, seq)
|
||||
repheader = struct.pack(">BLL", 0x02, self.session, seq)
|
||||
datalen = REPLEN - len(repheader)
|
||||
chunk = repheader + data[:datalen]
|
||||
chunk = chunk.ljust(REPLEN, b'\x00')
|
||||
chunk = chunk.ljust(REPLEN, b"\x00")
|
||||
transport.write_chunk(chunk)
|
||||
data = data[datalen:]
|
||||
seq += 1
|
||||
|
||||
def read(self, transport: Transport) -> protobuf.MessageType:
|
||||
if not self.session:
|
||||
raise RuntimeError('Missing session for v2 protocol')
|
||||
raise RuntimeError("Missing session for v2 protocol")
|
||||
|
||||
# Read header with first part of message data
|
||||
chunk = transport.read_chunk()
|
||||
@ -100,40 +102,46 @@ class ProtocolV2:
|
||||
|
||||
# Parse to protobuf
|
||||
msg = protobuf.load_message(data, mapping.get_class(msg_type))
|
||||
LOG.debug("[session {}] received message: {}".format(self.session, msg.__class__.__name__),
|
||||
extra={'protobuf': msg})
|
||||
LOG.debug(
|
||||
"[session {}] received message: {}".format(
|
||||
self.session, msg.__class__.__name__
|
||||
),
|
||||
extra={"protobuf": msg},
|
||||
)
|
||||
return msg
|
||||
|
||||
def parse_first(self, chunk: bytes) -> Tuple[int, int, bytes]:
|
||||
try:
|
||||
headerlen = struct.calcsize('>BLLL')
|
||||
magic, session, msg_type, datalen = struct.unpack('>BLLL', chunk[:headerlen])
|
||||
headerlen = struct.calcsize(">BLLL")
|
||||
magic, session, msg_type, datalen = struct.unpack(
|
||||
">BLLL", chunk[:headerlen]
|
||||
)
|
||||
except Exception:
|
||||
raise RuntimeError('Cannot parse header')
|
||||
raise RuntimeError("Cannot parse header")
|
||||
if magic != 0x01:
|
||||
raise RuntimeError('Unexpected magic character')
|
||||
raise RuntimeError("Unexpected magic character")
|
||||
if session != self.session:
|
||||
raise RuntimeError('Session id mismatch')
|
||||
raise RuntimeError("Session id mismatch")
|
||||
return msg_type, datalen, chunk[headerlen:]
|
||||
|
||||
def parse_next(self, chunk: bytes) -> bytes:
|
||||
try:
|
||||
headerlen = struct.calcsize('>BLL')
|
||||
magic, session, sequence = struct.unpack('>BLL', chunk[:headerlen])
|
||||
headerlen = struct.calcsize(">BLL")
|
||||
magic, session, sequence = struct.unpack(">BLL", chunk[:headerlen])
|
||||
except Exception:
|
||||
raise RuntimeError('Cannot parse header')
|
||||
raise RuntimeError("Cannot parse header")
|
||||
if magic != 0x02:
|
||||
raise RuntimeError('Unexpected magic characters')
|
||||
raise RuntimeError("Unexpected magic characters")
|
||||
if session != self.session:
|
||||
raise RuntimeError('Session id mismatch')
|
||||
raise RuntimeError("Session id mismatch")
|
||||
return chunk[headerlen:]
|
||||
|
||||
def parse_session_open(self, chunk: bytes) -> int:
|
||||
try:
|
||||
headerlen = struct.calcsize('>BL')
|
||||
magic, session = struct.unpack('>BL', chunk[:headerlen])
|
||||
headerlen = struct.calcsize(">BL")
|
||||
magic, session = struct.unpack(">BL", chunk[:headerlen])
|
||||
except Exception:
|
||||
raise RuntimeError('Cannot parse header')
|
||||
raise RuntimeError("Cannot parse header")
|
||||
if magic != 0x03:
|
||||
raise RuntimeError('Unexpected magic character')
|
||||
raise RuntimeError("Unexpected magic character")
|
||||
return session
|
||||
|
@ -14,16 +14,35 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import sys
|
||||
import math
|
||||
import sys
|
||||
|
||||
try:
|
||||
from PyQt4.QtGui import (QPushButton, QLineEdit, QSizePolicy, QRegExpValidator, QLabel,
|
||||
QApplication, QWidget, QGridLayout, QVBoxLayout, QHBoxLayout)
|
||||
from PyQt4.QtGui import (
|
||||
QPushButton,
|
||||
QLineEdit,
|
||||
QSizePolicy,
|
||||
QRegExpValidator,
|
||||
QLabel,
|
||||
QApplication,
|
||||
QWidget,
|
||||
QGridLayout,
|
||||
QVBoxLayout,
|
||||
QHBoxLayout,
|
||||
)
|
||||
from PyQt4.QtCore import QObject, SIGNAL, QRegExp, Qt, QT_VERSION_STR
|
||||
except ImportError:
|
||||
from PyQt5.QtWidgets import (QPushButton, QLineEdit, QSizePolicy, QLabel,
|
||||
QApplication, QWidget, QGridLayout, QVBoxLayout, QHBoxLayout)
|
||||
from PyQt5.QtWidgets import (
|
||||
QPushButton,
|
||||
QLineEdit,
|
||||
QSizePolicy,
|
||||
QLabel,
|
||||
QApplication,
|
||||
QWidget,
|
||||
QGridLayout,
|
||||
QVBoxLayout,
|
||||
QHBoxLayout,
|
||||
)
|
||||
from PyQt5.QtGui import QRegExpValidator
|
||||
from PyQt5.QtCore import QRegExp, Qt
|
||||
from PyQt5.Qt import QT_VERSION_STR
|
||||
@ -31,16 +50,16 @@ except ImportError:
|
||||
|
||||
class PinButton(QPushButton):
|
||||
def __init__(self, password, encoded_value):
|
||||
super(PinButton, self).__init__('?')
|
||||
super(PinButton, self).__init__("?")
|
||||
self.password = password
|
||||
self.encoded_value = encoded_value
|
||||
|
||||
if QT_VERSION_STR >= '5':
|
||||
if QT_VERSION_STR >= "5":
|
||||
self.clicked.connect(self._pressed)
|
||||
elif QT_VERSION_STR >= '4':
|
||||
QObject.connect(self, SIGNAL('clicked()'), self._pressed)
|
||||
elif QT_VERSION_STR >= "4":
|
||||
QObject.connect(self, SIGNAL("clicked()"), self._pressed)
|
||||
else:
|
||||
raise RuntimeError('Unsupported Qt version')
|
||||
raise RuntimeError("Unsupported Qt version")
|
||||
|
||||
def _pressed(self):
|
||||
self.password.setText(self.password.text() + str(self.encoded_value))
|
||||
@ -48,26 +67,29 @@ class PinButton(QPushButton):
|
||||
|
||||
|
||||
class PinMatrixWidget(QWidget):
|
||||
'''
|
||||
"""
|
||||
Displays widget with nine blank buttons and password box.
|
||||
Encodes button clicks into sequence of numbers for passing
|
||||
into PinAck messages of TREZOR.
|
||||
|
||||
show_strength=True may be useful for entering new PIN
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self, show_strength=True, parent=None):
|
||||
super(PinMatrixWidget, self).__init__(parent)
|
||||
|
||||
self.password = QLineEdit()
|
||||
self.password.setValidator(QRegExpValidator(QRegExp('[1-9]+'), None))
|
||||
self.password.setValidator(QRegExpValidator(QRegExp("[1-9]+"), None))
|
||||
self.password.setEchoMode(QLineEdit.Password)
|
||||
|
||||
if QT_VERSION_STR >= '5':
|
||||
if QT_VERSION_STR >= "5":
|
||||
self.password.textChanged.connect(self._password_changed)
|
||||
elif QT_VERSION_STR >= '4':
|
||||
QObject.connect(self.password, SIGNAL('textChanged(QString)'), self._password_changed)
|
||||
elif QT_VERSION_STR >= "4":
|
||||
QObject.connect(
|
||||
self.password, SIGNAL("textChanged(QString)"), self._password_changed
|
||||
)
|
||||
else:
|
||||
raise RuntimeError('Unsupported Qt version')
|
||||
raise RuntimeError("Unsupported Qt version")
|
||||
|
||||
self.strength = QLabel()
|
||||
self.strength.setMinimumWidth(75)
|
||||
@ -95,16 +117,16 @@ class PinMatrixWidget(QWidget):
|
||||
|
||||
def _set_strength(self, strength):
|
||||
if strength < 3000:
|
||||
self.strength.setText('weak')
|
||||
self.strength.setText("weak")
|
||||
self.strength.setStyleSheet("QLabel { color : #d00; }")
|
||||
elif strength < 60000:
|
||||
self.strength.setText('fine')
|
||||
self.strength.setText("fine")
|
||||
self.strength.setStyleSheet("QLabel { color : #db0; }")
|
||||
elif strength < 360000:
|
||||
self.strength.setText('strong')
|
||||
self.strength.setText("strong")
|
||||
self.strength.setStyleSheet("QLabel { color : #0a0; }")
|
||||
else:
|
||||
self.strength.setText('ULTIMATE')
|
||||
self.strength.setText("ULTIMATE")
|
||||
self.strength.setStyleSheet("QLabel { color : #000; font-weight: bold;}")
|
||||
|
||||
def _password_changed(self, password):
|
||||
@ -119,10 +141,10 @@ class PinMatrixWidget(QWidget):
|
||||
return self.password.text()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
'''
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
Demo application showing PinMatrix widget in action
|
||||
'''
|
||||
"""
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
matrix = PinMatrixWidget()
|
||||
@ -132,13 +154,13 @@ if __name__ == '__main__':
|
||||
print("Possible button combinations:", matrix.get_strength())
|
||||
sys.exit()
|
||||
|
||||
ok = QPushButton('OK')
|
||||
if QT_VERSION_STR >= '5':
|
||||
ok = QPushButton("OK")
|
||||
if QT_VERSION_STR >= "5":
|
||||
ok.clicked.connect(clicked)
|
||||
elif QT_VERSION_STR >= '4':
|
||||
QObject.connect(ok, SIGNAL('clicked()'), clicked)
|
||||
elif QT_VERSION_STR >= "4":
|
||||
QObject.connect(ok, SIGNAL("clicked()"), clicked)
|
||||
else:
|
||||
raise RuntimeError('Unsupported Qt version')
|
||||
raise RuntimeError("Unsupported Qt version")
|
||||
|
||||
vbox = QVBoxLayout()
|
||||
vbox.addWidget(matrix)
|
||||
|
@ -18,12 +18,14 @@
|
||||
from . import messages
|
||||
from .tools import expect
|
||||
|
||||
REQUIRED_FIELDS = ("Fee", "Sequence", "TransactionType", "Amount", "Destination")
|
||||
|
||||
|
||||
@expect(messages.RippleAddress, field="address")
|
||||
def get_address(client, address_n, show_display=False):
|
||||
return client.call(
|
||||
messages.RippleGetAddress(
|
||||
address_n=address_n, show_display=show_display))
|
||||
messages.RippleGetAddress(address_n=address_n, show_display=show_display)
|
||||
)
|
||||
|
||||
|
||||
@expect(messages.RippleSignedTx)
|
||||
@ -33,8 +35,8 @@ def sign_tx(client, address_n, msg: messages.RippleSignTx):
|
||||
|
||||
|
||||
def create_sign_tx_msg(transaction) -> messages.RippleSignTx:
|
||||
if not all(transaction.get(k) for k in ("Fee", "Sequence", "TransactionType", "Amount", "Destination")):
|
||||
raise ValueError("Some of the required fields missing (Fee, Sequence, TransactionType, Amount, Destination")
|
||||
if not all(transaction.get(k) for k in REQUIRED_FIELDS):
|
||||
raise ValueError("Some of the required fields missing")
|
||||
if transaction["TransactionType"] != "Payment":
|
||||
raise ValueError("Only Payment transaction type is supported")
|
||||
|
||||
@ -49,6 +51,5 @@ def create_sign_tx_msg(transaction) -> messages.RippleSignTx:
|
||||
|
||||
def _create_payment(transaction) -> messages.RipplePayment:
|
||||
return messages.RipplePayment(
|
||||
amount=transaction.get("Amount"),
|
||||
destination=transaction.get("Destination")
|
||||
amount=transaction.get("Amount"), destination=transaction.get("Destination")
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ import struct
|
||||
import xdrlib
|
||||
|
||||
from . import messages
|
||||
from .tools import expect, CallException
|
||||
from .tools import CallException, expect
|
||||
|
||||
# Memo types
|
||||
MEMO_TYPE_NONE = 0
|
||||
@ -65,7 +65,7 @@ def address_from_public_key(pk_bytes):
|
||||
# checksum
|
||||
final_bytes.extend(struct.pack("<H", _crc16_checksum(final_bytes)))
|
||||
|
||||
return str(base64.b32encode(final_bytes), 'utf-8')
|
||||
return str(base64.b32encode(final_bytes), "utf-8")
|
||||
|
||||
|
||||
def address_to_public_key(address_str):
|
||||
@ -92,14 +92,21 @@ def parse_transaction_bytes(tx_bytes):
|
||||
|
||||
# Timebounds is an optional field
|
||||
if unpacker.unpack_bool():
|
||||
max_timebound = 2**32 - 1 # max unsigned 32-bit int (trezor does not support the full 64-bit time value)
|
||||
max_timebound = 2 ** 32 - 1 # max unsigned 32-bit int
|
||||
# (trezor does not support the full 64-bit time value)
|
||||
|
||||
tx.timebounds_start = unpacker.unpack_uhyper()
|
||||
tx.timebounds_end = unpacker.unpack_uhyper()
|
||||
|
||||
if tx.timebounds_start > max_timebound or tx.timebounds_start < 0:
|
||||
raise ValueError("Starting timebound out of range (must be between 0 and " + max_timebound)
|
||||
raise ValueError(
|
||||
"Starting timebound out of range (must be between 0 and "
|
||||
+ max_timebound
|
||||
)
|
||||
if tx.timebounds_end > max_timebound or tx.timebounds_end < 0:
|
||||
raise ValueError("Ending timebound out of range (must be between 0 and " + max_timebound)
|
||||
raise ValueError(
|
||||
"Ending timebound out of range (must be between 0 and " + max_timebound
|
||||
)
|
||||
|
||||
# memo type determines what optional fields are set
|
||||
tx.memo_type = unpacker.unpack_uint()
|
||||
@ -117,7 +124,7 @@ def parse_transaction_bytes(tx_bytes):
|
||||
tx.num_operations = unpacker.unpack_uint()
|
||||
|
||||
operations = []
|
||||
for i in range(tx.num_operations):
|
||||
for _ in range(tx.num_operations):
|
||||
operations.append(_parse_operation_bytes(unpacker))
|
||||
|
||||
return tx, operations
|
||||
@ -140,7 +147,7 @@ def _parse_operation_bytes(unpacker):
|
||||
return messages.StellarCreateAccountOp(
|
||||
source_account=source_account,
|
||||
new_account=_xdr_read_address(unpacker),
|
||||
starting_balance=unpacker.unpack_hyper()
|
||||
starting_balance=unpacker.unpack_hyper(),
|
||||
)
|
||||
|
||||
if type == OP_PAYMENT:
|
||||
@ -148,7 +155,7 @@ def _parse_operation_bytes(unpacker):
|
||||
source_account=source_account,
|
||||
destination_account=_xdr_read_address(unpacker),
|
||||
asset=_xdr_read_asset(unpacker),
|
||||
amount=unpacker.unpack_hyper()
|
||||
amount=unpacker.unpack_hyper(),
|
||||
)
|
||||
|
||||
if type == OP_PATH_PAYMENT:
|
||||
@ -159,11 +166,11 @@ def _parse_operation_bytes(unpacker):
|
||||
destination_account=_xdr_read_address(unpacker),
|
||||
destination_asset=_xdr_read_asset(unpacker),
|
||||
destination_amount=unpacker.unpack_hyper(),
|
||||
paths=[]
|
||||
paths=[],
|
||||
)
|
||||
|
||||
num_paths = unpacker.unpack_uint()
|
||||
for i in range(num_paths):
|
||||
for _ in range(num_paths):
|
||||
op.paths.append(_xdr_read_asset(unpacker))
|
||||
|
||||
return op
|
||||
@ -176,7 +183,7 @@ def _parse_operation_bytes(unpacker):
|
||||
amount=unpacker.unpack_hyper(),
|
||||
price_n=unpacker.unpack_uint(),
|
||||
price_d=unpacker.unpack_uint(),
|
||||
offer_id=unpacker.unpack_uhyper()
|
||||
offer_id=unpacker.unpack_uhyper(),
|
||||
)
|
||||
|
||||
if type == OP_CREATE_PASSIVE_OFFER:
|
||||
@ -186,13 +193,11 @@ def _parse_operation_bytes(unpacker):
|
||||
buying_asset=_xdr_read_asset(unpacker),
|
||||
amount=unpacker.unpack_hyper(),
|
||||
price_n=unpacker.unpack_uint(),
|
||||
price_d=unpacker.unpack_uint()
|
||||
price_d=unpacker.unpack_uint(),
|
||||
)
|
||||
|
||||
if type == OP_SET_OPTIONS:
|
||||
op = messages.StellarSetOptionsOp(
|
||||
source_account=source_account
|
||||
)
|
||||
op = messages.StellarSetOptionsOp(source_account=source_account)
|
||||
|
||||
# Inflation destination
|
||||
if unpacker.unpack_bool():
|
||||
@ -238,14 +243,14 @@ def _parse_operation_bytes(unpacker):
|
||||
return messages.StellarChangeTrustOp(
|
||||
source_account=source_account,
|
||||
asset=_xdr_read_asset(unpacker),
|
||||
limit=unpacker.unpack_uhyper()
|
||||
limit=unpacker.unpack_uhyper(),
|
||||
)
|
||||
|
||||
if type == OP_ALLOW_TRUST:
|
||||
op = messages.StellarAllowTrustOp(
|
||||
source_account=source_account,
|
||||
trusted_account=_xdr_read_address(unpacker),
|
||||
asset_type=unpacker.unpack_uint()
|
||||
asset_type=unpacker.unpack_uint(),
|
||||
)
|
||||
|
||||
if op.asset_type == ASSET_TYPE_ALPHA4:
|
||||
@ -260,15 +265,14 @@ def _parse_operation_bytes(unpacker):
|
||||
if type == OP_ACCOUNT_MERGE:
|
||||
return messages.StellarAccountMergeOp(
|
||||
source_account=source_account,
|
||||
destination_account=_xdr_read_address(unpacker)
|
||||
destination_account=_xdr_read_address(unpacker),
|
||||
)
|
||||
|
||||
# Inflation is not implemented since anyone can submit this operation to the network
|
||||
|
||||
if type == OP_MANAGE_DATA:
|
||||
op = messages.StellarManageDataOp(
|
||||
source_account=source_account,
|
||||
key=unpacker.unpack_string(),
|
||||
source_account=source_account, key=unpacker.unpack_string()
|
||||
)
|
||||
|
||||
# Only set value if the field is present
|
||||
@ -281,8 +285,7 @@ def _parse_operation_bytes(unpacker):
|
||||
# see: https://github.com/stellar/stellar-core/blob/master/src/xdr/Stellar-transaction.x#L269
|
||||
if type == OP_BUMP_SEQUENCE:
|
||||
return messages.StellarBumpSequenceOp(
|
||||
source_account=source_account,
|
||||
bump_to=unpacker.unpack_uhyper()
|
||||
source_account=source_account, bump_to=unpacker.unpack_uhyper()
|
||||
)
|
||||
|
||||
raise ValueError("Unknown operation type: " + str(type))
|
||||
@ -290,9 +293,7 @@ def _parse_operation_bytes(unpacker):
|
||||
|
||||
def _xdr_read_asset(unpacker):
|
||||
"""Reads a stellar Asset from unpacker"""
|
||||
asset = messages.StellarAssetType(
|
||||
type=unpacker.unpack_uint()
|
||||
)
|
||||
asset = messages.StellarAssetType(type=unpacker.unpack_uint())
|
||||
|
||||
if asset.type == ASSET_TYPE_ALPHA4:
|
||||
asset.code = unpacker.unpack_fstring(4)
|
||||
@ -329,8 +330,8 @@ def _crc16_checksum(bytes):
|
||||
|
||||
for byte in bytes:
|
||||
for i in range(8):
|
||||
bit = ((byte >> (7 - i) & 1) == 1)
|
||||
c15 = ((crc >> 15 & 1) == 1)
|
||||
bit = (byte >> (7 - i) & 1) == 1
|
||||
c15 = (crc >> 15 & 1) == 1
|
||||
crc <<= 1
|
||||
if c15 ^ bit:
|
||||
crc ^= polynomial
|
||||
@ -343,15 +344,21 @@ def _crc16_checksum(bytes):
|
||||
|
||||
@expect(messages.StellarPublicKey, field="public_key")
|
||||
def get_public_key(client, address_n, show_display=False):
|
||||
return client.call(messages.StellarGetPublicKey(address_n=address_n, show_display=show_display))
|
||||
return client.call(
|
||||
messages.StellarGetPublicKey(address_n=address_n, show_display=show_display)
|
||||
)
|
||||
|
||||
|
||||
@expect(messages.StellarAddress, field="address")
|
||||
def get_address(client, address_n, show_display=False):
|
||||
return client.call(messages.StellarGetAddress(address_n=address_n, show_display=show_display))
|
||||
return client.call(
|
||||
messages.StellarGetAddress(address_n=address_n, show_display=show_display)
|
||||
)
|
||||
|
||||
|
||||
def sign_tx(client, tx, operations, address_n, network_passphrase=DEFAULT_NETWORK_PASSPHRASE):
|
||||
def sign_tx(
|
||||
client, tx, operations, address_n, network_passphrase=DEFAULT_NETWORK_PASSPHRASE
|
||||
):
|
||||
tx.network_passphrase = network_passphrase
|
||||
tx.address_n = address_n
|
||||
tx.num_operations = len(operations)
|
||||
@ -368,14 +375,18 @@ def sign_tx(client, tx, operations, address_n, network_passphrase=DEFAULT_NETWOR
|
||||
resp = client.call(operations.pop(0))
|
||||
except IndexError:
|
||||
# pop from empty list
|
||||
raise CallException("Stellar.UnexpectedEndOfOperations",
|
||||
"Reached end of operations without a signature.") from None
|
||||
raise CallException(
|
||||
"Stellar.UnexpectedEndOfOperations",
|
||||
"Reached end of operations without a signature.",
|
||||
) from None
|
||||
|
||||
if not isinstance(resp, messages.StellarSignedTx):
|
||||
raise CallException(messages.FailureType.UnexpectedMessage, resp)
|
||||
|
||||
if operations:
|
||||
raise CallException("Stellar.UnprocessedOperations",
|
||||
"Received a signature before processing all operations.")
|
||||
raise CallException(
|
||||
"Stellar.UnprocessedOperations",
|
||||
"Received a signature before processing all operations.",
|
||||
)
|
||||
|
||||
return resp
|
||||
|
@ -16,35 +16,34 @@
|
||||
|
||||
import os
|
||||
|
||||
from trezorlib import coins, debuglink, device, tx_api
|
||||
from trezorlib.client import TrezorClientDebugLink
|
||||
|
||||
from . import conftest
|
||||
|
||||
from trezorlib import coins
|
||||
from trezorlib import tx_api
|
||||
from trezorlib.client import TrezorClientDebugLink
|
||||
from trezorlib import debuglink
|
||||
from trezorlib import device
|
||||
|
||||
tests_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
tx_api.cache_dir = os.path.join(tests_dir, '../txcache')
|
||||
tx_api.cache_dir = os.path.join(tests_dir, "../txcache")
|
||||
|
||||
|
||||
class TrezorTest:
|
||||
# fmt: off
|
||||
# 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
mnemonic12 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
|
||||
mnemonic18 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
|
||||
mnemonic24 = 'dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic'
|
||||
mnemonic_all = ' '.join(['all'] * 12)
|
||||
mnemonic12 = "alcohol woman abuse must during monitor noble actual mixed trade anger aisle"
|
||||
mnemonic18 = "owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel"
|
||||
mnemonic24 = "dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic"
|
||||
mnemonic_all = " ".join(["all"] * 12)
|
||||
# fmt: on
|
||||
|
||||
pin4 = '1234'
|
||||
pin6 = '789456'
|
||||
pin8 = '45678978'
|
||||
pin4 = "1234"
|
||||
pin6 = "789456"
|
||||
pin8 = "45678978"
|
||||
|
||||
def setup_method(self, method):
|
||||
wirelink = conftest.get_device()
|
||||
debuglink = wirelink.find_debug()
|
||||
self.client = TrezorClientDebugLink(wirelink)
|
||||
self.client.set_debuglink(debuglink)
|
||||
self.client.set_tx_api(coins.tx_api['Bitcoin'])
|
||||
self.client.set_tx_api(coins.tx_api["Bitcoin"])
|
||||
# self.client.set_buttonwait(3)
|
||||
|
||||
device.wipe(self.client)
|
||||
@ -54,7 +53,7 @@ class TrezorTest:
|
||||
self.client.transport.session_end()
|
||||
self.client.close()
|
||||
|
||||
def _setup_mnemonic(self, mnemonic=None, pin='', passphrase=False):
|
||||
def _setup_mnemonic(self, mnemonic=None, pin="", passphrase=False):
|
||||
if mnemonic is None:
|
||||
mnemonic = TrezorTest.mnemonic12
|
||||
debuglink.load_device_by_mnemonic(
|
||||
@ -83,10 +82,10 @@ class TrezorTest:
|
||||
|
||||
|
||||
def generate_entropy(strength, internal_entropy, external_entropy):
|
||||
'''
|
||||
"""
|
||||
strength - length of produced seed. One of 128, 192, 256
|
||||
random - binary stream of random data from external HRNG
|
||||
'''
|
||||
"""
|
||||
import hashlib
|
||||
|
||||
if strength not in (128, 192, 256):
|
||||
|
@ -24,7 +24,7 @@ from trezorlib import log, coins
|
||||
|
||||
|
||||
def get_device():
|
||||
path = os.environ.get('TREZOR_PATH')
|
||||
path = os.environ.get("TREZOR_PATH")
|
||||
return get_transport(path)
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ def client():
|
||||
debuglink = wirelink.find_debug()
|
||||
client = TrezorClientDebugLink(wirelink)
|
||||
client.set_debuglink(debuglink)
|
||||
client.set_tx_api(coins.tx_api['Bitcoin'])
|
||||
client.set_tx_api(coins.tx_api["Bitcoin"])
|
||||
client.wipe_device()
|
||||
client.transport.session_begin()
|
||||
|
||||
@ -62,29 +62,41 @@ def client():
|
||||
client.close()
|
||||
|
||||
|
||||
def setup_client(mnemonic=None, pin='', passphrase=False):
|
||||
def setup_client(mnemonic=None, pin="", passphrase=False):
|
||||
if mnemonic is None:
|
||||
mnemonic = ' '.join(['all'] * 12)
|
||||
mnemonic = " ".join(["all"] * 12)
|
||||
if pin is True:
|
||||
pin = '1234'
|
||||
pin = "1234"
|
||||
|
||||
def client_decorator(function):
|
||||
@functools.wraps(function)
|
||||
def wrapper(client, *args, **kwargs):
|
||||
client.load_device_by_mnemonic(mnemonic=mnemonic, pin=pin, passphrase_protection=passphrase, label='test', language='english')
|
||||
client.load_device_by_mnemonic(
|
||||
mnemonic=mnemonic,
|
||||
pin=pin,
|
||||
passphrase_protection=passphrase,
|
||||
label="test",
|
||||
language="english",
|
||||
)
|
||||
return function(client, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return client_decorator
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
if config.getoption('verbose'):
|
||||
if config.getoption("verbose"):
|
||||
log.enable_debug_output()
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addini("run_xfail", "List of markers that will run even if marked as xfail", "args", [])
|
||||
parser.addini(
|
||||
"run_xfail",
|
||||
"List of markers that will run even tests that are marked as xfail",
|
||||
"args",
|
||||
[],
|
||||
)
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
@ -105,7 +117,8 @@ def pytest_runtest_setup(item):
|
||||
pytest.skip("Test excluded on Trezor 1")
|
||||
|
||||
xfail = item.get_marker("xfail")
|
||||
run_xfail = any(item.get_marker(marker) for marker in item.config.getini("run_xfail"))
|
||||
runxfail_markers = item.config.getini("run_xfail")
|
||||
run_xfail = any(item.get_marker(marker) for marker in runxfail_markers)
|
||||
if xfail and run_xfail:
|
||||
# Deep hack: pytest's private _evalxfail helper determines whether the test should xfail or not.
|
||||
# The helper caches its result even before this hook runs.
|
||||
|
@ -14,22 +14,20 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import device, messages
|
||||
|
||||
from trezorlib import messages
|
||||
from trezorlib import device
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestBasic(TrezorTest):
|
||||
|
||||
def test_features(self):
|
||||
f0 = self.client.features
|
||||
f1 = self.client.call(messages.Initialize())
|
||||
assert f0 == f1
|
||||
|
||||
def test_ping(self):
|
||||
ping = self.client.call(messages.Ping(message='ahoj!'))
|
||||
assert ping == messages.Success(message='ahoj!')
|
||||
ping = self.client.call(messages.Ping(message="ahoj!"))
|
||||
assert ping == messages.Success(message="ahoj!")
|
||||
|
||||
def test_device_id_same(self):
|
||||
id1 = self.client.get_device_id()
|
||||
|
@ -15,24 +15,24 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc
|
||||
from trezorlib.tools import H_
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib.tools import H_
|
||||
from trezorlib import btc
|
||||
|
||||
|
||||
class TestBip32Speed(TrezorTest):
|
||||
|
||||
def test_public_ckd(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
btc.get_address(self.client, 'Bitcoin', []) # to compute root node via BIP39
|
||||
btc.get_address(self.client, "Bitcoin", []) # to compute root node via BIP39
|
||||
|
||||
for depth in range(8):
|
||||
start = time.time()
|
||||
btc.get_address(self.client, 'Bitcoin', range(depth))
|
||||
btc.get_address(self.client, "Bitcoin", range(depth))
|
||||
delay = time.time() - start
|
||||
expected = (depth + 1) * 0.26
|
||||
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
|
||||
@ -41,12 +41,12 @@ class TestBip32Speed(TrezorTest):
|
||||
def test_private_ckd(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
btc.get_address(self.client, 'Bitcoin', []) # to compute root node via BIP39
|
||||
btc.get_address(self.client, "Bitcoin", []) # to compute root node via BIP39
|
||||
|
||||
for depth in range(8):
|
||||
start = time.time()
|
||||
address_n = [H_(-i) for i in range(-depth, 0)]
|
||||
btc.get_address(self.client, 'Bitcoin', address_n)
|
||||
btc.get_address(self.client, "Bitcoin", address_n)
|
||||
delay = time.time() - start
|
||||
expected = (depth + 1) * 0.26
|
||||
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
|
||||
@ -58,12 +58,12 @@ class TestBip32Speed(TrezorTest):
|
||||
|
||||
start = time.time()
|
||||
for x in range(10):
|
||||
btc.get_address(self.client, 'Bitcoin', [x, 2, 3, 4, 5, 6, 7, 8])
|
||||
btc.get_address(self.client, "Bitcoin", [x, 2, 3, 4, 5, 6, 7, 8])
|
||||
nocache_time = time.time() - start
|
||||
|
||||
start = time.time()
|
||||
for x in range(10):
|
||||
btc.get_address(self.client, 'Bitcoin', [1, 2, 3, 4, 5, 6, 7, x])
|
||||
btc.get_address(self.client, "Bitcoin", [1, 2, 3, 4, 5, 6, 7, x])
|
||||
cache_time = time.time() - start
|
||||
|
||||
print("NOCACHE TIME", nocache_time)
|
||||
|
@ -16,20 +16,24 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .conftest import setup_client
|
||||
import trezorlib.messages as m
|
||||
|
||||
from .conftest import setup_client
|
||||
|
||||
|
||||
@setup_client()
|
||||
@pytest.mark.parametrize("message", [
|
||||
@pytest.mark.parametrize(
|
||||
"message",
|
||||
[
|
||||
m.Ping(message="hello", button_protection=True),
|
||||
m.GetAddress(
|
||||
address_n=[0],
|
||||
coin_name="Bitcoin",
|
||||
script_type=m.InputScriptType.SPENDADDRESS,
|
||||
show_display=True
|
||||
show_display=True,
|
||||
),
|
||||
])
|
||||
],
|
||||
)
|
||||
def test_cancel_message_via_cancel(client, message):
|
||||
resp = client.call_raw(message)
|
||||
assert isinstance(resp, m.ButtonRequest)
|
||||
@ -44,15 +48,18 @@ def test_cancel_message_via_cancel(client, message):
|
||||
|
||||
|
||||
@setup_client()
|
||||
@pytest.mark.parametrize("message", [
|
||||
@pytest.mark.parametrize(
|
||||
"message",
|
||||
[
|
||||
m.Ping(message="hello", button_protection=True),
|
||||
m.GetAddress(
|
||||
address_n=[0],
|
||||
coin_name="Bitcoin",
|
||||
script_type=m.InputScriptType.SPENDADDRESS,
|
||||
show_display=True
|
||||
show_display=True,
|
||||
),
|
||||
])
|
||||
],
|
||||
)
|
||||
def test_cancel_message_via_initialize(client, message):
|
||||
resp = client.call_raw(message)
|
||||
assert isinstance(resp, m.ButtonRequest)
|
||||
|
@ -14,22 +14,22 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
from hashlib import sha256
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import cosi
|
||||
import pytest
|
||||
|
||||
from trezorlib import cosi
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestCosi(TrezorTest):
|
||||
|
||||
def test_cosi_commit(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
digest = sha256(b'this is a message').digest()
|
||||
digest = sha256(b"this is a message").digest()
|
||||
|
||||
c0 = cosi.commit(self.client, parse_path("10018'/0'"), digest)
|
||||
c1 = cosi.commit(self.client, parse_path("10018'/1'"), digest)
|
||||
@ -43,7 +43,7 @@ class TestCosi(TrezorTest):
|
||||
assert c0.commitment != c2.commitment
|
||||
assert c1.commitment != c2.commitment
|
||||
|
||||
digestb = sha256(b'this is a different message').digest()
|
||||
digestb = sha256(b"this is a different message").digest()
|
||||
|
||||
c0b = cosi.commit(self.client, parse_path("10018'/0'"), digestb)
|
||||
c1b = cosi.commit(self.client, parse_path("10018'/1'"), digestb)
|
||||
@ -60,7 +60,7 @@ class TestCosi(TrezorTest):
|
||||
def test_cosi_sign(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
digest = sha256(b'this is a message').digest()
|
||||
digest = sha256(b"this is a message").digest()
|
||||
|
||||
c0 = cosi.commit(self.client, parse_path("10018'/0'"), digest)
|
||||
c1 = cosi.commit(self.client, parse_path("10018'/1'"), digest)
|
||||
@ -69,29 +69,37 @@ class TestCosi(TrezorTest):
|
||||
global_pk = cosi.combine_keys([c0.pubkey, c1.pubkey, c2.pubkey])
|
||||
global_R = cosi.combine_keys([c0.commitment, c1.commitment, c2.commitment])
|
||||
|
||||
# fmt: off
|
||||
sig0 = cosi.sign(self.client, parse_path("10018'/0'"), digest, global_R, global_pk)
|
||||
sig1 = cosi.sign(self.client, parse_path("10018'/1'"), digest, global_R, global_pk)
|
||||
sig2 = cosi.sign(self.client, parse_path("10018'/2'"), digest, global_R, global_pk)
|
||||
# fmt: on
|
||||
|
||||
sig = cosi.combine_sig(global_R, [sig0.signature, sig1.signature, sig2.signature])
|
||||
sig = cosi.combine_sig(
|
||||
global_R, [sig0.signature, sig1.signature, sig2.signature]
|
||||
)
|
||||
|
||||
cosi.verify(sig, digest, global_pk)
|
||||
|
||||
def test_cosi_compat(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
digest = sha256(b'this is not a pipe').digest()
|
||||
digest = sha256(b"this is not a pipe").digest()
|
||||
remote_commit = cosi.commit(self.client, parse_path("10018'/0'"), digest)
|
||||
|
||||
local_privkey = sha256(b'private key').digest()[:32]
|
||||
local_privkey = sha256(b"private key").digest()[:32]
|
||||
local_pubkey = cosi.pubkey_from_privkey(local_privkey)
|
||||
local_nonce, local_commitment = cosi.get_nonce(local_privkey, digest, 42)
|
||||
|
||||
global_pk = cosi.combine_keys([remote_commit.pubkey, local_pubkey])
|
||||
global_R = cosi.combine_keys([remote_commit.commitment, local_commitment])
|
||||
|
||||
remote_sig = cosi.sign(self.client, parse_path("10018'/0'"), digest, global_R, global_pk)
|
||||
local_sig = cosi.sign_with_privkey(digest, local_privkey, global_pk, local_nonce, global_R)
|
||||
remote_sig = cosi.sign(
|
||||
self.client, parse_path("10018'/0'"), digest, global_R, global_pk
|
||||
)
|
||||
local_sig = cosi.sign_with_privkey(
|
||||
digest, local_privkey, global_pk, local_nonce, global_R
|
||||
)
|
||||
sig = cosi.combine_sig(global_R, [remote_sig.signature, local_sig])
|
||||
|
||||
cosi.verify(sig, digest, global_pk)
|
||||
|
@ -16,13 +16,13 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestDebuglink(TrezorTest):
|
||||
|
||||
def test_layout(self):
|
||||
layout = self.client.debug.read_layout()
|
||||
assert len(layout) == 1024
|
||||
@ -36,12 +36,12 @@ class TestDebuglink(TrezorTest):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
# Manually trigger PinMatrixRequest
|
||||
resp = self.client.call_raw(proto.Ping(message='test', pin_protection=True))
|
||||
resp = self.client.call_raw(proto.Ping(message="test", pin_protection=True))
|
||||
assert isinstance(resp, proto.PinMatrixRequest)
|
||||
|
||||
pin = self.client.debug.read_pin()
|
||||
assert pin[0] == '1234'
|
||||
assert pin[1] != ''
|
||||
assert pin[0] == "1234"
|
||||
assert pin[1] != ""
|
||||
|
||||
pin_encoded = self.client.debug.read_pin_encoded()
|
||||
resp = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
@ -14,45 +14,52 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import device, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
import time
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import device
|
||||
|
||||
|
||||
class TestMsgApplysettings(TrezorTest):
|
||||
|
||||
def test_apply_settings(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
assert self.client.features.label == 'test'
|
||||
assert self.client.features.label == "test"
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
proto.Features(),
|
||||
]
|
||||
)
|
||||
if self.client.features.major_version >= 2:
|
||||
self.client.expected_responses.pop(0) # skip PinMatrixRequest
|
||||
device.apply_settings(self.client, label='new label')
|
||||
device.apply_settings(self.client, label="new label")
|
||||
|
||||
assert self.client.features.label == 'new label'
|
||||
assert self.client.features.label == "new label"
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_invalid_language(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
assert self.client.features.language == 'english'
|
||||
assert self.client.features.language == "english"
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
device.apply_settings(self.client, language='nonexistent')
|
||||
proto.Features(),
|
||||
]
|
||||
)
|
||||
device.apply_settings(self.client, language="nonexistent")
|
||||
|
||||
assert self.client.features.language == 'english'
|
||||
assert self.client.features.language == "english"
|
||||
|
||||
def test_apply_settings_passphrase(self):
|
||||
self.setup_mnemonic_pin_nopassphrase()
|
||||
@ -60,10 +67,14 @@ class TestMsgApplysettings(TrezorTest):
|
||||
assert self.client.features.passphrase_protection is False
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
proto.Features(),
|
||||
]
|
||||
)
|
||||
if self.client.features.major_version >= 2:
|
||||
self.client.expected_responses.pop(0) # skip PinMatrixRequest
|
||||
device.apply_settings(self.client, use_passphrase=True)
|
||||
@ -71,17 +82,17 @@ class TestMsgApplysettings(TrezorTest):
|
||||
assert self.client.features.passphrase_protection is True
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest(), proto.Success(), proto.Features()]
|
||||
)
|
||||
device.apply_settings(self.client, use_passphrase=False)
|
||||
|
||||
assert self.client.features.passphrase_protection is False
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest(), proto.Success(), proto.Features()]
|
||||
)
|
||||
device.apply_settings(self.client, use_passphrase=True)
|
||||
|
||||
assert self.client.features.passphrase_protection is True
|
||||
@ -93,10 +104,14 @@ class TestMsgApplysettings(TrezorTest):
|
||||
img = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x04\x88\x02\x00\x00\x00\x02\x91\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x90@\x00\x11@\x00\x00\x00\x00\x00\x00\x08\x00\x10\x92\x12\x04\x00\x00\x05\x12D\x00\x00\x00\x00\x00 \x00\x00\x08\x00Q\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x10\x02 \x01\x04J\x00)$\x00\x00\x00\x00\x80\x00\x00\x00\x00\x08\x10\xa1\x00\x00\x02\x81 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\tP\x00\x00\x00\x00\x00\x00 \x00\x00\xa0\x00\xa0R \x12\x84\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x08\x00\tP\x00\x00\x00\x00 \x00\x04 \x00\x80\x02\x00@\x02T\xc2 \x00\x00\x00\x00\x00\x00\x00\x10@\x00)\t@\n\xa0\x80\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x80@\x14\xa9H\x04\x00\x00\x88@\x00\x00\x00\x00\x00\x02\x02$\x00\x15B@\x00\nP\x00\x00\x00\x00\x00\x80\x00\x00\x91\x01UP\x00\x00 \x02\x00\x00\x00\x00\x00\x00\x02\x08@ Z\xa5 \x00\x00\x80\x00\x00\x00\x00\x00\x00\x08\xa1%\x14*\xa0\x00\x00\x02\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xaa\x91 \x00\x05E\x80\x00\x00\x00\x00\x00\x02*T\x05-D\x00\x00\x05 @\x00\x00\x00\x00\x00%@\x80\x11V\xa0\x88\x00\x05@\xb0\x00\x00\x00\x00\x00\x818$\x04\xabD \x00\x06\xa1T\x00\x00\x00\x00\x02\x03\xb8\x01R\xd5\x01\x00\x00\x05AP\x00\x00\x00\x00\x08\xadT\x00\x05j\xa4@\x00\x87ah\x00\x00\x00\x00\x02\x8d\xb8\x08\x00.\x01\x00\x00\x02\xa5\xa8\x10\x00\x00\x00*\xc1\xec \n\xaa\x88 \x02@\xf6\xd0\x02\x00\x00\x00\x0bB\xb6\x14@U"\x80\x00\x01{`\x00\x00\x00\x00M\xa3\xf8 \x15*\x00\x00\x00\x10n\xc0\x04\x00\x00\x02\x06\xc2\xa8)\x00\x96\x84\x80\x00\x00\x1b\x00\x00\x80@\x10\x87\xa7\xf0\x84\x10\xaa\x10\x00\x00D\x00\x00\x02 \x00\x8a\x06\xfa\xe0P\n-\x02@\x00\x12\x00\x00\x00\x00\x10@\x83\xdf\xa0\x00\x08\xaa@\x00\x00\x01H\x00\x05H\x04\x12\x01\xf7\x81P\x02T\t\x00\x00\x00 \x00\x00\x84\x10\x00\x00z\x00@)* \x00\x00\x01\n\xa0\x02 \x05\n\x00\x00\x05\x10\x84\xa8\x84\x80\x00\x00@\x14\x00\x92\x10\x80\x00\x04\x11@\tT\x00\x00\x00\x00\n@\x00\x08\x84@$\x00H\x00\x12Q\x02\x00\x00\x00\x00\x90\x02A\x12\xa8\n\xaa\x92\x10\x04\xa8\x10@\x00\x00\x04\x04\x00\x04I\x00\x04\x14H\x80"R\x01\x00\x00\x00!@\x00\x00$\xa0EB\x80\x08\x95hH\x00\x00\x00\x84\x10 \x05Z\x00\x00(\x00\x02\x00\xa1\x01\x00\x00\x04\x00@\x82\x00\xadH*\x92P\x00\xaaP\x00\x00\x00\x00\x11\x02\x01*\xad\x01\x00\x01\x01"\x11D\x08\x00\x00\x10\x80 \x00\x81W\x80J\x94\x04\x08\xa5 !\x00\x00\x00\x02\x00B*\xae\xa1\x00\x80\x10\x01\x08\xa4\x00\x00\x00\x00\x00\x84\x00\t[@"HA\x04E\x00\x84\x00\x00\x00\x10\x00\x01J\xd5\x82\x90\x02\x00!\x02\xa2\x00\x00\x00\x00\x00\x00\x00\x05~\xa0\x00 \x10\n)\x00\x11\x00\x00\x00\x00\x00\x00!U\x80\xa8\x88\x82\x80\x01\x00\x00\x00\x00\x00\x00H@\x11\xaa\xc0\x82\x00 *\n\x00\x00\x00\x00\x00\x00\x00\x00\n\xabb@ \x04\x00! \x84\x00\x00\x00\x00\x02@\xa5\x15A$\x04\x81(\n\x00\x00\x00\x00\x00\x00 \x01\x10\x02\xe0\x91\x02\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01 \xa9\tQH@\x91 P\x00\x00\x00\x00\x00\x00\x08\x00\x00\xa0T\xa5\x00@\x80\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00 T\xa0\t\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00@\x02\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10\x00\x00\x10\x02\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00@\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x08@\x10\x00\x00\x00\x00'
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
proto.Features(),
|
||||
]
|
||||
)
|
||||
device.apply_settings(self.client, homescreen=img)
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
@ -104,23 +119,28 @@ class TestMsgApplysettings(TrezorTest):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
proto.Features(),
|
||||
]
|
||||
)
|
||||
device.apply_settings(self.client, auto_lock_delay_ms=int(10e3)) # 10 secs
|
||||
|
||||
time.sleep(0.1) # sleep less than auto-lock delay
|
||||
with self.client:
|
||||
# No PIN protection is required.
|
||||
self.client.set_expected_responses([proto.Success()])
|
||||
self.client.ping(msg='', pin_protection=True)
|
||||
self.client.ping(msg="", pin_protection=True)
|
||||
|
||||
time.sleep(10.1) # sleep more than auto-lock delay
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
proto.Success()])
|
||||
self.client.ping(msg='', pin_protection=True)
|
||||
self.client.set_expected_responses(
|
||||
[proto.PinMatrixRequest(), proto.Success()]
|
||||
)
|
||||
self.client.ping(msg="", pin_protection=True)
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_apply_minimal_auto_lock_delay(self):
|
||||
@ -131,10 +151,14 @@ class TestMsgApplysettings(TrezorTest):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
proto.Features(),
|
||||
]
|
||||
)
|
||||
# Note: the actual delay will be 10 secs (see above).
|
||||
device.apply_settings(self.client, auto_lock_delay_ms=int(1e3))
|
||||
|
||||
@ -142,16 +166,17 @@ class TestMsgApplysettings(TrezorTest):
|
||||
with self.client:
|
||||
# No PIN protection is required.
|
||||
self.client.set_expected_responses([proto.Success()])
|
||||
self.client.ping(msg='', pin_protection=True)
|
||||
self.client.ping(msg="", pin_protection=True)
|
||||
|
||||
time.sleep(2) # sleep less than the minimal auto-lock delay
|
||||
with self.client:
|
||||
# No PIN protection is required.
|
||||
self.client.set_expected_responses([proto.Success()])
|
||||
self.client.ping(msg='', pin_protection=True)
|
||||
self.client.ping(msg="", pin_protection=True)
|
||||
|
||||
time.sleep(10.1) # sleep more than the minimal auto-lock delay
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(),
|
||||
proto.Success()])
|
||||
self.client.ping(msg='', pin_protection=True)
|
||||
self.client.set_expected_responses(
|
||||
[proto.PinMatrixRequest(), proto.Success()]
|
||||
)
|
||||
self.client.ping(msg="", pin_protection=True)
|
||||
|
@ -16,14 +16,13 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgChangepin(TrezorTest):
|
||||
|
||||
def test_set_pin(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
features = self.client.call_raw(proto.Initialize())
|
||||
@ -206,7 +205,7 @@ class TestMsgChangepin(TrezorTest):
|
||||
|
||||
# Send the PIN for second time, but with typo
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
pin_encoded = self.client.debug.encode_pin(self.pin6 + '3')
|
||||
pin_encoded = self.client.debug.encode_pin(self.pin6 + "3")
|
||||
ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
# Now it should fail, because pins are different
|
||||
|
@ -15,69 +15,173 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import misc
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgCipherkeyvalue(TrezorTest):
|
||||
|
||||
def test_encrypt(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
# different ask values
|
||||
res = misc.encrypt_keyvalue(self.client, [0, 1, 2], b"test", b"testing message!", ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert hexlify(res) == b'676faf8f13272af601776bc31bc14e8f'
|
||||
res = misc.encrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert hexlify(res) == b"676faf8f13272af601776bc31bc14e8f"
|
||||
|
||||
res = misc.encrypt_keyvalue(self.client, [0, 1, 2], b"test", b"testing message!", ask_on_encrypt=True, ask_on_decrypt=False)
|
||||
assert hexlify(res) == b'5aa0fbcb9d7fa669880745479d80c622'
|
||||
res = misc.encrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert hexlify(res) == b"5aa0fbcb9d7fa669880745479d80c622"
|
||||
|
||||
res = misc.encrypt_keyvalue(self.client, [0, 1, 2], b"test", b"testing message!", ask_on_encrypt=False, ask_on_decrypt=True)
|
||||
assert hexlify(res) == b'958d4f63269b61044aaedc900c8d6208'
|
||||
res = misc.encrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert hexlify(res) == b"958d4f63269b61044aaedc900c8d6208"
|
||||
|
||||
res = misc.encrypt_keyvalue(self.client, [0, 1, 2], b"test", b"testing message!", ask_on_encrypt=False, ask_on_decrypt=False)
|
||||
assert hexlify(res) == b'e0cf0eb0425947000eb546cc3994bc6c'
|
||||
res = misc.encrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert hexlify(res) == b"e0cf0eb0425947000eb546cc3994bc6c"
|
||||
|
||||
# different key
|
||||
res = misc.encrypt_keyvalue(self.client, [0, 1, 2], b"test2", b"testing message!", ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert hexlify(res) == b'de247a6aa6be77a134bb3f3f925f13af'
|
||||
res = misc.encrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test2",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert hexlify(res) == b"de247a6aa6be77a134bb3f3f925f13af"
|
||||
|
||||
# different message
|
||||
res = misc.encrypt_keyvalue(self.client, [0, 1, 2], b"test", b"testing message! it is different", ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert hexlify(res) == b'676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d'
|
||||
res = misc.encrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
b"testing message! it is different",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert (
|
||||
hexlify(res)
|
||||
== b"676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"
|
||||
)
|
||||
|
||||
# different path
|
||||
res = misc.encrypt_keyvalue(self.client, [0, 1, 3], b"test", b"testing message!", ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert hexlify(res) == b'b4811a9d492f5355a5186ddbfccaae7b'
|
||||
res = misc.encrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 3],
|
||||
b"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert hexlify(res) == b"b4811a9d492f5355a5186ddbfccaae7b"
|
||||
|
||||
def test_decrypt(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
# different ask values
|
||||
res = misc.decrypt_keyvalue(self.client, [0, 1, 2], b"test", unhexlify("676faf8f13272af601776bc31bc14e8f"), ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert res == b'testing message!'
|
||||
res = misc.decrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
unhexlify("676faf8f13272af601776bc31bc14e8f"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
res = misc.decrypt_keyvalue(self.client, [0, 1, 2], b"test", unhexlify("5aa0fbcb9d7fa669880745479d80c622"), ask_on_encrypt=True, ask_on_decrypt=False)
|
||||
assert res == b'testing message!'
|
||||
res = misc.decrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
unhexlify("5aa0fbcb9d7fa669880745479d80c622"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
res = misc.decrypt_keyvalue(self.client, [0, 1, 2], b"test", unhexlify("958d4f63269b61044aaedc900c8d6208"), ask_on_encrypt=False, ask_on_decrypt=True)
|
||||
assert res == b'testing message!'
|
||||
res = misc.decrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
unhexlify("958d4f63269b61044aaedc900c8d6208"),
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
res = misc.decrypt_keyvalue(self.client, [0, 1, 2], b"test", unhexlify("e0cf0eb0425947000eb546cc3994bc6c"), ask_on_encrypt=False, ask_on_decrypt=False)
|
||||
assert res == b'testing message!'
|
||||
res = misc.decrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
unhexlify("e0cf0eb0425947000eb546cc3994bc6c"),
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
# different key
|
||||
res = misc.decrypt_keyvalue(self.client, [0, 1, 2], b"test2", unhexlify("de247a6aa6be77a134bb3f3f925f13af"), ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert res == b'testing message!'
|
||||
res = misc.decrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test2",
|
||||
unhexlify("de247a6aa6be77a134bb3f3f925f13af"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
# different message
|
||||
res = misc.decrypt_keyvalue(self.client, [0, 1, 2], b"test", unhexlify("676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"), ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert res == b'testing message! it is different'
|
||||
res = misc.decrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 2],
|
||||
b"test",
|
||||
unhexlify(
|
||||
"676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"
|
||||
),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message! it is different"
|
||||
|
||||
# different path
|
||||
res = misc.decrypt_keyvalue(self.client, [0, 1, 3], b"test", unhexlify("b4811a9d492f5355a5186ddbfccaae7b"), ask_on_encrypt=True, ask_on_decrypt=True)
|
||||
assert res == b'testing message!'
|
||||
res = misc.decrypt_keyvalue(
|
||||
self.client,
|
||||
[0, 1, 3],
|
||||
b"test",
|
||||
unhexlify("b4811a9d492f5355a5186ddbfccaae7b"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
def test_encrypt_badlen(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
@ -16,38 +16,81 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgClearsession(TrezorTest):
|
||||
|
||||
def test_clearsession(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success()])
|
||||
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
res = self.client.ping(
|
||||
"random data",
|
||||
button_protection=True,
|
||||
pin_protection=True,
|
||||
passphrase_protection=True,
|
||||
)
|
||||
assert res == "random data"
|
||||
|
||||
with self.client:
|
||||
# pin and passphrase are cached
|
||||
self.client.set_expected_responses([proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.Success()])
|
||||
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall),
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
res = self.client.ping(
|
||||
"random data",
|
||||
button_protection=True,
|
||||
pin_protection=True,
|
||||
passphrase_protection=True,
|
||||
)
|
||||
assert res == "random data"
|
||||
|
||||
self.client.clear_session()
|
||||
|
||||
# session cache is cleared
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success()])
|
||||
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
res = self.client.ping(
|
||||
"random data",
|
||||
button_protection=True,
|
||||
pin_protection=True,
|
||||
passphrase_protection=True,
|
||||
)
|
||||
assert res == "random data"
|
||||
|
||||
with self.client:
|
||||
# pin and passphrase are cached
|
||||
self.client.set_expected_responses([proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.Success()])
|
||||
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall),
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
res = self.client.ping(
|
||||
"random data",
|
||||
button_protection=True,
|
||||
pin_protection=True,
|
||||
passphrase_protection=True,
|
||||
)
|
||||
assert res == "random data"
|
||||
|
@ -15,21 +15,36 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib.tools import H_
|
||||
from trezorlib import ethereum
|
||||
from trezorlib.tools import H_
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
class TestMsgEthereumGetaddress(TrezorTest):
|
||||
|
||||
def test_ethereum_getaddress(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert hexlify(ethereum.get_address(self.client, [])) == b'1d1c328764a41bda0492b66baa30c4a339ff85ef'
|
||||
assert hexlify(ethereum.get_address(self.client, [1])) == b'437207ca3cf43bf2e47dea0756d736c5df4f597a'
|
||||
assert hexlify(ethereum.get_address(self.client, [0, H_(1)])) == b'e5d96dfa07bcf1a3ae43677840c31394258861bf'
|
||||
assert hexlify(ethereum.get_address(self.client, [H_(9), 0])) == b'f68804ac9eca9483ab4241d3e4751590d2c05102'
|
||||
assert hexlify(ethereum.get_address(self.client, [0, 9999999])) == b'7a6366ecfcaf0d5dcc1539c171696c6cdd1eb8ed'
|
||||
assert (
|
||||
hexlify(ethereum.get_address(self.client, []))
|
||||
== b"1d1c328764a41bda0492b66baa30c4a339ff85ef"
|
||||
)
|
||||
assert (
|
||||
hexlify(ethereum.get_address(self.client, [1]))
|
||||
== b"437207ca3cf43bf2e47dea0756d736c5df4f597a"
|
||||
)
|
||||
assert (
|
||||
hexlify(ethereum.get_address(self.client, [0, H_(1)]))
|
||||
== b"e5d96dfa07bcf1a3ae43677840c31394258861bf"
|
||||
)
|
||||
assert (
|
||||
hexlify(ethereum.get_address(self.client, [H_(9), 0]))
|
||||
== b"f68804ac9eca9483ab4241d3e4751590d2c05102"
|
||||
)
|
||||
assert (
|
||||
hexlify(ethereum.get_address(self.client, [0, 9999999]))
|
||||
== b"7a6366ecfcaf0d5dcc1539c171696c6cdd1eb8ed"
|
||||
)
|
||||
|
@ -15,20 +15,28 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import ethereum
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
class TestMsgEthereumSignmessage(TrezorTest):
|
||||
|
||||
PATH = [0]
|
||||
ADDRESS = b'cb3864960e8db1a751212c580af27ee8867d688f'
|
||||
ADDRESS = b"cb3864960e8db1a751212c580af27ee8867d688f"
|
||||
VECTORS = [
|
||||
('This is an example of a signed message.', b'b7837058907192dbc9427bf57d93a0acca3816c92927a08be573b785f2d72dab65dad9c92fbe03a358acdb455eab2107b869945d11f4e353d9cc6ea957d08a871b'),
|
||||
('VeryLongMessage!' * 64, b'da2b73b0170479c2bfba3dd4839bf0d67732a44df8c873f3f3a2aca8a57d7bdc0b5d534f54c649e2d44135717001998b176d3cd1212366464db51f5838430fb31c'),
|
||||
(
|
||||
"This is an example of a signed message.",
|
||||
b"b7837058907192dbc9427bf57d93a0acca3816c92927a08be573b785f2d72dab65dad9c92fbe03a358acdb455eab2107b869945d11f4e353d9cc6ea957d08a871b",
|
||||
),
|
||||
(
|
||||
"VeryLongMessage!" * 64,
|
||||
b"da2b73b0170479c2bfba3dd4839bf0d67732a44df8c873f3f3a2aca8a57d7bdc0b5d534f54c649e2d44135717001998b176d3cd1212366464db51f5838430fb31c",
|
||||
),
|
||||
]
|
||||
|
||||
def test_sign(self):
|
||||
|
@ -14,34 +14,44 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify, hexlify
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import ethereum, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import ethereum
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
class TestMsgEthereumSigntx(TrezorTest):
|
||||
|
||||
def test_ethereum_signtx_known_erc20_token(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=None),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
data = bytearray()
|
||||
# method id signalizing `transfer(address _to, uint256 _value)` function
|
||||
data.extend(unhexlify('a9059cbb'))
|
||||
data.extend(unhexlify("a9059cbb"))
|
||||
# 1st function argument (to - the receiver)
|
||||
data.extend(unhexlify('000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b'))
|
||||
data.extend(
|
||||
unhexlify(
|
||||
"000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b"
|
||||
)
|
||||
)
|
||||
# 2nd function argument (value - amount to be transferred)
|
||||
data.extend(unhexlify('000000000000000000000000000000000000000000000000000000000bebc200'))
|
||||
data.extend(
|
||||
unhexlify(
|
||||
"000000000000000000000000000000000000000000000000000000000bebc200"
|
||||
)
|
||||
)
|
||||
# 200 000 000 in dec, divisibility of ADT = 9, trezor1 displays 0.2 ADT, Trezor T 200 000 000 Wei ADT
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
@ -51,33 +61,50 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
gas_price=20,
|
||||
gas_limit=20,
|
||||
# ADT token address
|
||||
to=b'\xd0\xd6\xd6\xc5\xfe\x4a\x67\x7d\x34\x3c\xc4\x33\x53\x6b\xb7\x17\xba\xe1\x67\xdd',
|
||||
to=b"\xd0\xd6\xd6\xc5\xfe\x4a\x67\x7d\x34\x3c\xc4\x33\x53\x6b\xb7\x17\xba\xe1\x67\xdd",
|
||||
chain_id=1,
|
||||
# value needs to be 0, token value is set in the contract (data)
|
||||
value=0,
|
||||
data=data)
|
||||
data=data,
|
||||
)
|
||||
|
||||
# taken from T1 might not be 100% correct but still better than nothing
|
||||
assert hexlify(sig_r) == b'75cf48fa173d8ceb68af9e4fb6b78ef69e6ed5e7679ba6f8e3e91d74b2fb0f96'
|
||||
assert hexlify(sig_s) == b'65de4a8c35263b2cfff3954b12146e8e568aa67a1c2461d6865e74ef75c7e190'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"75cf48fa173d8ceb68af9e4fb6b78ef69e6ed5e7679ba6f8e3e91d74b2fb0f96"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"65de4a8c35263b2cfff3954b12146e8e568aa67a1c2461d6865e74ef75c7e190"
|
||||
)
|
||||
|
||||
def test_ethereum_signtx_unknown_erc20_token(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=None),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
data = bytearray()
|
||||
# method id signalizing `transfer(address _to, uint256 _value)` function
|
||||
data.extend(unhexlify('a9059cbb'))
|
||||
data.extend(unhexlify("a9059cbb"))
|
||||
# 1st function argument (to - the receiver)
|
||||
data.extend(unhexlify('000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b'))
|
||||
data.extend(
|
||||
unhexlify(
|
||||
"000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b"
|
||||
)
|
||||
)
|
||||
# 2nd function argument (value - amount to be transferred)
|
||||
data.extend(unhexlify('0000000000000000000000000000000000000000000000000000000000000123'))
|
||||
data.extend(
|
||||
unhexlify(
|
||||
"0000000000000000000000000000000000000000000000000000000000000123"
|
||||
)
|
||||
)
|
||||
# since this token is unknown trezor should display "unknown token value"
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
@ -87,25 +114,34 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
gas_price=20,
|
||||
gas_limit=20,
|
||||
# unknown token address (Grzegorz Brzęczyszczykiewicz Token)
|
||||
to=b'\xfc\x6b\x5d\x6a\xf8\xa1\x32\x58\xf7\xcb\xd0\xd3\x9e\x11\xb3\x5e\x01\xa3\x2f\x93',
|
||||
to=b"\xfc\x6b\x5d\x6a\xf8\xa1\x32\x58\xf7\xcb\xd0\xd3\x9e\x11\xb3\x5e\x01\xa3\x2f\x93",
|
||||
chain_id=1,
|
||||
# value needs to be 0, token value is set in the contract (data)
|
||||
value=0,
|
||||
data=data)
|
||||
data=data,
|
||||
)
|
||||
|
||||
# taken from T1 might not be 100% correct but still better than nothing
|
||||
assert hexlify(sig_r) == b'1707471fbf632e42d18144157aaf4cde101cd9aa9782ad8e30583cfc95ddeef6'
|
||||
assert hexlify(sig_s) == b'3d2e52ba5904a4bf131abde3f79db826199f5d6f4d241d531d7e8a30a3b9cfd9'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"1707471fbf632e42d18144157aaf4cde101cd9aa9782ad8e30583cfc95ddeef6"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"3d2e52ba5904a4bf131abde3f79db826199f5d6f4d241d531d7e8a30a3b9cfd9"
|
||||
)
|
||||
|
||||
def test_ethereum_signtx_nodata(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=None), # v,r,s checked with assert
|
||||
])
|
||||
proto.EthereumTxRequest(data_length=None), # v,r,s checked later
|
||||
]
|
||||
)
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
self.client,
|
||||
@ -113,19 +149,28 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=0,
|
||||
gas_price=20,
|
||||
gas_limit=20,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
value=10)
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=10,
|
||||
)
|
||||
|
||||
assert sig_v == 27
|
||||
assert hexlify(sig_r) == b'9b61192a161d056c66cfbbd331edb2d783a0193bd4f65f49ee965f791d898f72'
|
||||
assert hexlify(sig_s) == b'49c0bbe35131592c6ed5c871ac457feeb16a1493f64237387fab9b83c1a202f7'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"9b61192a161d056c66cfbbd331edb2d783a0193bd4f65f49ee965f791d898f72"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"49c0bbe35131592c6ed5c871ac457feeb16a1493f64237387fab9b83c1a202f7"
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=None),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
self.client,
|
||||
@ -133,22 +178,31 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=123456,
|
||||
gas_price=20000,
|
||||
gas_limit=20000,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
value=12345678901234567890)
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=12345678901234567890,
|
||||
)
|
||||
assert sig_v == 28
|
||||
assert hexlify(sig_r) == b'6de597b8ec1b46501e5b159676e132c1aa78a95bd5892ef23560a9867528975a'
|
||||
assert hexlify(sig_s) == b'6e33c4230b1ecf96a8dbb514b4aec0a6d6ba53f8991c8143f77812aa6daa993f'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"6de597b8ec1b46501e5b159676e132c1aa78a95bd5892ef23560a9867528975a"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"6e33c4230b1ecf96a8dbb514b4aec0a6d6ba53f8991c8143f77812aa6daa993f"
|
||||
)
|
||||
|
||||
def test_ethereum_signtx_data(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=None),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
self.client,
|
||||
@ -156,24 +210,38 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=0,
|
||||
gas_price=20,
|
||||
gas_limit=20,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=10,
|
||||
data=b'abcdefghijklmnop' * 16)
|
||||
data=b"abcdefghijklmnop" * 16,
|
||||
)
|
||||
assert sig_v == 28
|
||||
assert hexlify(sig_r) == b'6da89ed8627a491bedc9e0382f37707ac4e5102e25e7a1234cb697cedb7cd2c0'
|
||||
assert hexlify(sig_s) == b'691f73b145647623e2d115b208a7c3455a6a8a83e3b4db5b9c6d9bc75825038a'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"6da89ed8627a491bedc9e0382f37707ac4e5102e25e7a1234cb697cedb7cd2c0"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"691f73b145647623e2d115b208a7c3455a6a8a83e3b4db5b9c6d9bc75825038a"
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=1024, signature_r=None, signature_s=None, signature_v=None),
|
||||
proto.EthereumTxRequest(
|
||||
data_length=1024,
|
||||
signature_r=None,
|
||||
signature_s=None,
|
||||
signature_v=None,
|
||||
),
|
||||
proto.EthereumTxRequest(data_length=1024),
|
||||
proto.EthereumTxRequest(data_length=1024),
|
||||
proto.EthereumTxRequest(data_length=3),
|
||||
proto.EthereumTxRequest(),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
self.client,
|
||||
@ -181,27 +249,41 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=123456,
|
||||
gas_price=20000,
|
||||
gas_limit=20000,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=12345678901234567890,
|
||||
data=b'ABCDEFGHIJKLMNOP' * 256 + b'!!!')
|
||||
data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!",
|
||||
)
|
||||
assert sig_v == 28
|
||||
assert hexlify(sig_r) == b'4e90b13c45c6a9bf4aaad0e5427c3e62d76692b36eb727c78d332441b7400404'
|
||||
assert hexlify(sig_s) == b'3ff236e7d05f0f9b1ee3d70599bb4200638f28388a8faf6bb36db9e04dc544be'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"4e90b13c45c6a9bf4aaad0e5427c3e62d76692b36eb727c78d332441b7400404"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"3ff236e7d05f0f9b1ee3d70599bb4200638f28388a8faf6bb36db9e04dc544be"
|
||||
)
|
||||
|
||||
def test_ethereum_signtx_message(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=1024, signature_r=None, signature_s=None, signature_v=None),
|
||||
proto.EthereumTxRequest(
|
||||
data_length=1024,
|
||||
signature_r=None,
|
||||
signature_s=None,
|
||||
signature_v=None,
|
||||
),
|
||||
proto.EthereumTxRequest(data_length=1024),
|
||||
proto.EthereumTxRequest(data_length=1024),
|
||||
proto.EthereumTxRequest(data_length=3),
|
||||
proto.EthereumTxRequest(),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
self.client,
|
||||
@ -209,12 +291,19 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=0,
|
||||
gas_price=20000,
|
||||
gas_limit=20000,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=0,
|
||||
data=b'ABCDEFGHIJKLMNOP' * 256 + b'!!!')
|
||||
data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!",
|
||||
)
|
||||
assert sig_v == 28
|
||||
assert hexlify(sig_r) == b'070e9dafda4d9e733fa7b6747a75f8a4916459560efb85e3e73cd39f31aa160d'
|
||||
assert hexlify(sig_s) == b'7842db33ef15c27049ed52741db41fe3238a6fa3a6a0888fcfb74d6917600e41'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"070e9dafda4d9e733fa7b6747a75f8a4916459560efb85e3e73cd39f31aa160d"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"7842db33ef15c27049ed52741db41fe3238a6fa3a6a0888fcfb74d6917600e41"
|
||||
)
|
||||
|
||||
def test_ethereum_signtx_newcontract(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -227,21 +316,28 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=123456,
|
||||
gas_price=20000,
|
||||
gas_limit=20000,
|
||||
to='',
|
||||
value=12345678901234567890
|
||||
to="",
|
||||
value=12345678901234567890,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=1024, signature_r=None, signature_s=None, signature_v=None),
|
||||
proto.EthereumTxRequest(
|
||||
data_length=1024,
|
||||
signature_r=None,
|
||||
signature_s=None,
|
||||
signature_v=None,
|
||||
),
|
||||
proto.EthereumTxRequest(data_length=1024),
|
||||
proto.EthereumTxRequest(data_length=1024),
|
||||
proto.EthereumTxRequest(data_length=3),
|
||||
proto.EthereumTxRequest(),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
self.client,
|
||||
@ -249,12 +345,19 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=0,
|
||||
gas_price=20000,
|
||||
gas_limit=20000,
|
||||
to='',
|
||||
to="",
|
||||
value=12345678901234567890,
|
||||
data=b'ABCDEFGHIJKLMNOP' * 256 + b'!!!')
|
||||
data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!",
|
||||
)
|
||||
assert sig_v == 28
|
||||
assert hexlify(sig_r) == b'b401884c10ae435a2e792303b5fc257a09f94403b2883ad8c0ac7a7282f5f1f9'
|
||||
assert hexlify(sig_s) == b'4742fc9e6a5fa8db3db15c2d856914a7f3daab21603a6c1ce9e9927482f8352e'
|
||||
assert (
|
||||
hexlify(sig_r)
|
||||
== b"b401884c10ae435a2e792303b5fc257a09f94403b2883ad8c0ac7a7282f5f1f9"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig_s)
|
||||
== b"4742fc9e6a5fa8db3db15c2d856914a7f3daab21603a6c1ce9e9927482f8352e"
|
||||
)
|
||||
|
||||
def test_ethereum_sanity_checks(self):
|
||||
# gas overflow
|
||||
@ -265,8 +368,8 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
nonce=123456,
|
||||
gas_price=0xffffffffffffffffffffffffffffffff,
|
||||
gas_limit=0xffffffffffffffffffffffffffffff,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
value=12345678901234567890
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=12345678901234567890,
|
||||
)
|
||||
|
||||
# no gas price
|
||||
@ -276,8 +379,8 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
n=[0, 0],
|
||||
nonce=123456,
|
||||
gas_limit=10000,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
value=12345678901234567890
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=12345678901234567890,
|
||||
)
|
||||
|
||||
# no gas limit
|
||||
@ -287,8 +390,8 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
n=[0, 0],
|
||||
nonce=123456,
|
||||
gas_price=10000,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
value=12345678901234567890
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=12345678901234567890,
|
||||
)
|
||||
|
||||
# no nonce
|
||||
@ -298,6 +401,6 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
n=[0, 0],
|
||||
gas_price=10000,
|
||||
gas_limit=123456,
|
||||
to=unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||
value=12345678901234567890
|
||||
to=unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
|
||||
value=12345678901234567890,
|
||||
)
|
||||
|
@ -14,13 +14,15 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify, hexlify
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import ethereum
|
||||
from trezorlib.tools import H_
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
class TestMsgEthereumSigntxChainId(TrezorTest):
|
||||
|
@ -18,26 +18,30 @@ from binascii import unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import ethereum
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
class TestMsgEthereumVerifymessage(TrezorTest):
|
||||
|
||||
ADDRESS = b'cb3864960e8db1a751212c580af27ee8867d688f'
|
||||
ADDRESS = b"cb3864960e8db1a751212c580af27ee8867d688f"
|
||||
VECTORS = [
|
||||
('This is an example of a signed message.', b'b7837058907192dbc9427bf57d93a0acca3816c92927a08be573b785f2d72dab65dad9c92fbe03a358acdb455eab2107b869945d11f4e353d9cc6ea957d08a871b'),
|
||||
('VeryLongMessage!' * 64, b'da2b73b0170479c2bfba3dd4839bf0d67732a44df8c873f3f3a2aca8a57d7bdc0b5d534f54c649e2d44135717001998b176d3cd1212366464db51f5838430fb31c'),
|
||||
(
|
||||
"This is an example of a signed message.",
|
||||
b"b7837058907192dbc9427bf57d93a0acca3816c92927a08be573b785f2d72dab65dad9c92fbe03a358acdb455eab2107b869945d11f4e353d9cc6ea957d08a871b",
|
||||
),
|
||||
(
|
||||
"VeryLongMessage!" * 64,
|
||||
b"da2b73b0170479c2bfba3dd4839bf0d67732a44df8c873f3f3a2aca8a57d7bdc0b5d534f54c649e2d44135717001998b176d3cd1212366464db51f5838430fb31c",
|
||||
),
|
||||
]
|
||||
|
||||
def test_verify(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
for msg, sig in self.VECTORS:
|
||||
res = ethereum.verify_message(
|
||||
self.client,
|
||||
unhexlify(self.ADDRESS),
|
||||
unhexlify(sig),
|
||||
msg
|
||||
self.client, unhexlify(self.ADDRESS), unhexlify(sig), msg
|
||||
)
|
||||
assert res is True
|
||||
|
@ -15,57 +15,128 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support import ckd_public as bip32
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc, messages as proto
|
||||
from trezorlib.tools import H_, parse_path
|
||||
|
||||
from trezorlib.tools import parse_path, H_
|
||||
from trezorlib import btc
|
||||
from ..support import ckd_public as bip32
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgGetaddress(TrezorTest):
|
||||
|
||||
def test_btc(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert btc.get_address(self.client, 'Bitcoin', []) == '1EfKbQupktEMXf4gujJ9kCFo83k1iMqwqK'
|
||||
assert btc.get_address(self.client, 'Bitcoin', [1]) == '1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb'
|
||||
assert btc.get_address(self.client, 'Bitcoin', [0, H_(1)]) == '1JVq66pzRBvqaBRFeU9SPVvg3er4ZDgoMs'
|
||||
assert btc.get_address(self.client, 'Bitcoin', [H_(9), 0]) == '1F4YdQdL9ZQwvcNTuy5mjyQxXkyCfMcP2P'
|
||||
assert btc.get_address(self.client, 'Bitcoin', [0, 9999999]) == '1GS8X3yc7ntzwGw9vXwj9wqmBWZkTFewBV'
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [])
|
||||
== "1EfKbQupktEMXf4gujJ9kCFo83k1iMqwqK"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [1])
|
||||
== "1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [0, H_(1)])
|
||||
== "1JVq66pzRBvqaBRFeU9SPVvg3er4ZDgoMs"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [H_(9), 0])
|
||||
== "1F4YdQdL9ZQwvcNTuy5mjyQxXkyCfMcP2P"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [0, 9999999])
|
||||
== "1GS8X3yc7ntzwGw9vXwj9wqmBWZkTFewBV"
|
||||
)
|
||||
|
||||
def test_ltc(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert btc.get_address(self.client, 'Litecoin', []) == 'LYtGrdDeqYUQnTkr5sHT2DKZLG7Hqg7HTK'
|
||||
assert btc.get_address(self.client, 'Litecoin', [1]) == 'LKRGNecThFP3Q6c5fosLVA53Z2hUDb1qnE'
|
||||
assert btc.get_address(self.client, 'Litecoin', [0, H_(1)]) == 'LcinMK8pVrAtpz7Qpc8jfWzSFsDLgLYfG6'
|
||||
assert btc.get_address(self.client, 'Litecoin', [H_(9), 0]) == 'LZHVtcwAEDf1BR4d67551zUijyLUpDF9EX'
|
||||
assert btc.get_address(self.client, 'Litecoin', [0, 9999999]) == 'Laf5nGHSCT94C5dK6fw2RxuXPiw2ZuRR9S'
|
||||
assert (
|
||||
btc.get_address(self.client, "Litecoin", [])
|
||||
== "LYtGrdDeqYUQnTkr5sHT2DKZLG7Hqg7HTK"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Litecoin", [1])
|
||||
== "LKRGNecThFP3Q6c5fosLVA53Z2hUDb1qnE"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Litecoin", [0, H_(1)])
|
||||
== "LcinMK8pVrAtpz7Qpc8jfWzSFsDLgLYfG6"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Litecoin", [H_(9), 0])
|
||||
== "LZHVtcwAEDf1BR4d67551zUijyLUpDF9EX"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Litecoin", [0, 9999999])
|
||||
== "Laf5nGHSCT94C5dK6fw2RxuXPiw2ZuRR9S"
|
||||
)
|
||||
|
||||
def test_tbtc(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert btc.get_address(self.client, 'Testnet', [111, 42]) == 'moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa'
|
||||
assert (
|
||||
btc.get_address(self.client, "Testnet", [111, 42])
|
||||
== "moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa"
|
||||
)
|
||||
|
||||
def test_bch(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
assert btc.get_address(self.client, 'Bcash', parse_path("44'/145'/0'/0/0")) == 'bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv'
|
||||
assert btc.get_address(self.client, 'Bcash', parse_path("44'/145'/0'/0/1")) == 'bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4'
|
||||
assert btc.get_address(self.client, 'Bcash', parse_path("44'/145'/0'/1/0")) == 'bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw'
|
||||
assert (
|
||||
btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/0"))
|
||||
== "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/1"))
|
||||
== "bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/1/0"))
|
||||
== "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw"
|
||||
)
|
||||
|
||||
def test_bch_multisig(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
xpubs = []
|
||||
for n in map(lambda index: btc.get_public_node(self.client, parse_path("44'/145'/" + str(index) + "'")), range(1, 4)):
|
||||
for n in map(
|
||||
lambda index: btc.get_public_node(
|
||||
self.client, parse_path("44'/145'/" + str(index) + "'")
|
||||
),
|
||||
range(1, 4),
|
||||
):
|
||||
xpubs.append(n.xpub)
|
||||
|
||||
def getmultisig(chain, nr, signatures=[b'', b'', b''], xpubs=xpubs):
|
||||
def getmultisig(chain, nr, signatures=[b"", b"", b""], xpubs=xpubs):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda xpub: proto.HDNodePathType(node=bip32.deserialize(xpub), address_n=[chain, nr]), xpubs)),
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda xpub: proto.HDNodePathType(
|
||||
node=bip32.deserialize(xpub), address_n=[chain, nr]
|
||||
),
|
||||
xpubs,
|
||||
)
|
||||
),
|
||||
signatures=signatures,
|
||||
m=2,
|
||||
)
|
||||
|
||||
for nr in range(1, 4):
|
||||
assert btc.get_address(self.client, 'Bcash', parse_path("44'/145'/" + str(nr) + "'/0/0"), show_display=(nr == 1), multisig=getmultisig(0, 0)) == 'bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw'
|
||||
assert btc.get_address(self.client, 'Bcash', parse_path("44'/145'/" + str(nr) + "'/1/0"), show_display=(nr == 1), multisig=getmultisig(1, 0)) == 'bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a'
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Bcash",
|
||||
parse_path("44'/145'/" + str(nr) + "'/0/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(0, 0),
|
||||
)
|
||||
== "bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Bcash",
|
||||
parse_path("44'/145'/" + str(nr) + "'/1/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(1, 0),
|
||||
)
|
||||
== "bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a"
|
||||
)
|
||||
|
||||
def test_public_ckd(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -77,8 +148,8 @@ class TestMsgGetaddress(TrezorTest):
|
||||
assert node_sub1.chain_code == node_sub2.chain_code
|
||||
assert node_sub1.public_key == node_sub2.public_key
|
||||
|
||||
address1 = btc.get_address(self.client, 'Bitcoin', [1])
|
||||
address1 = btc.get_address(self.client, "Bitcoin", [1])
|
||||
address2 = bip32.get_address(node_sub2, 0)
|
||||
|
||||
assert address2 == '1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb'
|
||||
assert address2 == "1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb"
|
||||
assert address1 == address2
|
||||
|
@ -14,28 +14,79 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support import ckd_public as bip32
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc, messages as proto
|
||||
from trezorlib.tools import parse_path
|
||||
from trezorlib import btc
|
||||
|
||||
from ..support import ckd_public as bip32
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgGetaddressSegwit(TrezorTest):
|
||||
|
||||
def test_show_segwit(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("49'/1'/0'/1/0"), True, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS) == '2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX'
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("49'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS) == '2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp'
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS) == '2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc'
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDADDRESS) == 'mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q'
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/1/0"),
|
||||
True,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
== "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
|
||||
)
|
||||
|
||||
def test_show_multisig_3(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
nodes = map(lambda index: btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)), range(1, 4))
|
||||
nodes = map(
|
||||
lambda index: btc.get_public_node(
|
||||
self.client, parse_path("999'/1'/%d'" % index)
|
||||
),
|
||||
range(1, 4),
|
||||
)
|
||||
multisig1 = proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 0]), nodes)),
|
||||
signatures=[b'', b'', b''],
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda n: proto.HDNodePathType(
|
||||
node=bip32.deserialize(n.xpub), address_n=[2, 0]
|
||||
),
|
||||
nodes,
|
||||
)
|
||||
),
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
# multisig2 = proto.MultisigRedeemScriptType(
|
||||
@ -44,4 +95,14 @@ class TestMsgGetaddressSegwit(TrezorTest):
|
||||
# m=2,
|
||||
# )
|
||||
for i in [1, 2, 3]:
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("999'/1'/%d'/2/0" % i), False, multisig1, script_type=proto.InputScriptType.SPENDP2SHWITNESS) == '2N2MxyAfifVhb3AMagisxaj3uij8bfXqf4Y'
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("999'/1'/%d'/2/0" % i),
|
||||
False,
|
||||
multisig1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N2MxyAfifVhb3AMagisxaj3uij8bfXqf4Y"
|
||||
)
|
||||
|
@ -14,35 +14,111 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support import ckd_public as bip32
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc, messages as proto
|
||||
from trezorlib.tools import parse_path
|
||||
from trezorlib import btc
|
||||
|
||||
from ..support import ckd_public as bip32
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgGetaddressSegwitNative(TrezorTest):
|
||||
|
||||
def test_show_segwit(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("49'/1'/0'/0/0"), True, None, script_type=proto.InputScriptType.SPENDWITNESS) == 'tb1qqzv60m9ajw8drqulta4ld4gfx0rdh82un5s65s'
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("49'/1'/0'/1/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS) == 'tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu'
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS) == 'tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc'
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDADDRESS) == 'mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q'
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/0/0"),
|
||||
True,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
== "tb1qqzv60m9ajw8drqulta4ld4gfx0rdh82un5s65s"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/1/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
== "tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
== "tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
== "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
|
||||
)
|
||||
|
||||
def test_show_multisig_3(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
nodes = [btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)) for index in range(1, 4)]
|
||||
nodes = [
|
||||
btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index))
|
||||
for index in range(1, 4)
|
||||
]
|
||||
multisig1 = proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 0]), nodes)),
|
||||
signatures=[b'', b'', b''],
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda n: proto.HDNodePathType(
|
||||
node=bip32.deserialize(n.xpub), address_n=[2, 0]
|
||||
),
|
||||
nodes,
|
||||
)
|
||||
),
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
multisig2 = proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes)),
|
||||
signatures=[b'', b'', b''],
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda n: proto.HDNodePathType(
|
||||
node=bip32.deserialize(n.xpub), address_n=[2, 1]
|
||||
),
|
||||
nodes,
|
||||
)
|
||||
),
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
for i in [1, 2, 3]:
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("999'/1'/%d'/2/1" % i), False, multisig2, script_type=proto.InputScriptType.SPENDWITNESS) == 'tb1qch62pf820spe9mlq49ns5uexfnl6jzcezp7d328fw58lj0rhlhasge9hzy'
|
||||
assert btc.get_address(self.client, "Testnet", parse_path("999'/1'/%d'/2/0" % i), False, multisig1, script_type=proto.InputScriptType.SPENDWITNESS) == 'tb1qr6xa5v60zyt3ry9nmfew2fk5g9y3gerkjeu6xxdz7qga5kknz2ssld9z2z'
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("999'/1'/%d'/2/1" % i),
|
||||
False,
|
||||
multisig2,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
== "tb1qch62pf820spe9mlq49ns5uexfnl6jzcezp7d328fw58lj0rhlhasge9hzy"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client,
|
||||
"Testnet",
|
||||
parse_path("999'/1'/%d'/2/0" % i),
|
||||
False,
|
||||
multisig1,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
== "tb1qr6xa5v60zyt3ry9nmfew2fk5g9y3gerkjeu6xxdz7qga5kknz2ssld9z2z"
|
||||
)
|
||||
|
@ -14,51 +14,71 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import btc, messages as proto
|
||||
|
||||
from ..support import ckd_public as bip32
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgGetaddressShow(TrezorTest):
|
||||
|
||||
def test_show(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert btc.get_address(self.client, 'Bitcoin', [1], show_display=True) == '1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb'
|
||||
assert btc.get_address(self.client, 'Bitcoin', [2], show_display=True) == '15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG'
|
||||
assert btc.get_address(self.client, 'Bitcoin', [3], show_display=True) == '1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5'
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [1], show_display=True)
|
||||
== "1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [2], show_display=True)
|
||||
== "15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(self.client, "Bitcoin", [3], show_display=True)
|
||||
== "1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5"
|
||||
)
|
||||
|
||||
def test_show_multisig_3(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
|
||||
node = bip32.deserialize(
|
||||
"xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy"
|
||||
)
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3])
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
for i in [1, 2, 3]:
|
||||
assert btc.get_address(self.client, 'Bitcoin', [i], show_display=True, multisig=multisig) == '3E7GDtuHqnqPmDgwH59pVC7AvySiSkbibz'
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client, "Bitcoin", [i], show_display=True, multisig=multisig
|
||||
)
|
||||
== "3E7GDtuHqnqPmDgwH59pVC7AvySiSkbibz"
|
||||
)
|
||||
|
||||
def test_show_multisig_15(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
|
||||
node = bip32.deserialize(
|
||||
"xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy"
|
||||
)
|
||||
|
||||
pubs = []
|
||||
for x in range(15):
|
||||
pubs.append(proto.HDNodePathType(node=node, address_n=[x]))
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=pubs,
|
||||
signatures=[b''] * 15,
|
||||
m=15,
|
||||
pubkeys=pubs, signatures=[b""] * 15, m=15
|
||||
)
|
||||
|
||||
for i in range(15):
|
||||
assert btc.get_address(self.client, 'Bitcoin', [i], show_display=True, multisig=multisig) == '3QaKF8zobqcqY8aS6nxCD5ZYdiRfL3RCmU'
|
||||
assert (
|
||||
btc.get_address(
|
||||
self.client, "Bitcoin", [i], show_display=True, multisig=multisig
|
||||
)
|
||||
== "3QaKF8zobqcqY8aS6nxCD5ZYdiRfL3RCmU"
|
||||
)
|
||||
|
@ -16,27 +16,60 @@
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
from trezorlib import messages as proto, misc
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import misc
|
||||
|
||||
|
||||
class TestMsgGetECDHSessionKey(TrezorTest):
|
||||
|
||||
def test_ecdh(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
# URI : gpg://Satoshi Nakamoto <satoshi@bitcoin.org>
|
||||
identity = proto.IdentityType(proto='gpg', user='', host='Satoshi Nakamoto <satoshi@bitcoin.org>', port='', path='', index=0)
|
||||
identity = proto.IdentityType(
|
||||
proto="gpg",
|
||||
user="",
|
||||
host="Satoshi Nakamoto <satoshi@bitcoin.org>",
|
||||
port="",
|
||||
path="",
|
||||
index=0,
|
||||
)
|
||||
|
||||
peer_public_key = unhexlify('0407f2c6e5becf3213c1d07df0cfbe8e39f70a8c643df7575e5c56859ec52c45ca950499c019719dae0fda04248d851e52cf9d66eeb211d89a77be40de22b6c89d')
|
||||
result = misc.get_ecdh_session_key(self.client, identity=identity, peer_public_key=peer_public_key, ecdsa_curve_name='secp256k1')
|
||||
assert result.session_key == unhexlify('0495e5d8c9e5cc09e7cf4908774f52decb381ce97f2fc9ba56e959c13f03f9f47a03dd151cbc908bc1db84d46e2c33e7bbb9daddc800f985244c924fd64adf6647')
|
||||
peer_public_key = unhexlify(
|
||||
"0407f2c6e5becf3213c1d07df0cfbe8e39f70a8c643df7575e5c56859ec52c45ca950499c019719dae0fda04248d851e52cf9d66eeb211d89a77be40de22b6c89d"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
self.client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="secp256k1",
|
||||
)
|
||||
assert result.session_key == unhexlify(
|
||||
"0495e5d8c9e5cc09e7cf4908774f52decb381ce97f2fc9ba56e959c13f03f9f47a03dd151cbc908bc1db84d46e2c33e7bbb9daddc800f985244c924fd64adf6647"
|
||||
)
|
||||
|
||||
peer_public_key = unhexlify('04811a6c2bd2a547d0dd84747297fec47719e7c3f9b0024f027c2b237be99aac39a9230acbd163d0cb1524a0f5ea4bfed6058cec6f18368f72a12aa0c4d083ff64')
|
||||
result = misc.get_ecdh_session_key(self.client, identity=identity, peer_public_key=peer_public_key, ecdsa_curve_name='nist256p1')
|
||||
assert result.session_key == unhexlify('046d1f5c48af2cf2c57076ac2c9d7808db2086f614cb7b8107119ff2c6270cd209749809efe0196f01a0cc633788cef1f4a2bd650c99570d06962f923fca6d8fdf')
|
||||
peer_public_key = unhexlify(
|
||||
"04811a6c2bd2a547d0dd84747297fec47719e7c3f9b0024f027c2b237be99aac39a9230acbd163d0cb1524a0f5ea4bfed6058cec6f18368f72a12aa0c4d083ff64"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
self.client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="nist256p1",
|
||||
)
|
||||
assert result.session_key == unhexlify(
|
||||
"046d1f5c48af2cf2c57076ac2c9d7808db2086f614cb7b8107119ff2c6270cd209749809efe0196f01a0cc633788cef1f4a2bd650c99570d06962f923fca6d8fdf"
|
||||
)
|
||||
|
||||
peer_public_key = unhexlify('40a8cf4b6a64c4314e80f15a8ea55812bd735fbb365936a48b2d78807b575fa17a')
|
||||
result = misc.get_ecdh_session_key(self.client, identity=identity, peer_public_key=peer_public_key, ecdsa_curve_name='curve25519')
|
||||
assert result.session_key == unhexlify('04e24516669e0b7d3d72e5129fddd07b6644c30915f5c8b7f1f62324afb3624311')
|
||||
peer_public_key = unhexlify(
|
||||
"40a8cf4b6a64c4314e80f15a8ea55812bd735fbb365936a48b2d78807b575fa17a"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
self.client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="curve25519",
|
||||
)
|
||||
assert result.session_key == unhexlify(
|
||||
"04e24516669e0b7d3d72e5129fddd07b6644c30915f5c8b7f1f62324afb3624311"
|
||||
)
|
||||
|
@ -14,42 +14,121 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support import ckd_public as bip32
|
||||
|
||||
from trezorlib.tools import H_
|
||||
from trezorlib import btc
|
||||
from trezorlib.tools import H_
|
||||
|
||||
from ..support import ckd_public as bip32
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgGetpublickey(TrezorTest):
|
||||
|
||||
def test_btc(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert bip32.serialize(btc.get_public_node(self.client, []).node, 0x0488B21E) == 'xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy'
|
||||
assert btc.get_public_node(self.client, [], coin_name='Bitcoin').xpub == 'xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [1]).node, 0x0488B21E) == 'xpub68zNxjsTrV8y9AadThLW7dTAqEpZ7xBLFSyJ3X9pjTv6Njg6kxgjXJkzxq8u3ttnjBw1jupQHMP3gpGZzZqd1eh5S4GjkaMhPR18vMyUi8N'
|
||||
assert btc.get_public_node(self.client, [1], coin_name='Bitcoin').xpub == 'xpub68zNxjsTrV8y9AadThLW7dTAqEpZ7xBLFSyJ3X9pjTv6Njg6kxgjXJkzxq8u3ttnjBw1jupQHMP3gpGZzZqd1eh5S4GjkaMhPR18vMyUi8N'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [0, H_(1)]).node, 0x0488B21E) == 'xpub6A3FoZqYXj1AbW4thRwBh26YwZWbmoyjTaZwwxJjY1oKUpefLepL3RFS9DHKQrjAfxDrzDepYMDZPqXN6upQm3bHQ9xaXD5a3mqni3goF4v'
|
||||
assert btc.get_public_node(self.client, [0, H_(1)], coin_name='Bitcoin').xpub == 'xpub6A3FoZqYXj1AbW4thRwBh26YwZWbmoyjTaZwwxJjY1oKUpefLepL3RFS9DHKQrjAfxDrzDepYMDZPqXN6upQm3bHQ9xaXD5a3mqni3goF4v'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [H_(9), 0]).node, 0x0488B21E) == 'xpub6A2h5mzLDfYginoD7q7wCWbq18wTbN9gducRr2w5NRTwdLeoT3cJSwefFqW7uXTpVFGtpUyDMBNYs3DNvvXx6NPjF9YEbUQrtxFSWnPtVrv'
|
||||
assert btc.get_public_node(self.client, [H_(9), 0], coin_name='Bitcoin').xpub == 'xpub6A2h5mzLDfYginoD7q7wCWbq18wTbN9gducRr2w5NRTwdLeoT3cJSwefFqW7uXTpVFGtpUyDMBNYs3DNvvXx6NPjF9YEbUQrtxFSWnPtVrv'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [0, 9999999]).node, 0x0488B21E) == 'xpub6A3FoZqQEK6iwLZ4HFkqSo5fb35BH4bpjC4SPZ63prfLdGYPwYxEuC6o91bUvFFdMzKWe5rs3axHRUjxJaSvBnKKFtnfLwDACRxPxabsv2r'
|
||||
assert btc.get_public_node(self.client, [0, 9999999], coin_name='Bitcoin').xpub == 'xpub6A3FoZqQEK6iwLZ4HFkqSo5fb35BH4bpjC4SPZ63prfLdGYPwYxEuC6o91bUvFFdMzKWe5rs3axHRUjxJaSvBnKKFtnfLwDACRxPxabsv2r'
|
||||
assert (
|
||||
bip32.serialize(btc.get_public_node(self.client, []).node, 0x0488B21E)
|
||||
== "xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [], coin_name="Bitcoin").xpub
|
||||
== "xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(btc.get_public_node(self.client, [1]).node, 0x0488B21E)
|
||||
== "xpub68zNxjsTrV8y9AadThLW7dTAqEpZ7xBLFSyJ3X9pjTv6Njg6kxgjXJkzxq8u3ttnjBw1jupQHMP3gpGZzZqd1eh5S4GjkaMhPR18vMyUi8N"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [1], coin_name="Bitcoin").xpub
|
||||
== "xpub68zNxjsTrV8y9AadThLW7dTAqEpZ7xBLFSyJ3X9pjTv6Njg6kxgjXJkzxq8u3ttnjBw1jupQHMP3gpGZzZqd1eh5S4GjkaMhPR18vMyUi8N"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(
|
||||
btc.get_public_node(self.client, [0, H_(1)]).node, 0x0488B21E
|
||||
)
|
||||
== "xpub6A3FoZqYXj1AbW4thRwBh26YwZWbmoyjTaZwwxJjY1oKUpefLepL3RFS9DHKQrjAfxDrzDepYMDZPqXN6upQm3bHQ9xaXD5a3mqni3goF4v"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [0, H_(1)], coin_name="Bitcoin").xpub
|
||||
== "xpub6A3FoZqYXj1AbW4thRwBh26YwZWbmoyjTaZwwxJjY1oKUpefLepL3RFS9DHKQrjAfxDrzDepYMDZPqXN6upQm3bHQ9xaXD5a3mqni3goF4v"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(
|
||||
btc.get_public_node(self.client, [H_(9), 0]).node, 0x0488B21E
|
||||
)
|
||||
== "xpub6A2h5mzLDfYginoD7q7wCWbq18wTbN9gducRr2w5NRTwdLeoT3cJSwefFqW7uXTpVFGtpUyDMBNYs3DNvvXx6NPjF9YEbUQrtxFSWnPtVrv"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [H_(9), 0], coin_name="Bitcoin").xpub
|
||||
== "xpub6A2h5mzLDfYginoD7q7wCWbq18wTbN9gducRr2w5NRTwdLeoT3cJSwefFqW7uXTpVFGtpUyDMBNYs3DNvvXx6NPjF9YEbUQrtxFSWnPtVrv"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(
|
||||
btc.get_public_node(self.client, [0, 9999999]).node, 0x0488B21E
|
||||
)
|
||||
== "xpub6A3FoZqQEK6iwLZ4HFkqSo5fb35BH4bpjC4SPZ63prfLdGYPwYxEuC6o91bUvFFdMzKWe5rs3axHRUjxJaSvBnKKFtnfLwDACRxPxabsv2r"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [0, 9999999], coin_name="Bitcoin").xpub
|
||||
== "xpub6A3FoZqQEK6iwLZ4HFkqSo5fb35BH4bpjC4SPZ63prfLdGYPwYxEuC6o91bUvFFdMzKWe5rs3axHRUjxJaSvBnKKFtnfLwDACRxPxabsv2r"
|
||||
)
|
||||
|
||||
def test_ltc(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert bip32.serialize(btc.get_public_node(self.client, []).node, 0x019DA462) == 'Ltub2SSUS19CirucVPGDKDBatBDBEM2s9UbH66pBURfaKrMocCPLhQ7Z7hecy5VYLHA5fRdXwB2e61j2VJCNzVsqKTCVEU1vECjqi5EyczFX9xp'
|
||||
assert btc.get_public_node(self.client, [], coin_name='Litecoin').xpub == 'Ltub2SSUS19CirucVPGDKDBatBDBEM2s9UbH66pBURfaKrMocCPLhQ7Z7hecy5VYLHA5fRdXwB2e61j2VJCNzVsqKTCVEU1vECjqi5EyczFX9xp'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [1]).node, 0x019DA462) == 'Ltub2VRVRP5VjvSyPXra4BLVyVZPv397sjhUNjBGsbtw6xko77JuQyBULxFSKheviJJ3KQLbL3Cx8P2RnudguTw4raUVjCACRG7jsumUptYx55C'
|
||||
assert btc.get_public_node(self.client, [1], coin_name='Litecoin').xpub == 'Ltub2VRVRP5VjvSyPXra4BLVyVZPv397sjhUNjBGsbtw6xko77JuQyBULxFSKheviJJ3KQLbL3Cx8P2RnudguTw4raUVjCACRG7jsumUptYx55C'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [0, H_(1)]).node, 0x019DA462) == 'Ltub2WUNGD3aRAKAqsLqHuwBYtCn2MqAXbVsarmvn33quWe2DCHTzfK4s4jsW5oM5G8RGAdSaM3NPNrwVvtV1ourbyNhhHr3BtqcYGc8caf5GoT'
|
||||
assert btc.get_public_node(self.client, [0, H_(1)], coin_name='Litecoin').xpub == 'Ltub2WUNGD3aRAKAqsLqHuwBYtCn2MqAXbVsarmvn33quWe2DCHTzfK4s4jsW5oM5G8RGAdSaM3NPNrwVvtV1ourbyNhhHr3BtqcYGc8caf5GoT'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [H_(9), 0]).node, 0x019DA462) == 'Ltub2WToYRCN76rgyA59iK7w4Ni45wG2M9fpmBpQg7gBjvJeMiHc7473Gb96ci29Zvs55TgUQcMmCD1vy8aVqpdPwJB9YHRhGAAuPT1nRLLXmFu'
|
||||
assert btc.get_public_node(self.client, [H_(9), 0], coin_name='Litecoin').xpub == 'Ltub2WToYRCN76rgyA59iK7w4Ni45wG2M9fpmBpQg7gBjvJeMiHc7473Gb96ci29Zvs55TgUQcMmCD1vy8aVqpdPwJB9YHRhGAAuPT1nRLLXmFu'
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [0, 9999999]).node, 0x019DA462) == 'Ltub2WUNGD3S7kQjBhpzsjkqJfBtfqPk2r7xrUGRDdqACMW3MeBCbZSyiqbEVt7WaeesxCj6EDFQtcbfXa75DUYN2i6jZ2g81cyCgvijs9J2u2n'
|
||||
assert btc.get_public_node(self.client, [0, 9999999], coin_name='Litecoin').xpub == 'Ltub2WUNGD3S7kQjBhpzsjkqJfBtfqPk2r7xrUGRDdqACMW3MeBCbZSyiqbEVt7WaeesxCj6EDFQtcbfXa75DUYN2i6jZ2g81cyCgvijs9J2u2n'
|
||||
assert (
|
||||
bip32.serialize(btc.get_public_node(self.client, []).node, 0x019DA462)
|
||||
== "Ltub2SSUS19CirucVPGDKDBatBDBEM2s9UbH66pBURfaKrMocCPLhQ7Z7hecy5VYLHA5fRdXwB2e61j2VJCNzVsqKTCVEU1vECjqi5EyczFX9xp"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [], coin_name="Litecoin").xpub
|
||||
== "Ltub2SSUS19CirucVPGDKDBatBDBEM2s9UbH66pBURfaKrMocCPLhQ7Z7hecy5VYLHA5fRdXwB2e61j2VJCNzVsqKTCVEU1vECjqi5EyczFX9xp"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(btc.get_public_node(self.client, [1]).node, 0x019DA462)
|
||||
== "Ltub2VRVRP5VjvSyPXra4BLVyVZPv397sjhUNjBGsbtw6xko77JuQyBULxFSKheviJJ3KQLbL3Cx8P2RnudguTw4raUVjCACRG7jsumUptYx55C"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [1], coin_name="Litecoin").xpub
|
||||
== "Ltub2VRVRP5VjvSyPXra4BLVyVZPv397sjhUNjBGsbtw6xko77JuQyBULxFSKheviJJ3KQLbL3Cx8P2RnudguTw4raUVjCACRG7jsumUptYx55C"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(
|
||||
btc.get_public_node(self.client, [0, H_(1)]).node, 0x019DA462
|
||||
)
|
||||
== "Ltub2WUNGD3aRAKAqsLqHuwBYtCn2MqAXbVsarmvn33quWe2DCHTzfK4s4jsW5oM5G8RGAdSaM3NPNrwVvtV1ourbyNhhHr3BtqcYGc8caf5GoT"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [0, H_(1)], coin_name="Litecoin").xpub
|
||||
== "Ltub2WUNGD3aRAKAqsLqHuwBYtCn2MqAXbVsarmvn33quWe2DCHTzfK4s4jsW5oM5G8RGAdSaM3NPNrwVvtV1ourbyNhhHr3BtqcYGc8caf5GoT"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(
|
||||
btc.get_public_node(self.client, [H_(9), 0]).node, 0x019DA462
|
||||
)
|
||||
== "Ltub2WToYRCN76rgyA59iK7w4Ni45wG2M9fpmBpQg7gBjvJeMiHc7473Gb96ci29Zvs55TgUQcMmCD1vy8aVqpdPwJB9YHRhGAAuPT1nRLLXmFu"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [H_(9), 0], coin_name="Litecoin").xpub
|
||||
== "Ltub2WToYRCN76rgyA59iK7w4Ni45wG2M9fpmBpQg7gBjvJeMiHc7473Gb96ci29Zvs55TgUQcMmCD1vy8aVqpdPwJB9YHRhGAAuPT1nRLLXmFu"
|
||||
)
|
||||
assert (
|
||||
bip32.serialize(
|
||||
btc.get_public_node(self.client, [0, 9999999]).node, 0x019DA462
|
||||
)
|
||||
== "Ltub2WUNGD3S7kQjBhpzsjkqJfBtfqPk2r7xrUGRDdqACMW3MeBCbZSyiqbEVt7WaeesxCj6EDFQtcbfXa75DUYN2i6jZ2g81cyCgvijs9J2u2n"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [0, 9999999], coin_name="Litecoin").xpub
|
||||
== "Ltub2WUNGD3S7kQjBhpzsjkqJfBtfqPk2r7xrUGRDdqACMW3MeBCbZSyiqbEVt7WaeesxCj6EDFQtcbfXa75DUYN2i6jZ2g81cyCgvijs9J2u2n"
|
||||
)
|
||||
|
||||
def test_tbtc(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert bip32.serialize(btc.get_public_node(self.client, [111, 42]).node, 0x043587CF) == 'tpubDAgixSyai5PWbc8N1mBkHDR5nLgAnHFtY7r4y5EzxqAxrt9YUDpZL3kaRoHVvCfrcwNo31c2isBP2uTHcZxEosuKbyJhCAbrvGoPuLUZ7Mz'
|
||||
assert btc.get_public_node(self.client, [111, 42], coin_name='Testnet').xpub == 'tpubDAgixSyai5PWbc8N1mBkHDR5nLgAnHFtY7r4y5EzxqAxrt9YUDpZL3kaRoHVvCfrcwNo31c2isBP2uTHcZxEosuKbyJhCAbrvGoPuLUZ7Mz'
|
||||
assert (
|
||||
bip32.serialize(
|
||||
btc.get_public_node(self.client, [111, 42]).node, 0x043587CF
|
||||
)
|
||||
== "tpubDAgixSyai5PWbc8N1mBkHDR5nLgAnHFtY7r4y5EzxqAxrt9YUDpZL3kaRoHVvCfrcwNo31c2isBP2uTHcZxEosuKbyJhCAbrvGoPuLUZ7Mz"
|
||||
)
|
||||
assert (
|
||||
btc.get_public_node(self.client, [111, 42], coin_name="Testnet").xpub
|
||||
== "tpubDAgixSyai5PWbc8N1mBkHDR5nLgAnHFtY7r4y5EzxqAxrt9YUDpZL3kaRoHVvCfrcwNo31c2isBP2uTHcZxEosuKbyJhCAbrvGoPuLUZ7Mz"
|
||||
)
|
||||
|
@ -15,35 +15,84 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib.tools import CallException, H_
|
||||
from trezorlib import btc
|
||||
from trezorlib.tools import H_, CallException
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgGetpublickeyCurve(TrezorTest):
|
||||
|
||||
def test_default_curve(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), 42]).node.public_key).decode() == '02e7fcec053f0df94d88c86447970743e8a1979d242d09338dcf8687a9966f7fbc'
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), H_(42)]).node.public_key).decode() == '03ce7b690969d773ba9ed212464eb2b534b87b9b8a9383300bddabe1f093f79220'
|
||||
assert (
|
||||
hexlify(btc.get_public_node(self.client, [H_(111), 42]).node.public_key)
|
||||
== b"02e7fcec053f0df94d88c86447970743e8a1979d242d09338dcf8687a9966f7fbc"
|
||||
)
|
||||
assert (
|
||||
hexlify(btc.get_public_node(self.client, [H_(111), H_(42)]).node.public_key)
|
||||
== b"03ce7b690969d773ba9ed212464eb2b534b87b9b8a9383300bddabe1f093f79220"
|
||||
)
|
||||
|
||||
def test_secp256k1_curve(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), 42], ecdsa_curve_name='secp256k1').node.public_key).decode() == '02e7fcec053f0df94d88c86447970743e8a1979d242d09338dcf8687a9966f7fbc'
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), H_(42)], ecdsa_curve_name='secp256k1').node.public_key).decode() == '03ce7b690969d773ba9ed212464eb2b534b87b9b8a9383300bddabe1f093f79220'
|
||||
assert (
|
||||
hexlify(
|
||||
btc.get_public_node(
|
||||
self.client, [H_(111), 42], ecdsa_curve_name="secp256k1"
|
||||
).node.public_key
|
||||
)
|
||||
== b"02e7fcec053f0df94d88c86447970743e8a1979d242d09338dcf8687a9966f7fbc"
|
||||
)
|
||||
assert (
|
||||
hexlify(
|
||||
btc.get_public_node(
|
||||
self.client, [H_(111), H_(42)], ecdsa_curve_name="secp256k1"
|
||||
).node.public_key
|
||||
)
|
||||
== b"03ce7b690969d773ba9ed212464eb2b534b87b9b8a9383300bddabe1f093f79220"
|
||||
)
|
||||
|
||||
def test_nist256p1_curve(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), 42], ecdsa_curve_name='nist256p1').node.public_key).decode() == '02a9ce59b32bd64a70bc52aca96e5d09af65c6b9593ba2a60af8fccfe1437f2129'
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), H_(42)], ecdsa_curve_name='nist256p1').node.public_key).decode() == '026fe35d8afed67dbf0561a1d32922e8ad0cd0d86effbc82be970cbed7d9bab2c2'
|
||||
assert (
|
||||
hexlify(
|
||||
btc.get_public_node(
|
||||
self.client, [H_(111), 42], ecdsa_curve_name="nist256p1"
|
||||
).node.public_key
|
||||
)
|
||||
== b"02a9ce59b32bd64a70bc52aca96e5d09af65c6b9593ba2a60af8fccfe1437f2129"
|
||||
)
|
||||
assert (
|
||||
hexlify(
|
||||
btc.get_public_node(
|
||||
self.client, [H_(111), H_(42)], ecdsa_curve_name="nist256p1"
|
||||
).node.public_key
|
||||
)
|
||||
== b"026fe35d8afed67dbf0561a1d32922e8ad0cd0d86effbc82be970cbed7d9bab2c2"
|
||||
)
|
||||
|
||||
def test_ed25519_curve(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
# ed25519 curve does not support public derivation, so test only private derivation paths
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), H_(42)], ecdsa_curve_name='ed25519').node.public_key).decode() == '0069a14b478e508eab6e93303f4e6f5c50b8136627830f2ed5c3a835fc6c0ea2b7'
|
||||
assert hexlify(btc.get_public_node(self.client, [H_(111), H_(65535)], ecdsa_curve_name='ed25519').node.public_key).decode() == '00514f73a05184458611b14c348fee4fd988d36cf3aee7207737861bac611de991'
|
||||
assert (
|
||||
hexlify(
|
||||
btc.get_public_node(
|
||||
self.client, [H_(111), H_(42)], ecdsa_curve_name="ed25519"
|
||||
).node.public_key
|
||||
)
|
||||
== b"0069a14b478e508eab6e93303f4e6f5c50b8136627830f2ed5c3a835fc6c0ea2b7"
|
||||
)
|
||||
assert (
|
||||
hexlify(
|
||||
btc.get_public_node(
|
||||
self.client, [H_(111), H_(65535)], ecdsa_curve_name="ed25519"
|
||||
).node.public_key
|
||||
)
|
||||
== b"00514f73a05184458611b14c348fee4fd988d36cf3aee7207737861bac611de991"
|
||||
)
|
||||
# test failure when using public derivation
|
||||
with pytest.raises(CallException):
|
||||
btc.get_public_node(self.client, [H_(111), 42], ecdsa_curve_name='ed25519')
|
||||
btc.get_public_node(self.client, [H_(111), 42], ecdsa_curve_name="ed25519")
|
||||
|
@ -16,20 +16,23 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import lisk
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
LISK_PATH = parse_path("m/44h/134h/0h/1h")
|
||||
|
||||
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskGetaddress(TrezorTest):
|
||||
|
||||
def test_lisk_getaddress(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert lisk.get_address(self.client, LISK_PATH[:2]) == '1431530009238518937L'
|
||||
assert lisk.get_address(self.client, LISK_PATH[:3]) == '17563781916205589679L'
|
||||
assert lisk.get_address(self.client, LISK_PATH) == '1874186517773691964L'
|
||||
assert lisk.get_address(self.client, parse_path("m/44h/134h/999h/999h")) == '16295203558710684671L'
|
||||
assert lisk.get_address(self.client, LISK_PATH[:2]) == "1431530009238518937L"
|
||||
assert lisk.get_address(self.client, LISK_PATH[:3]) == "17563781916205589679L"
|
||||
assert lisk.get_address(self.client, LISK_PATH) == "1874186517773691964L"
|
||||
assert (
|
||||
lisk.get_address(self.client, parse_path("m/44h/134h/999h/999h"))
|
||||
== "16295203558710684671L"
|
||||
)
|
||||
|
@ -15,20 +15,24 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import lisk
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
LISK_PATH = parse_path("m/44h/134h/0h/0h")
|
||||
|
||||
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskGetPublicKey(TrezorTest):
|
||||
|
||||
def test_lisk_get_public_key(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = lisk.get_public_key(self.client, LISK_PATH)
|
||||
assert hexlify(sig.public_key) == b'eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'
|
||||
assert (
|
||||
hexlify(sig.public_key)
|
||||
== b"eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294"
|
||||
)
|
||||
|
@ -15,27 +15,42 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import lisk
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
LISK_PATH = parse_path("m/44h/134h/0h/0h")
|
||||
|
||||
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskSignmessage(TrezorTest):
|
||||
|
||||
def test_sign(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = lisk.sign_message(self.client, LISK_PATH, 'This is an example of a signed message.')
|
||||
assert hexlify(sig.public_key) == b'eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'
|
||||
assert hexlify(sig.signature) == b'7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05'
|
||||
sig = lisk.sign_message(
|
||||
self.client, LISK_PATH, "This is an example of a signed message."
|
||||
)
|
||||
assert (
|
||||
hexlify(sig.public_key)
|
||||
== b"eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05"
|
||||
)
|
||||
|
||||
def test_sign_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = lisk.sign_message(self.client, LISK_PATH, 'VeryLongMessage!' * 64)
|
||||
assert hexlify(sig.public_key) == b'eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'
|
||||
assert hexlify(sig.signature) == b'19c26f4b6f2ecf2feef57d22237cf97eb7862fdc2fb8c303878843f5dd728191f7837cf8d0ed41f8e470b15181223a3a5131881add9c22b2453b01be4edef104'
|
||||
sig = lisk.sign_message(self.client, LISK_PATH, "VeryLongMessage!" * 64)
|
||||
assert (
|
||||
hexlify(sig.public_key)
|
||||
== b"eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"19c26f4b6f2ecf2feef57d22237cf97eb7862fdc2fb8c303878843f5dd728191f7837cf8d0ed41f8e470b15181223a3a5131881add9c22b2453b01be4edef104"
|
||||
)
|
||||
|
@ -15,77 +15,100 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import lisk, messages as proto
|
||||
from trezorlib.tools import parse_path
|
||||
from trezorlib import lisk
|
||||
|
||||
PUBLIC_KEY = unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294')
|
||||
from .common import TrezorTest
|
||||
|
||||
PUBLIC_KEY = unhexlify(
|
||||
"eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskSignTx(TrezorTest):
|
||||
|
||||
def test_lisk_sign_tx_send(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.LiskSignedTx(
|
||||
signature=unhexlify('b62717d581e5713bca60b758b661e6cfa091addc6caedd57534e06cda805943ee80797b9fb9a1e1b2bd584e292d2a7f832a4d1b3f15f00e1ee1b72de7e195a08')
|
||||
signature=unhexlify(
|
||||
"b62717d581e5713bca60b758b661e6cfa091addc6caedd57534e06cda805943ee80797b9fb9a1e1b2bd584e292d2a7f832a4d1b3f15f00e1ee1b72de7e195a08"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
lisk.sign_tx(self.client, parse_path("m/44'/134'/0'/0'"), {
|
||||
lisk.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/134'/0'/0'"),
|
||||
{
|
||||
"amount": "10000000",
|
||||
"recipientId": "9971262264659915921L",
|
||||
"timestamp": 57525937,
|
||||
"type": 0,
|
||||
"fee": "10000000",
|
||||
"asset": {}
|
||||
})
|
||||
"asset": {},
|
||||
},
|
||||
)
|
||||
|
||||
def test_lisk_sign_tx_send_with_data(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.LiskSignedTx(
|
||||
signature=unhexlify('5dd0dbb87ee46f3e985b1ef2df85cb0bec481e8601d150388f73e198cdd57a698eab076c7cd5b281fbb6a83dd3dc64d91a6eccd1614dffd46f101194ffa3a004')
|
||||
signature=unhexlify(
|
||||
"5dd0dbb87ee46f3e985b1ef2df85cb0bec481e8601d150388f73e198cdd57a698eab076c7cd5b281fbb6a83dd3dc64d91a6eccd1614dffd46f101194ffa3a004"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
lisk.sign_tx(self.client, parse_path("m/44'/134'/0'/0'"), {
|
||||
lisk.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/134'/0'/0'"),
|
||||
{
|
||||
"amount": "10000000",
|
||||
"recipientId": "9971262264659915921L",
|
||||
"timestamp": 57525937,
|
||||
"type": 0,
|
||||
"fee": "20000000",
|
||||
"asset": {
|
||||
"data": "Test data"
|
||||
}
|
||||
})
|
||||
"asset": {"data": "Test data"},
|
||||
},
|
||||
)
|
||||
|
||||
def test_lisk_sign_tx_second_signature(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.PublicKey),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.LiskSignedTx(
|
||||
signature=unhexlify('f02bdc40a7599c21d29db4080ff1ff8934f76eedf5b0c4fa695c8a64af2f0b40a5c4f92db203863eebbbfad8f0611a23f451ed8bb711490234cdfb034728fd01')
|
||||
signature=unhexlify(
|
||||
"f02bdc40a7599c21d29db4080ff1ff8934f76eedf5b0c4fa695c8a64af2f0b40a5c4f92db203863eebbbfad8f0611a23f451ed8bb711490234cdfb034728fd01"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
lisk.sign_tx(self.client, parse_path("m/44'/134'/0'/0'"), {
|
||||
lisk.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/134'/0'/0'"),
|
||||
{
|
||||
"amount": "0",
|
||||
"timestamp": 57525937,
|
||||
"type": 1,
|
||||
@ -94,46 +117,58 @@ class TestMsgLiskSignTx(TrezorTest):
|
||||
"signature": {
|
||||
"publicKey": "5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09"
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
def test_lisk_sign_tx_delegate_registration(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.LiskSignedTx(
|
||||
signature=unhexlify('5ac02b2882b9d7d0f944e48baadc27de1296cc08c3533f7c8e380fbbb9fb4a6ac81b5dc57060d7d8c68912eea24eb6e39024801bccc0d55020e2052b0c2bb701')
|
||||
signature=unhexlify(
|
||||
"5ac02b2882b9d7d0f944e48baadc27de1296cc08c3533f7c8e380fbbb9fb4a6ac81b5dc57060d7d8c68912eea24eb6e39024801bccc0d55020e2052b0c2bb701"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
lisk.sign_tx(self.client, parse_path("m/44'/134'/0'/0'"), {
|
||||
lisk.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/134'/0'/0'"),
|
||||
{
|
||||
"amount": "0",
|
||||
"timestamp": 57525937,
|
||||
"type": 2,
|
||||
"fee": "2500000000",
|
||||
"asset": {
|
||||
"delegate": {
|
||||
"username": "trezor_t"
|
||||
}
|
||||
}
|
||||
})
|
||||
"asset": {"delegate": {"username": "trezor_t"}},
|
||||
},
|
||||
)
|
||||
|
||||
def test_lisk_sign_tx_cast_votes(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.LiskSignedTx(
|
||||
signature=unhexlify('1d0599a8387edaa4a6d309b8a78accd1ceaff20ff9d87136b01cba0efbcb9781c13dc2b0bab5a1ea4f196d8dcc9dbdbd2d56dbffcc088fc77686b2e2c2fe560f')
|
||||
signature=unhexlify(
|
||||
"1d0599a8387edaa4a6d309b8a78accd1ceaff20ff9d87136b01cba0efbcb9781c13dc2b0bab5a1ea4f196d8dcc9dbdbd2d56dbffcc088fc77686b2e2c2fe560f"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
lisk.sign_tx(self.client, parse_path("m/44'/134'/0'/0'"), {
|
||||
lisk.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/134'/0'/0'"),
|
||||
{
|
||||
"amount": "0",
|
||||
"timestamp": 57525937,
|
||||
"type": 3,
|
||||
@ -141,24 +176,32 @@ class TestMsgLiskSignTx(TrezorTest):
|
||||
"asset": {
|
||||
"votes": [
|
||||
"+b002f58531c074c7190714523eec08c48db8c7cfc0c943097db1a2e82ed87f84",
|
||||
"-ec111c8ad482445cfe83d811a7edd1f1d2765079c99d7d958cca1354740b7614"
|
||||
"-ec111c8ad482445cfe83d811a7edd1f1d2765079c99d7d958cca1354740b7614",
|
||||
]
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
def test_lisk_sign_tx_multisignature(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.LiskSignedTx(
|
||||
signature=unhexlify('88923866c2d500a6927715699ab41a0f58ea4b52e552d90e923bc24ac9da240f2328c93f9ce043a1da4937d4b61c7f57c02fc931f9824d06b24731e7be23c506')
|
||||
signature=unhexlify(
|
||||
"88923866c2d500a6927715699ab41a0f58ea4b52e552d90e923bc24ac9da240f2328c93f9ce043a1da4937d4b61c7f57c02fc931f9824d06b24731e7be23c506"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
lisk.sign_tx(self.client, parse_path("m/44'/134'/0'/0'"), {
|
||||
lisk.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/134'/0'/0'"),
|
||||
{
|
||||
"amount": "0",
|
||||
"timestamp": 57525937,
|
||||
"type": 4,
|
||||
@ -169,8 +212,9 @@ class TestMsgLiskSignTx(TrezorTest):
|
||||
"lifetime": 5,
|
||||
"keysgroup": [
|
||||
"+5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09",
|
||||
"+922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa"
|
||||
]
|
||||
"+922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa",
|
||||
],
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -15,43 +15,55 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import lisk, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import lisk
|
||||
|
||||
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskVerifymessage(TrezorTest):
|
||||
|
||||
def test_verify(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.Success(message='Message verified')
|
||||
])
|
||||
proto.Success(message="Message verified"),
|
||||
]
|
||||
)
|
||||
lisk.verify_message(
|
||||
self.client,
|
||||
unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'),
|
||||
unhexlify('7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05'),
|
||||
'This is an example of a signed message.'
|
||||
unhexlify(
|
||||
"eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294"
|
||||
),
|
||||
unhexlify(
|
||||
"7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
|
||||
def test_verify_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.Success(message='Message verified')
|
||||
])
|
||||
proto.Success(message="Message verified"),
|
||||
]
|
||||
)
|
||||
lisk.verify_message(
|
||||
self.client,
|
||||
unhexlify('8bca6b65a1a877767b746ea0b3c4310d404aa113df99c1b554e1802d70185ab5'),
|
||||
unhexlify('458ca5896d0934866992268f7509b5e954d568b1251e20c19bd3149ee3c86ffb5a44d1c2a0abbb99a3ab4767272dbb0e419b4579e890a24919ebbbe6cc0f970f'),
|
||||
'VeryLongMessage!' * 64
|
||||
unhexlify(
|
||||
"8bca6b65a1a877767b746ea0b3c4310d404aa113df99c1b554e1802d70185ab5"
|
||||
),
|
||||
unhexlify(
|
||||
"458ca5896d0934866992268f7509b5e954d568b1251e20c19bd3149ee3c86ffb5a44d1c2a0abbb99a3ab4767272dbb0e419b4579e890a24919ebbbe6cc0f970f"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
|
@ -16,10 +16,9 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc, debuglink, device
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import btc
|
||||
from trezorlib import debuglink
|
||||
from trezorlib import device
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
@ -36,12 +35,12 @@ class TestDeviceLoad(TrezorTest):
|
||||
passphrase_protection = self.client.debug.read_passphrase_protection()
|
||||
assert passphrase_protection is False
|
||||
|
||||
address = btc.get_address(self.client, 'Bitcoin', [])
|
||||
assert address == '1EfKbQupktEMXf4gujJ9kCFo83k1iMqwqK'
|
||||
address = btc.get_address(self.client, "Bitcoin", [])
|
||||
assert address == "1EfKbQupktEMXf4gujJ9kCFo83k1iMqwqK"
|
||||
|
||||
def test_load_device_2(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_passphrase('passphrase')
|
||||
self.client.set_passphrase("passphrase")
|
||||
|
||||
mnemonic = self.client.debug.read_mnemonic()
|
||||
assert mnemonic == self.mnemonic12
|
||||
@ -52,39 +51,79 @@ class TestDeviceLoad(TrezorTest):
|
||||
passphrase_protection = self.client.debug.read_passphrase_protection()
|
||||
assert passphrase_protection is True
|
||||
|
||||
address = btc.get_address(self.client, 'Bitcoin', [])
|
||||
assert address == '15fiTDFwZd2kauHYYseifGi9daH2wniDHH'
|
||||
address = btc.get_address(self.client, "Bitcoin", [])
|
||||
assert address == "15fiTDFwZd2kauHYYseifGi9daH2wniDHH"
|
||||
|
||||
def test_load_device_utf(self):
|
||||
words_nfkd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfkc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
words_nfkc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
words_nfd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
|
||||
passphrase_nfkd = u'Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko'
|
||||
passphrase_nfc = u'Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko'
|
||||
passphrase_nfkc = u'Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko'
|
||||
passphrase_nfd = u'Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko'
|
||||
passphrase_nfkd = (
|
||||
u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
||||
)
|
||||
passphrase_nfc = (
|
||||
u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
||||
)
|
||||
passphrase_nfkc = (
|
||||
u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
||||
)
|
||||
passphrase_nfd = (
|
||||
u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
||||
)
|
||||
|
||||
device.wipe(self.client)
|
||||
debuglink.load_device_by_mnemonic(self.client, mnemonic=words_nfkd, pin='', passphrase_protection=True, label='test', language='english', skip_checksum=True)
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
mnemonic=words_nfkd,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="english",
|
||||
skip_checksum=True,
|
||||
)
|
||||
self.client.set_passphrase(passphrase_nfkd)
|
||||
address_nfkd = btc.get_address(self.client, 'Bitcoin', [])
|
||||
address_nfkd = btc.get_address(self.client, "Bitcoin", [])
|
||||
|
||||
device.wipe(self.client)
|
||||
debuglink.load_device_by_mnemonic(self.client, mnemonic=words_nfc, pin='', passphrase_protection=True, label='test', language='english', skip_checksum=True)
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
mnemonic=words_nfc,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="english",
|
||||
skip_checksum=True,
|
||||
)
|
||||
self.client.set_passphrase(passphrase_nfc)
|
||||
address_nfc = btc.get_address(self.client, 'Bitcoin', [])
|
||||
address_nfc = btc.get_address(self.client, "Bitcoin", [])
|
||||
|
||||
device.wipe(self.client)
|
||||
debuglink.load_device_by_mnemonic(self.client, mnemonic=words_nfkc, pin='', passphrase_protection=True, label='test', language='english', skip_checksum=True)
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
mnemonic=words_nfkc,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="english",
|
||||
skip_checksum=True,
|
||||
)
|
||||
self.client.set_passphrase(passphrase_nfkc)
|
||||
address_nfkc = btc.get_address(self.client, 'Bitcoin', [])
|
||||
address_nfkc = btc.get_address(self.client, "Bitcoin", [])
|
||||
|
||||
device.wipe(self.client)
|
||||
debuglink.load_device_by_mnemonic(self.client, mnemonic=words_nfd, pin='', passphrase_protection=True, label='test', language='english', skip_checksum=True)
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
mnemonic=words_nfd,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="english",
|
||||
skip_checksum=True,
|
||||
)
|
||||
self.client.set_passphrase(passphrase_nfd)
|
||||
address_nfd = btc.get_address(self.client, 'Bitcoin', [])
|
||||
address_nfd = btc.get_address(self.client, "Bitcoin", [])
|
||||
|
||||
assert address_nfkd == address_nfc
|
||||
assert address_nfkd == address_nfkc
|
||||
|
@ -16,30 +16,43 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc, debuglink
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import btc
|
||||
from trezorlib import debuglink
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestDeviceLoadXprv(TrezorTest):
|
||||
|
||||
def test_load_device_xprv_1(self):
|
||||
debuglink.load_device_by_xprv(self.client, xprv='xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73', pin='', passphrase_protection=False, label='test', language='english')
|
||||
debuglink.load_device_by_xprv(
|
||||
self.client,
|
||||
xprv="xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73",
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label="test",
|
||||
language="english",
|
||||
)
|
||||
|
||||
passphrase_protection = self.client.debug.read_passphrase_protection()
|
||||
assert passphrase_protection is False
|
||||
|
||||
address = btc.get_address(self.client, 'Bitcoin', [])
|
||||
assert address == '128RdrAkJDmqasgvfRf6MC5VcX4HKqH4mR'
|
||||
address = btc.get_address(self.client, "Bitcoin", [])
|
||||
assert address == "128RdrAkJDmqasgvfRf6MC5VcX4HKqH4mR"
|
||||
|
||||
def test_load_device_xprv_2(self):
|
||||
debuglink.load_device_by_xprv(self.client, xprv='xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73', pin='', passphrase_protection=True, label='test', language='english')
|
||||
debuglink.load_device_by_xprv(
|
||||
self.client,
|
||||
xprv="xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73",
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="english",
|
||||
)
|
||||
|
||||
self.client.set_passphrase('passphrase')
|
||||
self.client.set_passphrase("passphrase")
|
||||
|
||||
passphrase_protection = self.client.debug.read_passphrase_protection()
|
||||
assert passphrase_protection is True
|
||||
|
||||
address = btc.get_address(self.client, 'Bitcoin', [])
|
||||
assert address == '1CHUbFa4wTTPYgkYaw2LHSd5D4qJjMU8ri'
|
||||
address = btc.get_address(self.client, "Bitcoin", [])
|
||||
assert address == "1CHUbFa4wTTPYgkYaw2LHSd5D4qJjMU8ri"
|
||||
|
@ -16,15 +16,21 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib.tools import parse_path
|
||||
from trezorlib import nem
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMGetaddress(TrezorTest):
|
||||
|
||||
def test_nem_getaddress(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x68) == "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN"
|
||||
assert nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x98) == "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF"
|
||||
assert (
|
||||
nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x68)
|
||||
== "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN"
|
||||
)
|
||||
assert (
|
||||
nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x98)
|
||||
== "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF"
|
||||
)
|
||||
|
@ -14,162 +14,160 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
from binascii import hexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
import pytest
|
||||
|
||||
from trezorlib import nem
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
|
||||
def test_nem_signtx_mosaic_supply_change(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"mosaicId": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000'
|
||||
assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a"
|
||||
)
|
||||
|
||||
def test_nem_signtx_mosaic_creation(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": {},
|
||||
"description": "lorem"
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000'
|
||||
assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e"
|
||||
)
|
||||
|
||||
def test_nem_signtx_mosaic_creation_properties(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": [
|
||||
{
|
||||
"name": "divisibility",
|
||||
"value": "4"
|
||||
},
|
||||
{
|
||||
"name": "initialSupply",
|
||||
"value": "200"
|
||||
},
|
||||
{
|
||||
"name": "supplyMutable",
|
||||
"value": "false"
|
||||
},
|
||||
{
|
||||
"name": "transferable",
|
||||
"value": "true"
|
||||
}
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"description": "lorem"
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000'
|
||||
assert hexlify(tx.signature) == b'f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e"
|
||||
)
|
||||
|
||||
def test_nem_signtx_mosaic_creation_levy(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"properties": [
|
||||
{
|
||||
"name": "divisibility",
|
||||
"value": "4"
|
||||
},
|
||||
{
|
||||
"name": "initialSupply",
|
||||
"value": "200"
|
||||
},
|
||||
{
|
||||
"name": "supplyMutable",
|
||||
"value": "false"
|
||||
},
|
||||
{
|
||||
"name": "transferable",
|
||||
"value": "true"
|
||||
}
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"levy": {
|
||||
"type": 1,
|
||||
"fee": 2,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"mosaicId": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
},
|
||||
},
|
||||
"description": "lorem"
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000'
|
||||
assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a"
|
||||
)
|
||||
|
@ -14,45 +14,51 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
import pytest
|
||||
import time
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import messages as proto, nem
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import nem
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
|
||||
def test_nem_signtx_mosaic_supply_change(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"mosaicId": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000'
|
||||
assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a"
|
||||
)
|
||||
|
||||
def test_nem_signtx_mosaic_creation(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -62,16 +68,12 @@ class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": {},
|
||||
"description": "lorem"
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
@ -80,8 +82,14 @@ class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
|
||||
# not using client.nem_sign_tx() because of swiping
|
||||
tx = self._nem_sign(2, test_suite)
|
||||
assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000'
|
||||
assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e"
|
||||
)
|
||||
|
||||
def test_nem_signtx_mosaic_creation_properties(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -91,33 +99,17 @@ class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": [
|
||||
{
|
||||
"name": "divisibility",
|
||||
"value": "4"
|
||||
},
|
||||
{
|
||||
"name": "initialSupply",
|
||||
"value": "200"
|
||||
},
|
||||
{
|
||||
"name": "supplyMutable",
|
||||
"value": "false"
|
||||
},
|
||||
{
|
||||
"name": "transferable",
|
||||
"value": "true"
|
||||
}
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"description": "lorem"
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
@ -126,8 +118,14 @@ class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
|
||||
# not using client.nem_sign_tx() because of swiping
|
||||
tx = self._nem_sign(2, test_suite)
|
||||
assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000'
|
||||
assert hexlify(tx.signature) == b'f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e"
|
||||
)
|
||||
|
||||
def test_nem_signtx_mosaic_creation_levy(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -137,41 +135,22 @@ class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"properties": [
|
||||
{
|
||||
"name": "divisibility",
|
||||
"value": "4"
|
||||
},
|
||||
{
|
||||
"name": "initialSupply",
|
||||
"value": "200"
|
||||
},
|
||||
{
|
||||
"name": "supplyMutable",
|
||||
"value": "false"
|
||||
},
|
||||
{
|
||||
"name": "transferable",
|
||||
"value": "true"
|
||||
}
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"levy": {
|
||||
"type": 1,
|
||||
"fee": 2,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"mosaicId": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
},
|
||||
},
|
||||
"description": "lorem"
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
@ -179,8 +158,14 @@ class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
}
|
||||
|
||||
tx = self._nem_sign(6, test_suite)
|
||||
assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000'
|
||||
assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a"
|
||||
)
|
||||
|
||||
def _nem_sign(self, num_of_swipes, test_suite):
|
||||
n = parse_path("m/44'/1'/0'/0'/0'")
|
||||
|
@ -15,46 +15,56 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import nem
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from trezorlib import nem
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMSignTxMultisig(TrezorTest):
|
||||
|
||||
def test_nem_signtx_aggregate_modification(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_AGGREGATE_MODIFICATION,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"modifications": [
|
||||
{
|
||||
"modificationType": 1, # Add
|
||||
"cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844"
|
||||
},
|
||||
"cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
}
|
||||
],
|
||||
"minCosignatories": {
|
||||
"relativeChange": 3
|
||||
},
|
||||
"minCosignatories": {"relativeChange": 3},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
assert hexlify(tx.data) == b'01100000020000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f878440400000003000000'
|
||||
assert hexlify(tx.signature) == b'1200e552d8732ce3eae96719731194abfc5a09d98f61bb35684f4eeaeff15b1bdf326ee7b1bbbe89d3f68c8e07ad3daf72e4c7f031094ad2236b97918ad98601'
|
||||
},
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01100000020000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f878440400000003000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"1200e552d8732ce3eae96719731194abfc5a09d98f61bb35684f4eeaeff15b1bdf326ee7b1bbbe89d3f68c8e07ad3daf72e4c7f031094ad2236b97918ad98601"
|
||||
)
|
||||
|
||||
def test_nem_signtx_multisig(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 1,
|
||||
"fee": 10000,
|
||||
"type": nem.TYPE_MULTISIG,
|
||||
@ -71,15 +81,25 @@ class TestMsgNEMSignTxMultisig(TrezorTest):
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844',
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'04100000010000980100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841027000000000000ff5f74049900000001010000010000980200000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844983a000000000000320901002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572'
|
||||
assert hexlify(tx.signature) == b'0cab2fddf2f02b5d7201675b9a71869292fe25ed33a366c7d2cbea7676fed491faaa03310079b7e17884b6ba2e3ea21c4f728d1cca8f190b8288207f6514820a'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"04100000010000980100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841027000000000000ff5f74049900000001010000010000980200000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844983a000000000000320901002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"0cab2fddf2f02b5d7201675b9a71869292fe25ed33a366c7d2cbea7676fed491faaa03310079b7e17884b6ba2e3ea21c4f728d1cca8f190b8288207f6514820a"
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 150,
|
||||
"type": nem.TYPE_MULTISIG,
|
||||
@ -89,25 +109,34 @@ class TestMsgNEMSignTxMultisig(TrezorTest):
|
||||
"fee": 2000,
|
||||
"type": nem.TYPE_PROVISION_NAMESPACE,
|
||||
"deadline": 100,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"newPart": "ABCDE",
|
||||
"rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"rentalFee": 1500,
|
||||
"parent": None,
|
||||
"version": (0x98 << 24),
|
||||
"signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844',
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620849600000000000000150300007d000000012000000100009840e2010020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844d007000000000000640000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff'
|
||||
assert hexlify(tx.signature) == b'c915ca3332380925f4050301cdc62269cf29437ac5955321b18da34e570c7fdbb1aec2940a2a553a2a5c90950a4db3c8d3ef899c1a108582e0657f66fbbb0b04'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620849600000000000000150300007d000000012000000100009840e2010020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844d007000000000000640000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"c915ca3332380925f4050301cdc62269cf29437ac5955321b18da34e570c7fdbb1aec2940a2a553a2a5c90950a4db3c8d3ef899c1a108582e0657f66fbbb0b04"
|
||||
)
|
||||
|
||||
def test_nem_signtx_multisig_signer(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 333,
|
||||
"fee": 200,
|
||||
"type": nem.TYPE_MULTISIG_SIGNATURE,
|
||||
@ -124,15 +153,25 @@ class TestMsgNEMSignTxMultisig(TrezorTest):
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844',
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'02100000010000984d01000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084c800000000000000bc010000240000002000000087923cd4805f3babe6b5af9cbb2b08be4458e39531618aed73c911f160c8e38528000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32'
|
||||
assert hexlify(tx.signature) == b'286358a16ae545bff798feab93a713440c7c2f236d52ac0e995669d17a1915b0903667c97fa04418eccb42333cba95b19bccc8ac1faa8224dcfaeb41890ae807'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"02100000010000984d01000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084c800000000000000bc010000240000002000000087923cd4805f3babe6b5af9cbb2b08be4458e39531618aed73c911f160c8e38528000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"286358a16ae545bff798feab93a713440c7c2f236d52ac0e995669d17a1915b0903667c97fa04418eccb42333cba95b19bccc8ac1faa8224dcfaeb41890ae807"
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 900000,
|
||||
"fee": 200000,
|
||||
"type": nem.TYPE_MULTISIG_SIGNATURE,
|
||||
@ -142,21 +181,24 @@ class TestMsgNEMSignTxMultisig(TrezorTest):
|
||||
"fee": 1000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 13123,
|
||||
"message": {
|
||||
},
|
||||
"mosaicId": {
|
||||
"namespaceId": "hellom",
|
||||
"name": "Hello mosaic"
|
||||
},
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
"signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844',
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'0210000001000098a0bb0d0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084400d030000000000640000002400000020000000c51395626a89a71c1ed785fb5974307a049b3b9e2165d56ed0302fe6b4f02a0128000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32'
|
||||
assert hexlify(tx.signature) == b'32b1fdf788c4a90c01eedf5972b7709745831d620c13e1e97b0de6481837e162ee551573f2409822754ae940731909ec4b79cf836487e898df476adb10467506'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"0210000001000098a0bb0d0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084400d030000000000640000002400000020000000c51395626a89a71c1ed785fb5974307a049b3b9e2165d56ed0302fe6b4f02a0128000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"32b1fdf788c4a90c01eedf5972b7709745831d620c13e1e97b0de6481837e162ee551573f2409822754ae940731909ec4b79cf836487e898df476adb10467506"
|
||||
)
|
||||
|
@ -15,56 +15,74 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
import pytest
|
||||
|
||||
from trezorlib import nem
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMSignTxOther(TrezorTest):
|
||||
|
||||
def test_nem_signtx_importance_transfer(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 12349215,
|
||||
"fee": 9900,
|
||||
"type": nem.TYPE_IMPORTANCE_TRANSFER,
|
||||
"deadline": 99,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"importanceTransfer": {
|
||||
"mode": 1, # activate
|
||||
"publicKey": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'01080000010000981f6fbc0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084ac26000000000000630000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844'
|
||||
assert hexlify(tx.signature) == b'b6d9434ec5df80e65e6e45d7f0f3c579b4adfe8567c42d981b06e8ac368b1aad2b24eebecd5efd41f4497051fca8ea8a5e77636a79afc46ee1a8e0fe9e3ba90b'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01080000010000981f6fbc0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084ac26000000000000630000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"b6d9434ec5df80e65e6e45d7f0f3c579b4adfe8567c42d981b06e8ac368b1aad2b24eebecd5efd41f4497051fca8ea8a5e77636a79afc46ee1a8e0fe9e3ba90b"
|
||||
)
|
||||
|
||||
def test_nem_signtx_provision_namespace(self):
|
||||
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_PROVISION_NAMESPACE,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"newPart": "ABCDE",
|
||||
"rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"rentalFee": 1500,
|
||||
"parent": None,
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff'
|
||||
assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d"
|
||||
)
|
||||
|
@ -15,19 +15,18 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import nem
|
||||
from trezorlib import messages as proto, nem
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMSignTx(TrezorTest):
|
||||
|
||||
def test_nem_signtx_simple(self):
|
||||
# tx hash: 209368053ac61969b6838ceb7e31badeb622ed6aa42d6c58365c42ad1a11e19d
|
||||
signature = unhexlify(
|
||||
@ -36,7 +35,8 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Unencrypted message
|
||||
@ -44,9 +44,13 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
# Confirm recipient
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.NEMSignedTx(),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"amount": 2000000,
|
||||
"fee": 2000000,
|
||||
@ -58,16 +62,21 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data) == b'01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572"
|
||||
)
|
||||
assert tx.signature == signature
|
||||
|
||||
def test_nem_signtx_encrypted_payload(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Ask for encryption
|
||||
@ -75,9 +84,13 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
# Confirm recipient
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.NEMSignedTx(),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"amount": 2000000,
|
||||
"fee": 2000000,
|
||||
@ -92,9 +105,13 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
"type": 2,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
assert hexlify(tx.data[:124]) == b'01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e0000000000680000000200000060000000'
|
||||
assert (
|
||||
hexlify(tx.data[:124])
|
||||
== b"01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e0000000000680000000200000060000000"
|
||||
)
|
||||
# after 124th byte comes iv (16B) salt (32B) and encrypted payload (48B)
|
||||
assert len(tx.data[124:]) == 16 + 32 + 48
|
||||
# because IV and salt are random (therefore the encrypted payload as well) those data can't be asserted
|
||||
@ -103,7 +120,10 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
def test_nem_signtx_xem_as_mosaic(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 5000000,
|
||||
"fee": 1000000,
|
||||
@ -111,27 +131,33 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x98 << 24),
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "nem",
|
||||
"name": "xem",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 9000000,
|
||||
},
|
||||
}
|
||||
],
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display 45 XEM (multiplied by amount)
|
||||
assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a404b4c000000000000000000010000001a0000000e000000030000006e656d0300000078656d4054890000000000'
|
||||
assert hexlify(tx.signature) == b'7b25a84b65adb489ea55739f1ca2d83a0ae069c3c58d0ea075fc30bfe8f649519199ad2324ca229c6c3214191469f95326e99712124592cae7cd3a092c93ac0c'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a404b4c000000000000000000010000001a0000000e000000030000006e656d0300000078656d4054890000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"7b25a84b65adb489ea55739f1ca2d83a0ae069c3c58d0ea075fc30bfe8f649519199ad2324ca229c6c3214191469f95326e99712124592cae7cd3a092c93ac0c"
|
||||
)
|
||||
|
||||
def test_nem_signtx_unknown_mosaic(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
@ -139,28 +165,34 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x98 << 24),
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "xxx",
|
||||
"name": "aa",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "xxx", "name": "aa"},
|
||||
"quantity": 3500000,
|
||||
},
|
||||
}
|
||||
],
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display warning about unknown mosaic and then dialog for 7000000 raw units of xxx.aa and 0 XEM
|
||||
assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e00000000000000000001000000190000000d00000003000000787878020000006161e067350000000000'
|
||||
assert hexlify(tx.signature) == b'2f0280420eceb41ef9e5d94fa44ddda9cdc70b8f423ae18af577f6d85df64bb4aaf40cf24fc6eef47c63b0963611f8682348cecdc49a9b64eafcbe7afcb49102'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e00000000000000000001000000190000000d00000003000000787878020000006161e067350000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"2f0280420eceb41ef9e5d94fa44ddda9cdc70b8f423ae18af577f6d85df64bb4aaf40cf24fc6eef47c63b0963611f8682348cecdc49a9b64eafcbe7afcb49102"
|
||||
)
|
||||
|
||||
def test_nem_signtx_known_mosaic(self):
|
||||
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 3000000,
|
||||
"fee": 1000000,
|
||||
@ -168,28 +200,34 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "dim",
|
||||
"name": "token",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "dim", "name": "token"},
|
||||
"quantity": 111000,
|
||||
},
|
||||
}
|
||||
],
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display 0 XEM and 0.333 DIMTOK
|
||||
assert hexlify(tx.data) == b'0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c54c0c62d000000000000000000010000001c000000100000000300000064696d05000000746f6b656e98b1010000000000'
|
||||
assert hexlify(tx.signature) == b'e7f14ef8c39727bfd257e109cd5acac31542f2e41f2e5deb258fc1db602b690eb1cabca41a627fe2adc51f3193db85c76b41c80bb60161eb8738ebf20b507104'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c54c0c62d000000000000000000010000001c000000100000000300000064696d05000000746f6b656e98b1010000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"e7f14ef8c39727bfd257e109cd5acac31542f2e41f2e5deb258fc1db602b690eb1cabca41a627fe2adc51f3193db85c76b41c80bb60161eb8738ebf20b507104"
|
||||
)
|
||||
|
||||
def test_nem_signtx_known_mosaic_with_levy(self):
|
||||
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
@ -197,27 +235,33 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "dim",
|
||||
"name": "coin",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "dim", "name": "coin"},
|
||||
"quantity": 222000,
|
||||
},
|
||||
}
|
||||
],
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display 0 XEM and 0.444 DIM and levy of 0.000444 DIM
|
||||
assert hexlify(tx.data) == b'0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000010000001b0000000f0000000300000064696d04000000636f696e3063030000000000'
|
||||
assert hexlify(tx.signature) == b'd3222dd7b83d66bda0539827ac6f909d06e40350b5e5e893d6fa762f954e9bf7da61022ef04950e7b6dfa88a2278f2f8a1b21df2bc3af22b388cb3a90bf76f07'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000010000001b0000000f0000000300000064696d04000000636f696e3063030000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"d3222dd7b83d66bda0539827ac6f909d06e40350b5e5e893d6fa762f954e9bf7da61022ef04950e7b6dfa88a2278f2f8a1b21df2bc3af22b388cb3a90bf76f07"
|
||||
)
|
||||
|
||||
def test_nem_signtx_multiple_mosaics(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
tx = nem.sign_tx(self.client, parse_path("m/44'/1'/0'/0'/0'"), {
|
||||
tx = nem.sign_tx(
|
||||
self.client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
@ -225,48 +269,39 @@ class TestMsgNEMSignTx(TrezorTest):
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {
|
||||
},
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "nem",
|
||||
"name": "xem",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 3000000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "abc",
|
||||
"name": "mosaic",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "abc", "name": "mosaic"},
|
||||
"quantity": 200,
|
||||
},
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "nem",
|
||||
"name": "xem",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 30000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "abc",
|
||||
"name": "mosaic",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "abc", "name": "mosaic"},
|
||||
"quantity": 2000000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "breeze",
|
||||
"name": "breeze-token",
|
||||
},
|
||||
"mosaicId": {"namespaceId": "breeze", "name": "breeze-token"},
|
||||
"quantity": 111000,
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display warning, 6.06 XEM, 4000400 raw units of abc.mosaic (mosaics are merged)
|
||||
# and 222000 BREEZE
|
||||
assert hexlify(tx.data) == b'0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000030000001d0000001100000003000000616263060000006d6f7361696348851e0000000000260000001a00000006000000627265657a650c000000627265657a652d746f6b656e98b10100000000001a0000000e000000030000006e656d0300000078656df03b2e0000000000'
|
||||
assert hexlify(tx.signature) == b'b2b9319fca87a05bee17108edd9a8f78aeffef74bf6b4badc6da5d46e8ff4fe82e24bf69d8e6c4097d072adf39d0c753e7580f8afb21e3288ebfb7c4d84e470d'
|
||||
assert (
|
||||
hexlify(tx.data)
|
||||
== b"0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000030000001d0000001100000003000000616263060000006d6f7361696348851e0000000000260000001a00000006000000627265657a650c000000627265657a652d746f6b656e98b10100000000001a0000000e000000030000006e656d0300000078656df03b2e0000000000"
|
||||
)
|
||||
assert (
|
||||
hexlify(tx.signature)
|
||||
== b"b2b9319fca87a05bee17108edd9a8f78aeffef74bf6b4badc6da5d46e8ff4fe82e24bf69d8e6c4097d072adf39d0c753e7580f8afb21e3288ebfb7c4d84e470d"
|
||||
)
|
||||
|
@ -16,47 +16,77 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgPing(TrezorTest):
|
||||
|
||||
def test_ping(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.Success()])
|
||||
res = self.client.ping('random data')
|
||||
assert res == 'random data'
|
||||
res = self.client.ping("random data")
|
||||
assert res == "random data"
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.Success()])
|
||||
res = self.client.ping('random data', button_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall),
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
res = self.client.ping("random data", button_protection=True)
|
||||
assert res == "random data"
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PinMatrixRequest(), proto.Success()])
|
||||
res = self.client.ping('random data', pin_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[proto.PinMatrixRequest(), proto.Success()]
|
||||
)
|
||||
res = self.client.ping("random data", pin_protection=True)
|
||||
assert res == "random data"
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.PassphraseRequest(), proto.Success()])
|
||||
res = self.client.ping('random data', passphrase_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[proto.PassphraseRequest(), proto.Success()]
|
||||
)
|
||||
res = self.client.ping("random data", passphrase_protection=True)
|
||||
assert res == "random data"
|
||||
|
||||
def test_ping_caching(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success()])
|
||||
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
res = self.client.ping(
|
||||
"random data",
|
||||
button_protection=True,
|
||||
pin_protection=True,
|
||||
passphrase_protection=True,
|
||||
)
|
||||
assert res == "random data"
|
||||
|
||||
with self.client:
|
||||
# pin and passphrase are cached
|
||||
self.client.set_expected_responses([proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.Success()])
|
||||
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
|
||||
assert res == 'random data'
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall),
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
res = self.client.ping(
|
||||
"random data",
|
||||
button_protection=True,
|
||||
pin_protection=True,
|
||||
passphrase_protection=True,
|
||||
)
|
||||
assert res == "random data"
|
||||
|
@ -16,22 +16,25 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import device, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import device
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgRecoverydevice(TrezorTest):
|
||||
|
||||
def test_pin_passphrase(self):
|
||||
mnemonic = self.mnemonic12.split(' ')
|
||||
ret = self.client.call_raw(proto.RecoveryDevice(word_count=12,
|
||||
mnemonic = self.mnemonic12.split(" ")
|
||||
ret = self.client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label='label',
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
label="label",
|
||||
language="english",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
@ -88,13 +91,17 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
self.client.call_raw(proto.Cancel())
|
||||
|
||||
def test_nopin_nopassphrase(self):
|
||||
mnemonic = self.mnemonic12.split(' ')
|
||||
ret = self.client.call_raw(proto.RecoveryDevice(word_count=12,
|
||||
mnemonic = self.mnemonic12.split(" ")
|
||||
ret = self.client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label='label',
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
label="label",
|
||||
language="english",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
@ -138,12 +145,16 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
assert isinstance(resp, proto.Success)
|
||||
|
||||
def test_word_fail(self):
|
||||
ret = self.client.call_raw(proto.RecoveryDevice(word_count=12,
|
||||
ret = self.client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label='label',
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
label="label",
|
||||
language="english",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
@ -154,19 +165,23 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
for _ in range(int(12 * 2)):
|
||||
(word, pos) = self.client.debug.read_recovery_word()
|
||||
if pos != 0:
|
||||
ret = self.client.call_raw(proto.WordAck(word='kwyjibo'))
|
||||
ret = self.client.call_raw(proto.WordAck(word="kwyjibo"))
|
||||
assert isinstance(ret, proto.Failure)
|
||||
break
|
||||
else:
|
||||
self.client.call_raw(proto.WordAck(word=word))
|
||||
|
||||
def test_pin_fail(self):
|
||||
ret = self.client.call_raw(proto.RecoveryDevice(word_count=12,
|
||||
ret = self.client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label='label',
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
label="label",
|
||||
language="english",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
@ -190,4 +205,4 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
def test_already_initialized(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with pytest.raises(Exception):
|
||||
device.recover(self.client, 12, False, False, 'label', 'english')
|
||||
device.recover(self.client, 12, False, False, "label", "english")
|
||||
|
@ -16,21 +16,25 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgRecoverydeviceDryrun(TrezorTest):
|
||||
|
||||
def recovery_loop(self, mnemonic, result):
|
||||
ret = self.client.call_raw(proto.RecoveryDevice(word_count=12,
|
||||
ret = self.client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label='label',
|
||||
language='english',
|
||||
label="label",
|
||||
language="english",
|
||||
enforce_wordlist=True,
|
||||
dry_run=True))
|
||||
dry_run=True,
|
||||
)
|
||||
)
|
||||
|
||||
fakes = 0
|
||||
for _ in range(int(12 * 2)):
|
||||
@ -54,15 +58,15 @@ class TestMsgRecoverydeviceDryrun(TrezorTest):
|
||||
|
||||
def test_correct_notsame(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
mnemonic = ['all'] * 12
|
||||
mnemonic = ["all"] * 12
|
||||
self.recovery_loop(mnemonic, proto.Failure)
|
||||
|
||||
def test_correct_same(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
mnemonic = self.mnemonic12.split(' ')
|
||||
mnemonic = self.mnemonic12.split(" ")
|
||||
self.recovery_loop(mnemonic, proto.Success)
|
||||
|
||||
def test_incorrect(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
mnemonic = ['stick'] * 12
|
||||
mnemonic = ["stick"] * 12
|
||||
self.recovery_loop(mnemonic, proto.Failure)
|
||||
|
@ -18,24 +18,28 @@ import time
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import device, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import device
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgRecoverydeviceT2(TrezorTest):
|
||||
|
||||
def test_pin_passphrase(self):
|
||||
mnemonic = self.mnemonic12.split(' ')
|
||||
ret = self.client.call_raw(proto.RecoveryDevice(
|
||||
mnemonic = self.mnemonic12.split(" ")
|
||||
ret = self.client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label='label',
|
||||
enforce_wordlist=True))
|
||||
label="label",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# Enter word count
|
||||
assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.MnemonicWordCount)
|
||||
assert ret == proto.ButtonRequest(
|
||||
code=proto.ButtonRequestType.MnemonicWordCount
|
||||
)
|
||||
self.client.debug.input(str(len(mnemonic)))
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
@ -49,16 +53,16 @@ class TestMsgRecoverydeviceT2(TrezorTest):
|
||||
|
||||
# Enter PIN for first time
|
||||
assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other)
|
||||
self.client.debug.input('654')
|
||||
self.client.debug.input("654")
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Enter PIN for second time
|
||||
assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other)
|
||||
self.client.debug.input('654')
|
||||
self.client.debug.input("654")
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Workflow succesfully ended
|
||||
assert ret == proto.Success(message='Device recovered')
|
||||
assert ret == proto.Success(message="Device recovered")
|
||||
|
||||
# Mnemonic is the same
|
||||
self.client.init_device()
|
||||
@ -68,15 +72,20 @@ class TestMsgRecoverydeviceT2(TrezorTest):
|
||||
assert self.client.features.passphrase_protection is True
|
||||
|
||||
def test_nopin_nopassphrase(self):
|
||||
mnemonic = self.mnemonic12.split(' ')
|
||||
ret = self.client.call_raw(proto.RecoveryDevice(
|
||||
mnemonic = self.mnemonic12.split(" ")
|
||||
ret = self.client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label='label',
|
||||
enforce_wordlist=True))
|
||||
label="label",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# Enter word count
|
||||
assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.MnemonicWordCount)
|
||||
assert ret == proto.ButtonRequest(
|
||||
code=proto.ButtonRequestType.MnemonicWordCount
|
||||
)
|
||||
self.client.debug.input(str(len(mnemonic)))
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
@ -89,7 +98,7 @@ class TestMsgRecoverydeviceT2(TrezorTest):
|
||||
ret = self.client.transport.read()
|
||||
|
||||
# Workflow succesfully ended
|
||||
assert ret == proto.Success(message='Device recovered')
|
||||
assert ret == proto.Success(message="Device recovered")
|
||||
|
||||
# Mnemonic is the same
|
||||
self.client.init_device()
|
||||
@ -101,4 +110,4 @@ class TestMsgRecoverydeviceT2(TrezorTest):
|
||||
def test_already_initialized(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with pytest.raises(Exception):
|
||||
device.recover(self.client, 12, False, False, 'label', 'english')
|
||||
device.recover(self.client, 12, False, False, "label", "english")
|
||||
|
@ -15,31 +15,31 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
from trezorlib import device, messages as proto
|
||||
|
||||
from .common import TrezorTest, generate_entropy
|
||||
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import device
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgResetDevice(TrezorTest):
|
||||
|
||||
def test_reset_device(self):
|
||||
|
||||
# No PIN, no passphrase
|
||||
external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 128
|
||||
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language='english',
|
||||
label='test'
|
||||
))
|
||||
language="english",
|
||||
label="test",
|
||||
)
|
||||
)
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
@ -48,7 +48,7 @@ class TestMsgResetDevice(TrezorTest):
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(strength, internal_entropy, external_entropy)
|
||||
expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(strength // 32 * 3):
|
||||
@ -57,7 +57,7 @@ class TestMsgResetDevice(TrezorTest):
|
||||
self.client.debug.press_yes()
|
||||
self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
mnemonic = ' '.join(mnemonic)
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
@ -71,7 +71,7 @@ class TestMsgResetDevice(TrezorTest):
|
||||
|
||||
assert isinstance(resp, proto.Success)
|
||||
|
||||
mnemonic = ' '.join(mnemonic)
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that second pass printed out the same mnemonic once again
|
||||
assert mnemonic == expected_mnemonic
|
||||
@ -92,17 +92,19 @@ class TestMsgResetDevice(TrezorTest):
|
||||
assert isinstance(resp, proto.Success)
|
||||
|
||||
def test_reset_device_pin(self):
|
||||
external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 128
|
||||
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
language='english',
|
||||
label='test'
|
||||
))
|
||||
language="english",
|
||||
label="test",
|
||||
)
|
||||
)
|
||||
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.press_yes()
|
||||
@ -111,12 +113,12 @@ class TestMsgResetDevice(TrezorTest):
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
pin_encoded = self.client.debug.encode_pin('654')
|
||||
pin_encoded = self.client.debug.encode_pin("654")
|
||||
ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for second time
|
||||
pin_encoded = self.client.debug.encode_pin('654')
|
||||
pin_encoded = self.client.debug.encode_pin("654")
|
||||
ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
# Provide entropy
|
||||
@ -126,7 +128,7 @@ class TestMsgResetDevice(TrezorTest):
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(strength, internal_entropy, external_entropy)
|
||||
expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(strength // 32 * 3):
|
||||
@ -135,7 +137,7 @@ class TestMsgResetDevice(TrezorTest):
|
||||
self.client.debug.press_yes()
|
||||
self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
mnemonic = ' '.join(mnemonic)
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
@ -149,7 +151,7 @@ class TestMsgResetDevice(TrezorTest):
|
||||
|
||||
assert isinstance(resp, proto.Success)
|
||||
|
||||
mnemonic = ' '.join(mnemonic)
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that second pass printed out the same mnemonic once again
|
||||
assert mnemonic == expected_mnemonic
|
||||
@ -175,14 +177,16 @@ class TestMsgResetDevice(TrezorTest):
|
||||
# external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
strength = 128
|
||||
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
language='english',
|
||||
label='test'
|
||||
))
|
||||
language="english",
|
||||
label="test",
|
||||
)
|
||||
)
|
||||
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.press_yes()
|
||||
@ -204,4 +208,4 @@ class TestMsgResetDevice(TrezorTest):
|
||||
def test_already_initialized(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with pytest.raises(Exception):
|
||||
device.reset(self.client, False, 128, True, True, 'label', 'english')
|
||||
device.reset(self.client, False, 128, True, True, "label", "english")
|
||||
|
@ -15,29 +15,31 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
from trezorlib import messages as proto
|
||||
|
||||
from .common import TrezorTest, generate_entropy
|
||||
from trezorlib import messages as proto
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgResetDeviceSkipbackup(TrezorTest):
|
||||
|
||||
def test_reset_device_skip_backup(self):
|
||||
|
||||
external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 128
|
||||
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language='english',
|
||||
label='test',
|
||||
skip_backup=True
|
||||
))
|
||||
language="english",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
)
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
@ -52,7 +54,7 @@ class TestMsgResetDeviceSkipbackup(TrezorTest):
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(strength, internal_entropy, external_entropy)
|
||||
expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# start Backup workflow
|
||||
ret = self.client.call_raw(proto.BackupDevice())
|
||||
@ -64,7 +66,7 @@ class TestMsgResetDeviceSkipbackup(TrezorTest):
|
||||
self.client.debug.press_yes()
|
||||
self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
mnemonic = ' '.join(mnemonic)
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
@ -78,7 +80,7 @@ class TestMsgResetDeviceSkipbackup(TrezorTest):
|
||||
|
||||
assert isinstance(resp, proto.Success)
|
||||
|
||||
mnemonic = ' '.join(mnemonic)
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that second pass printed out the same mnemonic once again
|
||||
assert mnemonic == expected_mnemonic
|
||||
@ -89,18 +91,20 @@ class TestMsgResetDeviceSkipbackup(TrezorTest):
|
||||
|
||||
def test_reset_device_skip_backup_break(self):
|
||||
|
||||
external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 128
|
||||
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language='english',
|
||||
label='test',
|
||||
skip_backup=True
|
||||
))
|
||||
language="english",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
)
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
|
@ -15,30 +15,31 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
from trezorlib import device, messages as proto
|
||||
|
||||
from .common import TrezorTest, generate_entropy
|
||||
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import device
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgResetDeviceT2(TrezorTest):
|
||||
|
||||
def test_reset_device(self):
|
||||
|
||||
# No PIN, no passphrase, don't display random
|
||||
external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 128
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label='test'
|
||||
))
|
||||
label="test",
|
||||
)
|
||||
)
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
@ -47,7 +48,7 @@ class TestMsgResetDeviceT2(TrezorTest):
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(strength, internal_entropy, external_entropy)
|
||||
expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# Safety warning
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
@ -69,7 +70,7 @@ class TestMsgResetDeviceT2(TrezorTest):
|
||||
words.extend(self.client.debug.read_reset_word().split())
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert ' '.join(words) == expected_mnemonic
|
||||
assert " ".join(words) == expected_mnemonic
|
||||
|
||||
# Confirm the mnemonic
|
||||
self.client.debug.press_yes()
|
||||
@ -99,24 +100,26 @@ class TestMsgResetDeviceT2(TrezorTest):
|
||||
def test_reset_device_pin(self):
|
||||
|
||||
# PIN, passphrase, display random
|
||||
external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 128
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label='test'
|
||||
))
|
||||
label="test",
|
||||
)
|
||||
)
|
||||
|
||||
# Enter PIN for first time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.input('654')
|
||||
self.client.debug.input("654")
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Enter PIN for second time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.input('654')
|
||||
self.client.debug.input("654")
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Confirm entropy
|
||||
@ -131,7 +134,7 @@ class TestMsgResetDeviceT2(TrezorTest):
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(strength, internal_entropy, external_entropy)
|
||||
expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# Safety warning
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
@ -153,7 +156,7 @@ class TestMsgResetDeviceT2(TrezorTest):
|
||||
words.extend(self.client.debug.read_reset_word().split())
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert ' '.join(words) == expected_mnemonic
|
||||
assert " ".join(words) == expected_mnemonic
|
||||
|
||||
# Confirm the mnemonic
|
||||
self.client.debug.press_yes()
|
||||
@ -183,20 +186,18 @@ class TestMsgResetDeviceT2(TrezorTest):
|
||||
def test_failed_pin(self):
|
||||
# external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
strength = 128
|
||||
ret = self.client.call_raw(proto.ResetDevice(
|
||||
strength=strength,
|
||||
pin_protection=True,
|
||||
label='test'
|
||||
))
|
||||
ret = self.client.call_raw(
|
||||
proto.ResetDevice(strength=strength, pin_protection=True, label="test")
|
||||
)
|
||||
|
||||
# Enter PIN for first time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.input('654')
|
||||
self.client.debug.input("654")
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Enter PIN for second time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.input('456')
|
||||
self.client.debug.input("456")
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
@ -204,4 +205,4 @@ class TestMsgResetDeviceT2(TrezorTest):
|
||||
def test_already_initialized(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with pytest.raises(Exception):
|
||||
device.reset(self.client, False, 128, True, True, 'label', 'english')
|
||||
device.reset(self.client, False, 128, True, True, "label", "english")
|
||||
|
@ -16,39 +16,40 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
from trezorlib import debuglink
|
||||
from trezorlib.ripple import get_address
|
||||
from trezorlib.tools import parse_path
|
||||
from trezorlib import debuglink
|
||||
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
|
||||
|
||||
@pytest.mark.ripple
|
||||
@pytest.mark.skip_t1 # T1 support is not planned
|
||||
@pytest.mark.xfail(TREZOR_VERSION == 2, reason="T2 support is not yet finished")
|
||||
class TestMsgRippleGetAddress(TrezorTest):
|
||||
|
||||
def test_ripple_get_address(self):
|
||||
# data from https://iancoleman.io/bip39/#english
|
||||
self.setup_mnemonic_allallall()
|
||||
|
||||
address = get_address(self.client, parse_path("m/44'/144'/0'/0/0"))
|
||||
assert address == 'rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H'
|
||||
assert address == "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H"
|
||||
address = get_address(self.client, parse_path("m/44'/144'/0'/0/1"))
|
||||
assert address == 'rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws'
|
||||
assert address == "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws"
|
||||
address = get_address(self.client, parse_path("m/44'/144'/1'/0/0"))
|
||||
assert address == 'rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX'
|
||||
assert address == "rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX"
|
||||
|
||||
def test_ripple_get_address_other(self):
|
||||
# data from https://github.com/you21979/node-ripple-bip32/blob/master/test/test.js
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
mnemonic='armed bundle pudding lazy strategy impulse where identify submit weekend physical antenna flight social acoustic absurd whip snack decide blur unfold fiction pumpkin athlete',
|
||||
pin='',
|
||||
mnemonic="armed bundle pudding lazy strategy impulse where identify submit weekend physical antenna flight social acoustic absurd whip snack decide blur unfold fiction pumpkin athlete",
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label='test',
|
||||
language='english')
|
||||
label="test",
|
||||
language="english",
|
||||
)
|
||||
address = get_address(self.client, parse_path("m/44'/144'/0'/0/0"))
|
||||
assert address == 'r4ocGE47gm4G4LkA9mriVHQqzpMLBTgnTY'
|
||||
assert address == "r4ocGE47gm4G4LkA9mriVHQqzpMLBTgnTY"
|
||||
address = get_address(self.client, parse_path("m/44'/144'/0'/0/1"))
|
||||
assert address == 'rUt9ULSrUvfCmke8HTFU1szbmFpWzVbBXW'
|
||||
assert address == "rUt9ULSrUvfCmke8HTFU1szbmFpWzVbBXW"
|
||||
|
@ -14,48 +14,61 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import messages, ripple
|
||||
from trezorlib.tools import CallException, parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
from binascii import unhexlify
|
||||
from trezorlib import messages
|
||||
from trezorlib import ripple
|
||||
from trezorlib.tools import parse_path, CallException
|
||||
|
||||
|
||||
@pytest.mark.ripple
|
||||
@pytest.mark.skip_t1 # T1 support is not planned
|
||||
@pytest.mark.xfail(TREZOR_VERSION == 2, reason="T2 support is not yet finished")
|
||||
class TestMsgRippleSignTx(TrezorTest):
|
||||
|
||||
def test_ripple_sign_simple_tx(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
|
||||
msg = ripple.create_sign_tx_msg({
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Destination": "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws",
|
||||
"Amount": 100000000,
|
||||
"Flags": 0x80000000,
|
||||
"Fee": 100000,
|
||||
"Sequence": 25,
|
||||
})
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/0"), msg)
|
||||
assert resp.signature == unhexlify('3045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c0')
|
||||
assert resp.serialized_tx == unhexlify('12000022800000002400000019614000000005f5e1006840000000000186a0732102131facd1eab748d6cddc492f54b04e8c35658894f4add2232ebc5afe7521dbe474473045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c081148fb40e1ffa5d557ce9851a535af94965e0dd098883147148ebebf7304ccdf1676fefcf9734cf1e780826')
|
||||
assert resp.signature == unhexlify(
|
||||
"3045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c0"
|
||||
)
|
||||
assert resp.serialized_tx == unhexlify(
|
||||
"12000022800000002400000019614000000005f5e1006840000000000186a0732102131facd1eab748d6cddc492f54b04e8c35658894f4add2232ebc5afe7521dbe474473045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c081148fb40e1ffa5d557ce9851a535af94965e0dd098883147148ebebf7304ccdf1676fefcf9734cf1e780826"
|
||||
)
|
||||
|
||||
msg = ripple.create_sign_tx_msg({
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
"Amount": 1,
|
||||
"Fee": 10,
|
||||
"Sequence": 1,
|
||||
})
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
assert resp.signature == unhexlify('3044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f')
|
||||
assert resp.serialized_tx == unhexlify('1200002280000000240000000161400000000000000168400000000000000a732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed274463044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988')
|
||||
assert resp.signature == unhexlify(
|
||||
"3044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f"
|
||||
)
|
||||
assert resp.serialized_tx == unhexlify(
|
||||
"1200002280000000240000000161400000000000000168400000000000000a732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed274463044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
|
||||
)
|
||||
|
||||
msg = ripple.create_sign_tx_msg({
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
"Amount": 100000009,
|
||||
@ -63,23 +76,32 @@ class TestMsgRippleSignTx(TrezorTest):
|
||||
"Fee": 100,
|
||||
"Sequence": 100,
|
||||
"LastLedgerSequence": 333111,
|
||||
})
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
assert resp.signature == unhexlify('30440220025a9cc2809527799e6ea5eb029488dc46c6632a8ca1ed7d3ca2d9211e80403a02202cfe8604e6c6d1d3c64246626cc1a1a9bd8a2163b969e561c6adda5dca8fc2a5')
|
||||
assert resp.serialized_tx == unhexlify('12000022800000002400000064201b00051537614000000005f5e109684000000000000064732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed2744630440220025a9cc2809527799e6ea5eb029488dc46c6632a8ca1ed7d3ca2d9211e80403a02202cfe8604e6c6d1d3c64246626cc1a1a9bd8a2163b969e561c6adda5dca8fc2a58114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988')
|
||||
assert resp.signature == unhexlify(
|
||||
"30440220025a9cc2809527799e6ea5eb029488dc46c6632a8ca1ed7d3ca2d9211e80403a02202cfe8604e6c6d1d3c64246626cc1a1a9bd8a2163b969e561c6adda5dca8fc2a5"
|
||||
)
|
||||
assert resp.serialized_tx == unhexlify(
|
||||
"12000022800000002400000064201b00051537614000000005f5e109684000000000000064732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed2744630440220025a9cc2809527799e6ea5eb029488dc46c6632a8ca1ed7d3ca2d9211e80403a02202cfe8604e6c6d1d3c64246626cc1a1a9bd8a2163b969e561c6adda5dca8fc2a58114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
|
||||
)
|
||||
|
||||
def test_ripple_sign_invalid_fee(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
|
||||
msg = ripple.create_sign_tx_msg({
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
"Amount": 1,
|
||||
"Flags": 1,
|
||||
"Fee": 1,
|
||||
"Sequence": 1,
|
||||
})
|
||||
}
|
||||
)
|
||||
with pytest.raises(CallException) as exc:
|
||||
ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
assert exc.value.args[0] == messages.FailureType.ProcessError
|
||||
assert exc.value.args[1].endswith('Fee must be in the range of 10 to 10,000 drops')
|
||||
assert exc.value.args[1].endswith(
|
||||
"Fee must be in the range of 10 to 10,000 drops"
|
||||
)
|
||||
|
@ -17,75 +17,122 @@
|
||||
import struct
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import misc
|
||||
from trezorlib import messages as proto, misc
|
||||
from trezorlib.tools import H_
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
def check_path(identity):
|
||||
from hashlib import sha256
|
||||
|
||||
m = sha256()
|
||||
m.update(struct.pack("<I", identity.index))
|
||||
uri = ''
|
||||
uri = ""
|
||||
if identity.proto:
|
||||
uri += identity.proto + '://'
|
||||
uri += identity.proto + "://"
|
||||
if identity.user:
|
||||
uri += identity.user + '@'
|
||||
uri += identity.user + "@"
|
||||
if identity.host:
|
||||
uri += identity.host
|
||||
if identity.port:
|
||||
uri += ':' + identity.port
|
||||
uri += ":" + identity.port
|
||||
if identity.path:
|
||||
uri += identity.path
|
||||
m.update(uri)
|
||||
print('hash:', m.hexdigest())
|
||||
(a, b, c, d, _, _, _, _) = struct.unpack('<8I', m.digest())
|
||||
print("hash:", m.hexdigest())
|
||||
(a, b, c, d, _, _, _, _) = struct.unpack("<8I", m.digest())
|
||||
address_n = [H_(13), H_(a), H_(b), H_(c), H_(d)]
|
||||
print('path:', 'm/' + '/'.join([str(x) for x in address_n]))
|
||||
print("path:", "m/" + "/".join([str(x) for x in address_n]))
|
||||
|
||||
|
||||
class TestMsgSignidentity(TrezorTest):
|
||||
|
||||
def test_sign(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
hidden = unhexlify('cd8552569d6e4509266ef137584d1e62c7579b5b8ed69bbafa4b864c6521e7c2')
|
||||
visual = '2015-03-23 17:39:22'
|
||||
hidden = unhexlify(
|
||||
"cd8552569d6e4509266ef137584d1e62c7579b5b8ed69bbafa4b864c6521e7c2"
|
||||
)
|
||||
visual = "2015-03-23 17:39:22"
|
||||
|
||||
# URI : https://satoshi@bitcoin.org/login
|
||||
# hash : d0e2389d4c8394a9f3e32de01104bf6e8db2d9e2bb0905d60fffa5a18fd696db
|
||||
# path : m/2147483661/2637750992/2845082444/3761103859/4005495825
|
||||
identity = proto.IdentityType(proto='https', user='satoshi', host='bitcoin.org', port='', path='/login', index=0)
|
||||
identity = proto.IdentityType(
|
||||
proto="https",
|
||||
user="satoshi",
|
||||
host="bitcoin.org",
|
||||
port="",
|
||||
path="/login",
|
||||
index=0,
|
||||
)
|
||||
sig = misc.sign_identity(self.client, identity, hidden, visual)
|
||||
assert sig.address == '17F17smBTX9VTZA9Mj8LM5QGYNZnmziCjL'
|
||||
assert hexlify(sig.public_key) == b'023a472219ad3327b07c18273717bb3a40b39b743756bf287fbd5fa9d263237f45'
|
||||
assert hexlify(sig.signature) == b'20f2d1a42d08c3a362be49275c3ffeeaa415fc040971985548b9f910812237bb41770bf2c8d488428799fbb7e52c11f1a3404011375e4080e077e0e42ab7a5ba02'
|
||||
assert sig.address == "17F17smBTX9VTZA9Mj8LM5QGYNZnmziCjL"
|
||||
assert (
|
||||
hexlify(sig.public_key)
|
||||
== b"023a472219ad3327b07c18273717bb3a40b39b743756bf287fbd5fa9d263237f45"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"20f2d1a42d08c3a362be49275c3ffeeaa415fc040971985548b9f910812237bb41770bf2c8d488428799fbb7e52c11f1a3404011375e4080e077e0e42ab7a5ba02"
|
||||
)
|
||||
|
||||
# URI : ftp://satoshi@bitcoin.org:2323/pub
|
||||
# hash : 79a6b53831c6ff224fb283587adc4ebae8fb0d734734a46c876838f52dff53f3
|
||||
# path : m/2147483661/3098912377/2734671409/3632509519/3125730426
|
||||
identity = proto.IdentityType(proto='ftp', user='satoshi', host='bitcoin.org', port='2323', path='/pub', index=3)
|
||||
identity = proto.IdentityType(
|
||||
proto="ftp",
|
||||
user="satoshi",
|
||||
host="bitcoin.org",
|
||||
port="2323",
|
||||
path="/pub",
|
||||
index=3,
|
||||
)
|
||||
sig = misc.sign_identity(self.client, identity, hidden, visual)
|
||||
assert sig.address == '1KAr6r5qF2kADL8bAaRQBjGKYEGxn9WrbS'
|
||||
assert hexlify(sig.public_key) == b'0266cf12d2ba381c5fd797da0d64f59c07a6f1b034ad276cca6bf2729e92b20d9c'
|
||||
assert hexlify(sig.signature) == b'20bbd12dc657d534fc0f7e40186e22c447e0866a016f654f380adffa9a84e9faf412a1bb0ae908296537838cf91145e77da08681c63d07b7dca40728b9e6cb17cf'
|
||||
assert sig.address == "1KAr6r5qF2kADL8bAaRQBjGKYEGxn9WrbS"
|
||||
assert (
|
||||
hexlify(sig.public_key)
|
||||
== b"0266cf12d2ba381c5fd797da0d64f59c07a6f1b034ad276cca6bf2729e92b20d9c"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"20bbd12dc657d534fc0f7e40186e22c447e0866a016f654f380adffa9a84e9faf412a1bb0ae908296537838cf91145e77da08681c63d07b7dca40728b9e6cb17cf"
|
||||
)
|
||||
|
||||
# URI : ssh://satoshi@bitcoin.org
|
||||
# hash : 5fa612f558a1a3b1fb7f010b2ea0a25cb02520a0ffa202ce74a92fc6145da5f3
|
||||
# path : m/2147483661/4111640159/2980290904/2332131323/3701645358
|
||||
identity = proto.IdentityType(proto='ssh', user='satoshi', host='bitcoin.org', port='', path='', index=47)
|
||||
sig = misc.sign_identity(self.client, identity, hidden, visual, ecdsa_curve_name='nist256p1')
|
||||
identity = proto.IdentityType(
|
||||
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
self.client, identity, hidden, visual, ecdsa_curve_name="nist256p1"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert hexlify(sig.public_key) == b'0373f21a3da3d0e96fc2189f81dd826658c3d76b2d55bd1da349bc6c3573b13ae4'
|
||||
assert hexlify(sig.signature) == b'005122cebabb852cdd32103b602662afa88e54c0c0c1b38d7099c64dcd49efe908288114e66ed2d8c82f23a70b769a4db723173ec53840c08aafb840d3f09a18d3'
|
||||
assert (
|
||||
hexlify(sig.public_key)
|
||||
== b"0373f21a3da3d0e96fc2189f81dd826658c3d76b2d55bd1da349bc6c3573b13ae4"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"005122cebabb852cdd32103b602662afa88e54c0c0c1b38d7099c64dcd49efe908288114e66ed2d8c82f23a70b769a4db723173ec53840c08aafb840d3f09a18d3"
|
||||
)
|
||||
|
||||
# URI : ssh://satoshi@bitcoin.org
|
||||
# hash : 5fa612f558a1a3b1fb7f010b2ea0a25cb02520a0ffa202ce74a92fc6145da5f3
|
||||
# path : m/2147483661/4111640159/2980290904/2332131323/3701645358
|
||||
identity = proto.IdentityType(proto='ssh', user='satoshi', host='bitcoin.org', port='', path='', index=47)
|
||||
sig = misc.sign_identity(self.client, identity, hidden, visual, ecdsa_curve_name='ed25519')
|
||||
identity = proto.IdentityType(
|
||||
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
self.client, identity, hidden, visual, ecdsa_curve_name="ed25519"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert hexlify(sig.public_key) == b'000fac2a491e0f5b871dc48288a4cae551bac5cb0ed19df0764d6e721ec5fade18'
|
||||
assert hexlify(sig.signature) == b'00f05e5085e666429de397c70a081932654369619c0bd2a6579ea6c1ef2af112ef79998d6c862a16b932d44b1ac1b83c8cbcd0fbda228274fde9e0d0ca6e9cb709'
|
||||
assert (
|
||||
hexlify(sig.public_key)
|
||||
== b"000fac2a491e0f5b871dc48288a4cae551bac5cb0ed19df0764d6e721ec5fade18"
|
||||
)
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"00f05e5085e666429de397c70a081932654369619c0bd2a6579ea6c1ef2af112ef79998d6c862a16b932d44b1ac1b83c8cbcd0fbda228274fde9e0d0ca6e9cb709"
|
||||
)
|
||||
|
@ -16,46 +16,70 @@
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import btc
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgSignmessage(TrezorTest):
|
||||
|
||||
def test_sign(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Bitcoin', [0], "This is an example of a signed message.")
|
||||
assert sig.address == '14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e'
|
||||
assert hexlify(sig.signature) == b'209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'
|
||||
sig = btc.sign_message(
|
||||
self.client, "Bitcoin", [0], "This is an example of a signed message."
|
||||
)
|
||||
assert sig.address == "14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
)
|
||||
|
||||
def test_sign_testnet(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Testnet', [0], "This is an example of a signed message.")
|
||||
assert sig.address == 'mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL'
|
||||
assert hexlify(sig.signature) == b'209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'
|
||||
sig = btc.sign_message(
|
||||
self.client, "Testnet", [0], "This is an example of a signed message."
|
||||
)
|
||||
assert sig.address == "mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
)
|
||||
|
||||
def test_sign_bch(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Bcash', [0], "This is an example of a signed message.")
|
||||
assert sig.address == 'bitcoincash:qqj22md58nm09vpwsw82fyletkxkq36zxyxh322pru'
|
||||
assert hexlify(sig.signature) == b'209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'
|
||||
sig = btc.sign_message(
|
||||
self.client, "Bcash", [0], "This is an example of a signed message."
|
||||
)
|
||||
assert sig.address == "bitcoincash:qqj22md58nm09vpwsw82fyletkxkq36zxyxh322pru"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
)
|
||||
|
||||
def test_sign_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Bitcoin', [0], "VeryLongMessage!" * 64)
|
||||
assert sig.address == '14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e'
|
||||
assert hexlify(sig.signature) == b'205ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed'
|
||||
sig = btc.sign_message(self.client, "Bitcoin", [0], "VeryLongMessage!" * 64)
|
||||
assert sig.address == "14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"205ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
)
|
||||
|
||||
def test_sign_utf(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
words_nfkd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
sig_nfkd = btc.sign_message(self.client, 'Bitcoin', [0], words_nfkd)
|
||||
assert sig_nfkd.address == '14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e'
|
||||
assert hexlify(sig_nfkd.signature) == b'20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'
|
||||
sig_nfkd = btc.sign_message(self.client, "Bitcoin", [0], words_nfkd)
|
||||
assert sig_nfkd.address == "14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e"
|
||||
assert (
|
||||
hexlify(sig_nfkd.signature)
|
||||
== b"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
)
|
||||
|
||||
sig_nfc = btc.sign_message(self.client, 'Bitcoin', [0], words_nfc)
|
||||
assert sig_nfc.address == '14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e'
|
||||
assert hexlify(sig_nfc.signature) == b'20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'
|
||||
sig_nfc = btc.sign_message(self.client, "Bitcoin", [0], words_nfc)
|
||||
assert sig_nfc.address == "14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e"
|
||||
assert (
|
||||
hexlify(sig_nfc.signature)
|
||||
== b"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
)
|
||||
|
@ -16,41 +16,85 @@
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
from trezorlib import btc, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc
|
||||
|
||||
|
||||
class TestMsgSignmessageSegwit(TrezorTest):
|
||||
|
||||
def test_sign(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Bitcoin', [0], "This is an example of a signed message.", script_type=proto.InputScriptType.SPENDP2SHWITNESS)
|
||||
assert sig.address == '3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1'
|
||||
assert hexlify(sig.signature) == b'249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'
|
||||
sig = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
"This is an example of a signed message.",
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert sig.address == "3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
)
|
||||
|
||||
def test_sign_testnet(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Testnet', [0], "This is an example of a signed message.", script_type=proto.InputScriptType.SPENDP2SHWITNESS)
|
||||
assert sig.address == '2N4VkePSzKH2sv5YBikLHGvzUYvfPxV6zS9'
|
||||
assert hexlify(sig.signature) == b'249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'
|
||||
sig = btc.sign_message(
|
||||
self.client,
|
||||
"Testnet",
|
||||
[0],
|
||||
"This is an example of a signed message.",
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert sig.address == "2N4VkePSzKH2sv5YBikLHGvzUYvfPxV6zS9"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
)
|
||||
|
||||
def test_sign_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Bitcoin', [0], "VeryLongMessage!" * 64, script_type=proto.InputScriptType.SPENDP2SHWITNESS)
|
||||
assert sig.address == '3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1'
|
||||
assert hexlify(sig.signature) == b'245ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed'
|
||||
sig = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
"VeryLongMessage!" * 64,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert sig.address == "3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"245ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
)
|
||||
|
||||
def test_sign_utf(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
words_nfkd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
sig_nfkd = btc.sign_message(self.client, 'Bitcoin', [0], words_nfkd, script_type=proto.InputScriptType.SPENDP2SHWITNESS)
|
||||
assert sig_nfkd.address == '3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1'
|
||||
assert hexlify(sig_nfkd.signature) == b'24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'
|
||||
sig_nfkd = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
words_nfkd,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert sig_nfkd.address == "3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1"
|
||||
assert (
|
||||
hexlify(sig_nfkd.signature)
|
||||
== b"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
)
|
||||
|
||||
sig_nfc = btc.sign_message(self.client, 'Bitcoin', [0], words_nfc, script_type=proto.InputScriptType.SPENDP2SHWITNESS)
|
||||
assert sig_nfc.address == '3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1'
|
||||
assert hexlify(sig_nfc.signature) == b'24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'
|
||||
sig_nfc = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
words_nfc,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert sig_nfc.address == "3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1"
|
||||
assert (
|
||||
hexlify(sig_nfc.signature)
|
||||
== b"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
)
|
||||
|
@ -16,41 +16,85 @@
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
from trezorlib import btc, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc
|
||||
|
||||
|
||||
class TestMsgSignmessageSegwitNative(TrezorTest):
|
||||
|
||||
def test_sign(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Bitcoin', [0], "This is an example of a signed message.", script_type=proto.InputScriptType.SPENDWITNESS)
|
||||
assert sig.address == 'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j'
|
||||
assert hexlify(sig.signature) == b'289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'
|
||||
sig = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
"This is an example of a signed message.",
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
assert sig.address == "bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
)
|
||||
|
||||
def test_sign_testnet(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Testnet', [0], "This is an example of a signed message.", script_type=proto.InputScriptType.SPENDWITNESS)
|
||||
assert sig.address == 'tb1qyjjkmdpu7metqt5r36jf872a34syws336p3n3p'
|
||||
assert hexlify(sig.signature) == b'289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'
|
||||
sig = btc.sign_message(
|
||||
self.client,
|
||||
"Testnet",
|
||||
[0],
|
||||
"This is an example of a signed message.",
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
assert sig.address == "tb1qyjjkmdpu7metqt5r36jf872a34syws336p3n3p"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
)
|
||||
|
||||
def test_sign_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = btc.sign_message(self.client, 'Bitcoin', [0], "VeryLongMessage!" * 64, script_type=proto.InputScriptType.SPENDWITNESS)
|
||||
assert sig.address == 'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j'
|
||||
assert hexlify(sig.signature) == b'285ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed'
|
||||
sig = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
"VeryLongMessage!" * 64,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
assert sig.address == "bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j"
|
||||
assert (
|
||||
hexlify(sig.signature)
|
||||
== b"285ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
)
|
||||
|
||||
def test_sign_utf(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
words_nfkd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
sig_nfkd = btc.sign_message(self.client, 'Bitcoin', [0], words_nfkd, script_type=proto.InputScriptType.SPENDWITNESS)
|
||||
assert sig_nfkd.address == 'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j'
|
||||
assert hexlify(sig_nfkd.signature) == b'28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'
|
||||
sig_nfkd = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
words_nfkd,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
assert sig_nfkd.address == "bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j"
|
||||
assert (
|
||||
hexlify(sig_nfkd.signature)
|
||||
== b"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
)
|
||||
|
||||
sig_nfc = btc.sign_message(self.client, 'Bitcoin', [0], words_nfc, script_type=proto.InputScriptType.SPENDWITNESS)
|
||||
assert sig_nfc.address == 'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j'
|
||||
assert hexlify(sig_nfc.signature) == b'28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'
|
||||
sig_nfc = btc.sign_message(
|
||||
self.client,
|
||||
"Bitcoin",
|
||||
[0],
|
||||
words_nfc,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
assert sig_nfc.address == "bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j"
|
||||
assert (
|
||||
hexlify(sig_nfc.signature)
|
||||
== b"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,21 +14,20 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support.ckd_public import deserialize
|
||||
from trezorlib import coins
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.tools import parse_path, CallException, H_
|
||||
from trezorlib import btc
|
||||
import pytest
|
||||
|
||||
TxApiBcash = coins.tx_api['Bcash']
|
||||
from trezorlib import btc, coins, messages as proto
|
||||
from trezorlib.tools import H_, CallException, parse_path
|
||||
|
||||
from ..support.ckd_public import deserialize
|
||||
from .common import TrezorTest
|
||||
|
||||
TxApiBcash = coins.tx_api["Bcash"]
|
||||
|
||||
|
||||
class TestMsgSigntxBch(TrezorTest):
|
||||
|
||||
def test_send_bch_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiBcash)
|
||||
@ -36,7 +35,9 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/0'/0/0"),
|
||||
# bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv
|
||||
amount=1995344,
|
||||
prev_hash=unhexlify('bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78'),
|
||||
prev_hash=unhexlify(
|
||||
"bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -46,25 +47,50 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address='bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4',
|
||||
address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bcash', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bcash", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000001781a716b1e15b41b07157933e5d777392a75bf87132650cb2e7d46fb8dc237bc000000006a473044022061aee4f17abe044d5df8c52c9ffd3b84e5a29743517e488b20ecf1ae0b3e4d3a02206bb84c55e407f3b684ff8d9bea0a3409cfd865795a19d10b3d3c31f12795c34a412103a020b36130021a0f037c1d1a02042e325c0cb666d6478c1afdcd9d913b9ef080ffffffff0272ee1c00000000001976a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488acec1e0100000000001976a914d51eca49695cdf47e7f4b55507893e3ad53fe9d888ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000001781a716b1e15b41b07157933e5d777392a75bf87132650cb2e7d46fb8dc237bc000000006a473044022061aee4f17abe044d5df8c52c9ffd3b84e5a29743517e488b20ecf1ae0b3e4d3a02206bb84c55e407f3b684ff8d9bea0a3409cfd865795a19d10b3d3c31f12795c34a412103a020b36130021a0f037c1d1a02042e325c0cb666d6478c1afdcd9d913b9ef080ffffffff0272ee1c00000000001976a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488acec1e0100000000001976a914d51eca49695cdf47e7f4b55507893e3ad53fe9d888ac00000000"
|
||||
)
|
||||
|
||||
def test_send_bch_nochange(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -73,7 +99,9 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'),
|
||||
prev_hash=unhexlify(
|
||||
"502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -81,30 +109,57 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'),
|
||||
prev_hash=unhexlify(
|
||||
"502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4',
|
||||
address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bcash', [inp1, inp2], [out1])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bcash", [inp1, inp2], [out1]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
)
|
||||
|
||||
def test_send_bch_oldaddr(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -113,7 +168,9 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'),
|
||||
prev_hash=unhexlify(
|
||||
"502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -121,30 +178,57 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'),
|
||||
prev_hash=unhexlify(
|
||||
"502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='15pnEDZJo3ycPUamqP3tEDnEju1oW5fBCz',
|
||||
address="15pnEDZJo3ycPUamqP3tEDnEju1oW5fBCz",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bcash', [inp1, inp2], [out1])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bcash", [inp1, inp2], [out1]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
)
|
||||
|
||||
def test_attack_amount(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -153,7 +237,9 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=300,
|
||||
prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'),
|
||||
prev_hash=unhexlify(
|
||||
"502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -161,12 +247,14 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=70,
|
||||
prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'),
|
||||
prev_hash=unhexlify(
|
||||
"502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4',
|
||||
address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
|
||||
amount=200,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -198,37 +286,83 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
|
||||
# test if passes without modifications
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
btc.sign_tx(self.client, 'Bcash', [inp1, inp2], [out1])
|
||||
]
|
||||
)
|
||||
btc.sign_tx(self.client, "Bcash", [inp1, inp2], [out1])
|
||||
|
||||
# now fails
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.Failure(),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
with pytest.raises(CallException) as exc:
|
||||
btc.sign_tx(self.client, 'Bcash', [inp1, inp2], [out1], debug_processor=attack_processor)
|
||||
btc.sign_tx(
|
||||
self.client,
|
||||
"Bcash",
|
||||
[inp1, inp2],
|
||||
[out1],
|
||||
debug_processor=attack_processor,
|
||||
)
|
||||
|
||||
assert exc.value.args[0] in (proto.FailureType.ProcessError, proto.FailureType.DataError)
|
||||
assert exc.value.args[1].endswith('Transaction has changed during signing')
|
||||
assert exc.value.args[0] in (
|
||||
proto.FailureType.ProcessError,
|
||||
proto.FailureType.DataError,
|
||||
)
|
||||
assert exc.value.args[1].endswith("Transaction has changed during signing")
|
||||
|
||||
def test_attack_change_input(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -237,7 +371,9 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/1000'/0/0"),
|
||||
# bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv
|
||||
amount=1995344,
|
||||
prev_hash=unhexlify('bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78'),
|
||||
prev_hash=unhexlify(
|
||||
"bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -247,7 +383,7 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address='bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4',
|
||||
address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -272,95 +408,178 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
return msg
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
])
|
||||
]
|
||||
)
|
||||
with pytest.raises(CallException):
|
||||
btc.sign_tx(self.client, 'Bcash', [inp1], [out1, out2], debug_processor=attack_processor)
|
||||
btc.sign_tx(
|
||||
self.client,
|
||||
"Bcash",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
debug_processor=attack_processor,
|
||||
)
|
||||
|
||||
def test_send_bch_multisig_wrongchange(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiBcash)
|
||||
xpubs = []
|
||||
for n in map(lambda index: btc.get_public_node(self.client, parse_path("44'/145'/" + str(index) + "'")), range(1, 4)):
|
||||
for n in map(
|
||||
lambda index: btc.get_public_node(
|
||||
self.client, parse_path("44'/145'/" + str(index) + "'")
|
||||
),
|
||||
range(1, 4),
|
||||
):
|
||||
xpubs.append(n.xpub)
|
||||
|
||||
def getmultisig(chain, nr, signatures=[b'', b'', b''], xpubs=xpubs):
|
||||
def getmultisig(chain, nr, signatures=[b"", b"", b""], xpubs=xpubs):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda xpub: proto.HDNodePathType(node=deserialize(xpub), address_n=[chain, nr]), xpubs)),
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda xpub: proto.HDNodePathType(
|
||||
node=deserialize(xpub), address_n=[chain, nr]
|
||||
),
|
||||
xpubs,
|
||||
)
|
||||
),
|
||||
signatures=signatures,
|
||||
m=2,
|
||||
)
|
||||
|
||||
correcthorse = proto.HDNodeType(
|
||||
depth=1, fingerprint=0, child_num=0,
|
||||
chain_code=unhexlify('0000000000000000000000000000000000000000000000000000000000000000'),
|
||||
public_key=unhexlify('0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71'))
|
||||
sig = unhexlify(b'304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae')
|
||||
depth=1,
|
||||
fingerprint=0,
|
||||
child_num=0,
|
||||
chain_code=unhexlify(
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
),
|
||||
public_key=unhexlify(
|
||||
"0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"
|
||||
),
|
||||
)
|
||||
sig = unhexlify(
|
||||
b"304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae"
|
||||
)
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/1'/1/0"),
|
||||
multisig=getmultisig(1, 0, [b'', sig, b'']),
|
||||
multisig=getmultisig(1, 0, [b"", sig, b""]),
|
||||
# bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a
|
||||
amount=24000,
|
||||
prev_hash=unhexlify('f68caf10df12d5b07a34601d88fa6856c6edcbf4d05ebef3486510ae1c293d5f'),
|
||||
prev_hash=unhexlify(
|
||||
"f68caf10df12d5b07a34601d88fa6856c6edcbf4d05ebef3486510ae1c293d5f"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/145'/1'/1/1"),
|
||||
multisig=proto.MultisigRedeemScriptType(
|
||||
pubkeys=[proto.HDNodePathType(node=deserialize(xpubs[0]), address_n=[1, 1]),
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=deserialize(xpubs[0]), address_n=[1, 1]),
|
||||
proto.HDNodePathType(node=correcthorse, address_n=[]),
|
||||
proto.HDNodePathType(node=correcthorse, address_n=[])],
|
||||
signatures=[b'', b'', b''],
|
||||
proto.HDNodePathType(node=correcthorse, address_n=[]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
),
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=23000
|
||||
amount=23000,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures1, serialized_tx) = btc.sign_tx(self.client, 'Bcash', [inp1], [out1])
|
||||
assert hexlify(signatures1[0]) == b'3044022052ccf022b3684ecce9f961ce8828387b97267c86bedf0ce16a24bf014e62e42c022035d315ddbeeef7ab3456bd09aed8b625ea58852216b60e4b84ba9f85827d305c'
|
||||
assert hexlify(serialized_tx) == b'01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc00473044022052ccf022b3684ecce9f961ce8828387b97267c86bedf0ce16a24bf014e62e42c022035d315ddbeeef7ab3456bd09aed8b625ea58852216b60e4b84ba9f85827d305c4147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522103d62b2af2272bbd67cbe30eeaf4226c7f2d57d2a0ed1aab5ab736fb40bb2f5ffe21036d5e0d7ca3589465711eec91436249d7234d3a994c219024fc75cec98fc02ae221024f58378a69b68e89301a6ff882116e0fa35446ec9bfd86532eeb05941ec1f8c853aeffffffff01d85900000000000017a9140bb11de6558871f49fc241341992ece9986f7c5c8700000000'
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bcash", [inp1], [out1]
|
||||
)
|
||||
assert (
|
||||
hexlify(signatures1[0])
|
||||
== b"3044022052ccf022b3684ecce9f961ce8828387b97267c86bedf0ce16a24bf014e62e42c022035d315ddbeeef7ab3456bd09aed8b625ea58852216b60e4b84ba9f85827d305c"
|
||||
)
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc00473044022052ccf022b3684ecce9f961ce8828387b97267c86bedf0ce16a24bf014e62e42c022035d315ddbeeef7ab3456bd09aed8b625ea58852216b60e4b84ba9f85827d305c4147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522103d62b2af2272bbd67cbe30eeaf4226c7f2d57d2a0ed1aab5ab736fb40bb2f5ffe21036d5e0d7ca3589465711eec91436249d7234d3a994c219024fc75cec98fc02ae221024f58378a69b68e89301a6ff882116e0fa35446ec9bfd86532eeb05941ec1f8c853aeffffffff01d85900000000000017a9140bb11de6558871f49fc241341992ece9986f7c5c8700000000"
|
||||
)
|
||||
|
||||
def test_send_bch_multisig_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiBcash)
|
||||
xpubs = []
|
||||
for n in map(lambda index: btc.get_public_node(self.client, parse_path("44'/145'/" + str(index) + "'")), range(1, 4)):
|
||||
for n in map(
|
||||
lambda index: btc.get_public_node(
|
||||
self.client, parse_path("44'/145'/" + str(index) + "'")
|
||||
),
|
||||
range(1, 4),
|
||||
):
|
||||
xpubs.append(n.xpub)
|
||||
|
||||
def getmultisig(chain, nr, signatures=[b'', b'', b''], xpubs=xpubs):
|
||||
def getmultisig(chain, nr, signatures=[b"", b"", b""], xpubs=xpubs):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda xpub: proto.HDNodePathType(node=deserialize(xpub), address_n=[chain, nr]), xpubs)),
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda xpub: proto.HDNodePathType(
|
||||
node=deserialize(xpub), address_n=[chain, nr]
|
||||
),
|
||||
xpubs,
|
||||
)
|
||||
),
|
||||
signatures=signatures,
|
||||
m=2,
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/3'/0/0"),
|
||||
multisig=getmultisig(0, 0),
|
||||
# bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw
|
||||
amount=48490,
|
||||
prev_hash=unhexlify('8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0'),
|
||||
prev_hash=unhexlify(
|
||||
"8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9',
|
||||
address="bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9",
|
||||
amount=24000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -368,48 +587,103 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
address_n=parse_path("44'/145'/3'/1/0"),
|
||||
multisig=getmultisig(1, 0),
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=24000
|
||||
amount=24000,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures1, serialized_tx) = btc.sign_tx(self.client, 'Bcash', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bcash", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(signatures1[0]) == b'3045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85'
|
||||
assert (
|
||||
hexlify(signatures1[0])
|
||||
== b"3045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85"
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/1'/0/0"),
|
||||
multisig=getmultisig(0, 0, [b'', b'', signatures1[0]]),
|
||||
multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]),
|
||||
# bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw
|
||||
amount=48490,
|
||||
prev_hash=unhexlify('8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0'),
|
||||
prev_hash=unhexlify(
|
||||
"8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out2.address_n[2] = H_(1)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures1, serialized_tx) = btc.sign_tx(self.client, 'Bcash', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bcash", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(signatures1[0]) == b'3045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa'
|
||||
assert hexlify(serialized_tx) == b'0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfe0000483045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa41483045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85414c69522102fcf63419c319ce1a42d69120a3599d6da8c5dd4caf2888220eccde5a1ff7c5d021036d7d5ef79370b7fabe2c058698a20219e97fc70868e65ecdd6b37cc18e8a88bd2103505dc649dab8cd1655a4c0daf0ec5f955881c9d7011478ea881fac11cab1e49953aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914756c06d7e77de3950a6124f026d8e1a2464b3ecf8700000000'
|
||||
assert (
|
||||
hexlify(signatures1[0])
|
||||
== b"3045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa"
|
||||
)
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfe0000483045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa41483045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85414c69522102fcf63419c319ce1a42d69120a3599d6da8c5dd4caf2888220eccde5a1ff7c5d021036d7d5ef79370b7fabe2c058698a20219e97fc70868e65ecdd6b37cc18e8a88bd2103505dc649dab8cd1655a4c0daf0ec5f955881c9d7011478ea881fac11cab1e49953aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914756c06d7e77de3950a6124f026d8e1a2464b3ecf8700000000"
|
||||
)
|
||||
|
@ -14,29 +14,30 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import pytest
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc, coins, messages as proto
|
||||
from trezorlib.tools import H_, CallException, parse_path
|
||||
|
||||
from ..support.ckd_public import deserialize
|
||||
from trezorlib import coins
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.tools import parse_path, CallException, H_
|
||||
from trezorlib import btc
|
||||
from .common import TrezorTest
|
||||
|
||||
TxApiBitcoinGold = coins.tx_api["Bgold"]
|
||||
|
||||
|
||||
# All data taken from T1
|
||||
class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
|
||||
def test_send_bitcoin_gold_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiBitcoinGold)
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/156'/0'/0/0"),
|
||||
amount=1995344,
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -46,25 +47,50 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address='GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe',
|
||||
address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bgold', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bgold", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'010000000185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b5225000000006b483045022100963904da0731b71ce468afd45366dd80fbff566ec0d39c1161ab85d17459c7ca02202f5c24a7a7272d98b14a3f5bc000c7cde8ac0eb773f20f4c3131518186cc98854121023bd0ec4022d12d0106c5b7308a25572953ba1951f576f691354a7b147ee0cc1fffffffff0272ee1c00000000001976a9141c82b9c11f193ad82413caadc0955730572b50ae88acec1e0100000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"010000000185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b5225000000006b483045022100963904da0731b71ce468afd45366dd80fbff566ec0d39c1161ab85d17459c7ca02202f5c24a7a7272d98b14a3f5bc000c7cde8ac0eb773f20f4c3131518186cc98854121023bd0ec4022d12d0106c5b7308a25572953ba1951f576f691354a7b147ee0cc1fffffffff0272ee1c00000000001976a9141c82b9c11f193ad82413caadc0955730572b50ae88acec1e0100000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac00000000"
|
||||
)
|
||||
|
||||
def test_send_bitcoin_gold_nochange(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -72,7 +98,9 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/156'/0'/1/0"),
|
||||
amount=1896050,
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -80,30 +108,57 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
address_n=parse_path("44'/156'/0'/0/1"),
|
||||
# 1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3
|
||||
amount=73452,
|
||||
prev_hash=unhexlify('db77c2461b840e6edbe7f9280043184a98e020d9795c1b65cb7cef2551a8fb18'),
|
||||
prev_hash=unhexlify(
|
||||
"db77c2461b840e6edbe7f9280043184a98e020d9795c1b65cb7cef2551a8fb18"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe',
|
||||
address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bgold', [inp1, inp2], [out1])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bgold", [inp1, inp2], [out1]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'010000000285c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b5225000000006b483045022100928852076c9fab160c07564cd54691af1cbc37fb28f0b7bee7299c7925ef62f0022058856387afecc6508f2f04ecdfd292a13026a5b2107ebdd2cc789bdf8820d552412102a6c3998d0d4e5197ff41aab5c53580253b3b91f583f4c31f7624be7dc83ce15fffffffff18fba85125ef7ccb651b5c79d920e0984a18430028f9e7db6e0e841b46c277db010000006b483045022100faa2f4f01cc95e680349a093923aae0aa2ea01429873555aa8a84bf630ef33a002204c3f4bf567e2d20540c0f71dc278481d6ccb6b95acda2a2f87ce521c79d6b872412102d54a7e5733b1635e5e9442943f48179b1700206b2d1925250ba10f1c86878be8ffffffff0170861d00000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"010000000285c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b5225000000006b483045022100928852076c9fab160c07564cd54691af1cbc37fb28f0b7bee7299c7925ef62f0022058856387afecc6508f2f04ecdfd292a13026a5b2107ebdd2cc789bdf8820d552412102a6c3998d0d4e5197ff41aab5c53580253b3b91f583f4c31f7624be7dc83ce15fffffffff18fba85125ef7ccb651b5c79d920e0984a18430028f9e7db6e0e841b46c277db010000006b483045022100faa2f4f01cc95e680349a093923aae0aa2ea01429873555aa8a84bf630ef33a002204c3f4bf567e2d20540c0f71dc278481d6ccb6b95acda2a2f87ce521c79d6b872412102d54a7e5733b1635e5e9442943f48179b1700206b2d1925250ba10f1c86878be8ffffffff0170861d00000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac00000000"
|
||||
)
|
||||
|
||||
def test_attack_change_input(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -112,7 +167,9 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
address_n=parse_path("44'/156'/1000'/0/0"),
|
||||
# 1MH9KKcvdCTY44xVDC2k3fjBbX5Cz29N1q
|
||||
amount=1995344,
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
@ -122,7 +179,7 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address='GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe',
|
||||
address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -147,42 +204,77 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
return msg
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
])
|
||||
]
|
||||
)
|
||||
with pytest.raises(CallException):
|
||||
btc.sign_tx(self.client, 'Bgold', [inp1], [out1, out2], debug_processor=attack_processor)
|
||||
btc.sign_tx(
|
||||
self.client,
|
||||
"Bgold",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
debug_processor=attack_processor,
|
||||
)
|
||||
|
||||
def test_send_bch_multisig_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiBitcoinGold)
|
||||
xpubs = []
|
||||
for n in map(lambda index: btc.get_public_node(self.client, parse_path("44'/156'/" + str(index) + "'")), range(1, 4)):
|
||||
for n in map(
|
||||
lambda index: btc.get_public_node(
|
||||
self.client, parse_path("44'/156'/" + str(index) + "'")
|
||||
),
|
||||
range(1, 4),
|
||||
):
|
||||
xpubs.append(n.xpub)
|
||||
|
||||
def getmultisig(chain, nr, signatures=[b'', b'', b''], xpubs=xpubs):
|
||||
def getmultisig(chain, nr, signatures=[b"", b"", b""], xpubs=xpubs):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda xpub: proto.HDNodePathType(node=deserialize(xpub), address_n=[chain, nr]), xpubs)),
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda xpub: proto.HDNodePathType(
|
||||
node=deserialize(xpub), address_n=[chain, nr]
|
||||
),
|
||||
xpubs,
|
||||
)
|
||||
),
|
||||
signatures=signatures,
|
||||
m=2,
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/156'/3'/0/0"),
|
||||
multisig=getmultisig(0, 0),
|
||||
# 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R
|
||||
amount=48490,
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe',
|
||||
address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
|
||||
amount=24000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -190,51 +282,106 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
address_n=parse_path("44'/156'/3'/1/0"),
|
||||
multisig=getmultisig(1, 0),
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=24000
|
||||
amount=24000,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures1, serialized_tx) = btc.sign_tx(self.client, 'Bgold', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bgold", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(signatures1[0]) == b'3045022100b1594f3b186d0dedbf61e53a1c407b1e0747098b7375941df85af045040f578e022013ba1893eb9e2fd854dd07073a83b261cf4beba76f66b07742e462b4088a7e4a'
|
||||
assert (
|
||||
hexlify(signatures1[0])
|
||||
== b"3045022100b1594f3b186d0dedbf61e53a1c407b1e0747098b7375941df85af045040f578e022013ba1893eb9e2fd854dd07073a83b261cf4beba76f66b07742e462b4088a7e4a"
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/156'/1'/0/0"),
|
||||
multisig=getmultisig(0, 0, [b'', b'', signatures1[0]]),
|
||||
multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]),
|
||||
# 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R
|
||||
amount=48490,
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out2.address_n[2] = H_(1)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures1, serialized_tx) = btc.sign_tx(self.client, 'Bgold', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bgold", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(signatures1[0]) == b'3044022006da8dbd14e6656ac8dcb956f4c0498574e88680eaeceb2cbafd8d2b2329d8cc02200972d076d444c5ff8f2ab18e14d8249ab661cb9c53335039bedcde037a40d747'
|
||||
assert hexlify(serialized_tx) == b'010000000185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b522500000000fdfd0000473044022006da8dbd14e6656ac8dcb956f4c0498574e88680eaeceb2cbafd8d2b2329d8cc02200972d076d444c5ff8f2ab18e14d8249ab661cb9c53335039bedcde037a40d74741483045022100b1594f3b186d0dedbf61e53a1c407b1e0747098b7375941df85af045040f578e022013ba1893eb9e2fd854dd07073a83b261cf4beba76f66b07742e462b4088a7e4a414c69522102290e6649574d17938c1ecb959ae92954f9ee48e1bd5b73f35ea931a3ab8a6087210379e0107b173e2c143426760627128c5eea3f862e8df92f3c2558eeeae4e347842103ff1746ca7dcf9e5c2eea9a73779b7c5bafed549f45cf3638a94cdf1e89c7f28f53aeffffffff02c05d0000000000001976a914ea5f904d195079a350b534db4446433b3cec222e88acc05d00000000000017a91445e917e46815d2b38d3f1cf072e63dd4f3b7a7e38700000000'
|
||||
assert (
|
||||
hexlify(signatures1[0])
|
||||
== b"3044022006da8dbd14e6656ac8dcb956f4c0498574e88680eaeceb2cbafd8d2b2329d8cc02200972d076d444c5ff8f2ab18e14d8249ab661cb9c53335039bedcde037a40d747"
|
||||
)
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"010000000185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b522500000000fdfd0000473044022006da8dbd14e6656ac8dcb956f4c0498574e88680eaeceb2cbafd8d2b2329d8cc02200972d076d444c5ff8f2ab18e14d8249ab661cb9c53335039bedcde037a40d74741483045022100b1594f3b186d0dedbf61e53a1c407b1e0747098b7375941df85af045040f578e022013ba1893eb9e2fd854dd07073a83b261cf4beba76f66b07742e462b4088a7e4a414c69522102290e6649574d17938c1ecb959ae92954f9ee48e1bd5b73f35ea931a3ab8a6087210379e0107b173e2c143426760627128c5eea3f862e8df92f3c2558eeeae4e347842103ff1746ca7dcf9e5c2eea9a73779b7c5bafed549f45cf3638a94cdf1e89c7f28f53aeffffffff02c05d0000000000001976a914ea5f904d195079a350b534db4446433b3cec222e88acc05d00000000000017a91445e917e46815d2b38d3f1cf072e63dd4f3b7a7e38700000000"
|
||||
)
|
||||
|
||||
def test_send_p2sh(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -242,37 +389,67 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/156'/0'/1/0"),
|
||||
amount=123456789,
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe',
|
||||
address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address='GZFLExxrvWFuFT1xRzhfwQWSE2bPDedBfn',
|
||||
address="GZFLExxrvWFuFT1xRzhfwQWSE2bPDedBfn",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bgold', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bgold", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b52250000000017160014b5355d001e720d8f4513da00ff2bba4dcf9d39fcffffffff02e0aebb00000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac3df39f06000000001976a914a8f757819ec6779409f45788f7b4a0e8f51ec50488ac02473044022073fcbf2876f073f78923ab427f14de5b2a0fbeb313a9b2b650b3567061f242a702202f45fc22c501108ff6222afe3aca7da9d8c7dc860f9cda335bef31fa184e7bef412102ecea08b559fc5abd009acf77cfae13fa8a3b1933e3e031956c65c12cec8ca3e300000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b52250000000017160014b5355d001e720d8f4513da00ff2bba4dcf9d39fcffffffff02e0aebb00000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac3df39f06000000001976a914a8f757819ec6779409f45788f7b4a0e8f51ec50488ac02473044022073fcbf2876f073f78923ab427f14de5b2a0fbeb313a9b2b650b3567061f242a702202f45fc22c501108ff6222afe3aca7da9d8c7dc860f9cda335bef31fa184e7bef412102ecea08b559fc5abd009acf77cfae13fa8a3b1933e3e031956c65c12cec8ca3e300000000"
|
||||
)
|
||||
|
||||
def test_send_p2sh_witness_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -280,12 +457,14 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/156'/0'/1/0"),
|
||||
amount=123456789,
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe',
|
||||
address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -295,73 +474,156 @@ class TestMsgSigntxBitcoinGold(TrezorTest):
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bgold', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bgold", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
# print(hexlify(serialized_tx))
|
||||
# assert False
|
||||
assert hexlify(serialized_tx) == b'0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b52250000000017160014b5355d001e720d8f4513da00ff2bba4dcf9d39fcffffffff02e0aebb00000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac3df39f060000000017a9140cd03822b799a452c106d1b3771844a067b17f118702483045022100d79b33384c686d8dd40ad5f84f46691d30994992c1cb42e934c2a625d86cb2f902206859805a9a98ba140b71a9d4b9a6b8df94a9424f9c40f3bd804149fd6e278d63412102ecea08b559fc5abd009acf77cfae13fa8a3b1933e3e031956c65c12cec8ca3e300000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b52250000000017160014b5355d001e720d8f4513da00ff2bba4dcf9d39fcffffffff02e0aebb00000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac3df39f060000000017a9140cd03822b799a452c106d1b3771844a067b17f118702483045022100d79b33384c686d8dd40ad5f84f46691d30994992c1cb42e934c2a625d86cb2f902206859805a9a98ba140b71a9d4b9a6b8df94a9424f9c40f3bd804149fd6e278d63412102ecea08b559fc5abd009acf77cfae13fa8a3b1933e3e031956c65c12cec8ca3e300000000"
|
||||
)
|
||||
|
||||
def test_send_multisig_1(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiBitcoinGold)
|
||||
nodes = map(lambda index: btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)), range(1, 4))
|
||||
nodes = map(
|
||||
lambda index: btc.get_public_node(
|
||||
self.client, parse_path("999'/1'/%d'" % index)
|
||||
),
|
||||
range(1, 4),
|
||||
)
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda n: proto.HDNodePathType(node=deserialize(n.xpub), address_n=[2, 0]), nodes)),
|
||||
signatures=[b'', b'', b''],
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda n: proto.HDNodePathType(
|
||||
node=deserialize(n.xpub), address_n=[2, 0]
|
||||
),
|
||||
nodes,
|
||||
)
|
||||
),
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("999'/1'/1'/2/0"),
|
||||
prev_hash=unhexlify('25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985'),
|
||||
prev_hash=unhexlify(
|
||||
"25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
multisig=multisig,
|
||||
amount=1610436
|
||||
amount=1610436,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(address='GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe',
|
||||
out1 = proto.TxOutputType(
|
||||
address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
|
||||
amount=1605000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS)
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures1, _) = btc.sign_tx(self.client, 'Bgold', [inp1], [out1])
|
||||
]
|
||||
)
|
||||
(signatures1, _) = btc.sign_tx(self.client, "Bgold", [inp1], [out1])
|
||||
# store signature
|
||||
inp1.multisig.signatures[0] = signatures1[0]
|
||||
# sign with third key
|
||||
inp1.address_n[2] = H_(3)
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures2, serialized_tx) = btc.sign_tx(self.client, 'Bgold', [inp1], [out1])
|
||||
]
|
||||
)
|
||||
(signatures2, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bgold", [inp1], [out1]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b522501000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac0400483045022100e728485c8337f9a09ebbf36edc0fef10f8bcf5c1ba601b7d8ba43a9250a898f002206b9e3401c297f9ab9afb7f1be59bb342db53b5b65aff7c557e3109679697df0f41473044022062ea69ecdc07d0dadc1971fbda50a629a56dd30f431db26327428f4992601ce602204a1c8ab9c7d81c36cb6f819109a26f9baaa9607b8d37bff5e24eee6fab4a04e441695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b522501000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac0400483045022100e728485c8337f9a09ebbf36edc0fef10f8bcf5c1ba601b7d8ba43a9250a898f002206b9e3401c297f9ab9afb7f1be59bb342db53b5b65aff7c557e3109679697df0f41473044022062ea69ecdc07d0dadc1971fbda50a629a56dd30f431db26327428f4992601ce602204a1c8ab9c7d81c36cb6f819109a26f9baaa9607b8d37bff5e24eee6fab4a04e441695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000"
|
||||
)
|
||||
|
@ -15,30 +15,40 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc, coins, messages as proto
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import coins
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.tools import parse_path
|
||||
from trezorlib import btc
|
||||
|
||||
TxApiDecredTestnet = coins.tx_api['Decred Testnet']
|
||||
TxApiDecredTestnet = coins.tx_api["Decred Testnet"]
|
||||
|
||||
|
||||
TXHASH_e16248 = unhexlify("e16248f0b39a0a0c0e53d6f2f84c2a944f0d50e017a82701e8e02e46e979d5ed")
|
||||
TXHASH_5e6e35 = unhexlify("5e6e3500a333c53c02f523db5f1a9b17538a8850b4c2c24ecb9b7ba48059b970")
|
||||
TXHASH_ccf95b = unhexlify("ccf95b0fd220ef59ae2e5b17005a81e222758122682d522eff8ae1fcbc93bc74")
|
||||
TXHASH_f395ef = unhexlify("f395ef3e72a831a766db15e7a38bc28025d4ee02234d68bdea2d8353b47a3113")
|
||||
TXHASH_3f7c39 = unhexlify("3f7c395521d38387e7617565fe17628723ef6635a08537ad9c46cfb1619e4c3f")
|
||||
TXHASH_16da18 = unhexlify("16da185052740d85a630e79c140558215b64e26c500212b90e16b55d13ca06a8")
|
||||
TXHASH_e16248 = unhexlify(
|
||||
"e16248f0b39a0a0c0e53d6f2f84c2a944f0d50e017a82701e8e02e46e979d5ed"
|
||||
)
|
||||
TXHASH_5e6e35 = unhexlify(
|
||||
"5e6e3500a333c53c02f523db5f1a9b17538a8850b4c2c24ecb9b7ba48059b970"
|
||||
)
|
||||
TXHASH_ccf95b = unhexlify(
|
||||
"ccf95b0fd220ef59ae2e5b17005a81e222758122682d522eff8ae1fcbc93bc74"
|
||||
)
|
||||
TXHASH_f395ef = unhexlify(
|
||||
"f395ef3e72a831a766db15e7a38bc28025d4ee02234d68bdea2d8353b47a3113"
|
||||
)
|
||||
TXHASH_3f7c39 = unhexlify(
|
||||
"3f7c395521d38387e7617565fe17628723ef6635a08537ad9c46cfb1619e4c3f"
|
||||
)
|
||||
TXHASH_16da18 = unhexlify(
|
||||
"16da185052740d85a630e79c140558215b64e26c500212b90e16b55d13ca06a8"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
@pytest.mark.decred
|
||||
class TestMsgSigntxDecred(TrezorTest):
|
||||
|
||||
def test_send_decred(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiDecredTestnet)
|
||||
@ -60,23 +70,56 @@ class TestMsgSigntxDecred(TrezorTest):
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_e16248)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_e16248, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_e16248, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_e16248, request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_e16248),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_e16248, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_e16248, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_e16248, request_index=1
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.FeeOverThreshold),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, "Decred Testnet", [inp1], [out1])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Decred Testnet", [inp1], [out1]
|
||||
)
|
||||
|
||||
# Accepted by network: 5e6e3500a333c53c02f523db5f1a9b17538a8850b4c2c24ecb9b7ba48059b970
|
||||
assert serialized_tx == unhexlify("0100000001edd579e9462ee0e80127a817e0500d4f942a4cf8f2d6530e0c0a9ab3f04862e10100000000ffffffff01802b530b0000000000001976a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac000000000000000001000000000000000000000000ffffffff6b483045022100bad68486491e449a731513805c129201d7f65601d6f07c97fda0588453c97d22022013e9ef59657ae4f344ac4f0db2b7a23dbfcdb51ebeb85277146ac189e547d3f7012102f5a745afb96077c071e4d19911a5d3d024faa1314ee8688bc6eec39751d0818f")
|
||||
assert serialized_tx == unhexlify(
|
||||
"0100000001edd579e9462ee0e80127a817e0500d4f942a4cf8f2d6530e0c0a9ab3f04862e10100000000ffffffff01802b530b0000000000001976a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac000000000000000001000000000000000000000000ffffffff6b483045022100bad68486491e449a731513805c129201d7f65601d6f07c97fda0588453c97d22022013e9ef59657ae4f344ac4f0db2b7a23dbfcdb51ebeb85277146ac189e547d3f7012102f5a745afb96077c071e4d19911a5d3d024faa1314ee8688bc6eec39751d0818f"
|
||||
)
|
||||
|
||||
def test_send_decred_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -125,51 +168,133 @@ class TestMsgSigntxDecred(TrezorTest):
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_5e6e35)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_5e6e35, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_5e6e35, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_ccf95b)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_ccf95b, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_ccf95b, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_ccf95b, request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=2)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_f395ef)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_f395ef, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_f395ef, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_f395ef, request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_5e6e35),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_5e6e35, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_5e6e35, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_ccf95b),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_ccf95b, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_ccf95b, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_ccf95b, request_index=1
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=2),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_f395ef),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_f395ef, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_f395ef, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_f395ef, request_index=1
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=2)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=2),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, "Decred Testnet", [inp1, inp2, inp3], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Decred Testnet", [inp1, inp2, inp3], [out1, out2]
|
||||
)
|
||||
|
||||
# Accepted by network: c5ff767141a162b665acf775fcc35b60ff622fbe21a21e0a6609ed768c3737f4
|
||||
assert serialized_tx == unhexlify("010000000370b95980a47b9bcb4ec2c2b450888a53179b1a5fdb23f5023cc533a300356e5e0000000000ffffffff74bc93bcfce18aff2e522d6822817522e2815a00175b2eae59ef20d20f5bf9cc0100000000ffffffff13317ab453832deabd684d2302eed42580c28ba3e715db66a731a8723eef95f30000000000ffffffff02d86c341d0000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac00e1f5050000000000001976a9146748ebb8694c069742ee69eab2159c33c7f57d2b88ac000000000000000003000000000000000000000000ffffffff6b483045022100d91237a32b8968e1d3316b76f045cc18fed12736aebd570dd023a61826279cc102204222b133189762368d3398d11eb9a6843a67de11d70ac58426a28b605fa102b1012102f5a745afb96077c071e4d19911a5d3d024faa1314ee8688bc6eec39751d0818f000000000000000000000000ffffffff69463043021f7cf9b0b180f3fcde8d3d036d81e575e368d6ab5c8c6a2ffef47c06a0170023022036b964bf26ff276c58862dfacafa93216618832d6240f16b6100a9d10d5eb753012102f5a745afb96077c071e4d19911a5d3d024faa1314ee8688bc6eec39751d0818f000000000000000000000000ffffffff6b48304502210098f3a0cc17c3383f5998c542950b5cccb1175cc94b8d0343f420dc64abe9a50e0220507974c6ef0761925634fe3e13ec458b8cd3e42856828d584d4a5d39cc4d0f890121022c6099c7af8124d58e97beefc85c529dcfb3865794d46ec04095e70872e32a2e")
|
||||
assert serialized_tx == unhexlify(
|
||||
"010000000370b95980a47b9bcb4ec2c2b450888a53179b1a5fdb23f5023cc533a300356e5e0000000000ffffffff74bc93bcfce18aff2e522d6822817522e2815a00175b2eae59ef20d20f5bf9cc0100000000ffffffff13317ab453832deabd684d2302eed42580c28ba3e715db66a731a8723eef95f30000000000ffffffff02d86c341d0000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac00e1f5050000000000001976a9146748ebb8694c069742ee69eab2159c33c7f57d2b88ac000000000000000003000000000000000000000000ffffffff6b483045022100d91237a32b8968e1d3316b76f045cc18fed12736aebd570dd023a61826279cc102204222b133189762368d3398d11eb9a6843a67de11d70ac58426a28b605fa102b1012102f5a745afb96077c071e4d19911a5d3d024faa1314ee8688bc6eec39751d0818f000000000000000000000000ffffffff69463043021f7cf9b0b180f3fcde8d3d036d81e575e368d6ab5c8c6a2ffef47c06a0170023022036b964bf26ff276c58862dfacafa93216618832d6240f16b6100a9d10d5eb753012102f5a745afb96077c071e4d19911a5d3d024faa1314ee8688bc6eec39751d0818f000000000000000000000000ffffffff6b48304502210098f3a0cc17c3383f5998c542950b5cccb1175cc94b8d0343f420dc64abe9a50e0220507974c6ef0761925634fe3e13ec458b8cd3e42856828d584d4a5d39cc4d0f890121022c6099c7af8124d58e97beefc85c529dcfb3865794d46ec04095e70872e32a2e"
|
||||
)
|
||||
|
||||
def test_decred_multisig_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiDecredTestnet)
|
||||
|
||||
paths = [parse_path("m/48'/1'/%d'" % index) for index in range(3)]
|
||||
nodes = [btc.get_public_node(self.client, address_n, coin_name="Decred Testnet").node for address_n in paths]
|
||||
|
||||
signatures = [
|
||||
[b'', b'', b''],
|
||||
[b'', b'', b''],
|
||||
nodes = [
|
||||
btc.get_public_node(self.client, address_n, coin_name="Decred Testnet").node
|
||||
for address_n in paths
|
||||
]
|
||||
|
||||
signatures = [[b"", b"", b""], [b"", b"", b""]]
|
||||
|
||||
def create_multisig(index, address, signatures=None):
|
||||
address_n = parse_path(address)
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[proto.HDNodePathType(node=node, address_n=address_n) for node in nodes],
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=address_n)
|
||||
for node in nodes
|
||||
],
|
||||
signatures=signatures,
|
||||
m=2,
|
||||
)
|
||||
@ -217,26 +342,84 @@ class TestMsgSigntxDecred(TrezorTest):
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_3f7c39)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_3f7c39, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_3f7c39, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_3f7c39, request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_16da18)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_16da18, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_16da18, request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(tx_hash=TXHASH_16da18, request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_3f7c39),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_3f7c39, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_3f7c39, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_3f7c39, request_index=1
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_16da18),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_16da18, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_16da18, request_index=0
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
tx_hash=TXHASH_16da18, request_index=1
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signature, serialized_tx) = btc.sign_tx(self.client, "Decred Testnet", [inp1, inp2], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signature, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Decred Testnet", [inp1, inp2], [out1, out2]
|
||||
)
|
||||
|
||||
signatures[0][index] = signature[0]
|
||||
signatures[1][index] = signature[1]
|
||||
@ -246,4 +429,6 @@ class TestMsgSigntxDecred(TrezorTest):
|
||||
serialized_tx = test_multisig(0)
|
||||
|
||||
# Accepted by network: eccfecc0dc3275f7fa5a966b58c8d503f8b3d23964f2ce2c3336e5883919f45f
|
||||
assert serialized_tx == unhexlify("01000000023f4c9e61b1cf469cad3785a03566ef23876217fe657561e78783d32155397c3f0100000000ffffffffa806ca135db5160eb91202506ce2645b215805149ce730a6850d74525018da160000000000ffffffff02605af40500000000000017a914d42253369723b43e114b31807ef68f84363e54418700a3e1110000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac000000000000000002000000000000000000000000fffffffffc483045022100be61bbcfd804f1e092c432511884bf8bdc00b6d302f00811149d20628bf3d33502200680721d1d03a71476f65e8815e2fba35bec6be982aa7686a57134eeae9a66f3014730440220016f9dd48ca0ceecf481d96f2c65389abb491af5f0eb63d76eb0f6a67a99718b02204fdeadace9167472411bb44bb63009ebd2373aa77cc08989a25fca37648dc685014c69522102a7ee50c2ceeacaed42aea05b29ac2ac3ec3c7e151dd95780929f53a0011f97a121038f9ebf01b25d80b4b8ad179542859ca96a9c5c8cbf0b5a50a92c0d9a7501efe62103b8d7f5663458e545af7de7a037e61a0e32c291ed2695f3cae120d6a0fe98052e53ae000000000000000000000000fffffffffdfd00483045022100ca8dd36eee86c4cefecfdd91cdf40a35a4274f71c4283e5b98af6bc242e2d5ad022009247ea5663367c2964f61b6111ea1a0790b381a40310f4e867a3725b249f12c01483045022100abc7b1440c31a564e1cd9d0a75abaa5abd8c1285b874c0e97e311e697782954302202fa43fb00149bb2d14b1a31a81b7660d6c9a17c4621a07eb4c2290b627aa540a014c69522103334dd6c58fae3d462f359125f0d6835e57ad885e5058b417f217decc21fdbba4210392af36b8a65ea0bb6f0acdec9069a0b5b75b00d9667b89e2a77f92d4efc92b9821025945b9f11a71546afe4af28cd291830fd77cb184006a90223de1b2c26502bfc353ae")
|
||||
assert serialized_tx == unhexlify(
|
||||
"01000000023f4c9e61b1cf469cad3785a03566ef23876217fe657561e78783d32155397c3f0100000000ffffffffa806ca135db5160eb91202506ce2645b215805149ce730a6850d74525018da160000000000ffffffff02605af40500000000000017a914d42253369723b43e114b31807ef68f84363e54418700a3e1110000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac000000000000000002000000000000000000000000fffffffffc483045022100be61bbcfd804f1e092c432511884bf8bdc00b6d302f00811149d20628bf3d33502200680721d1d03a71476f65e8815e2fba35bec6be982aa7686a57134eeae9a66f3014730440220016f9dd48ca0ceecf481d96f2c65389abb491af5f0eb63d76eb0f6a67a99718b02204fdeadace9167472411bb44bb63009ebd2373aa77cc08989a25fca37648dc685014c69522102a7ee50c2ceeacaed42aea05b29ac2ac3ec3c7e151dd95780929f53a0011f97a121038f9ebf01b25d80b4b8ad179542859ca96a9c5c8cbf0b5a50a92c0d9a7501efe62103b8d7f5663458e545af7de7a037e61a0e32c291ed2695f3cae120d6a0fe98052e53ae000000000000000000000000fffffffffdfd00483045022100ca8dd36eee86c4cefecfdd91cdf40a35a4274f71c4283e5b98af6bc242e2d5ad022009247ea5663367c2964f61b6111ea1a0790b381a40310f4e867a3725b249f12c01483045022100abc7b1440c31a564e1cd9d0a75abaa5abd8c1285b874c0e97e311e697782954302202fa43fb00149bb2d14b1a31a81b7660d6c9a17c4621a07eb4c2290b627aa540a014c69522103334dd6c58fae3d462f359125f0d6835e57ad885e5058b417f217decc21fdbba4210392af36b8a65ea0bb6f0acdec9069a0b5b75b00d9667b89e2a77f92d4efc92b9821025945b9f11a71546afe4af28cd291830fd77cb184006a90223de1b2c26502bfc353ae"
|
||||
)
|
||||
|
@ -15,22 +15,21 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from ..support.ckd_public import deserialize
|
||||
from .conftest import TREZOR_VERSION
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc, messages as proto
|
||||
from trezorlib.tools import H_, CallException, parse_path
|
||||
from trezorlib.tx_api import TxApiInsight
|
||||
from trezorlib.tools import parse_path, CallException, H_
|
||||
from trezorlib import btc
|
||||
|
||||
from ..support.ckd_public import deserialize
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
|
||||
TxApiTestnet = TxApiInsight("insight_testnet")
|
||||
|
||||
|
||||
class TestMsgSigntxSegwit(TrezorTest):
|
||||
|
||||
def test_send_p2sh(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
@ -38,37 +37,67 @@ class TestMsgSigntxSegwit(TrezorTest):
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
|
||||
prev_hash=unhexlify(
|
||||
"20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address='2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX',
|
||||
address="2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
)
|
||||
|
||||
def test_send_p2sh_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
@ -77,12 +106,14 @@ class TestMsgSigntxSegwit(TrezorTest):
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
|
||||
prev_hash=unhexlify(
|
||||
"20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -92,74 +123,157 @@ class TestMsgSigntxSegwit(TrezorTest):
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
)
|
||||
|
||||
def test_send_multisig_1(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
nodes = map(lambda index: btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)), range(1, 4))
|
||||
nodes = map(
|
||||
lambda index: btc.get_public_node(
|
||||
self.client, parse_path("999'/1'/%d'" % index)
|
||||
),
|
||||
range(1, 4),
|
||||
)
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=list(map(lambda n: proto.HDNodePathType(node=deserialize(n.xpub), address_n=[2, 0]), nodes)),
|
||||
signatures=[b'', b'', b''],
|
||||
pubkeys=list(
|
||||
map(
|
||||
lambda n: proto.HDNodePathType(
|
||||
node=deserialize(n.xpub), address_n=[2, 0]
|
||||
),
|
||||
nodes,
|
||||
)
|
||||
),
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("999'/1'/1'/2/0"),
|
||||
prev_hash=unhexlify('9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'),
|
||||
prev_hash=unhexlify(
|
||||
"9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
multisig=multisig,
|
||||
amount=1610436
|
||||
amount=1610436,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=1605000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS)
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures1, _) = btc.sign_tx(self.client, 'Testnet', [inp1], [out1])
|
||||
]
|
||||
)
|
||||
(signatures1, _) = btc.sign_tx(self.client, "Testnet", [inp1], [out1])
|
||||
# store signature
|
||||
inp1.multisig.signatures[0] = signatures1[0]
|
||||
# sign with third key
|
||||
inp1.address_n[2] = H_(3)
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures2, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [inp1], [out1])
|
||||
]
|
||||
)
|
||||
(signatures2, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [inp1], [out1]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000"
|
||||
)
|
||||
|
||||
def test_attack_change_input_address(self):
|
||||
# This unit test attempts to modify input address after the Trezor checked
|
||||
@ -171,12 +285,14 @@ class TestMsgSigntxSegwit(TrezorTest):
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
|
||||
prev_hash=unhexlify(
|
||||
"20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
@ -210,38 +326,88 @@ class TestMsgSigntxSegwit(TrezorTest):
|
||||
|
||||
# Test if the transaction can be signed normally
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [inp1], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a914dae9e09a7fc3bbe5a716fffec1bbb340b82a4fb9870248304502210099b5c4f8fd4402c9c0136fee5f711137d64fc9f14587e01bfa7798f5428f845d0220253e21c98f5b1b64efae69bc2ea9799c5620a43450baa6762a0c3cf4fdc886e5012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a914dae9e09a7fc3bbe5a716fffec1bbb340b82a4fb9870248304502210099b5c4f8fd4402c9c0136fee5f711137d64fc9f14587e01bfa7798f5428f845d0220253e21c98f5b1b64efae69bc2ea9799c5620a43450baa6762a0c3cf4fdc886e5012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
)
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
])
|
||||
]
|
||||
)
|
||||
with pytest.raises(CallException) as exc:
|
||||
btc.sign_tx(self.client, 'Testnet', [inp1], [out1, out2], debug_processor=attack_processor)
|
||||
btc.sign_tx(
|
||||
self.client,
|
||||
"Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
debug_processor=attack_processor,
|
||||
)
|
||||
assert exc.value.args[0] == proto.FailureType.ProcessError
|
||||
if TREZOR_VERSION == 1:
|
||||
assert exc.value.args[1].endswith("Failed to compile input")
|
||||
else:
|
||||
assert exc.value.args[1].endswith('Transaction has changed during signing')
|
||||
assert exc.value.args[1].endswith(
|
||||
"Transaction has changed during signing"
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,24 +14,24 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify, hexlify
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc, coins, messages as proto
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import coins
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.tools import parse_path
|
||||
from trezorlib import btc
|
||||
TxApiZcashTestnet = coins.tx_api["Zcash Testnet"]
|
||||
|
||||
TxApiZcashTestnet = coins.tx_api['Zcash Testnet']
|
||||
|
||||
TXHASH_aaf51e = unhexlify('aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc')
|
||||
TXHASH_aaf51e = unhexlify(
|
||||
"aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.zcash
|
||||
class TestMsgSigntxZcash(TrezorTest):
|
||||
|
||||
def test_one_one_fee(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
|
||||
@ -39,31 +39,57 @@ class TestMsgSigntxZcash(TrezorTest):
|
||||
# input 1: 3.0 TAZ
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("m/Zcash Testnet/0h/0/0"), # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path(
|
||||
"m/Zcash Testnet/0h/0/0"
|
||||
), # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_aaf51e,
|
||||
prev_index=1,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z',
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_tx_api(TxApiZcashTestnet)
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Zcash Testnet', [inp1, ], [out1, ], version=3, overwintered=True)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client,
|
||||
"Zcash Testnet",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=3,
|
||||
overwintered=True,
|
||||
)
|
||||
|
||||
# Accepted by network: tx eda9b772c47f0c29310759960e0081c98707aa67a0a2738bcc71439fcf360675
|
||||
assert hexlify(serialized_tx) == b'030000807082c40301dc754d63eff4698ee321476872519c53f14cfe58c9425c7ee464c206461ef5aa010000006a47304402207e45f303b4e42be824513855eb21653e1d2749cd94dcd0f0613d3f85d4efd1e20220699ffbdbcad889af7ede5ce9febf7a5ef8f5619b2464824529974c400cffaebc0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac000000000000000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"030000807082c40301dc754d63eff4698ee321476872519c53f14cfe58c9425c7ee464c206461ef5aa010000006a47304402207e45f303b4e42be824513855eb21653e1d2749cd94dcd0f0613d3f85d4efd1e20220699ffbdbcad889af7ede5ce9febf7a5ef8f5619b2464824529974c400cffaebc0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac000000000000000000"
|
||||
)
|
||||
|
@ -16,45 +16,54 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import debuglink, messages as proto, stellar
|
||||
from trezorlib.tools import CallException, parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
from trezorlib import stellar
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.tools import parse_path, CallException
|
||||
from trezorlib import debuglink
|
||||
|
||||
|
||||
@pytest.mark.stellar
|
||||
class TestMsgStellarGetAddress(TrezorTest):
|
||||
|
||||
def test_stellar_get_address(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
address = stellar.get_address(self.client, parse_path(stellar.DEFAULT_BIP32_PATH))
|
||||
assert address == 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
address = stellar.get_address(
|
||||
self.client, parse_path(stellar.DEFAULT_BIP32_PATH)
|
||||
)
|
||||
assert address == "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
|
||||
def test_stellar_get_address_sep(self):
|
||||
# data from https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
mnemonic='illness spike retreat truth genius clock brain pass fit cave bargain toe',
|
||||
pin='',
|
||||
mnemonic="illness spike retreat truth genius clock brain pass fit cave bargain toe",
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label='test',
|
||||
language='english')
|
||||
label="test",
|
||||
language="english",
|
||||
)
|
||||
|
||||
address = stellar.get_address(self.client, parse_path(stellar.DEFAULT_BIP32_PATH))
|
||||
assert address == 'GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RGZGIEKWE4SOOHSUJUJ6'
|
||||
address = stellar.get_address(
|
||||
self.client, parse_path(stellar.DEFAULT_BIP32_PATH)
|
||||
)
|
||||
assert address == "GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RGZGIEKWE4SOOHSUJUJ6"
|
||||
|
||||
address = stellar.get_address(self.client, parse_path("m/44h/148h/1h"), show_display=True)
|
||||
assert address == 'GBAW5XGWORWVFE2XTJYDTLDHXTY2Q2MO73HYCGB3XMFMQ562Q2W2GJQX'
|
||||
address = stellar.get_address(
|
||||
self.client, parse_path("m/44h/148h/1h"), show_display=True
|
||||
)
|
||||
assert address == "GBAW5XGWORWVFE2XTJYDTLDHXTY2Q2MO73HYCGB3XMFMQ562Q2W2GJQX"
|
||||
|
||||
def test_stellar_get_address_get_pubkey(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
pubkey = stellar.get_public_key(self.client, parse_path(stellar.DEFAULT_BIP32_PATH))
|
||||
pubkey = stellar.get_public_key(
|
||||
self.client, parse_path(stellar.DEFAULT_BIP32_PATH)
|
||||
)
|
||||
# GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW
|
||||
address = stellar.get_address(self.client, parse_path(stellar.DEFAULT_BIP32_PATH))
|
||||
address = stellar.get_address(
|
||||
self.client, parse_path(stellar.DEFAULT_BIP32_PATH)
|
||||
)
|
||||
|
||||
assert stellar.address_from_public_key(pubkey) == address
|
||||
|
||||
@ -62,11 +71,11 @@ class TestMsgStellarGetAddress(TrezorTest):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with pytest.raises(CallException) as exc:
|
||||
stellar.get_address(self.client, parse_path('m/0/1'))
|
||||
stellar.get_address(self.client, parse_path("m/0/1"))
|
||||
|
||||
if TREZOR_VERSION == 1:
|
||||
assert exc.value.args[0] == proto.FailureType.ProcessError
|
||||
assert exc.value.args[1].endswith('Failed to derive private key')
|
||||
assert exc.value.args[1].endswith("Failed to derive private key")
|
||||
else:
|
||||
assert exc.value.args[0] == proto.FailureType.FirmwareError
|
||||
assert exc.value.args[1].endswith('Firmware error')
|
||||
assert exc.value.args[1].endswith("Firmware error")
|
||||
|
@ -14,36 +14,44 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import messages, stellar
|
||||
from trezorlib.tools import CallException, parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
from binascii import hexlify
|
||||
from trezorlib import stellar
|
||||
from trezorlib import messages
|
||||
from trezorlib.tools import parse_path, CallException
|
||||
|
||||
|
||||
@pytest.mark.stellar
|
||||
class TestMsgStellarGetPublicKey(TrezorTest):
|
||||
|
||||
def test_stellar_get_public_key(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
# GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW
|
||||
response = stellar.get_public_key(self.client, parse_path(stellar.DEFAULT_BIP32_PATH), show_display=True)
|
||||
assert hexlify(response) == b'15d648bfe4d36f196cfb5735ffd8ca54cd4b8233f743f22449de7cf301cdb469'
|
||||
assert stellar.address_from_public_key(response) == 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
response = stellar.get_public_key(
|
||||
self.client, parse_path(stellar.DEFAULT_BIP32_PATH), show_display=True
|
||||
)
|
||||
assert (
|
||||
hexlify(response)
|
||||
== b"15d648bfe4d36f196cfb5735ffd8ca54cd4b8233f743f22449de7cf301cdb469"
|
||||
)
|
||||
assert (
|
||||
stellar.address_from_public_key(response)
|
||||
== "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
)
|
||||
|
||||
def test_stellar_get_public_key_fail(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with pytest.raises(CallException) as exc:
|
||||
stellar.get_public_key(self.client, parse_path('m/0/1'))
|
||||
stellar.get_public_key(self.client, parse_path("m/0/1"))
|
||||
|
||||
if TREZOR_VERSION == 1:
|
||||
assert exc.value.args[0] == messages.FailureType.ProcessError
|
||||
assert exc.value.args[1].endswith('Failed to derive private key')
|
||||
assert exc.value.args[1].endswith("Failed to derive private key")
|
||||
else:
|
||||
assert exc.value.args[0] == messages.FailureType.FirmwareError
|
||||
assert exc.value.args[1].endswith('Firmware error')
|
||||
assert exc.value.args[1].endswith("Firmware error")
|
||||
|
@ -47,19 +47,21 @@
|
||||
#
|
||||
|
||||
from base64 import b64encode
|
||||
from .common import TrezorTest
|
||||
from binascii import hexlify
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import stellar
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import messages as proto, stellar
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.stellar
|
||||
class TestMsgStellarSignTransaction(TrezorTest):
|
||||
|
||||
ADDRESS_N = parse_path(stellar.DEFAULT_BIP32_PATH)
|
||||
NETWORK_PASSPHRASE = 'Test SDF Network ; September 2015'
|
||||
NETWORK_PASSPHRASE = "Test SDF Network ; September 2015"
|
||||
|
||||
def test_sign_tx_bump_sequence_op(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -68,35 +70,55 @@ class TestMsgStellarSignTransaction(TrezorTest):
|
||||
op.bump_to = 0x7fffffffffffffff
|
||||
tx = self._create_msg()
|
||||
|
||||
response = stellar.sign_tx(self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE)
|
||||
assert b64encode(response.signature) == b'ZMIfHWhpyXdg40PzwOtkcXYnbZIO12Qy0WvkGqoYpb7jyWbG2HQCG7dgWhCoU5K81pvZTA2pMwiPjMwCXA//Bg=='
|
||||
response = stellar.sign_tx(
|
||||
self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE
|
||||
)
|
||||
assert (
|
||||
b64encode(response.signature)
|
||||
== b"ZMIfHWhpyXdg40PzwOtkcXYnbZIO12Qy0WvkGqoYpb7jyWbG2HQCG7dgWhCoU5K81pvZTA2pMwiPjMwCXA//Bg=="
|
||||
)
|
||||
|
||||
def test_sign_tx_account_merge_op(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
op = proto.StellarAccountMergeOp()
|
||||
op.destination_account = 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
op.destination_account = (
|
||||
"GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
|
||||
tx = self._create_msg()
|
||||
|
||||
response = stellar.sign_tx(self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE)
|
||||
response = stellar.sign_tx(
|
||||
self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE
|
||||
)
|
||||
|
||||
assert hexlify(response.public_key) == b'15d648bfe4d36f196cfb5735ffd8ca54cd4b8233f743f22449de7cf301cdb469'
|
||||
assert b64encode(response.signature) == b'2R3Pj89U+dWrqy7otUrLLjtANjAg0lmBQL8E+89Po0Y94oqZkauP8j3WE7+/z7vF6XvAMLoOdqRYkUzr2oh7Dg=='
|
||||
assert (
|
||||
hexlify(response.public_key)
|
||||
== b"15d648bfe4d36f196cfb5735ffd8ca54cd4b8233f743f22449de7cf301cdb469"
|
||||
)
|
||||
assert (
|
||||
b64encode(response.signature)
|
||||
== b"2R3Pj89U+dWrqy7otUrLLjtANjAg0lmBQL8E+89Po0Y94oqZkauP8j3WE7+/z7vF6XvAMLoOdqRYkUzr2oh7Dg=="
|
||||
)
|
||||
|
||||
def test_sign_tx_create_account_op(self):
|
||||
"""Create new account with initial balance of 100.0333"""
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
op = proto.StellarCreateAccountOp()
|
||||
op.new_account = 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
op.new_account = "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
op.starting_balance = 1000333000
|
||||
|
||||
tx = self._create_msg()
|
||||
|
||||
response = stellar.sign_tx(self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE)
|
||||
response = stellar.sign_tx(
|
||||
self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE
|
||||
)
|
||||
|
||||
assert b64encode(response.signature) == b'vrRYqkM4b54NrDR05UrW7ZHU7CNcidV0fn+bk9dqOW1bCbmX3YfeRbk2Tf1aea8nr9SD0sfBhtrDpdyxUenjBw=='
|
||||
assert (
|
||||
b64encode(response.signature)
|
||||
== b"vrRYqkM4b54NrDR05UrW7ZHU7CNcidV0fn+bk9dqOW1bCbmX3YfeRbk2Tf1aea8nr9SD0sfBhtrDpdyxUenjBw=="
|
||||
)
|
||||
|
||||
def test_sign_tx_payment_op_native(self):
|
||||
"""Native payment of 50.0111 XLM to GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"""
|
||||
@ -104,13 +126,20 @@ class TestMsgStellarSignTransaction(TrezorTest):
|
||||
|
||||
op = proto.StellarPaymentOp()
|
||||
op.amount = 500111000
|
||||
op.destination_account = 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
op.destination_account = (
|
||||
"GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
|
||||
tx = self._create_msg()
|
||||
|
||||
response = stellar.sign_tx(self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE)
|
||||
response = stellar.sign_tx(
|
||||
self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE
|
||||
)
|
||||
|
||||
assert b64encode(response.signature) == b'pDc6ghKCLNoYbt3h4eBw+533237m0BB0Jp/d/TxJCA83mF3o5Fr4l5vwAWBR62hdTWAP9MhVluY0cd5i54UwDg=='
|
||||
assert (
|
||||
b64encode(response.signature)
|
||||
== b"pDc6ghKCLNoYbt3h4eBw+533237m0BB0Jp/d/TxJCA83mF3o5Fr4l5vwAWBR62hdTWAP9MhVluY0cd5i54UwDg=="
|
||||
)
|
||||
|
||||
def test_sign_tx_payment_op_custom_asset1(self):
|
||||
"""Custom asset payment (code length 1) of 50.0111 X to GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"""
|
||||
@ -118,14 +147,23 @@ class TestMsgStellarSignTransaction(TrezorTest):
|
||||
|
||||
op = proto.StellarPaymentOp()
|
||||
op.amount = 500111000
|
||||
op.destination_account = 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
op.destination_account = (
|
||||
"GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
|
||||
op.asset = proto.StellarAssetType(1, 'X', 'GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC')
|
||||
op.asset = proto.StellarAssetType(
|
||||
1, "X", "GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC"
|
||||
)
|
||||
tx = self._create_msg()
|
||||
|
||||
response = stellar.sign_tx(self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE)
|
||||
response = stellar.sign_tx(
|
||||
self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE
|
||||
)
|
||||
|
||||
assert b64encode(response.signature) == b'ArZydOtXU2whoRuSjJLFIWPSIsq3AbsncJZ+THF24CRSriVWw5Fy/dHrDlUOu4fzU28I6osDMeI39aWezg5tDw=='
|
||||
assert (
|
||||
b64encode(response.signature)
|
||||
== b"ArZydOtXU2whoRuSjJLFIWPSIsq3AbsncJZ+THF24CRSriVWw5Fy/dHrDlUOu4fzU28I6osDMeI39aWezg5tDw=="
|
||||
)
|
||||
|
||||
def test_sign_tx_payment_op_custom_asset12(self):
|
||||
"""Custom asset payment (code length 12) of 50.0111 ABCDEFGHIJKL to GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"""
|
||||
@ -133,30 +171,48 @@ class TestMsgStellarSignTransaction(TrezorTest):
|
||||
|
||||
op = proto.StellarPaymentOp()
|
||||
op.amount = 500111000
|
||||
op.destination_account = 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
op.destination_account = (
|
||||
"GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
|
||||
op.asset = proto.StellarAssetType(2, 'ABCDEFGHIJKL', 'GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC')
|
||||
op.asset = proto.StellarAssetType(
|
||||
2,
|
||||
"ABCDEFGHIJKL",
|
||||
"GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC",
|
||||
)
|
||||
tx = self._create_msg()
|
||||
|
||||
response = stellar.sign_tx(self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE)
|
||||
response = stellar.sign_tx(
|
||||
self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE
|
||||
)
|
||||
|
||||
assert b64encode(response.signature) == b'QZIP4XKPfe4OpZtuJiyrMZBX9YBzvGpHGcngdgFfHn2kcdONreF384/pCF80xfEnGm8grKaoOnUEKxqcMKvxAA=='
|
||||
assert (
|
||||
b64encode(response.signature)
|
||||
== b"QZIP4XKPfe4OpZtuJiyrMZBX9YBzvGpHGcngdgFfHn2kcdONreF384/pCF80xfEnGm8grKaoOnUEKxqcMKvxAA=="
|
||||
)
|
||||
|
||||
def test_sign_tx_set_options_op_inflation(self):
|
||||
"""Set inflation destination"""
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
op = proto.StellarSetOptionsOp()
|
||||
op.inflation_destination_account = 'GAFXTC5OV5XQD66T7WGOB2HUVUC3ZVJDJMBDPTVQYV3G3K7TUHC6CLBR'
|
||||
op.inflation_destination_account = (
|
||||
"GAFXTC5OV5XQD66T7WGOB2HUVUC3ZVJDJMBDPTVQYV3G3K7TUHC6CLBR"
|
||||
)
|
||||
|
||||
tx = self._create_msg()
|
||||
response = stellar.sign_tx(self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE)
|
||||
response = stellar.sign_tx(
|
||||
self.client, tx, [op], self.ADDRESS_N, self.NETWORK_PASSPHRASE
|
||||
)
|
||||
|
||||
assert b64encode(response.signature) == b'dveWhKY8x7b0YqGHWH6Fo1SskxaHP11NXd2n6oHKGiv+T/LqB+CCzbmJA0tplZ+0HNPJbHD7L3Bsg/y462qLDA=='
|
||||
assert (
|
||||
b64encode(response.signature)
|
||||
== b"dveWhKY8x7b0YqGHWH6Fo1SskxaHP11NXd2n6oHKGiv+T/LqB+CCzbmJA0tplZ+0HNPJbHD7L3Bsg/y462qLDA=="
|
||||
)
|
||||
|
||||
def _create_msg(self) -> proto.StellarSignTx:
|
||||
tx = proto.StellarSignTx()
|
||||
tx.source_account = 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
tx.source_account = "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
tx.fee = 100
|
||||
tx.sequence_number = 0x100000000
|
||||
tx.memo_type = 0
|
||||
|
@ -16,20 +16,22 @@
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import btc
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgVerifymessage(TrezorTest):
|
||||
|
||||
def test_message_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
ret = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
unhexlify('205ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed'),
|
||||
"VeryLongMessage!" * 64
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
unhexlify(
|
||||
"205ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
@ -37,10 +39,12 @@ class TestMsgVerifymessage(TrezorTest):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
ret = btc.verify_message(
|
||||
self.client,
|
||||
'Testnet',
|
||||
'mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL',
|
||||
unhexlify('209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.'
|
||||
"Testnet",
|
||||
"mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL",
|
||||
unhexlify(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
@ -50,88 +54,108 @@ class TestMsgVerifymessage(TrezorTest):
|
||||
# uncompressed pubkey - OK
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T',
|
||||
unhexlify('1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
unhexlify(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# uncompressed pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T',
|
||||
unhexlify('1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c800'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
unhexlify(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c800"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# uncompressed pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T',
|
||||
unhexlify('1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2'),
|
||||
'This is an example of a signed message!'
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
unhexlify(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# compressed pubkey - OK
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8',
|
||||
unhexlify('1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf'),
|
||||
'This is an example of a signed message.')
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
unhexlify(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# compressed pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8',
|
||||
unhexlify('1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaa00'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
unhexlify(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaa00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# compressed pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8',
|
||||
unhexlify('1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf'),
|
||||
'This is an example of a signed message!')
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
unhexlify(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - OK
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
unhexlify('209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
unhexlify(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
unhexlify('209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
unhexlify(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
unhexlify('209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message!'
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
unhexlify(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
@ -139,10 +163,12 @@ class TestMsgVerifymessage(TrezorTest):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bcash',
|
||||
'bitcoincash:qqj22md58nm09vpwsw82fyletkxkq36zxyxh322pru',
|
||||
unhexlify('209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.'
|
||||
"Bcash",
|
||||
"bitcoincash:qqj22md58nm09vpwsw82fyletkxkq36zxyxh322pru",
|
||||
unhexlify(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
@ -151,10 +177,12 @@ class TestMsgVerifymessage(TrezorTest):
|
||||
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'1KzXE97kV7DrpxCViCN3HbGbiKhzzPM7TQ',
|
||||
unhexlify('1cc694f0f23901dfe3603789142f36a3fc582d0d5c0ec7215cf2ccd641e4e37228504f3d4dc3eea28bbdbf5da27c49d4635c097004d9f228750ccd836a8e1460c0'),
|
||||
u'\u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy'
|
||||
"Bitcoin",
|
||||
"1KzXE97kV7DrpxCViCN3HbGbiKhzzPM7TQ",
|
||||
unhexlify(
|
||||
"1cc694f0f23901dfe3603789142f36a3fc582d0d5c0ec7215cf2ccd641e4e37228504f3d4dc3eea28bbdbf5da27c49d4635c097004d9f228750ccd836a8e1460c0"
|
||||
),
|
||||
u"\u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy",
|
||||
)
|
||||
|
||||
assert res is True
|
||||
@ -162,23 +190,27 @@ class TestMsgVerifymessage(TrezorTest):
|
||||
def test_verify_utf(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
words_nfkd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
unhexlify('20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'),
|
||||
words_nfkd
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
unhexlify(
|
||||
"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
unhexlify('20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'),
|
||||
words_nfc
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
unhexlify(
|
||||
"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
|
@ -16,20 +16,22 @@
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import btc
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgVerifymessageSegwit(TrezorTest):
|
||||
|
||||
def test_message_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
ret = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1',
|
||||
unhexlify('245ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed'),
|
||||
"VeryLongMessage!" * 64
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
unhexlify(
|
||||
"245ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
@ -37,10 +39,12 @@ class TestMsgVerifymessageSegwit(TrezorTest):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
ret = btc.verify_message(
|
||||
self.client,
|
||||
'Testnet',
|
||||
'2N4VkePSzKH2sv5YBikLHGvzUYvfPxV6zS9',
|
||||
unhexlify('249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.'
|
||||
"Testnet",
|
||||
"2N4VkePSzKH2sv5YBikLHGvzUYvfPxV6zS9",
|
||||
unhexlify(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
@ -50,53 +54,63 @@ class TestMsgVerifymessageSegwit(TrezorTest):
|
||||
# trezor pubkey - OK
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1',
|
||||
unhexlify('249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
unhexlify(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1',
|
||||
unhexlify('249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
unhexlify(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1',
|
||||
unhexlify('249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message!'
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
unhexlify(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
def test_verify_utf(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
words_nfkd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1',
|
||||
unhexlify('24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'),
|
||||
words_nfkd
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
unhexlify(
|
||||
"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1',
|
||||
unhexlify('24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'),
|
||||
words_nfc
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
unhexlify(
|
||||
"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
|
@ -16,20 +16,22 @@
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import btc
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgVerifymessageSegwitNative(TrezorTest):
|
||||
|
||||
def test_message_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
ret = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j',
|
||||
unhexlify('285ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed'),
|
||||
"VeryLongMessage!" * 64
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
unhexlify(
|
||||
"285ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
@ -37,10 +39,12 @@ class TestMsgVerifymessageSegwitNative(TrezorTest):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
ret = btc.verify_message(
|
||||
self.client,
|
||||
'Testnet',
|
||||
'tb1qyjjkmdpu7metqt5r36jf872a34syws336p3n3p',
|
||||
unhexlify('289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.'
|
||||
"Testnet",
|
||||
"tb1qyjjkmdpu7metqt5r36jf872a34syws336p3n3p",
|
||||
unhexlify(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
@ -50,53 +54,63 @@ class TestMsgVerifymessageSegwitNative(TrezorTest):
|
||||
# trezor pubkey - OK
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j',
|
||||
unhexlify('289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
unhexlify(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j',
|
||||
unhexlify('289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00'),
|
||||
'This is an example of a signed message.'
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
unhexlify(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j',
|
||||
unhexlify('289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message!'
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
unhexlify(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
def test_verify_utf(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
words_nfkd = u'Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a'
|
||||
words_nfc = u'P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f'
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j',
|
||||
unhexlify('28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'),
|
||||
words_nfkd
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
unhexlify(
|
||||
"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j',
|
||||
unhexlify('28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6'),
|
||||
words_nfc
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
unhexlify(
|
||||
"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
|
@ -14,14 +14,12 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import device, messages as proto
|
||||
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import device
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
class TestMsgWipedevice(TrezorTest):
|
||||
|
||||
def test_wipe_device(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
features = self.client.call_raw(proto.Initialize())
|
||||
|
@ -15,15 +15,18 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support import ckd_public as bip32
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc, messages as proto
|
||||
from trezorlib.tools import CallException
|
||||
from trezorlib import btc
|
||||
|
||||
TXHASH_c6091a = unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52')
|
||||
from ..support import ckd_public as bip32
|
||||
from .common import TrezorTest
|
||||
|
||||
TXHASH_c6091a = unhexlify(
|
||||
"c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"
|
||||
)
|
||||
|
||||
|
||||
# Multisig howto:
|
||||
@ -33,7 +36,6 @@ TXHASH_c6091a = unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9
|
||||
|
||||
|
||||
class TestMultisig(TrezorTest):
|
||||
|
||||
def test_2_of_3(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
@ -58,15 +60,17 @@ class TestMultisig(TrezorTest):
|
||||
# tx: c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52
|
||||
# input 1: 0.001 BTC
|
||||
|
||||
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
|
||||
node = bip32.deserialize(
|
||||
"xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy"
|
||||
)
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3])
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
@ -80,31 +84,69 @@ class TestMultisig(TrezorTest):
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss',
|
||||
address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss",
|
||||
amount=100000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_c6091a
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_c6091a
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=1, tx_hash=TXHASH_c6091a
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
# Now we have first signature
|
||||
(signatures1, _) = btc.sign_tx(self.client, 'Bitcoin', [inp1, ], [out1, ])
|
||||
(signatures1, _) = btc.sign_tx(self.client, "Bitcoin", [inp1], [out1])
|
||||
|
||||
assert hexlify(signatures1[0]) == b'3045022100985cc1ba316d140eb4b2d4028d8cd1c451f87bff8ff679858732e516ad04cd3402207af6edda99972af0baa7702a3b7448517c8242e7bca669f6861771cdd16ee058'
|
||||
assert (
|
||||
hexlify(signatures1[0])
|
||||
== b"3045022100985cc1ba316d140eb4b2d4028d8cd1c451f87bff8ff679858732e516ad04cd3402207af6edda99972af0baa7702a3b7448517c8242e7bca669f6861771cdd16ee058"
|
||||
)
|
||||
|
||||
# ---------------------------------------
|
||||
# Let's do second signature using 3rd key
|
||||
@ -113,9 +155,13 @@ class TestMultisig(TrezorTest):
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3])
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[signatures1[0], b'', b''], # Fill signature from previous signing process
|
||||
signatures=[
|
||||
signatures1[0],
|
||||
b"",
|
||||
b"",
|
||||
], # Fill signature from previous signing process
|
||||
m=2,
|
||||
)
|
||||
|
||||
@ -129,26 +175,69 @@ class TestMultisig(TrezorTest):
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_c6091a)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_c6091a
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_c6091a
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=1, tx_hash=TXHASH_c6091a
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures2, serialized_tx) = btc.sign_tx(self.client, 'Bitcoin', [inp3, ], [out1, ])
|
||||
]
|
||||
)
|
||||
(signatures2, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bitcoin", [inp3], [out1]
|
||||
)
|
||||
|
||||
assert hexlify(signatures2[0]) == b'3045022100f5428fe0531b3095675b40d87cab607ee036fac823b22e8dcec35b65aff6e52b022032129b4577ff923d321a1c70db5a6cec5bcc142cb2c51901af8b989cced23e0d'
|
||||
assert (
|
||||
hexlify(signatures2[0])
|
||||
== b"3045022100f5428fe0531b3095675b40d87cab607ee036fac823b22e8dcec35b65aff6e52b022032129b4577ff923d321a1c70db5a6cec5bcc142cb2c51901af8b989cced23e0d"
|
||||
)
|
||||
|
||||
# Accepted by network: tx 8382a2b2e3ec8788800c1d46d285dfa9dd4051edddd75982fad166b9273e5ac6
|
||||
assert hexlify(serialized_tx) == b'010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fdfe0000483045022100985cc1ba316d140eb4b2d4028d8cd1c451f87bff8ff679858732e516ad04cd3402207af6edda99972af0baa7702a3b7448517c8242e7bca669f6861771cdd16ee05801483045022100f5428fe0531b3095675b40d87cab607ee036fac823b22e8dcec35b65aff6e52b022032129b4577ff923d321a1c70db5a6cec5bcc142cb2c51901af8b989cced23e0d014c6952210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a621038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e32103477b9f0f34ae85434ce795f0c5e1e90c9420e5b5fad084d7cce9a487b94a790253aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fdfe0000483045022100985cc1ba316d140eb4b2d4028d8cd1c451f87bff8ff679858732e516ad04cd3402207af6edda99972af0baa7702a3b7448517c8242e7bca669f6861771cdd16ee05801483045022100f5428fe0531b3095675b40d87cab607ee036fac823b22e8dcec35b65aff6e52b022032129b4577ff923d321a1c70db5a6cec5bcc142cb2c51901af8b989cced23e0d014c6952210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a621038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e32103477b9f0f34ae85434ce795f0c5e1e90c9420e5b5fad084d7cce9a487b94a790253aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000"
|
||||
)
|
||||
|
||||
def test_15_of_15(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -162,7 +251,9 @@ class TestMultisig(TrezorTest):
|
||||
# xpub:
|
||||
# print(bip32.serialize(self.client.get_public_node([]).node))
|
||||
# xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy
|
||||
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
|
||||
node = bip32.deserialize(
|
||||
"xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy"
|
||||
)
|
||||
|
||||
pubs = []
|
||||
for x in range(15):
|
||||
@ -174,35 +265,40 @@ class TestMultisig(TrezorTest):
|
||||
# multisig address
|
||||
# 3QaKF8zobqcqY8aS6nxCD5ZYdiRfL3RCmU
|
||||
|
||||
signatures = [b''] * 15
|
||||
signatures = [b""] * 15
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1',
|
||||
address="17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1",
|
||||
amount=10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
for x in range(15):
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=pubs,
|
||||
signatures=signatures,
|
||||
m=15,
|
||||
pubkeys=pubs, signatures=signatures, m=15
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=[x],
|
||||
prev_hash=unhexlify('6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315'),
|
||||
prev_hash=unhexlify(
|
||||
"6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
(sig, serialized_tx) = btc.sign_tx(self.client, 'Bitcoin', [inp1, ], [out1, ])
|
||||
(sig, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bitcoin", [inp1], [out1]
|
||||
)
|
||||
signatures[x] = sig[0]
|
||||
|
||||
# Accepted as tx id dd320786d1f58c095be0509dc56b277b6de8f2fb5517f519c6e6708414e3300b
|
||||
assert hexlify(serialized_tx) == b'01000000011553ef34c683f4d6a8d346844409e6e7fc4ff01eaa25b7e8ce215abbfee3896101000000fd43060048304502210098e23085ad7282de988bf98afa1e9add9c9830009132f8902a9fa4624d5dc98b0220733216e70ab67791aa64be5c83d2050cb4ed9ff7eda2a1acc35da024d2ab2a670147304402201f8c11fb6e90fd616e484986e9451929797eba039882a9abcc203210948060b9022044da031530de7d9747d3c5a8e7cec04b04b7af495c9120b854ce7362af7fa05a01483045022100ea67c70186acef019bdf1551881bf38e6f88186501b64d3a756a2ce18e4ba18002201c35110325653e21e448b60053a4b5dda46b61096faf701a1faca61fcde91f00014730440220315598992f156d2f9d7b4275395fa067aa61ea95829fa17730885c86df4de70d02203eda9ade1656e2198c668603b17e197acb0969ed183ab0841303ea261205618901473044022060fdd6621edde9b8cf6776bc4eef26ace9b57514d725b7214ba11d333520a30e022044c30744f94484aec0f896233c5613a3256878ec0379f566226906b6d1b6061401483045022100b1d907e3574f60f7834c7e9f2e367998ce0461dad7d742d84ef8917d713f41f902203b3ac54f7bb2f7fb8685f582d2a94f7213a37cb508acffe29090cc06ae01588b01483045022100e3bf90ff3ad6395e42f46002f253f94ca0e8ffaa0620f2ceb4fa21493abdca4d02201d4c28b10b740bb2dc4b3695b4205c18f8c0dad2bb69540eb8a36576463cd5280147304402202cfaf9fab7dc1c9f0c3c23bd46bd6d5cea0664d914139fc9add80766ce998808022012db2802c07853e4cbe147afdf0b47e60bdcbcd31f9df19e04c177ed9aa66c6d0147304402207cbc2d83f351eee5ee91df26bb0c7e1cb07fe328cbbcdb0bb9656d37922c497302201b3435d4c71ffd1b34d45892f2a487bd79c8c7f57cc04373287642bb9610cb840147304402202dc3eab30ccb06553703e794212f43ee9a659f5e787a8374e9ea0bf6de0def7402201a70e970c21a807783313ed102bf4f0a3406ac7c84f94bc8194c5e209464d7230147304402206b04530c190c46a879d7771a6ad53acd33547e0d7fd320d5ad0b5b1fdeb5d4c202207b812be81c3419daadc942cca0c55aa32c7759fa7566c6dc35f030ca87a1c5be01483045022100ce523dddd6eef73d5ae7c44c870466e1ac5a7a77d43475e8def024af68977a1e022028be0276435bfa2ea887d6cf89fa829f96c1c7a55edc57bb3fd667d523fd3bf601473044022019410b20ebcd8eb3ee7ec1eff6bf0f9cbfaea82116811c61f3cf24af7e4434b1022009e5823f3349f695be09ae40754185300d8442a22715ddb5ffa17c4213140e7201483045022100964ef26a9074c3cdafffcfbe4bd445933f8c842ba11fd887922adcf7fabe0c82022023055d94c75ab223c767fbaa825c917e9beecbc7d5758cccf20d886c63d4b72a0147304402207aa3a98197697d258a8baae681f0b4c0ee682982f4205534e6c95a37dabaddd60220517a7ed5c03da2f242e17ccfdae0d81d6f454d7f9ea931fc62df6c0eab922186014d01025f21023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43d210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a621038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e32103477b9f0f34ae85434ce795f0c5e1e90c9420e5b5fad084d7cce9a487b94a79022103fe91eca10602d7dad4c9dab2b2a0858f71e25a219a6940749ce7a48118480dae210234716c01c2dd03fa7ee302705e2b8fbd1311895d94b1dca15e62eedea9b0968f210341fb2ead334952cf60f4481ba435c4693d0be649be01d2cfe9b02018e483e7bd2102dad8b2bce360a705c16e74a50a36459b4f8f4b78f9cd67def29d54ef6f7c7cf9210222dbe3f5f197a34a1d50e2cbe2a1085cac2d605c9e176f9a240e0fd0c669330d2103fb41afab56c9cdb013fda63d777d4938ddc3cb2ad939712da688e3ed333f95982102435f177646bdc717cb3211bf46656ca7e8d642726144778c9ce816b8b8c36ccf2102158d8e20095364031d923c7e9f7f08a14b1be1ddee21fe1a5431168e31345e5521026259794892428ca0818c8fb61d2d459ddfe20e57f50803c7295e6f4e2f5586652102815f910a8689151db627e6e262e0a2075ad5ec2993a6bc1b876a9d420923d681210318f54647f645ff01bd49fedc0219343a6a22d3ea3180a3c3d3097e4b888a8db45faeffffffff0110270000000000001976a9144a087d89f8ad16ca029c675b037c02fd1c5f9aec88ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"01000000011553ef34c683f4d6a8d346844409e6e7fc4ff01eaa25b7e8ce215abbfee3896101000000fd43060048304502210098e23085ad7282de988bf98afa1e9add9c9830009132f8902a9fa4624d5dc98b0220733216e70ab67791aa64be5c83d2050cb4ed9ff7eda2a1acc35da024d2ab2a670147304402201f8c11fb6e90fd616e484986e9451929797eba039882a9abcc203210948060b9022044da031530de7d9747d3c5a8e7cec04b04b7af495c9120b854ce7362af7fa05a01483045022100ea67c70186acef019bdf1551881bf38e6f88186501b64d3a756a2ce18e4ba18002201c35110325653e21e448b60053a4b5dda46b61096faf701a1faca61fcde91f00014730440220315598992f156d2f9d7b4275395fa067aa61ea95829fa17730885c86df4de70d02203eda9ade1656e2198c668603b17e197acb0969ed183ab0841303ea261205618901473044022060fdd6621edde9b8cf6776bc4eef26ace9b57514d725b7214ba11d333520a30e022044c30744f94484aec0f896233c5613a3256878ec0379f566226906b6d1b6061401483045022100b1d907e3574f60f7834c7e9f2e367998ce0461dad7d742d84ef8917d713f41f902203b3ac54f7bb2f7fb8685f582d2a94f7213a37cb508acffe29090cc06ae01588b01483045022100e3bf90ff3ad6395e42f46002f253f94ca0e8ffaa0620f2ceb4fa21493abdca4d02201d4c28b10b740bb2dc4b3695b4205c18f8c0dad2bb69540eb8a36576463cd5280147304402202cfaf9fab7dc1c9f0c3c23bd46bd6d5cea0664d914139fc9add80766ce998808022012db2802c07853e4cbe147afdf0b47e60bdcbcd31f9df19e04c177ed9aa66c6d0147304402207cbc2d83f351eee5ee91df26bb0c7e1cb07fe328cbbcdb0bb9656d37922c497302201b3435d4c71ffd1b34d45892f2a487bd79c8c7f57cc04373287642bb9610cb840147304402202dc3eab30ccb06553703e794212f43ee9a659f5e787a8374e9ea0bf6de0def7402201a70e970c21a807783313ed102bf4f0a3406ac7c84f94bc8194c5e209464d7230147304402206b04530c190c46a879d7771a6ad53acd33547e0d7fd320d5ad0b5b1fdeb5d4c202207b812be81c3419daadc942cca0c55aa32c7759fa7566c6dc35f030ca87a1c5be01483045022100ce523dddd6eef73d5ae7c44c870466e1ac5a7a77d43475e8def024af68977a1e022028be0276435bfa2ea887d6cf89fa829f96c1c7a55edc57bb3fd667d523fd3bf601473044022019410b20ebcd8eb3ee7ec1eff6bf0f9cbfaea82116811c61f3cf24af7e4434b1022009e5823f3349f695be09ae40754185300d8442a22715ddb5ffa17c4213140e7201483045022100964ef26a9074c3cdafffcfbe4bd445933f8c842ba11fd887922adcf7fabe0c82022023055d94c75ab223c767fbaa825c917e9beecbc7d5758cccf20d886c63d4b72a0147304402207aa3a98197697d258a8baae681f0b4c0ee682982f4205534e6c95a37dabaddd60220517a7ed5c03da2f242e17ccfdae0d81d6f454d7f9ea931fc62df6c0eab922186014d01025f21023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43d210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a621038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e32103477b9f0f34ae85434ce795f0c5e1e90c9420e5b5fad084d7cce9a487b94a79022103fe91eca10602d7dad4c9dab2b2a0858f71e25a219a6940749ce7a48118480dae210234716c01c2dd03fa7ee302705e2b8fbd1311895d94b1dca15e62eedea9b0968f210341fb2ead334952cf60f4481ba435c4693d0be649be01d2cfe9b02018e483e7bd2102dad8b2bce360a705c16e74a50a36459b4f8f4b78f9cd67def29d54ef6f7c7cf9210222dbe3f5f197a34a1d50e2cbe2a1085cac2d605c9e176f9a240e0fd0c669330d2103fb41afab56c9cdb013fda63d777d4938ddc3cb2ad939712da688e3ed333f95982102435f177646bdc717cb3211bf46656ca7e8d642726144778c9ce816b8b8c36ccf2102158d8e20095364031d923c7e9f7f08a14b1be1ddee21fe1a5431168e31345e5521026259794892428ca0818c8fb61d2d459ddfe20e57f50803c7295e6f4e2f5586652102815f910a8689151db627e6e262e0a2075ad5ec2993a6bc1b876a9d420923d681210318f54647f645ff01bd49fedc0219343a6a22d3ea3180a3c3d3097e4b888a8db45faeffffffff0110270000000000001976a9144a087d89f8ad16ca029c675b037c02fd1c5f9aec88ac00000000"
|
||||
)
|
||||
|
||||
def test_missing_pubkey(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -221,15 +317,17 @@ class TestMultisig(TrezorTest):
|
||||
# xpub:
|
||||
# print(bip32.serialize(self.client.get_public_node([]).node))
|
||||
# xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy
|
||||
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
|
||||
node = bip32.deserialize(
|
||||
"xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy"
|
||||
)
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3])
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
@ -243,13 +341,13 @@ class TestMultisig(TrezorTest):
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss',
|
||||
address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss",
|
||||
amount=100000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with pytest.raises(CallException) as exc:
|
||||
btc.sign_tx(self.client, 'Bitcoin', [inp1, ], [out1, ])
|
||||
btc.sign_tx(self.client, "Bitcoin", [inp1], [out1])
|
||||
|
||||
assert exc.value.args[0] == proto.FailureType.DataError
|
||||
assert exc.value.args[1].endswith('Pubkey not found in multisig script')
|
||||
assert exc.value.args[1].endswith("Pubkey not found in multisig script")
|
||||
|
@ -16,35 +16,42 @@
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support import ckd_public as bip32
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.tools import parse_path, H_
|
||||
from trezorlib import btc, messages as proto
|
||||
from trezorlib.tools import H_, parse_path
|
||||
from trezorlib.tx_api import TxApiInsight
|
||||
from trezorlib import btc
|
||||
|
||||
from ..support import ckd_public as bip32
|
||||
from .common import TrezorTest
|
||||
|
||||
TxApiTestnet = TxApiInsight("insight_testnet")
|
||||
|
||||
|
||||
class TestMultisigChange(TrezorTest):
|
||||
|
||||
def setup_method(self, method):
|
||||
super(TestMultisigChange, self).setup_method(method)
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
|
||||
node_ext1 = bip32.deserialize('tpubDADHV9u9Y6gkggintTdMjJE3be58zKNLhpxBQyuEM6Pwx3sN9JVLmMCMN4DNVwL9AKec27z5TaWcWuHzMXiGAtcra5DjwWbvppGX4gaEGVN')
|
||||
node_ext1 = bip32.deserialize(
|
||||
"tpubDADHV9u9Y6gkggintTdMjJE3be58zKNLhpxBQyuEM6Pwx3sN9JVLmMCMN4DNVwL9AKec27z5TaWcWuHzMXiGAtcra5DjwWbvppGX4gaEGVN"
|
||||
)
|
||||
# m/1 => 02c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e
|
||||
# m/2 => 0375b9dfaad928ce1a7eed88df7c084e67d99e9ab74332419458a9a45779706801
|
||||
|
||||
node_ext2 = bip32.deserialize('tpubDADHV9u9Y6gkhWXBmDJ6TUhZajLWjvKukRe2w9FfhdbQpUux8Z8jnPHNAZqFRgHPg9sR7YR93xThM32M7NfRu8S5WyDtext7S62sqxeJNkd')
|
||||
node_ext2 = bip32.deserialize(
|
||||
"tpubDADHV9u9Y6gkhWXBmDJ6TUhZajLWjvKukRe2w9FfhdbQpUux8Z8jnPHNAZqFRgHPg9sR7YR93xThM32M7NfRu8S5WyDtext7S62sqxeJNkd"
|
||||
)
|
||||
# m/1 => 0388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1
|
||||
# m/2 => 03a04f945d5a3685729dde697d574076de4bdf38e904f813b22a851548e1110fc0
|
||||
|
||||
node_ext3 = bip32.deserialize('tpubDADHV9u9Y6gkmM5ohWRGTswrc6fr7soH7e2D2ic5a86PDUaHc5Ln9EbER69cEr5bDZPa7EXguJ1MhWVzPZpZWVdG5fvoF3hfirXvRbpCCBg')
|
||||
node_ext3 = bip32.deserialize(
|
||||
"tpubDADHV9u9Y6gkmM5ohWRGTswrc6fr7soH7e2D2ic5a86PDUaHc5Ln9EbER69cEr5bDZPa7EXguJ1MhWVzPZpZWVdG5fvoF3hfirXvRbpCCBg"
|
||||
)
|
||||
# m/1 => 02e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648
|
||||
# m/2 => 03928301ffb8c0d7a364b794914c716ba3107cc78a6fe581028b0d8638b22e8573
|
||||
|
||||
node_int = bip32.deserialize('tpubDADHV9u9Y6gke2Vw3rWE8KRXmeK8PTtsF5B3Cqjo6h3SoiyRtzxjnDVG1knxrqB8BpP1dMAd6MR3Ps5UXibiFDtQuWVPXLkJ3HvttZYbH12')
|
||||
node_int = bip32.deserialize(
|
||||
"tpubDADHV9u9Y6gke2Vw3rWE8KRXmeK8PTtsF5B3Cqjo6h3SoiyRtzxjnDVG1knxrqB8BpP1dMAd6MR3Ps5UXibiFDtQuWVPXLkJ3HvttZYbH12"
|
||||
)
|
||||
# m/1 => 03f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff35
|
||||
# m/2 => 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3
|
||||
|
||||
@ -70,9 +77,9 @@ class TestMultisigChange(TrezorTest):
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node_ext2, address_n=[0, 0]),
|
||||
proto.HDNodePathType(node=node_ext1, address_n=[0, 0]),
|
||||
proto.HDNodePathType(node=node_int, address_n=[0, 0])
|
||||
proto.HDNodePathType(node=node_int, address_n=[0, 0]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
@ -82,7 +89,7 @@ class TestMultisigChange(TrezorTest):
|
||||
proto.HDNodePathType(node=node_ext2, address_n=[0, 1]),
|
||||
proto.HDNodePathType(node=node_int, address_n=[0, 1]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
@ -90,16 +97,18 @@ class TestMultisigChange(TrezorTest):
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node_ext1, address_n=[0, 1]),
|
||||
proto.HDNodePathType(node=node_ext3, address_n=[0, 1]),
|
||||
proto.HDNodePathType(node=node_int, address_n=[0, 1])
|
||||
proto.HDNodePathType(node=node_int, address_n=[0, 1]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
# 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 0],
|
||||
prev_hash=unhexlify('16c6c8471b8db7a628f2b2bb86bfeefae1766463ce8692438c7fd3fce3f43ce5'),
|
||||
prev_hash=unhexlify(
|
||||
"16c6c8471b8db7a628f2b2bb86bfeefae1766463ce8692438c7fd3fce3f43ce5"
|
||||
),
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in1,
|
||||
@ -108,7 +117,9 @@ class TestMultisigChange(TrezorTest):
|
||||
# 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 1],
|
||||
prev_hash=unhexlify('d80c34ee14143a8bf61125102b7ef594118a3796cad670fa8ee15080ae155318'),
|
||||
prev_hash=unhexlify(
|
||||
"d80c34ee14143a8bf61125102b7ef594118a3796cad670fa8ee15080ae155318"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in2,
|
||||
@ -117,7 +128,9 @@ class TestMultisigChange(TrezorTest):
|
||||
# 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4
|
||||
inp3 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 1],
|
||||
prev_hash=unhexlify('b0946dc27ba308a749b11afecc2018980af18f79e89ad6b080b58220d856f739'),
|
||||
prev_hash=unhexlify(
|
||||
"b0946dc27ba308a749b11afecc2018980af18f79e89ad6b080b58220d856f739"
|
||||
),
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in3,
|
||||
@ -125,41 +138,115 @@ class TestMultisigChange(TrezorTest):
|
||||
|
||||
def _responses(self, inp1, inp2, change=0):
|
||||
resp = [
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=inp1.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp1.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp1.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=inp1.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=inp2.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp2.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp2.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=inp2.prev_hash)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=inp1.prev_hash),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=inp1.prev_hash
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=inp1.prev_hash
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=1, tx_hash=inp1.prev_hash
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=inp2.prev_hash),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=inp2.prev_hash
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=inp2.prev_hash
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=1, tx_hash=inp2.prev_hash
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
]
|
||||
if change != 1:
|
||||
resp.append(proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput))
|
||||
resp.append(
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput)
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
)
|
||||
resp.append(
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1))
|
||||
)
|
||||
if change != 2:
|
||||
resp.append(
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput)
|
||||
)
|
||||
resp.append(proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput))
|
||||
resp += [
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
]
|
||||
return resp
|
||||
@ -169,44 +256,56 @@ class TestMultisigChange(TrezorTest):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='muevUcG1Bb8eM2nGUGhqmeujHRX7YXjSEu',
|
||||
address="muevUcG1Bb8eM2nGUGhqmeujHRX7YXjSEu",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address='mwdrpMVSJxxsM8f8xbnCHn9ERaRT1NG1UX',
|
||||
address="mwdrpMVSJxxsM8f8xbnCHn9ERaRT1NG1UX",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp2))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp2, ], [out1, out2, ])
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
# first external, second internal
|
||||
def test_external_internal(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='muevUcG1Bb8eM2nGUGhqmeujHRX7YXjSEu',
|
||||
address="muevUcG1Bb8eM2nGUGhqmeujHRX7YXjSEu",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("45'/0/1/1"),
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=2))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp2, ], [out1, out2, ])
|
||||
self.client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=2)
|
||||
)
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
# first internal, second external
|
||||
def test_internal_external(self):
|
||||
@ -215,42 +314,54 @@ class TestMultisigChange(TrezorTest):
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("45'/0/1/0"),
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address='mwdrpMVSJxxsM8f8xbnCHn9ERaRT1NG1UX',
|
||||
address="mwdrpMVSJxxsM8f8xbnCHn9ERaRT1NG1UX",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=1))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp2, ], [out1, out2, ])
|
||||
self.client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=1)
|
||||
)
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
# both outputs are external
|
||||
def test_multisig_external_external(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR',
|
||||
address="2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address='2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw',
|
||||
address="2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp2))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp2, ], [out1, out2, ])
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
# inputs match, change matches (first is change)
|
||||
def test_multisig_change_match_first(self):
|
||||
@ -260,9 +371,9 @@ class TestMultisigChange(TrezorTest):
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=self.node_ext2, address_n=[1, 0]),
|
||||
proto.HDNodePathType(node=self.node_ext1, address_n=[1, 0]),
|
||||
proto.HDNodePathType(node=self.node_int, address_n=[1, 0])
|
||||
proto.HDNodePathType(node=self.node_int, address_n=[1, 0]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
@ -270,20 +381,27 @@ class TestMultisigChange(TrezorTest):
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out1,
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address='2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw',
|
||||
address="2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=1))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp2, ], [out1, out2, ])
|
||||
self.client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=1)
|
||||
)
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
# inputs match, change matches (second is change)
|
||||
def test_multisig_change_match_second(self):
|
||||
@ -293,30 +411,37 @@ class TestMultisigChange(TrezorTest):
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=self.node_ext1, address_n=[1, 1]),
|
||||
proto.HDNodePathType(node=self.node_ext2, address_n=[1, 1]),
|
||||
proto.HDNodePathType(node=self.node_int, address_n=[1, 1])
|
||||
proto.HDNodePathType(node=self.node_int, address_n=[1, 1]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR',
|
||||
address="2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 1],
|
||||
multisig=multisig_out2,
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=2))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp2, ], [out1, out2, ])
|
||||
self.client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=2)
|
||||
)
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
# inputs match, change mismatches (second tries to be change but isn't)
|
||||
def test_multisig_mismatch_change(self):
|
||||
@ -326,30 +451,35 @@ class TestMultisigChange(TrezorTest):
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=self.node_ext1, address_n=[1, 0]),
|
||||
proto.HDNodePathType(node=self.node_int, address_n=[1, 0]),
|
||||
proto.HDNodePathType(node=self.node_ext3, address_n=[1, 0])
|
||||
proto.HDNodePathType(node=self.node_ext3, address_n=[1, 0]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR',
|
||||
address="2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out2,
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp2))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp2, ], [out1, out2, ])
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b40047304402207f9992cc0230527faf54ec6bd233307db82bc8fac039dcee418bc6feb4e96a3a02206bb4cb157ad27c123277328a877572563a45d70b844d9ab07cc42238112f8c2a014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b400473044022078a41bfa87d72d6ba810d84bf568b5a29acf8b851ba6c3a8dbff079b34a7feb0022037b770c776db0b6c883c38a684a121b90a59ed1958774cbf64de70e53e29639f014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914e6a3e2fbadb7f559f8d20c46aceae78c96fcf1d18700000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b40047304402207f9992cc0230527faf54ec6bd233307db82bc8fac039dcee418bc6feb4e96a3a02206bb4cb157ad27c123277328a877572563a45d70b844d9ab07cc42238112f8c2a014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b400473044022078a41bfa87d72d6ba810d84bf568b5a29acf8b851ba6c3a8dbff079b34a7feb0022037b770c776db0b6c883c38a684a121b90a59ed1958774cbf64de70e53e29639f014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914e6a3e2fbadb7f559f8d20c46aceae78c96fcf1d18700000000"
|
||||
)
|
||||
|
||||
# inputs mismatch, change matches with first input
|
||||
def test_multisig_mismatch_inputs(self):
|
||||
@ -359,9 +489,9 @@ class TestMultisigChange(TrezorTest):
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=self.node_ext2, address_n=[1, 0]),
|
||||
proto.HDNodePathType(node=self.node_ext1, address_n=[1, 0]),
|
||||
proto.HDNodePathType(node=self.node_int, address_n=[1, 0])
|
||||
proto.HDNodePathType(node=self.node_int, address_n=[1, 0]),
|
||||
],
|
||||
signatures=[b'', b'', b''],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
@ -369,17 +499,22 @@ class TestMultisigChange(TrezorTest):
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out1,
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address='2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw',
|
||||
address="2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw",
|
||||
amount=65000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses(self._responses(self.inp1, self.inp3))
|
||||
(_, serialized_tx) = btc.sign_tx(self.client, 'Testnet', [self.inp1, self.inp3, ], [out1, out2, ])
|
||||
(_, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Testnet", [self.inp1, self.inp3], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b500483045022100d907b9339951c96ef4515ef7aff8b3c28c4c8c5875d7421aa1de9f3a94e3508302205cdc311a6c91dfbb74f1a9a940a994a65dbfb0cf6dedcaaaeee839e0b8fd016d014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff39f756d82082b580b0d69ae8798ff10a981820ccfe1ab149a708a37bc26d94b000000000b500483045022100fdad4a47d15f47cc364fe0cbed11b1ced1f9ef210bc1bd413ec4384f630c63720220752e4f09ea4e5e6623f5ebe89b3983ec6e5702f63f9bce696f10b2d594d23532014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103b6321a1194e5cc47b6b7edc3f67a096e6f71ccb72440f84f390b6e98df0ea8ec2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948740d2df030000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b500483045022100d907b9339951c96ef4515ef7aff8b3c28c4c8c5875d7421aa1de9f3a94e3508302205cdc311a6c91dfbb74f1a9a940a994a65dbfb0cf6dedcaaaeee839e0b8fd016d014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff39f756d82082b580b0d69ae8798ff10a981820ccfe1ab149a708a37bc26d94b000000000b500483045022100fdad4a47d15f47cc364fe0cbed11b1ced1f9ef210bc1bd413ec4384f630c63720220752e4f09ea4e5e6623f5ebe89b3983ec6e5702f63f9bce696f10b2d594d23532014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103b6321a1194e5cc47b6b7edc3f67a096e6f71ccb72440f84f390b6e98df0ea8ec2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948740d2df030000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
@ -14,20 +14,22 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify, hexlify
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc, messages as proto
|
||||
from trezorlib.tools import CallException
|
||||
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.tools import CallException
|
||||
from trezorlib import btc
|
||||
|
||||
TXHASH_d5f65e = unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')
|
||||
TXHASH_d5f65e = unhexlify(
|
||||
"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
|
||||
)
|
||||
|
||||
|
||||
class TestOpReturn(TrezorTest):
|
||||
|
||||
def test_opreturn(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
@ -42,39 +44,88 @@ class TestOpReturn(TrezorTest):
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
|
||||
address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
op_return_data=b'test of the op_return data',
|
||||
op_return_data=b"test of the op_return data",
|
||||
amount=0,
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=1, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=1),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bitcoin', [inp1, ], [out1, out2])
|
||||
]
|
||||
)
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bitcoin", [inp1], [out1, out2]
|
||||
)
|
||||
|
||||
assert hexlify(serialized_tx) == b'010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006a4730440220187b7b9c340a32fc8445418ad11fb3827d2e8bac7d730e1c9ad800353e7ba62f02206c0c5820ba8882c82923a39aee8d36d6d32e13daed73f7a3d6199de5f8e7ddfd0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0260cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000000000001c6a1a74657374206f6620746865206f705f72657475726e206461746100000000'
|
||||
assert (
|
||||
hexlify(serialized_tx)
|
||||
== b"010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006a4730440220187b7b9c340a32fc8445418ad11fb3827d2e8bac7d730e1c9ad800353e7ba62f02206c0c5820ba8882c82923a39aee8d36d6d32e13daed73f7a3d6199de5f8e7ddfd0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0260cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000000000001c6a1a74657374206f6620746865206f705f72657475726e206461746100000000"
|
||||
)
|
||||
|
||||
def test_nonzero_opreturn(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -90,28 +141,56 @@ class TestOpReturn(TrezorTest):
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
op_return_data=b'test of the op_return data',
|
||||
op_return_data=b"test of the op_return data",
|
||||
amount=10000,
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.Failure()
|
||||
])
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=1, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.Failure(),
|
||||
]
|
||||
)
|
||||
|
||||
with pytest.raises(CallException) as exc:
|
||||
btc.sign_tx(self.client, 'Bitcoin', [inp1], [out1])
|
||||
btc.sign_tx(self.client, "Bitcoin", [inp1], [out1])
|
||||
|
||||
if TREZOR_VERSION == 1:
|
||||
assert exc.value.args[0] == proto.FailureType.ProcessError
|
||||
assert exc.value.args[1].endswith("Failed to compile output")
|
||||
else:
|
||||
assert exc.value.args[0] == proto.FailureType.DataError
|
||||
assert exc.value.args[1].endswith('OP_RETURN output with non-zero amount')
|
||||
assert exc.value.args[1].endswith(
|
||||
"OP_RETURN output with non-zero amount"
|
||||
)
|
||||
|
@ -15,28 +15,28 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.client import PinException
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
# FIXME TODO Add passphrase tests
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestProtectCall(TrezorTest):
|
||||
|
||||
def _some_protected_call(self, button, pin, passphrase):
|
||||
# This method perform any call which have protection in the device
|
||||
res = self.client.ping(
|
||||
'random data',
|
||||
"random data",
|
||||
button_protection=button,
|
||||
pin_protection=pin,
|
||||
passphrase_protection=passphrase
|
||||
passphrase_protection=passphrase,
|
||||
)
|
||||
assert res == 'random data'
|
||||
assert res == "random data"
|
||||
|
||||
"""
|
||||
def test_expected_responses(self):
|
||||
@ -99,9 +99,9 @@ class TestProtectCall(TrezorTest):
|
||||
with self.client:
|
||||
assert self.client.debug.read_pin()[0] == self.pin4
|
||||
self.client.setup_debuglink(button=True, pin_correct=True)
|
||||
self.client.set_expected_responses([proto.ButtonRequest(),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.Success()])
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest(), proto.PinMatrixRequest(), proto.Success()]
|
||||
)
|
||||
self._some_protected_call(True, True, False)
|
||||
|
||||
def test_incorrect_pin(self):
|
||||
@ -128,7 +128,10 @@ class TestProtectCall(TrezorTest):
|
||||
expected = (2 ** (attempts - 1)) - 1
|
||||
got = round(time.time() - start, 2)
|
||||
|
||||
msg = "Pin delay expected to be at least %s seconds, got %s" % (expected, got)
|
||||
msg = "Pin delay expected to be at least %s seconds, got %s" % (
|
||||
expected,
|
||||
got,
|
||||
)
|
||||
print(msg)
|
||||
assert got >= expected
|
||||
|
||||
|
@ -15,22 +15,20 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import btc, debuglink, device, messages as proto, misc
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc
|
||||
from trezorlib import debuglink
|
||||
from trezorlib import device
|
||||
from trezorlib import misc
|
||||
|
||||
|
||||
TXHASH_d5f65e = unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')
|
||||
TXHASH_d5f65e = unhexlify(
|
||||
"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestProtectionLevels(TrezorTest):
|
||||
|
||||
def test_initialize(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
@ -40,131 +38,156 @@ class TestProtectionLevels(TrezorTest):
|
||||
def test_apply_settings(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()
|
||||
]) # TrezorClient reinitializes device
|
||||
device.apply_settings(self.client, label='nazdar')
|
||||
proto.Features(),
|
||||
]
|
||||
) # TrezorClient reinitializes device
|
||||
device.apply_settings(self.client, label="nazdar")
|
||||
|
||||
def test_change_pin(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()
|
||||
])
|
||||
proto.Features(),
|
||||
]
|
||||
)
|
||||
device.change_pin(self.client)
|
||||
|
||||
def test_ping(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.Success()
|
||||
])
|
||||
self.client.ping('msg', True, True, True)
|
||||
proto.Success(),
|
||||
]
|
||||
)
|
||||
self.client.ping("msg", True, True, True)
|
||||
|
||||
def test_get_entropy(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
proto.ButtonRequest(),
|
||||
proto.Entropy()
|
||||
])
|
||||
self.client.set_expected_responses([proto.ButtonRequest(), proto.Entropy()])
|
||||
misc.get_entropy(self.client, 10)
|
||||
|
||||
def test_get_public_key(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.PublicKey()
|
||||
])
|
||||
self.client.set_expected_responses(
|
||||
[proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.PublicKey()]
|
||||
)
|
||||
btc.get_public_node(self.client, [])
|
||||
|
||||
def test_get_address(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.Address()
|
||||
])
|
||||
btc.get_address(self.client, 'Bitcoin', [])
|
||||
self.client.set_expected_responses(
|
||||
[proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Address()]
|
||||
)
|
||||
btc.get_address(self.client, "Bitcoin", [])
|
||||
|
||||
def test_wipe_device(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()
|
||||
])
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest(), proto.Success(), proto.Features()]
|
||||
)
|
||||
device.wipe(self.client)
|
||||
|
||||
def test_load_device(self):
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.ButtonRequest(),
|
||||
proto.Success(),
|
||||
proto.Features()])
|
||||
debuglink.load_device_by_mnemonic(self.client, 'this is mnemonic', '1234', True, 'label', 'english', skip_checksum=True)
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest(), proto.Success(), proto.Features()]
|
||||
)
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
"this is mnemonic",
|
||||
"1234",
|
||||
True,
|
||||
"label",
|
||||
"english",
|
||||
skip_checksum=True,
|
||||
)
|
||||
|
||||
# This must fail, because device is already initialized
|
||||
with pytest.raises(Exception):
|
||||
debuglink.load_device_by_mnemonic(self.client, 'this is mnemonic', '1234', True, 'label', 'english', skip_checksum=True)
|
||||
debuglink.load_device_by_mnemonic(
|
||||
self.client,
|
||||
"this is mnemonic",
|
||||
"1234",
|
||||
True,
|
||||
"label",
|
||||
"english",
|
||||
skip_checksum=True,
|
||||
)
|
||||
|
||||
def test_reset_device(self):
|
||||
with self.client:
|
||||
self.client.set_expected_responses([proto.EntropyRequest()] + [proto.ButtonRequest()] * 24 + [proto.Success(), proto.Features()])
|
||||
device.reset(self.client, False, 128, True, False, 'label', 'english')
|
||||
self.client.set_expected_responses(
|
||||
[proto.EntropyRequest()]
|
||||
+ [proto.ButtonRequest()] * 24
|
||||
+ [proto.Success(), proto.Features()]
|
||||
)
|
||||
device.reset(self.client, False, 128, True, False, "label", "english")
|
||||
|
||||
# This must fail, because device is already initialized
|
||||
with pytest.raises(Exception):
|
||||
device.reset(self.client, False, 128, True, False, 'label', 'english')
|
||||
device.reset(self.client, False, 128, True, False, "label", "english")
|
||||
|
||||
def test_recovery_device(self):
|
||||
with self.client:
|
||||
self.client.set_mnemonic(self.mnemonic12)
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest()] +
|
||||
[proto.WordRequest()] * 24 +
|
||||
[proto.Success(), proto.Features()])
|
||||
device.recover(self.client, 12, False, False, 'label', 'english')
|
||||
[proto.ButtonRequest()]
|
||||
+ [proto.WordRequest()] * 24
|
||||
+ [proto.Success(), proto.Features()]
|
||||
)
|
||||
device.recover(self.client, 12, False, False, "label", "english")
|
||||
|
||||
# This must fail, because device is already initialized
|
||||
with pytest.raises(Exception):
|
||||
device.recover(self.client, 12, False, False, 'label', 'english')
|
||||
device.recover(self.client, 12, False, False, "label", "english")
|
||||
|
||||
def test_sign_message(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(),
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.MessageSignature()
|
||||
])
|
||||
btc.sign_message(self.client, 'Bitcoin', [], 'testing message')
|
||||
proto.MessageSignature(),
|
||||
]
|
||||
)
|
||||
btc.sign_message(self.client, "Bitcoin", [], "testing message")
|
||||
|
||||
def test_verify_message(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([proto.ButtonRequest(), proto.ButtonRequest(), proto.Success()])
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest(), proto.ButtonRequest(), proto.Success()]
|
||||
)
|
||||
btc.verify_message(
|
||||
self.client,
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
unhexlify('209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80'),
|
||||
'This is an example of a signed message.')
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
unhexlify(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
|
||||
def test_signtx(self):
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
@ -176,30 +199,65 @@ class TestProtectionLevels(TrezorTest):
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
|
||||
address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with self.client:
|
||||
|
||||
self.client.set_expected_responses([
|
||||
self.client.set_expected_responses(
|
||||
[
|
||||
proto.PinMatrixRequest(),
|
||||
proto.PassphraseRequest(),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXMETA,
|
||||
details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=1, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(
|
||||
request_index=0, tx_hash=TXHASH_d5f65e
|
||||
),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXINPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(
|
||||
request_type=proto.RequestType.TXOUTPUT,
|
||||
details=proto.TxRequestDetailsType(request_index=0),
|
||||
),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
|
||||
])
|
||||
btc.sign_tx(self.client, 'Bitcoin', [inp1, ], [out1, ])
|
||||
]
|
||||
)
|
||||
btc.sign_tx(self.client, "Bitcoin", [inp1], [out1])
|
||||
|
||||
# def test_firmware_erase(self):
|
||||
# pass
|
||||
|
@ -16,19 +16,20 @@
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
from trezorlib import btc, messages as proto
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib import btc
|
||||
|
||||
|
||||
TXHASH_d5f65e = unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')
|
||||
TXHASH_d5f65e = unhexlify(
|
||||
"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
|
||||
)
|
||||
|
||||
|
||||
# address_n = [177] < 68
|
||||
# address_n = [16518] < 66
|
||||
class TestZerosig(TrezorTest):
|
||||
|
||||
'''
|
||||
"""
|
||||
def test_mine_zero_signature(self):
|
||||
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
|
||||
# input 0: 0.0039 BTC
|
||||
@ -57,7 +58,7 @@ class TestZerosig(TrezorTest):
|
||||
print("!!!!", n)
|
||||
print(hexlify(tx.serialized_tx))
|
||||
return
|
||||
'''
|
||||
"""
|
||||
|
||||
def test_one_zero_signature(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -76,7 +77,9 @@ class TestZerosig(TrezorTest):
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bitcoin', [inp1, ], [out1, ])
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bitcoin", [inp1], [out1]
|
||||
)
|
||||
siglen = serialized_tx[44]
|
||||
|
||||
# TREZOR must strip leading zero from signature
|
||||
@ -99,7 +102,9 @@ class TestZerosig(TrezorTest):
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
(signatures, serialized_tx) = btc.sign_tx(self.client, 'Bitcoin', [inp1, ], [out1, ])
|
||||
(signatures, serialized_tx) = btc.sign_tx(
|
||||
self.client, "Bitcoin", [inp1], [out1]
|
||||
)
|
||||
siglen = serialized_tx[44]
|
||||
|
||||
# TREZOR must strip leading zero from signature
|
||||
|
@ -14,17 +14,16 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import struct
|
||||
import hmac
|
||||
import hashlib
|
||||
import hmac
|
||||
import struct
|
||||
|
||||
import ecdsa
|
||||
from ecdsa.util import string_to_number, number_to_string
|
||||
from ecdsa.curves import SECP256k1
|
||||
from ecdsa.ellipticcurve import Point, INFINITY
|
||||
from ecdsa.ellipticcurve import INFINITY, Point
|
||||
from ecdsa.util import number_to_string, string_to_number
|
||||
|
||||
from trezorlib import tools
|
||||
from trezorlib import messages
|
||||
from trezorlib import messages, tools
|
||||
|
||||
|
||||
def point_to_pubkey(point):
|
||||
@ -32,14 +31,14 @@ def point_to_pubkey(point):
|
||||
x_str = number_to_string(point.x(), order)
|
||||
y_str = number_to_string(point.y(), order)
|
||||
vk = x_str + y_str
|
||||
return struct.pack('B', (vk[63] & 1) + 2) + vk[0:32] # To compressed key
|
||||
return struct.pack("B", (vk[63] & 1) + 2) + vk[0:32] # To compressed key
|
||||
|
||||
|
||||
def sec_to_public_pair(pubkey):
|
||||
"""Convert a public key in sec binary format to a public pair."""
|
||||
x = string_to_number(pubkey[1:33])
|
||||
sec0 = pubkey[:1]
|
||||
if sec0 not in (b'\2', b'\3'):
|
||||
if sec0 not in (b"\2", b"\3"):
|
||||
raise ValueError("Compressed pubkey expected")
|
||||
|
||||
def public_pair_for_x(generator, x, is_even):
|
||||
@ -51,7 +50,9 @@ def sec_to_public_pair(pubkey):
|
||||
return (x, p - beta)
|
||||
return (x, beta)
|
||||
|
||||
return public_pair_for_x(ecdsa.ecdsa.generator_secp256k1, x, is_even=(sec0 == b'\2'))
|
||||
return public_pair_for_x(
|
||||
ecdsa.ecdsa.generator_secp256k1, x, is_even=(sec0 == b"\2")
|
||||
)
|
||||
|
||||
|
||||
def is_prime(n):
|
||||
@ -68,7 +69,7 @@ def get_address(public_node, address_type):
|
||||
|
||||
def public_ckd(public_node, n):
|
||||
if not isinstance(n, list):
|
||||
raise ValueError('Parameter must be a list')
|
||||
raise ValueError("Parameter must be a list")
|
||||
|
||||
node = messages.HDNodeType()
|
||||
node.CopyFrom(public_node)
|
||||
@ -100,7 +101,9 @@ def get_subnode(node, i):
|
||||
|
||||
# BIP32 magic converts old public key to new public point
|
||||
x, y = sec_to_public_pair(node.public_key)
|
||||
point = I_left_as_exponent * SECP256k1.generator + Point(SECP256k1.curve, x, y, SECP256k1.order)
|
||||
point = I_left_as_exponent * SECP256k1.generator + Point(
|
||||
SECP256k1.curve, x, y, SECP256k1.order
|
||||
)
|
||||
|
||||
if point == INFINITY:
|
||||
raise ValueError("Point cannot be INFINITY")
|
||||
@ -112,14 +115,14 @@ def get_subnode(node, i):
|
||||
|
||||
|
||||
def serialize(node, version=0x0488B21E):
|
||||
s = b''
|
||||
s += struct.pack('>I', version)
|
||||
s += struct.pack('>B', node.depth)
|
||||
s += struct.pack('>I', node.fingerprint)
|
||||
s += struct.pack('>I', node.child_num)
|
||||
s = b""
|
||||
s += struct.pack(">I", version)
|
||||
s += struct.pack(">B", node.depth)
|
||||
s += struct.pack(">I", node.fingerprint)
|
||||
s += struct.pack(">I", node.child_num)
|
||||
s += node.chain_code
|
||||
if node.private_key:
|
||||
s += b'\x00' + node.private_key
|
||||
s += b"\x00" + node.private_key
|
||||
else:
|
||||
s += node.public_key
|
||||
s += tools.btc_hash(s)[:4]
|
||||
@ -133,9 +136,9 @@ def deserialize(xpub):
|
||||
raise ValueError("Checksum failed")
|
||||
|
||||
node = messages.HDNodeType()
|
||||
node.depth = struct.unpack('>B', data[4:5])[0]
|
||||
node.fingerprint = struct.unpack('>I', data[5:9])[0]
|
||||
node.child_num = struct.unpack('>I', data[9:13])[0]
|
||||
node.depth = struct.unpack(">B", data[4:5])[0]
|
||||
node.fingerprint = struct.unpack(">I", data[5:9])[0]
|
||||
node.child_num = struct.unpack(">I", data[9:13])[0]
|
||||
node.chain_code = data[13:45]
|
||||
|
||||
key = data[45:-4]
|
||||
|
@ -18,11 +18,17 @@ from ..support import ckd_public
|
||||
|
||||
|
||||
def test_ckd_public():
|
||||
xpub1 = 'xpub661MyMwAqRbcEnKbXcCqD2GT1di5zQxVqoHPAgHNe8dv5JP8gWmDproS6kFHJnLZd23tWevhdn4urGJ6b264DfTGKr8zjmYDjyDTi9U7iyT'
|
||||
xpub1 = "xpub661MyMwAqRbcEnKbXcCqD2GT1di5zQxVqoHPAgHNe8dv5JP8gWmDproS6kFHJnLZd23tWevhdn4urGJ6b264DfTGKr8zjmYDjyDTi9U7iyT"
|
||||
node1 = ckd_public.deserialize(xpub1)
|
||||
node2 = ckd_public.public_ckd(node1, [0])
|
||||
node3 = ckd_public.public_ckd(node1, [0, 0])
|
||||
xpub2 = ckd_public.serialize(node2)
|
||||
xpub3 = ckd_public.serialize(node3)
|
||||
assert xpub2 == 'xpub67ymn1YTdE2iSGXitxUEZeUdHF2FsejJATroeAxVMtzTAK9o3vjmFLrE7TqE1X76iobkVc3p8h3gNzNRTwPeQGYW3CCmYCG8n5ThVkXaQzs'
|
||||
assert xpub3 == 'xpub6BD2MwdEg5PJPqiGetL9DJs7oDo6zP3XwAABX2vAQb5eLpY3QhHGUEm25V4nkQhnFMsqEVfTwtax2gKz8EFrt1PnBN6xQjE9jGmWDR6modu'
|
||||
assert (
|
||||
xpub2
|
||||
== "xpub67ymn1YTdE2iSGXitxUEZeUdHF2FsejJATroeAxVMtzTAK9o3vjmFLrE7TqE1X76iobkVc3p8h3gNzNRTwPeQGYW3CCmYCG8n5ThVkXaQzs"
|
||||
)
|
||||
assert (
|
||||
xpub3
|
||||
== "xpub6BD2MwdEg5PJPqiGetL9DJs7oDo6zP3XwAABX2vAQb5eLpY3QhHGUEm25V4nkQhnFMsqEVfTwtax2gKz8EFrt1PnBN6xQjE9jGmWDR6modu"
|
||||
)
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
import binascii
|
||||
import hashlib
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import cosi
|
||||
@ -30,62 +31,91 @@ from trezorlib import cosi
|
||||
|
||||
pytestmark = pytest.mark.slow_cosi
|
||||
if "slow_cosi" not in pytest.config.getoption("-m"):
|
||||
pytestmark = pytest.mark.skip("Skipping slow CoSi tests. 'pytest -m slow_cosi' to run.")
|
||||
pytestmark = pytest.mark.skip(
|
||||
"Skipping slow CoSi tests. 'pytest -m slow_cosi' to run."
|
||||
)
|
||||
|
||||
|
||||
RFC8032_VECTORS = (
|
||||
( # test 1
|
||||
# privkey
|
||||
binascii.unhexlify("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"),
|
||||
binascii.unhexlify(
|
||||
"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"
|
||||
),
|
||||
# pubkey
|
||||
binascii.unhexlify("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"),
|
||||
binascii.unhexlify(
|
||||
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"
|
||||
),
|
||||
# message
|
||||
binascii.unhexlify(""),
|
||||
# signature
|
||||
binascii.unhexlify("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155"
|
||||
"5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"),
|
||||
binascii.unhexlify(
|
||||
"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155"
|
||||
"5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"
|
||||
),
|
||||
),
|
||||
( # test 2
|
||||
# privkey
|
||||
binascii.unhexlify("4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"),
|
||||
binascii.unhexlify(
|
||||
"4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"
|
||||
),
|
||||
# pubkey
|
||||
binascii.unhexlify("3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"),
|
||||
binascii.unhexlify(
|
||||
"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"
|
||||
),
|
||||
# message
|
||||
binascii.unhexlify("72"),
|
||||
# signature
|
||||
binascii.unhexlify("92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da"
|
||||
"085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"),
|
||||
binascii.unhexlify(
|
||||
"92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da"
|
||||
"085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"
|
||||
),
|
||||
),
|
||||
( # test 3
|
||||
# privkey
|
||||
binascii.unhexlify("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"),
|
||||
binascii.unhexlify(
|
||||
"c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"
|
||||
),
|
||||
# pubkey
|
||||
binascii.unhexlify("fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"),
|
||||
binascii.unhexlify(
|
||||
"fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"
|
||||
),
|
||||
# message
|
||||
binascii.unhexlify("af82"),
|
||||
# signature
|
||||
binascii.unhexlify("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac"
|
||||
"18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"),
|
||||
binascii.unhexlify(
|
||||
"6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac"
|
||||
"18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"
|
||||
),
|
||||
),
|
||||
( # test SHA(abc)
|
||||
# privkey
|
||||
binascii.unhexlify("833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42"),
|
||||
binascii.unhexlify(
|
||||
"833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42"
|
||||
),
|
||||
# pubkey
|
||||
binascii.unhexlify("ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf"),
|
||||
binascii.unhexlify(
|
||||
"ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf"
|
||||
),
|
||||
# message
|
||||
hashlib.sha512(b"abc").digest(),
|
||||
# signature
|
||||
binascii.unhexlify("dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b589"
|
||||
"09351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"),
|
||||
binascii.unhexlify(
|
||||
"dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b589"
|
||||
"09351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
COMBINED_KEY = binascii.unhexlify("283967b1c19ff93d2924cdcba95e586547cafef509ea402963ceefe96ccb44f2")
|
||||
GLOBAL_COMMIT = binascii.unhexlify("75bd5806c6366e0374a1c6e020c53feb0791d6cc07560d27d8c158f886ecf389")
|
||||
COMBINED_KEY = binascii.unhexlify(
|
||||
"283967b1c19ff93d2924cdcba95e586547cafef509ea402963ceefe96ccb44f2"
|
||||
)
|
||||
GLOBAL_COMMIT = binascii.unhexlify(
|
||||
"75bd5806c6366e0374a1c6e020c53feb0791d6cc07560d27d8c158f886ecf389"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("privkey, pubkey, message, signature",
|
||||
RFC8032_VECTORS)
|
||||
@pytest.mark.parametrize("privkey, pubkey, message, signature", RFC8032_VECTORS)
|
||||
def test_single_eddsa_vector(privkey, pubkey, message, signature):
|
||||
my_pubkey = cosi.pubkey_from_privkey(privkey)
|
||||
assert my_pubkey == pubkey
|
||||
@ -94,7 +124,7 @@ def test_single_eddsa_vector(privkey, pubkey, message, signature):
|
||||
except ValueError:
|
||||
pytest.fail("Signature does not verify.")
|
||||
|
||||
fake_signature = b'\xf1' + signature[1:]
|
||||
fake_signature = b"\xf1" + signature[1:]
|
||||
with pytest.raises(ValueError):
|
||||
cosi.verify(fake_signature, message, pubkey)
|
||||
|
||||
@ -103,17 +133,14 @@ def test_combine_keys():
|
||||
pubkeys = [pubkey for _, pubkey, _, _ in RFC8032_VECTORS]
|
||||
assert cosi.combine_keys(pubkeys) == COMBINED_KEY
|
||||
|
||||
Rs = [cosi.get_nonce(privkey, message)[1] for privkey, _, message, _ in RFC8032_VECTORS]
|
||||
Rs = [
|
||||
cosi.get_nonce(privkey, message)[1]
|
||||
for privkey, _, message, _ in RFC8032_VECTORS
|
||||
]
|
||||
assert cosi.combine_keys(Rs) == GLOBAL_COMMIT
|
||||
|
||||
|
||||
@pytest.mark.parametrize("keyset", [
|
||||
(0,),
|
||||
(0, 1),
|
||||
(0, 1, 2),
|
||||
(0, 1, 2, 3),
|
||||
(1, 3),
|
||||
])
|
||||
@pytest.mark.parametrize("keyset", [(0,), (0, 1), (0, 1, 2), (0, 1, 2, 3), (1, 3)])
|
||||
def test_cosi_combination(keyset):
|
||||
message = hashlib.sha512(b"You all have to sign this.").digest()
|
||||
selection = [RFC8032_VECTORS[i] for i in keyset]
|
||||
@ -128,8 +155,10 @@ def test_cosi_combination(keyset):
|
||||
global_commit = cosi.combine_keys(commits)
|
||||
|
||||
# generate individual signatures
|
||||
signatures = [cosi.sign_with_privkey(message, privkey, global_pk, nonce, global_commit)
|
||||
for privkey, nonce in zip(privkeys, nonces)]
|
||||
signatures = [
|
||||
cosi.sign_with_privkey(message, privkey, global_pk, nonce, global_commit)
|
||||
for privkey, nonce in zip(privkeys, nonces)
|
||||
]
|
||||
|
||||
# combine signatures
|
||||
global_sig = cosi.combine_sig(global_commit, signatures)
|
||||
|
@ -15,6 +15,7 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import binascii
|
||||
|
||||
from trezorlib import nem
|
||||
|
||||
|
||||
@ -27,18 +28,9 @@ def test_nem_basic():
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x98 << 24),
|
||||
"message": {
|
||||
"payload": binascii.hexlify(b'hello world'),
|
||||
"type": 1,
|
||||
},
|
||||
"message": {"payload": binascii.hexlify(b"hello world"), "type": 1},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {
|
||||
"namespaceId": "nem",
|
||||
"name": "xem",
|
||||
},
|
||||
"quantity": 1000000,
|
||||
},
|
||||
{"mosaicId": {"namespaceId": "nem", "name": "xem"}, "quantity": 1000000}
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib import protobuf
|
||||
@ -42,20 +43,20 @@ def dump_uvarint(value):
|
||||
|
||||
|
||||
def test_dump_uvarint():
|
||||
assert dump_uvarint(0) == b'\x00'
|
||||
assert dump_uvarint(1) == b'\x01'
|
||||
assert dump_uvarint(0xff) == b'\xff\x01'
|
||||
assert dump_uvarint(123456) == b'\xc0\xc4\x07'
|
||||
assert dump_uvarint(0) == b"\x00"
|
||||
assert dump_uvarint(1) == b"\x01"
|
||||
assert dump_uvarint(0xff) == b"\xff\x01"
|
||||
assert dump_uvarint(123456) == b"\xc0\xc4\x07"
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
dump_uvarint(-1)
|
||||
|
||||
|
||||
def test_load_uvarint():
|
||||
assert load_uvarint(b'\x00') == 0
|
||||
assert load_uvarint(b'\x01') == 1
|
||||
assert load_uvarint(b'\xff\x01') == 0xff
|
||||
assert load_uvarint(b'\xc0\xc4\x07') == 123456
|
||||
assert load_uvarint(b"\x00") == 0
|
||||
assert load_uvarint(b"\x01") == 1
|
||||
assert load_uvarint(b"\xff\x01") == 0xff
|
||||
assert load_uvarint(b"\xc0\xc4\x07") == 123456
|
||||
|
||||
|
||||
def test_sint_uint():
|
||||
@ -75,12 +76,8 @@ def test_sint_uint():
|
||||
assert protobuf.uint_to_sint(2) == 1
|
||||
|
||||
# roundtrip:
|
||||
assert protobuf.uint_to_sint(
|
||||
protobuf.sint_to_uint(1234567891011)
|
||||
) == 1234567891011
|
||||
assert protobuf.uint_to_sint(
|
||||
protobuf.sint_to_uint(- 2 ** 32)
|
||||
) == - 2 ** 32
|
||||
assert protobuf.uint_to_sint(protobuf.sint_to_uint(1234567891011)) == 1234567891011
|
||||
assert protobuf.uint_to_sint(protobuf.sint_to_uint(-2 ** 32)) == -2 ** 32
|
||||
|
||||
|
||||
def test_simple_message():
|
||||
@ -88,7 +85,7 @@ def test_simple_message():
|
||||
uvarint=12345678910,
|
||||
svarint=-12345678910,
|
||||
bool=True,
|
||||
bytes=b'\xDE\xAD\xCA\xFE',
|
||||
bytes=b"\xDE\xAD\xCA\xFE",
|
||||
unicode="Příliš žluťoučký kůň úpěl ďábelské ódy 😊",
|
||||
)
|
||||
|
||||
@ -102,5 +99,5 @@ def test_simple_message():
|
||||
assert retr.uvarint == 12345678910
|
||||
assert retr.svarint == -12345678910
|
||||
assert retr.bool is True
|
||||
assert retr.bytes == b'\xDE\xAD\xCA\xFE'
|
||||
assert retr.bytes == b"\xDE\xAD\xCA\xFE"
|
||||
assert retr.unicode == "Příliš žluťoučký kůň úpěl ďábelské ódy 😊"
|
||||
|
@ -15,16 +15,18 @@
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import base64
|
||||
from trezorlib import stellar
|
||||
from trezorlib import messages
|
||||
|
||||
from trezorlib import messages, stellar
|
||||
|
||||
|
||||
def test_stellar_parse_transaction_bytes_simple():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAO5/eyAAAAAA='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAO5/eyAAAAAA="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
|
||||
assert tx.source_account == 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
assert (
|
||||
tx.source_account == "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
)
|
||||
assert tx.fee == 100
|
||||
assert tx.sequence_number == 4294967296
|
||||
assert tx.timebounds_start is None
|
||||
@ -37,28 +39,32 @@ def test_stellar_parse_transaction_bytes_simple():
|
||||
|
||||
|
||||
def test_stellar_parse_transaction_bytes_memo_text():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAEAAAAMZXhhbXBsZSBtZW1vAAAAAQAAAAAAAAAAAAAAAF1VZCRmsYW4QxUuniGRUdvFiSAn7EAQGlF77VygMMLgAAAAADuf3sgAAAAA'
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAEAAAAMZXhhbXBsZSBtZW1vAAAAAQAAAAAAAAAAAAAAAF1VZCRmsYW4QxUuniGRUdvFiSAn7EAQGlF77VygMMLgAAAAADuf3sgAAAAA"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
|
||||
assert tx.source_account == 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
assert (
|
||||
tx.source_account == "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
)
|
||||
assert tx.fee == 100
|
||||
assert tx.sequence_number == 4294967296
|
||||
assert tx.timebounds_start is None
|
||||
assert tx.timebounds_end is None
|
||||
assert tx.memo_type == stellar.MEMO_TYPE_TEXT
|
||||
assert tx.memo_text == b'example memo'
|
||||
assert tx.memo_text == b"example memo"
|
||||
assert tx.memo_id is None
|
||||
assert tx.memo_hash is None
|
||||
assert tx.num_operations == len(operations)
|
||||
|
||||
|
||||
def test_stellar_parse_transaction_bytes_memo_id():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAIAAAAAB1vNFQAAAAEAAAAAAAAAAAAAAABdVWQkZrGFuEMVLp4hkVHbxYkgJ+xAEBpRe+1coDDC4AAAAAA7n97IAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAIAAAAAB1vNFQAAAAEAAAAAAAAAAAAAAABdVWQkZrGFuEMVLp4hkVHbxYkgJ+xAEBpRe+1coDDC4AAAAAA7n97IAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
|
||||
assert tx.source_account == 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
assert (
|
||||
tx.source_account == "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
)
|
||||
assert tx.fee == 100
|
||||
assert tx.sequence_number == 4294967296
|
||||
assert tx.timebounds_start is None
|
||||
@ -71,11 +77,13 @@ def test_stellar_parse_transaction_bytes_memo_id():
|
||||
|
||||
|
||||
def test_stellar_parse_transaction_bytes_memo_hash():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAMjLtb5+r8U47tVOSsYz+PQ/ryU0gzGMnw4odB11uoRjAAAAAEAAAAAAAAAAAAAAABdVWQkZrGFuEMVLp4hkVHbxYkgJ+xAEBpRe+1coDDC4AAAAAA7n97IAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAMjLtb5+r8U47tVOSsYz+PQ/ryU0gzGMnw4odB11uoRjAAAAAEAAAAAAAAAAAAAAABdVWQkZrGFuEMVLp4hkVHbxYkgJ+xAEBpRe+1coDDC4AAAAAA7n97IAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
|
||||
assert tx.source_account == 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
assert (
|
||||
tx.source_account == "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
)
|
||||
assert tx.fee == 100
|
||||
assert tx.sequence_number == 4294967296
|
||||
assert tx.timebounds_start is None
|
||||
@ -84,16 +92,21 @@ def test_stellar_parse_transaction_bytes_memo_hash():
|
||||
assert tx.memo_text is None
|
||||
assert tx.memo_id is None
|
||||
# base-64 encoding of the raw bytes of sha256('stellar')
|
||||
assert base64.b64encode(tx.memo_hash) == b'Iy7W+fq/FOO7VTkrGM/j0P68lNIMxjJ8OKHQddbqEYw='
|
||||
assert (
|
||||
base64.b64encode(tx.memo_hash)
|
||||
== b"Iy7W+fq/FOO7VTkrGM/j0P68lNIMxjJ8OKHQddbqEYw="
|
||||
)
|
||||
assert tx.num_operations == len(operations)
|
||||
|
||||
|
||||
def test_stellar_parse_transaction_bytes_memo_return():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAQjLtb5+r8U47tVOSsYz+PQ/ryU0gzGMnw4odB11uoRjAAAAAEAAAAAAAAAAAAAAABdVWQkZrGFuEMVLp4hkVHbxYkgJ+xAEBpRe+1coDDC4AAAAAA7n97IAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAQjLtb5+r8U47tVOSsYz+PQ/ryU0gzGMnw4odB11uoRjAAAAAEAAAAAAAAAAAAAAABdVWQkZrGFuEMVLp4hkVHbxYkgJ+xAEBpRe+1coDDC4AAAAAA7n97IAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
|
||||
assert tx.source_account == 'GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW'
|
||||
assert (
|
||||
tx.source_account == "GAK5MSF74TJW6GLM7NLTL76YZJKM2S4CGP3UH4REJHPHZ4YBZW2GSBPW"
|
||||
)
|
||||
assert tx.fee == 100
|
||||
assert tx.sequence_number == 4294967296
|
||||
assert tx.timebounds_start is None
|
||||
@ -102,115 +115,147 @@ def test_stellar_parse_transaction_bytes_memo_return():
|
||||
assert tx.memo_text is None
|
||||
assert tx.memo_id is None
|
||||
# base-64 encoding of the raw bytes of sha256('stellar')
|
||||
assert base64.b64encode(tx.memo_hash) == b'Iy7W+fq/FOO7VTkrGM/j0P68lNIMxjJ8OKHQddbqEYw='
|
||||
assert (
|
||||
base64.b64encode(tx.memo_hash)
|
||||
== b"Iy7W+fq/FOO7VTkrGM/j0P68lNIMxjJ8OKHQddbqEYw="
|
||||
)
|
||||
assert tx.num_operations == len(operations)
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_create_account_simple():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAO5/eyAAAAAA='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAO5/eyAAAAAA="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
|
||||
assert isinstance(op, messages.StellarCreateAccountOp)
|
||||
assert op.source_account is None
|
||||
assert op.new_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert op.new_account == "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
assert op.starting_balance == 1000333000
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_payment_native():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAAAAAAB3PFpgAAAAA'
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAAAAAAB3PFpgAAAAA"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
|
||||
assert isinstance(op, messages.StellarPaymentOp)
|
||||
assert op.source_account is None
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
assert op.asset.type == stellar.ASSET_TYPE_NATIVE
|
||||
assert op.amount == 500111000
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_payment_custom4():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAABVEVTVAAAAAAphJYCwg5YNl8SPBLYehykVQ0QzSGwrg4Y1E4+Vv1qFQAAAAAdzxaYAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAABVEVTVAAAAAAphJYCwg5YNl8SPBLYehykVQ0QzSGwrg4Y1E4+Vv1qFQAAAAAdzxaYAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
|
||||
assert op.source_account is None
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
assert op.asset.type == stellar.ASSET_TYPE_ALPHA4
|
||||
assert op.asset.code == b'TEST'
|
||||
assert op.asset.issuer == 'GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC'
|
||||
assert op.asset.code == b"TEST"
|
||||
assert op.asset.issuer == "GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC"
|
||||
assert op.amount == 500111000
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_payment_custom7():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAACU0VWRU5YWAAAAAAAAAAAACmElgLCDlg2XxI8Eth6HKRVDRDNIbCuDhjUTj5W/WoVAAAAAB3PFpgAAAAA'
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAACU0VWRU5YWAAAAAAAAAAAACmElgLCDlg2XxI8Eth6HKRVDRDNIbCuDhjUTj5W/WoVAAAAAB3PFpgAAAAA"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
|
||||
assert isinstance(op, messages.StellarPaymentOp)
|
||||
assert op.source_account is None
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
assert op.asset.type == stellar.ASSET_TYPE_ALPHA12
|
||||
# asset codes are either 4 or 12 characters, so this will be null-padded at the end
|
||||
assert op.asset.code == b'SEVENXX\x00\x00\x00\x00\x00'
|
||||
assert op.asset.issuer == 'GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC'
|
||||
assert op.asset.code == b"SEVENXX\x00\x00\x00\x00\x00"
|
||||
assert op.asset.issuer == "GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC"
|
||||
assert op.amount == 500111000
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_path_payment_none():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAHfOKn8AAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAABSlBZAAAAAADE+xa3Eb3cy85WSdqgwnUtC6UDwrC41YDANuCqe8vGxgAAAAAL68IBAAAAAAAAAAA='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAHfOKn8AAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAABSlBZAAAAAADE+xa3Eb3cy85WSdqgwnUtC6UDwrC41YDANuCqe8vGxgAAAAAL68IBAAAAAAAAAAA="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
|
||||
assert isinstance(op, messages.StellarPathPaymentOp)
|
||||
assert op.source_account is None
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
|
||||
assert op.send_asset.type == stellar.ASSET_TYPE_NATIVE
|
||||
assert op.send_max == 2009999999
|
||||
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
assert op.destination_asset.type == stellar.ASSET_TYPE_ALPHA4
|
||||
# asset codes are either 4 or 12 characters, so this will be null-padded at the end
|
||||
assert op.destination_asset.code == b'JPY\x00'
|
||||
assert op.destination_asset.issuer == 'GDCPWFVXCG65ZS6OKZE5VIGCOUWQXJIDYKYLRVMAYA3OBKT3ZPDMNTIJ'
|
||||
assert op.destination_asset.code == b"JPY\x00"
|
||||
assert (
|
||||
op.destination_asset.issuer
|
||||
== "GDCPWFVXCG65ZS6OKZE5VIGCOUWQXJIDYKYLRVMAYA3OBKT3ZPDMNTIJ"
|
||||
)
|
||||
|
||||
assert len(op.paths) == 0
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_path_payment_one():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAHfOKn8AAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAABSlBZAAAAAADE+xa3Eb3cy85WSdqgwnUtC6UDwrC41YDANuCqe8vGxgAAAAAL68IBAAAAAQAAAAFQVEgxAAAAAMz/d9fJ3rFifblw3jT7sRZv/Ja+fqLfob//aLZQRQibAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAHfOKn8AAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAABSlBZAAAAAADE+xa3Eb3cy85WSdqgwnUtC6UDwrC41YDANuCqe8vGxgAAAAAL68IBAAAAAQAAAAFQVEgxAAAAAMz/d9fJ3rFifblw3jT7sRZv/Ja+fqLfob//aLZQRQibAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
|
||||
assert isinstance(op, messages.StellarPathPaymentOp)
|
||||
assert op.source_account is None
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
|
||||
assert op.send_asset.type == stellar.ASSET_TYPE_NATIVE
|
||||
assert op.send_max == 2009999999
|
||||
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
assert op.destination_asset.type == stellar.ASSET_TYPE_ALPHA4
|
||||
# asset codes are either 4 or 12 characters, so this will be null-padded at the end
|
||||
assert op.destination_asset.code == b'JPY\x00'
|
||||
assert op.destination_asset.issuer == 'GDCPWFVXCG65ZS6OKZE5VIGCOUWQXJIDYKYLRVMAYA3OBKT3ZPDMNTIJ'
|
||||
assert op.destination_asset.code == b"JPY\x00"
|
||||
assert (
|
||||
op.destination_asset.issuer
|
||||
== "GDCPWFVXCG65ZS6OKZE5VIGCOUWQXJIDYKYLRVMAYA3OBKT3ZPDMNTIJ"
|
||||
)
|
||||
assert op.destination_amount == 200000001
|
||||
|
||||
assert len(op.paths) == 1
|
||||
assert op.paths[0].type == stellar.ASSET_TYPE_ALPHA4
|
||||
assert op.paths[0].code == b'PTH1'
|
||||
assert op.paths[0].issuer == 'GDGP656XZHPLCYT5XFYN4NH3WELG77EWXZ7KFX5BX77WRNSQIUEJXAJK'
|
||||
assert op.paths[0].code == b"PTH1"
|
||||
assert (
|
||||
op.paths[0].issuer == "GDGP656XZHPLCYT5XFYN4NH3WELG77EWXZ7KFX5BX77WRNSQIUEJXAJK"
|
||||
)
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_manage_offer_new():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAMAAAAAAAAAAVVTRAAAAAAABkAD8fq0d+bofA1LCatUL0dCTJexnyYYd4Y1ghnNUXMAAAAAdzWUAAAKSzYAD0JAAAAAAAAAAAAAAAAA'
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAMAAAAAAAAAAVVTRAAAAAAABkAD8fq0d+bofA1LCatUL0dCTJexnyYYd4Y1ghnNUXMAAAAAdzWUAAAKSzYAD0JAAAAAAAAAAAAAAAAA"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
@ -222,8 +267,11 @@ def test_stellar_parse_operation_bytes_manage_offer_new():
|
||||
|
||||
assert op.buying_asset.type == stellar.ASSET_TYPE_ALPHA4
|
||||
# asset codes are either 4 or 12 characters, so this will be null-padded at the end
|
||||
assert op.buying_asset.code == b'USD\x00'
|
||||
assert op.buying_asset.issuer == 'GADEAA7R7K2HPZXIPQGUWCNLKQXUOQSMS6YZ6JQYO6DDLAQZZVIXG74A'
|
||||
assert op.buying_asset.code == b"USD\x00"
|
||||
assert (
|
||||
op.buying_asset.issuer
|
||||
== "GADEAA7R7K2HPZXIPQGUWCNLKQXUOQSMS6YZ6JQYO6DDLAQZZVIXG74A"
|
||||
)
|
||||
|
||||
assert op.amount == 2000000000
|
||||
assert op.price_n == 674614
|
||||
@ -232,7 +280,7 @@ def test_stellar_parse_operation_bytes_manage_offer_new():
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_passive_offer_new():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAQAAAAAAAAAAVVTRAAAAAAABkAD8fq0d+bofA1LCatUL0dCTJexnyYYd4Y1ghnNUXMAAAAAdzWUAAAKSzYAD0JAAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAQAAAAAAAAAAVVTRAAAAAAABkAD8fq0d+bofA1LCatUL0dCTJexnyYYd4Y1ghnNUXMAAAAAdzWUAAAKSzYAD0JAAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
@ -244,8 +292,11 @@ def test_stellar_parse_operation_bytes_passive_offer_new():
|
||||
|
||||
assert op.buying_asset.type == stellar.ASSET_TYPE_ALPHA4
|
||||
# asset codes are either 4 or 12 characters, so this will be null-padded at the end
|
||||
assert op.buying_asset.code == b'USD\x00'
|
||||
assert op.buying_asset.issuer == 'GADEAA7R7K2HPZXIPQGUWCNLKQXUOQSMS6YZ6JQYO6DDLAQZZVIXG74A'
|
||||
assert op.buying_asset.code == b"USD\x00"
|
||||
assert (
|
||||
op.buying_asset.issuer
|
||||
== "GADEAA7R7K2HPZXIPQGUWCNLKQXUOQSMS6YZ6JQYO6DDLAQZZVIXG74A"
|
||||
)
|
||||
|
||||
assert op.amount == 2000000000
|
||||
assert op.price_n == 674614
|
||||
@ -253,7 +304,7 @@ def test_stellar_parse_operation_bytes_passive_offer_new():
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_set_options_inflation():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAUAAAABAAAAAAt5i66vbwH70/2M4Oj0rQW81SNLAjfOsMV2bavzocXhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAUAAAABAAAAAAt5i66vbwH70/2M4Oj0rQW81SNLAjfOsMV2bavzocXhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
@ -261,11 +312,14 @@ def test_stellar_parse_operation_bytes_set_options_inflation():
|
||||
assert isinstance(op, messages.StellarSetOptionsOp)
|
||||
assert op.source_account is None
|
||||
|
||||
assert op.inflation_destination_account == 'GAFXTC5OV5XQD66T7WGOB2HUVUC3ZVJDJMBDPTVQYV3G3K7TUHC6CLBR'
|
||||
assert (
|
||||
op.inflation_destination_account
|
||||
== "GAFXTC5OV5XQD66T7WGOB2HUVUC3ZVJDJMBDPTVQYV3G3K7TUHC6CLBR"
|
||||
)
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_change_trust_add():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABVVNEAAAAAACkn7CoQZEWAlyO6z6VBUAddrDDR078TtLt/nP/hZJ9KQAAAAJUC+QAAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABVVNEAAAAAACkn7CoQZEWAlyO6z6VBUAddrDDR078TtLt/nP/hZJ9KQAAAAJUC+QAAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
@ -274,14 +328,14 @@ def test_stellar_parse_operation_bytes_change_trust_add():
|
||||
assert op.source_account is None
|
||||
|
||||
assert op.asset.type == stellar.ASSET_TYPE_ALPHA4
|
||||
assert op.asset.code == b'USD\x00'
|
||||
assert op.asset.issuer == 'GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF'
|
||||
assert op.asset.code == b"USD\x00"
|
||||
assert op.asset.issuer == "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF"
|
||||
|
||||
assert op.limit == 10000000000
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_allow_trust_allow():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAcAAAAAZ0Me3OnxI2tuaC8qt95THF1fuB42qARTnP2ookJapQUAAAABSlBZAAAAAAEAAAAA'
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAcAAAAAZ0Me3OnxI2tuaC8qt95THF1fuB42qARTnP2ookJapQUAAAABSlBZAAAAAAEAAAAA"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
@ -290,13 +344,15 @@ def test_stellar_parse_operation_bytes_allow_trust_allow():
|
||||
assert op.source_account is None
|
||||
|
||||
assert op.asset_type == stellar.ASSET_TYPE_ALPHA4
|
||||
assert op.asset_code == b'JPY\x00'
|
||||
assert op.asset_code == b"JPY\x00"
|
||||
|
||||
assert op.trusted_account == 'GBTUGHW45HYSG23ONAXSVN66KMOF2X5YDY3KQBCTTT62RISCLKSQLYF4'
|
||||
assert (
|
||||
op.trusted_account == "GBTUGHW45HYSG23ONAXSVN66KMOF2X5YDY3KQBCTTT62RISCLKSQLYF4"
|
||||
)
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_account_merge_simple():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAA'
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAA"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
@ -304,11 +360,14 @@ def test_stellar_parse_operation_bytes_account_merge_simple():
|
||||
assert isinstance(op, messages.StellarAccountMergeOp)
|
||||
assert op.source_account is None
|
||||
|
||||
assert op.destination_account == 'GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V'
|
||||
assert (
|
||||
op.destination_account
|
||||
== "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V"
|
||||
)
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_manage_data_set_simple():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAoAAAAJdGVzdCBkYXRhAAAAAAAAAQAAAARhc2RmAAAAAA=='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAoAAAAJdGVzdCBkYXRhAAAAAAAAAQAAAARhc2RmAAAAAA=="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
@ -316,12 +375,12 @@ def test_stellar_parse_operation_bytes_manage_data_set_simple():
|
||||
assert isinstance(op, messages.StellarManageDataOp)
|
||||
assert op.source_account is None
|
||||
|
||||
assert op.key == b'test data'
|
||||
assert op.value == b'asdf'
|
||||
assert op.key == b"test data"
|
||||
assert op.value == b"asdf"
|
||||
|
||||
|
||||
def test_stellar_parse_operation_bytes_bump_sequence_simple():
|
||||
b64 = b'AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAsAAAAASZYC0gAAAAA='
|
||||
b64 = b"AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAsAAAAASZYC0gAAAAA="
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64))
|
||||
op = operations[0]
|
||||
|
@ -23,7 +23,7 @@ def test_all_transports_without_hid():
|
||||
# import all transports, assume this doesn't fail
|
||||
transports_ref = all_transports()
|
||||
# also shouldn't fail when bridge transport is missing
|
||||
with mock.patch.dict('sys.modules', {'trezorlib.transport.bridge': None}):
|
||||
with mock.patch.dict("sys.modules", {"trezorlib.transport.bridge": None}):
|
||||
transports = all_transports()
|
||||
# there should now be less transports
|
||||
assert len(transports_ref) > len(transports)
|
||||
|
@ -14,36 +14,61 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import binascii
|
||||
import os
|
||||
|
||||
from trezorlib import coins
|
||||
from trezorlib import tx_api
|
||||
import binascii
|
||||
from trezorlib import coins, tx_api
|
||||
|
||||
TxApiBitcoin = coins.tx_api['Bitcoin']
|
||||
TxApiBitcoin = coins.tx_api["Bitcoin"]
|
||||
TxApiTestnet = tx_api.TxApiInsight("insight_testnet")
|
||||
TxApiZencash = coins.tx_api['Zencash']
|
||||
TxApiZencash = coins.tx_api["Zencash"]
|
||||
|
||||
tests_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def test_tx_api_gettx():
|
||||
tx_api.cache_dir = os.path.join(tests_dir, '../txcache')
|
||||
tx_api.cache_dir = os.path.join(tests_dir, "../txcache")
|
||||
|
||||
TxApiBitcoin.get_tx('39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5')
|
||||
TxApiBitcoin.get_tx('54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3')
|
||||
TxApiBitcoin.get_tx('58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e')
|
||||
TxApiBitcoin.get_tx('6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315')
|
||||
TxApiBitcoin.get_tx('a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396')
|
||||
TxApiBitcoin.get_tx('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52')
|
||||
TxApiBitcoin.get_tx('c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb')
|
||||
TxApiBitcoin.get_tx('c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c')
|
||||
TxApiBitcoin.get_tx('d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d')
|
||||
TxApiBitcoin.get_tx('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')
|
||||
TxApiBitcoin.get_tx('e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3')
|
||||
TxApiBitcoin.get_tx(
|
||||
"39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
|
||||
)
|
||||
TxApiBitcoin.get_tx(
|
||||
"e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3"
|
||||
)
|
||||
|
||||
TxApiTestnet.get_tx('6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54')
|
||||
TxApiTestnet.get_tx('d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236')
|
||||
TxApiTestnet.get_tx(
|
||||
"6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"
|
||||
)
|
||||
TxApiTestnet.get_tx(
|
||||
"d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236"
|
||||
)
|
||||
|
||||
|
||||
def test_tx_api_current_block():
|
||||
@ -53,4 +78,6 @@ def test_tx_api_current_block():
|
||||
|
||||
def test_tx_api_get_block_hash():
|
||||
hash = TxApiZencash.get_block_hash(110000)
|
||||
assert hash == binascii.unhexlify('000000003f5d6ba1385c6cd2d4f836dfc5adf7f98834309ad67e26faef462454')
|
||||
assert hash == binascii.unhexlify(
|
||||
"000000003f5d6ba1385c6cd2d4f836dfc5adf7f98834309ad67e26faef462454"
|
||||
)
|
||||
|
@ -18,13 +18,13 @@ import functools
|
||||
import hashlib
|
||||
import struct
|
||||
import unicodedata
|
||||
from typing import NewType, List
|
||||
from typing import List, NewType
|
||||
|
||||
from .coins import slip44
|
||||
|
||||
HARDENED_FLAG = 1 << 31
|
||||
|
||||
Address = NewType('Address', List[int])
|
||||
Address = NewType("Address", List[int])
|
||||
|
||||
|
||||
def H_(x: int) -> int:
|
||||
@ -42,13 +42,13 @@ def btc_hash(data):
|
||||
|
||||
|
||||
def hash_160(public_key):
|
||||
md = hashlib.new('ripemd160')
|
||||
md = hashlib.new("ripemd160")
|
||||
md.update(hashlib.sha256(public_key).digest())
|
||||
return md.digest()
|
||||
|
||||
|
||||
def hash_160_to_bc_address(h160, address_type):
|
||||
vh160 = struct.pack('<B', address_type) + h160
|
||||
vh160 = struct.pack("<B", address_type) + h160
|
||||
h = btc_hash(vh160)
|
||||
addr = vh160 + h[0:4]
|
||||
return b58encode(addr)
|
||||
@ -61,14 +61,14 @@ def compress_pubkey(public_key):
|
||||
|
||||
|
||||
def public_key_to_bc_address(public_key, address_type, compress=True):
|
||||
if public_key[0] == '\x04' and compress:
|
||||
if public_key[0] == "\x04" and compress:
|
||||
public_key = compress_pubkey(public_key)
|
||||
|
||||
h160 = hash_160(public_key)
|
||||
return hash_160_to_bc_address(h160, address_type)
|
||||
|
||||
|
||||
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
__b58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
__b58base = len(__b58chars)
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ def b58encode(v):
|
||||
for c in v:
|
||||
long_value = long_value * 256 + c
|
||||
|
||||
result = ''
|
||||
result = ""
|
||||
while long_value >= __b58base:
|
||||
div, mod = divmod(long_value, __b58base)
|
||||
result = __b58chars[mod] + result
|
||||
@ -104,12 +104,12 @@ def b58decode(v, length):
|
||||
for (i, c) in enumerate(v[::-1]):
|
||||
long_value += __b58chars.find(c) * (__b58base ** i)
|
||||
|
||||
result = b''
|
||||
result = b""
|
||||
while long_value >= 256:
|
||||
div, mod = divmod(long_value, 256)
|
||||
result = struct.pack('B', mod) + result
|
||||
result = struct.pack("B", mod) + result
|
||||
long_value = div
|
||||
result = struct.pack('B', long_value) + result
|
||||
result = struct.pack("B", long_value) + result
|
||||
|
||||
nPad = 0
|
||||
for c in v:
|
||||
@ -118,7 +118,7 @@ def b58decode(v, length):
|
||||
else:
|
||||
break
|
||||
|
||||
result = b'\x00' * nPad + result
|
||||
result = b"\x00" * nPad + result
|
||||
if length is not None and len(result) != length:
|
||||
return None
|
||||
|
||||
@ -138,21 +138,21 @@ def parse_path(nstr: str) -> Address:
|
||||
if not nstr:
|
||||
return []
|
||||
|
||||
n = nstr.split('/')
|
||||
n = nstr.split("/")
|
||||
|
||||
# m/a/b/c => a/b/c
|
||||
if n[0] == 'm':
|
||||
if n[0] == "m":
|
||||
n = n[1:]
|
||||
|
||||
# coin_name/a/b/c => 44'/SLIP44_constant'/a/b/c
|
||||
if n[0] in slip44:
|
||||
coin_id = slip44[n[0]]
|
||||
n[0:1] = ['44h', '{}h'.format(coin_id)]
|
||||
n[0:1] = ["44h", "{}h".format(coin_id)]
|
||||
|
||||
def str_to_harden(x: str) -> int:
|
||||
if x.startswith('-'):
|
||||
if x.startswith("-"):
|
||||
return H_(abs(int(x)))
|
||||
elif x.endswith(('h', "'")):
|
||||
elif x.endswith(("h", "'")):
|
||||
return H_(int(x[:-1]))
|
||||
else:
|
||||
return int(x)
|
||||
@ -160,17 +160,17 @@ def parse_path(nstr: str) -> Address:
|
||||
try:
|
||||
return [str_to_harden(x) for x in n]
|
||||
except Exception:
|
||||
raise ValueError('Invalid BIP32 path', nstr)
|
||||
raise ValueError("Invalid BIP32 path", nstr)
|
||||
|
||||
|
||||
def normalize_nfc(txt):
|
||||
'''
|
||||
"""
|
||||
Normalize message to NFC and return bytes suitable for protobuf.
|
||||
This seems to be bitcoin-qt standard of doing things.
|
||||
'''
|
||||
"""
|
||||
if isinstance(txt, bytes):
|
||||
txt = txt.decode('utf-8')
|
||||
return unicodedata.normalize('NFC', txt).encode('utf-8')
|
||||
txt = txt.decode("utf-8")
|
||||
return unicodedata.normalize("NFC", txt).encode("utf-8")
|
||||
|
||||
|
||||
class CallException(Exception):
|
||||
@ -190,7 +190,9 @@ class expect:
|
||||
def wrapped_f(*args, **kwargs):
|
||||
ret = f(*args, **kwargs)
|
||||
if not isinstance(ret, self.expected):
|
||||
raise RuntimeError("Got %s, expected %s" % (ret.__class__, self.expected))
|
||||
raise RuntimeError(
|
||||
"Got %s, expected %s" % (ret.__class__, self.expected)
|
||||
)
|
||||
if self.field is not None:
|
||||
return getattr(ret, self.field)
|
||||
else:
|
||||
@ -204,11 +206,12 @@ def session(f):
|
||||
# with session activation / deactivation
|
||||
@functools.wraps(f)
|
||||
def wrapped_f(*args, **kwargs):
|
||||
__tracebackhide__ = True # pytest traceback hiding - this function won't appear in tracebacks
|
||||
__tracebackhide__ = True # for pytest # pylint: disable=W0612
|
||||
client = args[0]
|
||||
client.transport.session_begin()
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
finally:
|
||||
client.transport.session_end()
|
||||
|
||||
return wrapped_f
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user