1
0
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:
matejcik 2018-08-13 18:21:24 +02:00
parent e336f578af
commit 3d3e9b67b4
106 changed files with 8503 additions and 4057 deletions

864
trezorctl

File diff suppressed because it is too large Load Diff

View File

@ -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")

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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"]
}

View File

@ -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,
)
)

View File

@ -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"
)
)

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -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"]

View File

@ -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)

View File

@ -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

View File

@ -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,
)
)

View File

@ -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)

View File

@ -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),
)

View File

@ -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:]

View File

@ -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

View File

@ -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)

View File

@ -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")
)

View File

@ -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

View File

@ -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):

View File

@ -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.

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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"

View File

@ -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"
)

View File

@ -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):

View File

@ -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,
)

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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")

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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",
],
}
}
})
},
},
)

View File

@ -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,
)

View File

@ -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

View File

@ -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"

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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'")

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"

View File

@ -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")

View File

@ -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)

View File

@ -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")

View File

@ -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")

View File

@ -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)

View File

@ -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")

View File

@ -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"

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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

View File

@ -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"
)

View File

@ -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")

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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())

View File

@ -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")

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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"
)

View File

@ -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)

View File

@ -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}
],
}

View File

@ -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 😊"

View File

@ -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]

View File

@ -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)

View File

@ -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"
)

View File

@ -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