def test_address_from_bytes_rskip60(self): # https://github.com/rsksmart/RSKIPs/blob/master/IPs/RSKIP60.md rskip60_chain_30 = [ '0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD', '0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359', '0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB', '0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB' ] rskip60_chain_31 = [ '0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd', '0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359', '0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB', '0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB' ] n = NetworkInfo(chain_id=30, slip44=1, shortcut='T', name='T', rskip60=True) for s in rskip60_chain_30: s = s[2:] b = bytes([int(s[i:i + 2], 16) for i in range(0, len(s), 2)]) h = address_from_bytes(b, n) self.assertEqual(h, '0x' + s) n.chain_id = 31 for s in rskip60_chain_31: s = s[2:] b = bytes([int(s[i:i + 2], 16) for i in range(0, len(s), 2)]) h = address_from_bytes(b, n) self.assertEqual(h, '0x' + s)
async def verify_message(ctx, msg): digest = message_digest(msg.message) if len(msg.signature) != 65: raise wire.DataError("Invalid signature") sig = bytearray([msg.signature[64]]) + msg.signature[:64] try: pubkey = secp256k1.verify_recover(sig, digest) except ValueError: raise wire.DataError("Invalid signature") if not pubkey: raise wire.DataError("Invalid signature") pkh = sha3_256(pubkey[1:], keccak=True).digest()[-20:] address_bytes = bytes_from_address(msg.address) if address_bytes != pkh: raise wire.DataError("Invalid signature") address = address_from_bytes(address_bytes) await require_confirm_verify_message(ctx, address, msg.message) return Success(message="Message verified")
async def require_confirm_tx(ctx, to_bytes, value, chain_id, token=None, tx_type=None): if to_bytes: to_str = address_from_bytes(to_bytes, networks.by_chain_id(chain_id)) else: to_str = "new contract?" text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN, new_lines=False) text.bold(format_ethereum_amount(value, token, chain_id, tx_type)) text.normal(ui.GREY, "to", ui.FG) for to_line in split_address(to_str): text.br() text.mono(to_line) # we use SignTx, not ConfirmOutput, for compatibility with T1 await require_confirm(ctx, text, ButtonRequestType.SignTx)
async def sign_message(ctx, msg, keychain): await paths.validate_path(ctx, address.validate_full_path, path=msg.address_n) await require_confirm_sign_message(ctx, msg.message) node = keychain.derive(msg.address_n) signature = secp256k1.sign( node.private_key(), message_digest(msg.message), False, secp256k1.CANONICAL_SIG_ETHEREUM, ) sig = EthereumMessageSignature() sig.address = address.address_from_bytes(node.ethereum_pubkeyhash()) sig.signature = signature[1:] + bytearray([signature[0]]) return sig
def test_address_from_bytes_eip55(self): # https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md eip55 = [ '0x52908400098527886E0F7030069857D2E4169EE7', '0x8617E340B3D01FA5F11F306F4090FD50E238070D', '0xde709f2102306220921060314715629080e2fb77', '0x27b1fdb04752bbc536007a920d24acb045561c26', '0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed', '0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359', '0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB', '0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb', ] for s in eip55: s = s[2:] b = bytes([int(s[i:i + 2], 16) for i in range(0, len(s), 2)]) h = address_from_bytes(b) self.assertEqual(h, '0x' + s)
async def get_address(ctx, msg, keychain): await paths.validate_path(ctx, validate_full_path, path=msg.address_n) node = keychain.derive(msg.address_n) seckey = node.private_key() public_key = secp256k1.publickey(seckey, False) # uncompressed address_bytes = sha3_256(public_key[1:], keccak=True).digest()[12:] if len(msg.address_n) > 1: # path has slip44 network identifier network = networks.by_slip44(msg.address_n[1] & 0x7FFFFFFF) else: network = None address = address_from_bytes(address_bytes, network) if msg.show_display: desc = address_n_to_str(msg.address_n) while True: if await show_address(ctx, address, desc=desc): break if await show_qr(ctx, address, desc=desc): break return EthereumAddress(address)