def test_authorize_ownership_proof(self): msg = GetOwnershipProof( address_n=[H_(84), H_(0), H_(0), 1, 2], coin_name=self.coin.coin_name, script_type=InputScriptType.SPENDWITNESS, user_confirmation=True, commitment_data=b"www.example.com" + int.to_bytes(1, _ROUND_ID_LEN, "big"), ) self.assertTrue(self.authorization.check_get_ownership_proof(msg))
def test_ownership_proof_wrong_round_id(self): # Wrong round ID length. msg = GetOwnershipProof( address_n=[H_(84), H_(0), H_(0), 1, 2], coin_name=self.coin.coin_name, script_type=InputScriptType.SPENDWITNESS, user_confirmation=True, commitment_data=b"www.example.com" + int.to_bytes(1, _ROUND_ID_LEN - 1, "big"), ) self.assertFalse(self.authorization.check_get_ownership_proof(msg)) msg = GetOwnershipProof( address_n=[H_(84), H_(0), H_(0), 1, 2], coin_name=self.coin.coin_name, script_type=InputScriptType.SPENDWITNESS, user_confirmation=True, commitment_data=b"www.example.com" + int.to_bytes(1, _ROUND_ID_LEN + 1, "big"), ) self.assertFalse(self.authorization.check_get_ownership_proof(msg))
async def get_ownership_proof( ctx: wire.Context, msg: GetOwnershipProof, keychain: Keychain, coin: CoinInfo, authorization: Optional[CoinJoinAuthorization] = None, ) -> OwnershipProof: if authorization: if not authorization.check_get_ownership_proof(msg): raise wire.ProcessError("Unauthorized operation") else: await validate_path( ctx, keychain, msg.address_n, validate_path_against_script_type(coin, msg), ) 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 and not authorization: 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)
async def get_ownership_proof( ctx: wire.Context, msg: GetOwnershipProof, keychain: Keychain, coin: CoinInfo, authorization: CoinJoinAuthorization | None = None, ) -> OwnershipProof: if authorization: if not authorization.check_get_ownership_proof(msg): raise wire.ProcessError("Unauthorized operation") else: await validate_path( ctx, keychain, msg.address_n, validate_path_against_script_type(coin, msg), ) 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 and not authorization: if not msg.commitment_data: await confirm_action( ctx, "confirm_ownership_proof", title="Proof of ownership", description="Do you want to create a proof of ownership?", ) else: await confirm_hex( ctx, "confirm_ownership_proof", title="Proof of ownership", description="Do you want to create a proof of ownership for:", data=hexlify(msg.commitment_data).decode(), icon=ui.ICON_CONFIG, icon_color=ui.ORANGE_ICON, truncate_middle=True, ) 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)