def test_publickey(self): for sk, pk in self.vectors: sk = hex(sk)[2:] if len(sk) < 64: sk = '0' * (64 - len(sk)) + sk pk = pk.lower() pk65 = hexlify(secp256k1.publickey(unhexlify(sk), False)).decode('ascii') # uncompressed self.assertEqual(str(pk65), '04' + pk) pk33 = hexlify(secp256k1.publickey(unhexlify(sk))).decode('ascii') if pk[-1] in '02468ace': self.assertEqual(pk33, '02' + pk[:64]) else: self.assertEqual(pk33, '03' + pk[:64])
def test_slip77(self): seed = bip39.seed( "alcohol woman abuse must during monitor noble actual mixed trade anger aisle", "") keychain = Keychain(seed, [["slip21", b"SLIP-0077"], ["secp256k1"]]) node = keychain.derive( [44 | HARDENED, 1 | HARDENED, 0 | HARDENED, 0, 0]) coin = coins.by_name('Elements') pubkey_hash = addresses.ecdsa_hash_pubkey(node.public_key(), coin) script = scripts.output_script_p2pkh(pubkey_hash) private_key = keychain.derive_slip77_blinding_private_key(script) self.assertEqual( private_key, unhexlify( b"26f1dc2c52222394236d76e0809516255cfcca94069fd5187c0f090d18f42ad6" )) public_key = keychain.derive_slip77_blinding_public_key(script) self.assertEqual( public_key, unhexlify( b"03e84cd853fea825bd94f5d2d46580ae0d059c734707fa7a08f5e2f612a51c1acb" )) self.assertEqual(secp256k1.publickey(private_key), public_key)
def test_sign_verify_random(self): for _ in range(100): sk = secp256k1.generate_secret() pk = secp256k1.publickey(sk) dig = random.bytes(32) sig = secp256k1.sign(sk, dig) self.assertTrue(secp256k1.verify(pk, sig, dig))
async def 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, address_n): break if await show_qr(ctx, hex_addr): break return EthereumAddress(address=address)
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:]).digest(True)[12:] # Keccak if msg.show_display: network = networks.by_slip44(address_n[1] & 0x7fffffff) 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)
def test_verify_recover(self): for compressed in [False, True]: for _ in range(100): sk = secp256k1.generate_secret() pk = secp256k1.publickey(sk, compressed) dig = random.bytes(32) sig = secp256k1.sign(sk, dig, compressed) pk2 = secp256k1.verify_recover(sig, dig) self.assertEqual(pk, pk2)
def test_privkey_to_address(self): #source of test data - binance javascript SDK privkey = "90335b9d2153ad1a9799a3ccc070bd64b4164e9642ee1dd48053c33f9a3a05e9" expected_address = "tbnb1hgm0p7khfk85zpz5v0j8wnej3a90w709zzlffd" pubkey = secp256k1.publickey(unhexlify(privkey), True) address = address_from_public_key(pubkey, "tbnb") self.assertEqual(address, expected_address)
def test_sign_verify_min_max(self): sk = secp256k1.generate_secret() pk = secp256k1.publickey(sk) dig = bytes([1] + [0] * 31) sig = secp256k1.sign(sk, dig) self.assertTrue(secp256k1.verify(pk, sig, dig)) dig = bytes([0] * 31 + [1]) sig = secp256k1.sign(sk, dig) self.assertTrue(secp256k1.verify(pk, sig, dig)) dig = bytes([0xFF] * 32) sig = secp256k1.sign(sk, dig) self.assertTrue(secp256k1.verify(pk, sig, dig))
async def get_address(ctx, msg): address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n) seckey = node.private_key() public_key = secp256k1.publickey(seckey, False) address = get_address_from_public_key(public_key[:65]) if msg.show_display: while True: if await show_address(ctx, address): break if await show_qr(ctx, address): break return TronAddress(address=address)
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)
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)
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, 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)
async def sign_tx(ctx, msg: TronSignTx): """Parse and sign TRX transaction""" validate(msg) address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n) seckey = node.private_key() public_key = secp256k1.publickey(seckey, False) address = get_address_from_public_key(public_key[:65]) try: await _require_confirm_by_type(ctx, msg, address) except AttributeError: raise wire.DataError("The transaction has invalid asset data field") raw_data = serialize(msg, address) data_hash = sha256(raw_data).digest() signature = secp256k1.sign(seckey, data_hash, False) signature = signature[1:65] + bytes([~signature[0] & 0x01]) return TronSignedTx(signature=signature, serialized_tx=raw_data)
async def sign_tx(ctx, msg, keychain): msg = sanitize(msg) #TODO refine `sanitize` to support more fields check(msg) #TODO refine check to support ~ await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE) node = keychain.derive(msg.address_n) seckey = node.private_key() public_key = secp256k1.publickey(seckey, False) # uncompressed sender_address = sha3_256(public_key[1:], keccak=True).digest()[12:] recipient = address.bytes_from_address(msg.to) # TODO- check sender and real sender addr value = int.from_bytes(msg.value, "big") await require_confirm_tx(ctx, recipient, value, msg.chain_id, None, msg.tx_type) # TODO if fee delegation tx? -> require_confirm_fee_delegation await require_confirm_fee( ctx, value, int.from_bytes(msg.gas_price, "big"), int.from_bytes(msg.gas_limit, "big"), msg.chain_id, msg.fee_ratio, None, msg.tx_type, ) data_total = msg.data_length data = bytearray() data += msg.data_initial_chunk data_left = data_total - len(msg.data_initial_chunk) total_length = get_total_length(msg, data_total) print("total length: ", total_length) sha = HashWriter(sha3_256(keccak=True)) if msg.tx_type is None: sha.extend(rlp.encode_length(total_length, True)) # total length for field in (msg.nonce, msg.gas_price, msg.gas_limit, recipient, 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)) if msg.chain_id: sha.extend(rlp.encode(msg.chain_id)) sha.extend(rlp.encode(0)) sha.extend(rlp.encode(0)) else: basic_type = to_basic_type(msg.tx_type) attributes = [msg.tx_type, msg.nonce, msg.gas_price, msg.gas_limit] # TxTypeValueTransfer(0x08) if basic_type == 0x08: attributes += [recipient, msg.value, sender_address] if to_fee_type(msg.tx_type) == TX_TYPE_PARTIAL_FEE_DELEGATION: attributes.append(msg.fee_ratio) # TxTypeValueTransferMemo(0x10), TxTypeSmartContractExecution(0x30) elif basic_type == 0x10 or basic_type == 0x30: attributes += [recipient, msg.value, sender_address, data] if to_fee_type(msg.tx_type) == TX_TYPE_PARTIAL_FEE_DELEGATION: attributes.append(msg.fee_ratio) # TxTypeSmartContractDeploy(0x28) elif basic_type == 0x28: human_readable = 0x00 if msg.human_readable: human_readable = 0x01 attributes += [ recipient, msg.value, sender_address, data, human_readable ] if to_fee_type(msg.tx_type) == TX_TYPE_PARTIAL_FEE_DELEGATION: attributes.append(msg.fee_ratio) attributes.append(msg.code_format) # TxTypeCancel(0x38) elif basic_type == 0x38: attributes.append(sender_address) if to_fee_type(msg.tx_type) == TX_TYPE_PARTIAL_FEE_DELEGATION: attributes.append(msg.fee_ratio) # not supported tx type else: raise wire.DataError("Not supported transaction type") encoded_out = rlp.encode(attributes) sha.extend(rlp.encode([encoded_out, msg.chain_id, 0, 0], True)) digest = sha.get_digest() result = sign_digest(msg, keychain, digest) return result
def _get_public_key(node: bip32.HDNode) -> Tuple[str, bytes]: seckey = node.private_key() public_key = secp256k1.publickey(seckey, True) wif = public_key_to_wif(public_key) return wif, public_key
def _get_public_key(node): seckey = node.private_key() public_key = secp256k1.publickey(seckey, True) wif = _public_key_to_wif(public_key) return wif, public_key
def derive_slip77_blinding_public_key(self, script: bytes) -> bytes: private_key = self.derive_slip77_blinding_private_key(script) return secp256k1.publickey(private_key)