async def ethereum_get_address(ctx, msg): from trezor.messages.EthereumAddress import EthereumAddress from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import sha3_256 from apps.common import seed address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n) seckey = node.private_key() public_key = secp256k1.publickey(seckey, False) # uncompressed address = sha3_256(public_key[1:], keccak=True).digest()[12:] if msg.show_display: if len(address_n) > 1: # path has slip44 network identifier network = networks.by_slip44(address_n[1] & 0x7fffffff) else: network = None hex_addr = _ethereum_address_hex(address, network) while True: if await show_address(ctx, hex_addr): break if await show_qr(ctx, hex_addr): break return EthereumAddress(address=address)
async def ethereum_verify_message(ctx, msg): from .sign_message import message_digest from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import sha3_256 from trezor import ui from trezor.messages.Success import Success digest = message_digest(msg.message) sig = bytearray([msg.signature[64]]) + msg.signature[:64] pubkey = secp256k1.verify_recover(sig, digest) if not pubkey: raise ValueError('Invalid signature') pkh = sha3_256(pubkey[1:]).digest(True)[-20:] if msg.address != pkh: raise ValueError('Invalid signature') ui.display.clear() ui.display.text(10, 30, 'Verifying message', ui.BOLD, ui.LIGHT_GREEN, ui.BG) ui.display.text(10, 60, msg.message, ui.MONO, ui.FG, ui.BG) ui.display.text(10, 80, msg.address, ui.MONO, ui.FG, ui.BG) return Success(message='Message verified')
def address_from_bytes(address_bytes: bytes, network=None) -> str: """ Converts address in bytes to a checksummed string as defined in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md """ from ubinascii import hexlify from trezor.crypto.hashlib import sha3_256 rskip60 = network is not None and network.rskip60 hx = hexlify(address_bytes).decode() prefix = str(network.chain_id) + "0x" if rskip60 else "" hs = sha3_256(prefix + hx, keccak=True).digest() h = "" for i in range(20): l = hx[i * 2] if hs[i] & 0x80 and l >= "a" and l <= "f": l = l.upper() h += l l = hx[i * 2 + 1] if hs[i] & 0x08 and l >= "a" and l <= "f": l = l.upper() h += l return "0x" + h
def message_digest(message): h = HashWriter(sha3_256(keccak=True)) signed_message_header = "\x19Klaytn Signed Message:\n" h.extend(signed_message_header) h.extend(str(len(message))) h.extend(message) return h.get_digest()
def message_digest(message: bytes) -> bytes: h = HashWriter(sha3_256(keccak=True)) signed_message_header = b"\x19Ethereum Signed Message:\n" h.extend(signed_message_header) h.extend(str(len(message)).encode()) h.extend(message) return h.get_digest()
def address_from_bytes(address_bytes: bytes, network: NetworkInfo | None = None) -> str: """ Converts address in bytes to a checksummed string as defined in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md """ from trezor.crypto.hashlib import sha3_256 if network is not None and network.rskip60: prefix = str(network.chain_id) + "0x" else: prefix = "" address_hex = hexlify(address_bytes).decode() digest = sha3_256((prefix + address_hex).encode(), keccak=True).digest() def maybe_upper(i: int) -> str: """Uppercase i-th letter only if the corresponding nibble has high bit set.""" digest_byte = digest[i // 2] hex_letter = address_hex[i] if i % 2 == 0: # even letter -> high nibble bit = 0x80 else: # odd letter -> low nibble bit = 0x08 if digest_byte & bit: return hex_letter.upper() else: return hex_letter return "0x" + "".join(maybe_upper(i) for i in range(len(address_hex)))
def test_nem_transaction_mosaic_creation_with_description(self): # http://chain.nem.ninja/#/mosaic/269c6fda657aba3053a0e5b138c075808cc20e244e1182d9b730798b60a1f77b/0 m = _create_msg( NEM_NETWORK_MAINNET, 26729938, 108000000, 26733538, "jabo38", "red_token", "This token is to celebrate the release of Namespaces and Mosaics " "on the NEM system. This token was the fist ever mosaic created " "other than nem.xem. There are only 10,000 Red Tokens that will " "ever be created. It has no levy and can be traded freely among " "third parties.", 2, 10000, False, True, 0, 0, "", "", "", "NBMOSAICOD4F54EE5CDMR23CCBGOAM2XSIUX6TRS", 50000000000) t = serialize_mosaic_creation( m.transaction, m.mosaic_creation, unhexlify( "58956ac77951622dc5f1c938affbf017c458e30e6b21ddb5783d38b302531f23" )) self.assertEqual( t, unhexlify( '0140000001000068d2dd97012000000058956ac77951622dc5f1c938affbf017c458e30e6b21ddb5783d38b302531f2300f36f0600000000e2eb9701c80100002000000058956ac77951622dc5f1c938affbf017c458e30e6b21ddb5783d38b302531f2317000000060000006a61626f3338090000007265645f746f6b656e0c0100005468697320746f6b656e20697320746f2063656c656272617465207468652072656c65617365206f66204e616d6573706163657320616e64204d6f7361696373206f6e20746865204e454d2073797374656d2e205468697320746f6b656e207761732074686520666973742065766572206d6f736169632063726561746564206f74686572207468616e206e656d2e78656d2e20546865726520617265206f6e6c792031302c3030302052656420546f6b656e7320746861742077696c6c206576657220626520637265617465642e20497420686173206e6f206c65767920616e642063616e2062652074726164656420667265656c7920616d6f6e6720746869726420706172746965732e04000000150000000c00000064697669736962696c69747901000000321a0000000d000000696e697469616c537570706c790500000031303030301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756500000000280000004e424d4f534149434f443446353445453543444d523233434342474f414d3258534955583654525300743ba40b000000' )) self.assertEqual( hashlib.sha3_256(t, keccak=True).digest(), unhexlify( '269c6fda657aba3053a0e5b138c075808cc20e244e1182d9b730798b60a1f77b' ))
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] pubkey = secp256k1.verify_recover(sig, digest) 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 confirm_signverify(ctx, "ETH", decode_message(msg.message), address=address) return Success(message="Message verified")
def test_nem_transaction_mosaic_creation(self): # http://bob.nem.ninja:8765/#/mosaic/68364353c29105e6d361ad1a42abbccbf419cfc7adb8b74c8f35d8f8bdaca3fa/0 m = _create_msg(NEM_NETWORK_TESTNET, 14070896, 108000000, 14074496, 'gimre.games.pong', 'paddles', 'Paddles for the bong game.\n', 0, 10000, True, True, 0, 0, '', '', '', 'TBMOSAICOD4F54EE5CDMR23CCBGOAM2XSJBR5OLC', 50000000000) t = serialize_mosaic_creation( m.transaction, m.mosaic_creation, unhexlify( '994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324' )) self.assertEqual( t, unhexlify( '014000000100009870b4d60020000000994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd32400f36f060000000080c2d600de00000020000000994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd3241f0000001000000067696d72652e67616d65732e706f6e6707000000706164646c65731b000000506164646c657320666f722074686520626f6e672067616d652e0a04000000150000000c00000064697669736962696c69747901000000301a0000000d000000696e697469616c537570706c79050000003130303030190000000d000000737570706c794d757461626c650400000074727565180000000c0000007472616e7366657261626c650400000074727565000000002800000054424d4f534149434f443446353445453543444d523233434342474f414d3258534a4252354f4c4300743ba40b000000' )) self.assertEqual( hashlib.sha3_256(t, keccak=True).digest(), unhexlify( '68364353c29105e6d361ad1a42abbccbf419cfc7adb8b74c8f35d8f8bdaca3fa' ))
async def sign_tx(ctx: wire.Context, msg: EthereumSignTx, keychain: Keychain) -> EthereumTxRequest: check(msg) await paths.validate_path(ctx, keychain, msg.address_n) # Handle ERC20s token, address_bytes, recipient, value = await handle_erc20(ctx, msg) data_total = msg.data_length await require_confirm_tx(ctx, recipient, value, msg.chain_id, token) if token is None and msg.data_length > 0: await require_confirm_data(ctx, msg.data_initial_chunk, data_total) await require_confirm_fee( ctx, value, int.from_bytes(msg.gas_price, "big"), int.from_bytes(msg.gas_limit, "big"), msg.chain_id, token, ) data = bytearray() data += msg.data_initial_chunk data_left = data_total - len(msg.data_initial_chunk) total_length = get_total_length(msg, data_total) sha = HashWriter(sha3_256(keccak=True)) rlp.write_header(sha, total_length, rlp.LIST_HEADER_BYTE) if msg.tx_type is not None: rlp.write(sha, msg.tx_type) for field in (msg.nonce, msg.gas_price, msg.gas_limit, address_bytes, msg.value): rlp.write(sha, field) if data_left == 0: rlp.write(sha, data) else: rlp.write_header(sha, data_total, rlp.STRING_HEADER_BYTE, data) sha.extend(data) while data_left > 0: resp = await send_request_chunk(ctx, data_left) data_left -= len(resp.data_chunk) sha.extend(resp.data_chunk) # eip 155 replay protection rlp.write(sha, msg.chain_id) rlp.write(sha, 0) rlp.write(sha, 0) digest = sha.get_digest() result = sign_digest(msg, keychain, digest) return result
def test_nem_transaction_mosaic_creation_with_levy(self): # http://bob.nem.ninja:8765/#/mosaic/b2f4a98113ff1f3a8f1e9d7197aa982545297fe0aa3fa6094af8031569953a55/0 m = _create_msg(NEM_NETWORK_TESTNET, 21497248, 108000000, 21500848, "alice.misc", "bar", "Special offer: get one bar extra by bying one foo!", 0, 1000, False, True, 1, 1, "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "nem", "xem", "TBMOSAICOD4F54EE5CDMR23CCBGOAM2XSJBR5OLC", 50000000000) t = serialize_mosaic_creation( m.transaction, m.mosaic_creation, unhexlify( "244fa194e2509ac0d2fbc18779c2618d8c2ebb61c16a3bcbebcf448c661ba8dc" ), ) self.assertEqual( hashlib.sha3_256(t).digest(True), unhexlify( 'b2f4a98113ff1f3a8f1e9d7197aa982545297fe0aa3fa6094af8031569953a55' )) # http://chain.nem.ninja/#/mosaic/e8dc14821dbea4831d9051f86158ef348001447968fc22c01644fdaf2bda75c6/0 m = _create_msg(NEM_NETWORK_MAINNET, 69251020, 20000000, 69337420, "dim", "coin", "DIM COIN", 6, 9000000000, False, True, 2, 10, "NCGGLVO2G3CUACVI5GNX2KRBJSQCN4RDL2ZWJ4DP", "dim", "coin", "NBMOSAICOD4F54EE5CDMR23CCBGOAM2XSIUX6TRS", 500000000) t = serialize_mosaic_creation( m.transaction, m.mosaic_creation, unhexlify( "a1df5306355766bd2f9a64efdc089eb294be265987b3359093ae474c051d7d5a" )) self.assertEqual( t, unhexlify( '0140000001000068ccaf200420000000a1df5306355766bd2f9a64efdc089eb294be265987b3359093ae474c051d7d5a002d3101000000004c0122040c01000020000000a1df5306355766bd2f9a64efdc089eb294be265987b3359093ae474c051d7d5a0f0000000300000064696d04000000636f696e0800000044494d20434f494e04000000150000000c00000064697669736962696c69747901000000361f0000000d000000696e697469616c537570706c790a000000393030303030303030301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c6504000000747275654b00000002000000280000004e4347474c564f32473343554143564935474e58324b52424a5351434e3452444c325a574a3444500f0000000300000064696d04000000636f696e0a00000000000000280000004e424d4f534149434f443446353445453543444d523233434342474f414d325853495558365452530065cd1d00000000' )) self.assertEqual( hashlib.sha3_256(t).digest(True), unhexlify( 'e8dc14821dbea4831d9051f86158ef348001447968fc22c01644fdaf2bda75c6' ))
def test_update(self): x = hashlib.sha3_256() self.assertEqual( x.digest(), unhexlify( 'a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a' )) x = hashlib.sha3_256() x.update(b'abc') self.assertEqual( x.digest(), unhexlify( '3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532' )) x = hashlib.sha3_256() x.update(b'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') self.assertEqual( x.digest(), unhexlify( '41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376' )) x = hashlib.sha3_256() x.update( b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu' ) self.assertEqual( x.digest(), unhexlify( '916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18' )) x = hashlib.sha3_256() for i in range(1000000): x.update(b'a') self.assertEqual( x.digest(), unhexlify( '5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1' )) '''
def test_create_transfer_with_mosaic(self): # http://bob.nem.ninja:8765/#/transfer/3409d9ece28d6296d6d5e220a7e3cb8641a3fb235ffcbd20c95da64f003ace6c m = _create_msg(NEM_NETWORK_TESTNET, 14072100, 194000000, 14075700, 'TBLOODPLWOWMZ2TARX4RFPOSOWLULHXMROBN2WXI', 3000000, 2) t = serialize_transfer( m.transaction, m.transfer, unhexlify( '994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324' ), bytearray('sending you 3 pairs of paddles\n'), False) self.assertEqual( t, unhexlify( '010100000200009824b9d60020000000994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd3248034900b0000000034c7d6002800000054424c4f4f44504c574f574d5a3254415258345246504f534f574c554c48584d524f424e32575849c0c62d000000000027000000010000001f00000073656e64696e6720796f752033207061697273206f6620706164646c65730a02000000' )) serialize_mosaic(t, 'gimre.games.pong', 'paddles', 2) serialize_mosaic(t, 'nem', 'xem', 44000000) self.assertEqual( hashlib.sha3_256(t, keccak=True).digest(), unhexlify( '3409d9ece28d6296d6d5e220a7e3cb8641a3fb235ffcbd20c95da64f003ace6c' )) # http://chain.nem.ninja/#/transfer/882dca18dcbe075e15e0ec5a1d7e6ccd69cc0f1309ffd3fde227bfbc107b3f6e m = _create_msg(NEM_NETWORK_MAINNET, 26730750, 179500000, 26734350, 'NBE223WPKEBHQPCYUC4U4CDUQCRRFMPZLOQLB5OP', 1000000, 1) t = serialize_transfer( m.transaction, m.transfer, unhexlify( 'f85ab43dad059b9d2331ddacc384ad925d3467f03207182e01296bacfb242d01' ), bytearray('enjoy! :)'), False) serialize_mosaic(t, 'imre.g', 'tokens', 1) self.assertEqual( hashlib.sha3_256(t, keccak=True).digest(), unhexlify( '882dca18dcbe075e15e0ec5a1d7e6ccd69cc0f1309ffd3fde227bfbc107b3f6e' ))
def serialize_multisig_signature(common: NEMTransactionCommon, public_key: bytes, inner: bytes, address_public_key: bytes): address = nem.compute_address(address_public_key, common.network) w = write_common(common, bytearray(public_key), NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE) digest = hashlib.sha3_256(inner).digest(True) write_uint32(w, 4 + len(digest)) write_bytes_with_length(w, digest) write_bytes_with_length(w, address) return w
def test_nem_transaction_aggregate_modification(self): # http://bob.nem.ninja:8765/#/aggregate/6a55471b17159e5b6cd579c421e95a4e39d92e3f78b0a55ee337e785a601d3a2 m = _create_msg(NEM_NETWORK_TESTNET, 0, 22000000, 0, 2, 0) t = serialize_aggregate_modification(m.transaction, m.aggregate_modification, unhexlify("462ee976890916e54fa825d26bdd0235f5eb5b6a143c199ab0ae5ee9328e08ce")) serialize_cosignatory_modification(t, 1, unhexlify( "994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324")) serialize_cosignatory_modification(t, 1, unhexlify( "c54d6e33ed1446eedd7f7a80a588dd01857f723687a09200c1917d5524752f8b")) self.assertEqual(hashlib.sha3_256(t).digest(True), unhexlify("6a55471b17159e5b6cd579c421e95a4e39d92e3f78b0a55ee337e785a601d3a2")) # http://chain.nem.ninja/#/aggregate/cc64ca69bfa95db2ff7ac1e21fe6d27ece189c603200ebc9778d8bb80ca25c3c m = _create_msg(NEM_NETWORK_MAINNET, 0, 40000000, 0, 5, 0) t = serialize_aggregate_modification(m.transaction, m.aggregate_modification, unhexlify("f41b99320549741c5cce42d9e4bb836d98c50ed5415d0c3c2912d1bb50e6a0e5")) serialize_cosignatory_modification(t, 1, unhexlify( "1fbdbdde28daf828245e4533765726f0b7790e0b7146e2ce205df3e86366980b")) serialize_cosignatory_modification(t, 1, unhexlify( "f94e8702eb1943b23570b1b83be1b81536df35538978820e98bfce8f999e2d37")) serialize_cosignatory_modification(t, 1, unhexlify( "826cedee421ff66e708858c17815fcd831a4bb68e3d8956299334e9e24380ba8")) serialize_cosignatory_modification(t, 1, unhexlify( "719862cd7d0f4e875a6a0274c9a1738f38f40ad9944179006a54c34724c1274d")) serialize_cosignatory_modification(t, 1, unhexlify( "43aa69177018fc3e2bdbeb259c81cddf24be50eef9c5386db51d82386c41475a")) self.assertEqual(hashlib.sha3_256(t).digest(True), unhexlify("cc64ca69bfa95db2ff7ac1e21fe6d27ece189c603200ebc9778d8bb80ca25c3c"))
def test_create_transfer(self): # http://bob.nem.ninja:8765/#/transfer/0acbf8df91e6a65dc56c56c43d65f31ff2a6a48d06fc66e78c7f3436faf3e74f m = _create_msg(NEM_NETWORK_TESTNET, 0, 0, 0, 'TBGIMRE4SBFRUJXMH7DVF2IBY36L2EDWZ37GVSC4', 50000000000000) t = serialize_transfer(m.transaction, m.transfer, unhexlify('e59ef184a612d4c3c4d89b5950eb57262c69862b2f96e59c5043bf41765c482f')) self.assertEqual(t, unhexlify('01010000010000980000000020000000e59ef184a612d4c3c4d89b5950eb57262c69862b2f96e59c5043bf41765c482f00000000000000000000000028000000544247494d52453453424652554a584d48374456463249425933364c324544575a3337475653433400203d88792d000000000000')) self.assertEqual(hashlib.sha3_256(t).digest(True), unhexlify('0acbf8df91e6a65dc56c56c43d65f31ff2a6a48d06fc66e78c7f3436faf3e74f'))
def address_from_bytes(address_bytes: bytes) -> str: """ Converts address in bytes to a checksummed string as defined in https://github.com/icon-project/icon-sdk-python/blob/d77fbe9bbb26bf96d1e55d4debe85f15f02bcb10/iconsdk/wallet/wallet.py#L177 """ from ubinascii import hexlify from trezor.crypto.hashlib import sha3_256 hx = hexlify(address_bytes).decode() hs = sha3_256(hx, keccak=False).digest() h = hs[:40] return "hx" + h
def test_create_provision_namespace(self): # http://bob.nem.ninja:8765/#/transfer/0acbf8df91e6a65dc56c56c43d65f31ff2a6a48d06fc66e78c7f3436faf3e74f m = _create_msg(NEM_NETWORK_TESTNET, 56999445, 20000000, 57003045, 'gimre', '', 'TAMESPACEWH4MKFMBCVFERDPOOP4FK7MTDJEYP35', 5000000000) t = serialize_provision_namespace(m.transaction, m.provision_namespace, unhexlify('84afa1bbc993b7f5536344914dde86141e61f8cbecaf8c9cefc07391f3287cf5')) self.assertEqual(hashlib.sha3_256(t, keccak=True).digest(), unhexlify('f7cab28da57204d01a907c697836577a4ae755e6c9bac60dcc318494a22debb3')) # http://bob.nem.ninja:8765/#/namespace/7ddd5fe607e1bfb5606e0ac576024c318c8300d237273117d4db32a60c49524d m = _create_msg(NEM_NETWORK_TESTNET, 21496797, 108000000, 21500397, 'misc', 'alice', 'TAMESPACEWH4MKFMBCVFERDPOOP4FK7MTDJEYP35', 5000000000) t = serialize_provision_namespace(m.transaction, m.provision_namespace, unhexlify('244fa194e2509ac0d2fbc18779c2618d8c2ebb61c16a3bcbebcf448c661ba8dc')) self.assertEqual(hashlib.sha3_256(t, keccak=True).digest(), unhexlify('7ddd5fe607e1bfb5606e0ac576024c318c8300d237273117d4db32a60c49524d')) # http://chain.nem.ninja/#/namespace/57071aad93ca125dc231dc02c07ad8610cd243d35068f9b36a7d231383907569 m = _create_msg(NEM_NETWORK_MAINNET, 26699717, 108000000, 26703317, 'sex', '', 'NAMESPACEWH4MKFMBCVFERDPOOP4FK7MTBXDPZZA', 50000000000) t = serialize_provision_namespace(m.transaction, m.provision_namespace, unhexlify('9f3c14f304309c8b72b2821339c4428793b1518bea72d58dd01f19d523518614')) self.assertEqual(hashlib.sha3_256(t, keccak=True).digest(), unhexlify('57071aad93ca125dc231dc02c07ad8610cd243d35068f9b36a7d231383907569'))
def test_create_transfer_with_payload(self): # http://chain.nem.ninja/#/transfer/e90e98614c7598fbfa4db5411db1b331d157c2f86b558fb7c943d013ed9f71cb m = _create_msg(NEM_NETWORK_MAINNET, 0, 0, 0, 'NBT3WHA2YXG2IR4PWKFFMO772JWOITTD2V4PECSB', 5175000000000) t = serialize_transfer(m.transaction, m.transfer, unhexlify('8d07f90fb4bbe7715fa327c926770166a11be2e494a970605f2e12557f66c9b9'), bytearray('Good luck!')) self.assertEqual(hashlib.sha3_256(t).digest(True), unhexlify('e90e98614c7598fbfa4db5411db1b331d157c2f86b558fb7c943d013ed9f71cb'))
async def sign_tx(ctx, msg, keychain): await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE) address_bytes = recipient = address.bytes_from_address(msg.to) value = int.from_bytes(msg.value, "big") recipient = msg.data_initial_chunk[16:36] value = int.from_bytes(msg.data_initial_chunk[36:68], "big") await require_confirm_tx(ctx, recipient, value, msg.chain_id, token, msg.tx_type) data = bytearray() data += msg.data_initial_chunk data_left = data_total - len(msg.data_initial_chunk) total_length = get_total_length(msg, data_total) sha = HashWriter(sha3_256(keccak=True)) sha.extend(rlp.encode_length(total_length, True)) # total length if msg.tx_type is not None: sha.extend(rlp.encode(msg.tx_type)) for field in (msg.nonce, msg.gas_price, msg.gas_limit, address_bytes, msg.value): sha.extend(rlp.encode(field)) if data_left == 0: sha.extend(rlp.encode(data)) else: sha.extend(rlp.encode_length(data_total, False)) sha.extend(rlp.encode(data, False)) while data_left > 0: resp = await send_request_chunk(ctx, data_left) data_left -= len(resp.data_chunk) sha.extend(resp.data_chunk) # eip 155 replay protection if msg.chain_id: sha.extend(rlp.encode(msg.chain_id)) sha.extend(rlp.encode(0)) sha.extend(rlp.encode(0)) digest = sha.get_digest() result = sign_digest(msg, keychain, digest) return result
def serialize_multisig_signature( common: NEMTransactionCommon, public_key: bytes, inner: bytes, address_public_key: bytes, ) -> bytes: w = serialize_tx_common(common, public_key, NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE) digest = hashlib.sha3_256(inner, keccak=True).digest() address = nem.compute_address(address_public_key, common.network) write_uint32_le(w, 4 + len(digest)) write_bytes_with_len(w, digest) write_bytes_with_len(w, address.encode()) return w
def test_create_transfer_with_encrypted_payload(self): # http://chain.nem.ninja/#/transfer/40e89160e6f83d37f7c82defc0afe2c1605ae8c919134570a51dd27ea1bb516c m = _create_msg(NEM_NETWORK_MAINNET, 77229, 30000000, 80829, 'NALICEPFLZQRZGPRIJTMJOCPWDNECXTNNG7QLSG3', 30000000) t = serialize_transfer(m.transaction, m.transfer, unhexlify('f85ab43dad059b9d2331ddacc384ad925d3467f03207182e01296bacfb242d01'), unhexlify('4d9dcf9186967d30be93d6d5404ded22812dbbae7c3f0de501bcd7228cba45bded13000eec7b4c6215fc4d3588168c9218167cec98e6977359153a4132e050f594548e61e0dc61c153f0f53c5e65c595239c9eb7c4e7d48e0f4bb8b1dd2f5ddc'), True) self.assertEqual(hashlib.sha3_256(t).digest(True), unhexlify('40e89160e6f83d37f7c82defc0afe2c1605ae8c919134570a51dd27ea1bb516c'))
async def layout_ethereum_get_address(session_id, msg): from trezor.messages.EthereumAddress import EthereumAddress from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import sha3_256 from ..common import seed node = await seed.get_root(session_id) node.derive_path(msg.address_n or ()) seckey = node.private_key() public_key = secp256k1.publickey(seckey, False) # uncompressed address = sha3_256(public_key[1:]).digest(True)[12:] # Keccak if msg.show_display: await _show_address(session_id, address) return EthereumAddress(address=address)
def test_nem_transaction_aggregate_modification_relative_change(self): # http://bob.nem.ninja:8765/#/aggregate/1fbdae5ba753e68af270930413ae90f671eb8ab58988116684bac0abd5726584 m = _create_msg(NEM_NETWORK_TESTNET, 6542254, 40000000, 6545854, 4, 2) t = serialize_aggregate_modification( m.transaction, m.aggregate_modification, unhexlify( "6bf7849c1eec6a2002995cc457dc00c4e29bad5c88de63f51e42dfdcd7b2131d" ), ) write_cosignatory_modification( t, 1, unhexlify( "5f53d076c8c3ec3110b98364bc423092c3ec2be2b1b3c40fd8ab68d54fa39295" ), ) write_cosignatory_modification( t, 1, unhexlify( "9eb199c2b4d406f64cb7aa5b2b0815264b56ba8fe44d558a6cb423a31a33c4c2" ), ) write_cosignatory_modification( t, 1, unhexlify( "94b2323dab23a3faba24fa6ddda0ece4fbb06acfedd74e76ad9fae38d006882b" ), ) write_cosignatory_modification( t, 1, unhexlify( "d88c6ee2a2cd3929d0d76b6b14ecb549d21296ab196a2b3a4cb2536bcce32e87" ), ) write_minimum_cosignatories(t, 2) self.assertEqual( hashlib.sha3_256(t, keccak=True).digest(), unhexlify( "1fbdae5ba753e68af270930413ae90f671eb8ab58988116684bac0abd5726584" ), )
async def verify_message(ctx, msg): digest = message_digest(msg.message) sig = bytearray([msg.signature[64]]) + msg.signature[:64] pubkey = secp256k1.verify_recover(sig, digest) if not pubkey: raise ValueError("Invalid signature") pkh = sha3_256(pubkey[1:], keccak=True).digest()[-20:] if msg.address != pkh: raise ValueError("Invalid signature") address = "0x" + hexlify(msg.address).decode() await require_confirm_verify_message(ctx, address, msg.message) return Success(message="Message verified")
async def get_address(ctx, msg, keychain): await paths.validate_path(ctx, keychain, 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] & 0x7FFF_FFFF) else: network = None address = address_from_bytes(address_bytes, network) if msg.show_display: desc = address_n_to_str(msg.address_n) await show_address(ctx, address=address, address_qr=address, desc=desc) return EthereumAddress(address=address)
async def get_address(ctx, msg, keychain): await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE) node = keychain.derive(msg.address_n) secret_key = node.private_key() public_key = secp256k1.publickey(secret_key, False) # uncompressed address_bytes = sha3_256(public_key[1:], keccak=False).digest()[12:] address = address_from_bytes(address_bytes) 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 IconAddress(address=address)
def _ethereum_address_hex(address): from ubinascii import hexlify from trezor.crypto.hashlib import sha3_256 hx = hexlify(address).decode() hs = sha3_256(hx).digest(True) h = '' for i in range(20): l = hx[i * 2] if hs[i] & 0x80 and l >= 'a' and l <= 'f': l = l.upper() h += l l = hx[i * 2 + 1] if hs[i] & 0x08 and l >= 'a' and l <= 'f': l = l.upper() h += l return '0x' + h
async def ethereum_verify_message(ctx, msg): digest = message_digest(msg.message) sig = bytearray([msg.signature[64]]) + msg.signature[:64] pubkey = secp256k1.verify_recover(sig, digest) if not pubkey: raise ValueError('Invalid signature') pkh = sha3_256(pubkey[1:]).digest(True)[-20:] if msg.address != pkh: raise ValueError('Invalid signature') address = '0x' + hexlify(msg.address).decode() await require_confirm_verify_message(ctx, address, msg.message) return Success(message='Message verified')
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 = sha3_256(public_key[1:], keccak=True).digest()[12:] if msg.show_display: if len(msg.address_n) > 1: # path has slip44 network identifier network = networks.by_slip44(msg.address_n[1] & 0x7FFFFFFF) else: network = None hex_addr = ethereum_address_hex(address, network) desc = address_n_to_str(msg.address_n) while True: if await show_address(ctx, hex_addr, desc=desc): break if await show_qr(ctx, hex_addr, desc=desc): break return EthereumAddress(address=address)