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.
93 lines
3.1 KiB
93 lines
3.1 KiB
4 years ago
|
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)
|