def test_decode_check(self): for a, b in self.vectors: self.assertEqual(base58.decode_check(b), unhexlify(a)) for a, b in self.vectors_graphene: self.assertEqual( base58.decode_check(b, digestfunc=digestfunc_graphene), unhexlify(a))
async def layout_verify_message(ctx, msg): from trezor.messages.Success import Success from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import ripemd160, sha256 from trezor.crypto import base58 from ..common import address_type from ..common import coins from ..common.signverify import message_digest coin_name = msg.coin_name or 'Bitcoin' coin = coins.by_name(coin_name) digest = message_digest(coin, msg.message) pubkey = secp256k1.verify_recover(msg.signature, digest) if not pubkey: raise ValueError('Invalid signature') raw_address = base58.decode_check(msg.address) at, pkh = address_type.split(coin, raw_address) pkh2 = ripemd160(sha256(pubkey).digest()).digest() if pkh != pkh2: 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 output_derive_script(address: str, coin: CoinInfo) -> bytes: if coin.bech32_prefix and address.startswith(coin.bech32_prefix): # p2wpkh or p2wsh witprog = common.decode_bech32_address(coin.bech32_prefix, address) return output_script_native_p2wpkh_or_p2wsh(witprog) if (not utils.BITCOIN_ONLY and coin.cashaddr_prefix is not None and address.startswith(coin.cashaddr_prefix + ":")): prefix, addr = address.split(":") version, data = cashaddr.decode(prefix, addr) if version == cashaddr.ADDRESS_TYPE_P2KH: version = coin.address_type elif version == cashaddr.ADDRESS_TYPE_P2SH: version = coin.address_type_p2sh else: raise wire.DataError("Unknown cashaddr address type") raw_address = bytes([version]) + data else: try: raw_address = base58.decode_check(address, coin.b58_hash) except ValueError: raise wire.DataError("Invalid address") if address_type.check(coin.address_type, raw_address): # p2pkh pubkeyhash = address_type.strip(coin.address_type, raw_address) script = output_script_p2pkh(pubkeyhash) return script elif address_type.check(coin.address_type_p2sh, raw_address): # p2sh scripthash = address_type.strip(coin.address_type_p2sh, raw_address) script = output_script_p2sh(scripthash) return script raise wire.DataError("Invalid address type")
def output_derive_script(o: TxOutputType, coin: CoinInfo, root: bip32.HDNode) -> bytes: if o.script_type == OutputScriptType.PAYTOOPRETURN: # op_return output if o.amount != 0: raise SigningError( FailureType.DataError, "OP_RETURN output with non-zero amount" ) return output_script_paytoopreturn(o.op_return_data) if o.address_n: # change output if o.address: raise SigningError(FailureType.DataError, "Address in change output") o.address = get_address_for_change(o, coin, root) else: if not o.address: raise SigningError(FailureType.DataError, "Missing address") if coin.bech32_prefix and o.address.startswith(coin.bech32_prefix): # p2wpkh or p2wsh witprog = decode_bech32_address(coin.bech32_prefix, o.address) return output_script_native_p2wpkh_or_p2wsh(witprog) if coin.cashaddr_prefix is not None and o.address.startswith( coin.cashaddr_prefix + ":" ): prefix, addr = o.address.split(":") version, data = cashaddr.decode(prefix, addr) if version == cashaddr.ADDRESS_TYPE_P2KH: version = coin.address_type elif version == cashaddr.ADDRESS_TYPE_P2SH: version = coin.address_type_p2sh else: raise ValueError("Unknown cashaddr address type") raw_address = bytes([version]) + data else: raw_address = base58.decode_check(o.address, coin.b58_hash) if address_type.check(coin.address_type, raw_address): # p2pkh pubkeyhash = address_type.strip(coin.address_type, raw_address) script = output_script_p2pkh(pubkeyhash) if coin.bip115: script += script_replay_protection_bip115( o.block_hash_bip115, o.block_height_bip115 ) return script elif address_type.check(coin.address_type_p2sh, raw_address): # p2sh scripthash = address_type.strip(coin.address_type_p2sh, raw_address) script = output_script_p2sh(scripthash) if coin.bip115: script += script_replay_protection_bip115( o.block_hash_bip115, o.block_height_bip115 ) return script raise SigningError(FailureType.DataError, "Invalid address type")
def output_derive_script(o: TxOutputType, coin: CoinType, root) -> bytes: if o.script_type == OutputScriptType.PAYTOOPRETURN: if o.amount != 0: raise SigningError(FailureType.DataError, 'OP_RETURN output with non-zero amount') return output_script_paytoopreturn(o.op_return_data) if o.address_n: # change output if o.address: raise SigningError(FailureType.DataError, 'Address in change output') o.address = get_address_for_change(o, coin, root) else: if not o.address: raise SigningError(FailureType.DataError, 'Missing address') if coin.bech32_prefix and o.address.startswith( coin.bech32_prefix): # p2wpkh or p2wsh witprog = decode_bech32_address(coin.bech32_prefix, o.address) return output_script_native_p2wpkh_or_p2wsh(witprog) raw_address = base58.decode_check(o.address) if address_type.check(coin.address_type, raw_address): # p2pkh pubkeyhash = address_type.strip(coin.address_type, raw_address) return output_script_p2pkh(pubkeyhash) elif address_type.check(coin.address_type_p2sh, raw_address): # p2sh scripthash = address_type.strip(coin.address_type_p2sh, raw_address) return output_script_p2sh(scripthash) raise SigningError(FailureType.DataError, 'Invalid address type')
def output_paytoaddress_extract_raw_address( o: TxOutputType, coin: CoinType, root, p2sh: bool=False) -> bytes: addr_type = coin.address_type_p2sh if p2sh else coin.address_type # TODO: dont encode/decode more then necessary if o.address_n is not None: node = node_derive(root, o.address_n) address = node.address(addr_type) return base58.decode_check(address) if o.address: raw = base58.decode_check(o.address) if not address_type.check(addr_type, raw): raise SigningError(FailureType.SyntaxError, 'Invalid address type') return raw raise SigningError(FailureType.SyntaxError, 'Missing address')
def address_to_script_type(address: str, coin: CoinInfo) -> InputScriptType: # Determines the script type from a non-multisig address. if coin.bech32_prefix and address.startswith(coin.bech32_prefix): witver, _ = common.decode_bech32_address(coin.bech32_prefix, address) if witver == 0: return InputScriptType.SPENDWITNESS elif witver == 1: return InputScriptType.SPENDTAPROOT else: raise wire.DataError("Invalid address") if (not utils.BITCOIN_ONLY and coin.cashaddr_prefix is not None and address.startswith(coin.cashaddr_prefix + ":")): return InputScriptType.SPENDADDRESS try: raw_address = base58.decode_check(address, coin.b58_hash) except ValueError: raise wire.DataError("Invalid address") if address_type.check(coin.address_type, raw_address): # p2pkh return InputScriptType.SPENDADDRESS elif address_type.check(coin.address_type_p2sh, raw_address): # p2sh return InputScriptType.SPENDP2SHWITNESS raise wire.DataError("Invalid address")
def address_to_cashaddr(address: str, coin: CoinInfo) -> str: raw = base58.decode_check(address, coin.b58_hash) version, data = raw[0], raw[1:] if version == coin.address_type: version = cashaddr.ADDRESS_TYPE_P2KH elif version == coin.address_type_p2sh: version = cashaddr.ADDRESS_TYPE_P2SH else: raise ValueError("Unknown cashaddr address type") return cashaddr.encode(coin.cashaddr_prefix, version, data)
def output_script_sstxchange(addr: str) -> bytearray: try: raw_address = base58.decode_check(addr, blake256d_32) except ValueError: raise wire.DataError("Invalid address") w = utils.empty_bytearray(26) w.append(0xBD) # OP_SSTXCHANGE scripts.write_output_script_p2pkh(w, raw_address[2:]) return w
def output_derive_script( o: TxOutputType, coin: coininfo.CoinInfo, keychain: seed.Keychain ) -> bytes: if o.script_type == OutputScriptType.PAYTOOPRETURN: return scripts.output_script_paytoopreturn(o.op_return_data) if o.address_n: # change output o.address = get_address_for_change(o, coin, keychain) if coin.bech32_prefix and o.address.startswith(coin.bech32_prefix): # p2wpkh or p2wsh witprog = addresses.decode_bech32_address(coin.bech32_prefix, o.address) return scripts.output_script_native_p2wpkh_or_p2wsh(witprog) if ( not utils.BITCOIN_ONLY and coin.cashaddr_prefix is not None and o.address.startswith(coin.cashaddr_prefix + ":") ): prefix, addr = o.address.split(":") version, data = cashaddr.decode(prefix, addr) if version == cashaddr.ADDRESS_TYPE_P2KH: version = coin.address_type elif version == cashaddr.ADDRESS_TYPE_P2SH: version = coin.address_type_p2sh else: raise SigningError("Unknown cashaddr address type") raw_address = bytes([version]) + data else: try: raw_address = base58.decode_check(o.address, coin.b58_hash) except ValueError: raise SigningError(FailureType.DataError, "Invalid address") if address_type.check(coin.address_type, raw_address): # p2pkh pubkeyhash = address_type.strip(coin.address_type, raw_address) script = scripts.output_script_p2pkh(pubkeyhash) return script elif address_type.check(coin.address_type_p2sh, raw_address): # p2sh scripthash = address_type.strip(coin.address_type_p2sh, raw_address) script = scripts.output_script_p2sh(scripthash) return script raise SigningError(FailureType.DataError, "Invalid address type")
def output_script_sstxchange(addr: str) -> bytearray: try: raw_address = base58.decode_check(addr, blake256d_32) except ValueError: raise wire.DataError("Invalid address") w = utils.empty_bytearray(26) w.append(0xBD) # OP_SSTXCHANGE w.append(0x76) # OP_DUP w.append(0xA9) # OP_HASH160 w.append(0x14) # OP_DATA_20 write_bytes_fixed(w, raw_address[2:], 20) w.append(0x88) # OP_EQUALVERIFY w.append(0xAC) # OP_CHECKSIG return w
def test_valid_address(self): # b58 -> cashaddr for b58, ca in VALID_ADDRESS: data = base58.decode_check(b58) version = data[0] if version == 5: version = 8 enc = cashaddr.encode('bitcoincash', version, data[1:]) self.assertEqual(ca, enc) # cashaddr -> base58 for b58, ca in VALID_ADDRESS: prefix, addr = ca.split(':') version, data = cashaddr.decode(prefix, addr) if version == 8: version = 5 enc = base58.encode_check(bytes([version]) + data) self.assertEqual(b58, enc)
async def verify_message(ctx, msg): message = msg.message address = msg.address signature = msg.signature coin_name = msg.coin_name or 'Bitcoin' coin = coins.by_name(coin_name) await confirm_verify_message(ctx, message) digest = message_digest(coin, message) pubkey = secp256k1.verify_recover(signature, digest) if not pubkey: raise wire.FailureError(ProcessError, 'Invalid signature') raw_address = base58.decode_check(address) _, pkh = address_type.split(coin, raw_address) pkh2 = ripemd160(sha256(pubkey).digest()).digest() if pkh != pkh2: raise wire.FailureError(ProcessError, 'Invalid signature') return Success(message='Message verified')
def pack_contract(contract, owner_address): """ Pack Tron Proto3 Contract See: https://github.com/tronprotocol/protocol/blob/master/core/Tron.proto and https://github.com/tronprotocol/protocol/blob/master/core/Contract.proto """ retc = bytearray() add_field(retc, 1, TYPE_VARINT) # contract message cmessage = bytearray() if contract.transfer_contract: write_varint(retc, 1) api = "TransferContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, bytes(contract.transfer_contract.to_address)) add_field(cmessage, 3, TYPE_VARINT) write_varint(cmessage, contract.transfer_contract.amount) if contract.transfer_asset_contract: write_varint(retc, 2) api = "TransferAssetContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, contract.transfer_asset_contract.asset_name) add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 3, TYPE_STRING) write_bytes_with_length( cmessage, bytes(contract.transfer_asset_contract.to_address) ) add_field(cmessage, 4, TYPE_VARINT) write_varint(cmessage, contract.transfer_asset_contract.amount) if contract.vote_witness_contract: write_varint(retc, 4) api = "VoteWitnessContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) # vote list for i in range(len(contract.vote_witness_contract.votes)): vote = bytearray() add_field(vote, 1, TYPE_STRING) write_bytes_with_length( vote, bytes(contract.vote_witness_contract.votes[i].vote_address) ) add_field(vote, 2, TYPE_VARINT) write_varint(vote, contract.vote_witness_contract.votes[i].vote_count) # add to buffer add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, vote) if contract.witness_create_contract: write_varint(retc, 5) api = "WitnessCreateContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, contract.witness_create_contract.url) if contract.asset_issue_contract: write_varint(retc, 6) api = "AssetIssueContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, contract.asset_issue_contract.name) add_field(cmessage, 3, TYPE_STRING) write_bytes_with_length(cmessage, contract.asset_issue_contract.abbr) add_field(cmessage, 4, TYPE_VARINT) write_varint(cmessage, contract.asset_issue_contract.total_supply) # asset frozen list for i in range(len(contract.asset_issue_contract.frozen_supply)): listarr = bytearray() add_field(listarr, 1, TYPE_VARINT) write_varint( listarr, contract.asset_issue_contract.frozen_supply[i].frozen_amount ) add_field(listarr, 2, TYPE_VARINT) write_varint( listarr, contract.asset_issue_contract.frozen_supply[i].frozen_days ) # add to vote list add_field(cmessage, 5, TYPE_STRING) write_bytes_with_length(cmessage, listarr) add_field(cmessage, 6, TYPE_VARINT) write_varint(cmessage, contract.asset_issue_contract.trx_num) add_field(cmessage, 8, TYPE_VARINT) write_varint(cmessage, contract.asset_issue_contract.num) add_field(cmessage, 9, TYPE_VARINT) write_varint(cmessage, contract.asset_issue_contract.start_time) add_field(cmessage, 10, TYPE_VARINT) write_varint(cmessage, contract.asset_issue_contract.end_time) add_field(cmessage, 20, TYPE_STRING) write_bytes_with_length(cmessage, contract.asset_issue_contract.description) add_field(cmessage, 21, TYPE_STRING) write_bytes_with_length(cmessage, contract.asset_issue_contract.url) if contract.witness_update_contract: write_varint(retc, 8) api = "WitnessUpdateContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 12, TYPE_STRING) write_bytes_with_length(cmessage, contract.witness_update_contract.update_url) if contract.participate_asset_issue_contract: write_varint(retc, 9) api = "ParticipateAssetIssueContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length( cmessage, bytes(contract.participate_asset_issue_contract.to_address) ) add_field(cmessage, 3, TYPE_STRING) write_bytes_with_length( cmessage, contract.participate_asset_issue_contract.asset_name ) add_field(cmessage, 4, TYPE_VARINT) write_varint(cmessage, contract.participate_asset_issue_contract.amount) if contract.account_update_contract: write_varint(retc, 10) api = "AccountUpdateContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, contract.account_update_contract.account_name) add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) if contract.freeze_balance_contract: write_varint(retc, 11) api = "FreezeBalanceContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_VARINT) write_varint(cmessage, contract.freeze_balance_contract.frozen_balance) add_field(cmessage, 3, TYPE_VARINT) write_varint(cmessage, contract.freeze_balance_contract.frozen_duration) if contract.unfreeze_balance_contract: write_varint(retc, 12) api = "UnfreezeBalanceContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) if contract.withdraw_balance_contract: write_varint(retc, 13) api = "WithdrawBalanceContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) if contract.unfreeze_asset_contract: write_varint(retc, 14) api = "UnfreezeAssetContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) if contract.update_asset_contract: write_varint(retc, 15) api = "UpdateAssetContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, contract.update_asset_contract.description) add_field(cmessage, 3, TYPE_STRING) write_bytes_with_length(cmessage, contract.update_asset_contract.url) if contract.proposal_create_contract: write_varint(retc, 16) api = "ProposalCreateContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) # Parameters list for i in range(len(contract.proposal_create_contract.parameters)): pair = bytearray() add_field(pair, 1, TYPE_VARINT) write_varint(pair, contract.proposal_create_contract.parameters[i].key) add_field(pair, 2, TYPE_VARINT) write_varint(pair, contract.proposal_create_contract.parameters[i].value) # add to buffer add_field(cmessage, 2, TYPE_STRING) write_bytes_with_length(cmessage, pair) if contract.proposal_approve_contract: write_varint(retc, 17) api = "ProposalApproveContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_VARINT) write_varint(cmessage, contract.proposal_approve_contract.proposal_id) add_field(cmessage, 3, TYPE_VARINT) write_varint(cmessage, contract.proposal_approve_contract.is_add_approval) if contract.proposal_delete_contract: write_varint(retc, 18) api = "ProposalDeleteContract" add_field(cmessage, 1, TYPE_STRING) write_bytes_with_length(cmessage, base58.decode_check(owner_address)) add_field(cmessage, 2, TYPE_VARINT) write_varint(cmessage, contract.proposal_delete_contract.proposal_id) # write API capi = bytearray() add_field(capi, 1, TYPE_STRING) write_bytes_with_length(capi, "type.googleapis.com/protocol." + api) # extend to capi add_field(capi, 2, TYPE_STRING) write_bytes_with_length(capi, cmessage) # extend to contract add_field(retc, 2, TYPE_STRING) write_bytes_with_length(retc, capi) return retc
def base58_decode_check(enc, prefix=None): decoded = base58.decode_check(enc) if prefix is not None: decoded = decoded[len(TEZOS_PREFIX_BYTES[prefix]):] return decoded
def base58_decode_check(enc: str, prefix: str | None = None) -> bytes: decoded = base58.decode_check(enc) if prefix is not None: decoded = decoded[len(TEZOS_PREFIX_BYTES[prefix]) :] return decoded