You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/bitcoin/get_ownership_proof.py

93 lines
3.1 KiB

from ubinascii import hexlify
from trezor import ui, wire
from trezor.messages.GetOwnershipProof import GetOwnershipProof
from trezor.messages.OwnershipProof import OwnershipProof
from trezor.ui.text import Text
from apps.common import coininfo
from apps.common.confirm import require_confirm
from apps.common.paths import validate_path
from . import addresses, common, scripts
from .keychain import with_keychain
from .ownership import generate_proof, get_identifier
if False:
from apps.common.seed import Keychain
# Maximum number of characters per line in monospace font.
_MAX_MONO_LINE = 18
@with_keychain
async def get_ownership_proof(
ctx, msg: GetOwnershipProof, keychain: Keychain, coin: coininfo.CoinInfo
) -> OwnershipProof:
await validate_path(
ctx,
addresses.validate_full_path,
keychain,
msg.address_n,
coin.curve_name,
coin=coin,
script_type=msg.script_type,
)
if msg.script_type not in common.INTERNAL_INPUT_SCRIPT_TYPES:
raise wire.DataError("Invalid script type")
if msg.script_type in common.SEGWIT_INPUT_SCRIPT_TYPES and not coin.segwit:
raise wire.DataError("Segwit not enabled on this coin")
node = keychain.derive(msg.address_n)
address = addresses.get_address(msg.script_type, coin, node, msg.multisig)
script_pubkey = scripts.output_derive_script(address, coin)
ownership_id = get_identifier(script_pubkey, keychain)
# If the scriptPubKey is multisig, then the caller has to provide
# ownership IDs, otherwise providing an ID is optional.
if msg.multisig:
if ownership_id not in msg.ownership_ids:
raise wire.DataError("Missing ownership identifier")
elif msg.ownership_ids:
if msg.ownership_ids != [ownership_id]:
raise wire.DataError("Invalid ownership identifier")
else:
msg.ownership_ids = [ownership_id]
# In order to set the "user confirmation" bit in the proof, the user must actually confirm.
if msg.user_confirmation:
text = Text("Proof of ownership", ui.ICON_CONFIG)
text.normal("Do you want to create a")
if not msg.commitment_data:
text.normal("proof of ownership?")
else:
hex_data = hexlify(msg.commitment_data).decode()
text.normal("proof of ownership for:")
if len(hex_data) > 3 * _MAX_MONO_LINE:
text.mono(hex_data[0:_MAX_MONO_LINE])
text.mono(
hex_data[_MAX_MONO_LINE : 3 * _MAX_MONO_LINE // 2 - 1]
+ "..."
+ hex_data[-3 * _MAX_MONO_LINE // 2 + 2 : -_MAX_MONO_LINE]
)
text.mono(hex_data[-_MAX_MONO_LINE:])
else:
text.mono(hex_data)
await require_confirm(ctx, text)
ownership_proof, signature = generate_proof(
node,
msg.script_type,
msg.multisig,
coin,
msg.user_confirmation,
msg.ownership_ids,
script_pubkey,
msg.commitment_data,
)
return OwnershipProof(ownership_proof=ownership_proof, signature=signature)