From a82a0b3af202a14be8c14f715d41beb195346b96 Mon Sep 17 00:00:00 2001
From: M1nd3r <petrsedlacek.km@seznam.cz>
Date: Mon, 27 Jan 2025 14:04:51 +0100
Subject: [PATCH] temp: update pairing process, part 1

---
 common/protob/messages-thp.proto              |  114 +-
 core/src/apps/debug/__init__.py               |    4 +-
 core/src/apps/thp/pairing.py                  |  261 ++--
 core/src/trezor/enums/ThpMessageType.py       |   16 +-
 core/src/trezor/enums/ThpPairingMethod.py     |    4 +-
 core/src/trezor/enums/__init__.py             |   20 +-
 core/src/trezor/messages.py                   |   84 +-
 core/src/trezor/wire/thp/__init__.py          |   23 +-
 core/src/trezor/wire/thp/channel.py           |    1 -
 core/src/trezor/wire/thp/cpace.py             |    8 +-
 core/src/trezor/wire/thp/pairing_context.py   |   23 +-
 .../wire/thp/received_message_handler.py      |   12 +-
 core/tests/test_trezor.wire.thp.py            |   10 +-
 python/src/trezorlib/messages.py              |  112 +-
 .../trezorlib/transport/thp/protocol_v2.py    |    2 +-
 .../src/protos/generated/messages_thp.rs      | 1269 +++++++++--------
 16 files changed, 1022 insertions(+), 941 deletions(-)

diff --git a/common/protob/messages-thp.proto b/common/protob/messages-thp.proto
index bfb15edbbc..36e882dcc0 100644
--- a/common/protob/messages-thp.proto
+++ b/common/protob/messages-thp.proto
@@ -13,28 +13,28 @@ option (include_in_bitcoin_only) = true;
  * Mapping between Trezor wire identifier (uint) and a Thp protobuf message
  */
 enum ThpMessageType {
-    reserved 0 to 999; // Values reserved by other messages, see messages.proto
+    reserved 0 to 999;  // Values reserved by other messages, see messages.proto
 
-    ThpMessageType_ThpCreateNewSession = 1000[(bitcoin_only)=true];
-    ThpMessageType_ThpNewSession = 1001[(bitcoin_only)=true];
-    ThpMessageType_ThpStartPairingRequest = 1008 [(bitcoin_only) = true];
+    ThpMessageType_ThpCreateNewSession = 1000 [(bitcoin_only)=true];
+    ThpMessageType_ThpPairingRequest = 1006 [(bitcoin_only) = true];
+    ThpMessageType_ThpPairingRequestAck = 1007 [(bitcoin_only) = true];
+    ThpMessageType_ThpSelectMethod = 1008 [(bitcoin_only) = true];
     ThpMessageType_ThpPairingPreparationsFinished = 1009 [(bitcoin_only) = true];
     ThpMessageType_ThpCredentialRequest = 1010 [(bitcoin_only) = true];
     ThpMessageType_ThpCredentialResponse = 1011 [(bitcoin_only) = true];
     ThpMessageType_ThpEndRequest = 1012 [(bitcoin_only) = true];
-    ThpMessageType_ThpEndResponse = 1013[(bitcoin_only) = true];
-    ThpMessageType_ThpCodeEntryCommitment = 1016[(bitcoin_only)=true];
-    ThpMessageType_ThpCodeEntryChallenge = 1017[(bitcoin_only)=true];
-    ThpMessageType_ThpCodeEntryCpaceHost = 1018[(bitcoin_only)=true];
-    ThpMessageType_ThpCodeEntryCpaceTrezor = 1019[(bitcoin_only)=true];
-    ThpMessageType_ThpCodeEntryTag = 1020[(bitcoin_only)=true];
-    ThpMessageType_ThpCodeEntrySecret = 1021[(bitcoin_only)=true];
-    ThpMessageType_ThpQrCodeTag = 1024[(bitcoin_only)=true];
-    ThpMessageType_ThpQrCodeSecret = 1025[(bitcoin_only)=true];
-    ThpMessageType_ThpNfcUnidirectionalTag = 1032[(bitcoin_only)=true];
-    ThpMessageType_ThpNfcUnidirectionalSecret = 1033[(bitcoin_only)=true];
+    ThpMessageType_ThpEndResponse = 1013 [(bitcoin_only) = true];
+    ThpMessageType_ThpCodeEntryCommitment = 1016 [(bitcoin_only)=true];
+    ThpMessageType_ThpCodeEntryChallenge = 1017 [(bitcoin_only)=true];
+    ThpMessageType_ThpCodeEntryCpaceTrezor = 1018 [(bitcoin_only)=true];
+    ThpMessageType_ThpCodeEntryCpaceHostTag = 1019 [(bitcoin_only)=true];
+    ThpMessageType_ThpCodeEntrySecret = 1020 [(bitcoin_only)=true];
+    ThpMessageType_ThpQrCodeTag = 1024 [(bitcoin_only)=true];
+    ThpMessageType_ThpQrCodeSecret = 1025 [(bitcoin_only)=true];
+    ThpMessageType_ThpNfcTagHost = 1032 [(bitcoin_only)=true];
+    ThpMessageType_ThpNfcTagTrezor = 1033 [(bitcoin_only)=true];
 
-    reserved 1100 to 2147483647; // Values reserved by other messages, see messages.proto
+    reserved 1100 to 2147483647;  // Values reserved by other messages, see messages.proto
 }
 
 
@@ -43,10 +43,10 @@ enum ThpMessageType {
  * @embed
  */
 enum ThpPairingMethod {
-    NoMethod = 1;             // Trust without MITM protection.
+    SkipPairing = 1;          // Trust without MITM protection.
     CodeEntry = 2;            // User types code diplayed on Trezor into the host application.
     QrCode = 3;               // User scans code displayed on Trezor into host application.
-    NFC_Unidirectional = 4;   // Trezor transmits an authentication key to the host device via NFC.
+    NFC = 4;                  // Trezor and host application exchange authentication secrets via NFC.
 }
 
 /**
@@ -55,8 +55,8 @@ enum ThpPairingMethod {
 message ThpDeviceProperties {
     optional string internal_model = 1;               // Internal model name e.g. "T2B1".
     optional uint32 model_variant = 2;                // Encodes the device properties such as color.
-    optional bool bootloader_mode = 3;                // Indicates whether the device is in bootloader or firmware mode.
-    optional uint32 protocol_version = 4;             // The communication protocol version supported by the firmware.
+    optional uint32 protocol_version_major = 3;       // The major version of the communication protocol used by the firmware.
+    optional uint32 protocol_version_minor = 4;       // The minor version of the communication protocol used by the firmware.
     repeated ThpPairingMethod pairing_methods = 5;    // The pairing methods supported by the Trezor.
 }
 
@@ -65,13 +65,11 @@ message ThpDeviceProperties {
  */
 message ThpHandshakeCompletionReqNoisePayload {
     optional bytes host_pairing_credential = 1;       // Host's pairing credential
-    repeated ThpPairingMethod pairing_methods = 2;    // The pairing methods chosen by the host
 }
 
 /**
  * Request: Ask device for a new session with given passphrase.
  * @start
- * @next ThpNewSession
  * @next Success
  */
 message ThpCreateNewSession{
@@ -80,31 +78,41 @@ message ThpCreateNewSession{
     optional bool derive_cardano = 3;  // If True, Cardano keys will be derived. Ignored with BTC-only
 }
 
-/**
- * Response: Contains session_id of the newly created session.
- * @end
- */
-message ThpNewSession{
-    optional uint32 new_session_id = 1;
-}
 
 /**
  * Request: Start pairing process.
  * @start
- * @next ThpCodeEntryCommitment
- * @next ThpPairingPreparationsFinished
+ * @next ThpPairingRequestAck
  */
-message ThpStartPairingRequest{
-    optional string host_name = 1;      // Human-readable host name
+message ThpPairingRequest{
+    optional string host_name = 1;     // Human-readable host name
+}
+
+/**
+ * Response: Host is allowed to start pairing process.
+ * @start
+ * @next ThpSelectMethod
+ */
+message ThpPairingRequestAck{
+}
+
+/**
+ * Request: Start pairing using the method selected.
+ * @start
+ * @next ThpPairingPreparationsFinished
+ * @next ThpCodeEntryCommitment
+ */
+message ThpSelectMethod {
+    optional ThpPairingMethod selected_pairing_method = 1; 
 }
 
 /**
  * Response: Pairing is ready for user input / OOB communication.
  * @next ThpCodeEntryCpace
  * @next ThpQrCodeTag
- * @next ThpNfcUnidirectionalTag
+ * @next ThpNfcTagHost
  */
- message ThpPairingPreparationsFinished{
+message ThpPairingPreparationsFinished{
 }
 
 /**
@@ -117,34 +125,30 @@ message ThpCodeEntryCommitment {
 
 /**
  * Response: Host responds to Trezor's Code Entry commitment with a challenge.
- * @next ThpPairingPreparationsFinished
- */
-message ThpCodeEntryChallenge {
-    optional bytes challenge = 1;      // host's random 32-byte challenge
-}
-
-/**
- * Request: User selected Code Entry option in Host. Host starts CPACE protocol with Trezor.
  * @next ThpCodeEntryCpaceTrezor
  */
-message ThpCodeEntryCpaceHost {
-    optional bytes cpace_host_public_key = 1;    // Host's ephemeral CPace public key
+message ThpCodeEntryChallenge {
+    optional bytes challenge = 1;      // Host's random 32-byte challenge
 }
 
+
+
 /**
  * Response: Trezor continues with the CPACE protocol.
- * @next ThpCodeEntryTag
+ * @next ThpCodeEntryCpaceHostTag
  */
 message ThpCodeEntryCpaceTrezor {
     optional bytes cpace_trezor_public_key = 1;  // Trezor's ephemeral CPace public key
 }
 
 /**
- * Response: Host continues with the CPACE protocol.
+ * Request: User selected Code Entry option in Host. Host starts CPACE protocol with Trezor.
  * @next ThpCodeEntrySecret
  */
-message ThpCodeEntryTag {
-    optional bytes tag = 2;       // SHA-256 of shared secret
+ message ThpCodeEntryCpaceHostTag {
+    optional bytes cpace_host_public_key = 1;    // Host's ephemeral CPace public key
+    optional bytes tag = 2;                      // SHA-256 of shared secret
+
 }
 
 /**
@@ -175,10 +179,10 @@ message ThpQrCodeSecret {
 
 /**
  * Request: User selected Unidirectional NFC pairing option. Host sends an Unidirectional NFC Tag.
- * @next ThpNfcUnidirectionalSecret
+ * @next ThpNfcTagTrezor
  */
-message ThpNfcUnidirectionalTag {
-    optional bytes tag = 1;       // SHA-256 of shared secret
+message ThpNfcTagHost {
+    optional bytes tag = 1;       // Host's tag
 }
 
 /**
@@ -186,8 +190,8 @@ message ThpNfcUnidirectionalTag {
  * @next ThpCredentialRequest
  * @next ThpEndRequest
  */
-message ThpNfcUnidirectionalSecret {
-    optional bytes secret = 1;    // Trezor's secret
+message ThpNfcTagTrezor {
+    optional bytes tag = 1;       // Trezor's tag
 }
 
 /**
@@ -197,6 +201,7 @@ message ThpNfcUnidirectionalSecret {
  */
 message ThpCredentialRequest {
     optional bytes host_static_pubkey = 1;       // Host's static public key used in the handshake.
+    optional bool autoconnect = 2;               // Whether host wants to autoconnect without user confirmation
 }
 
 /**
@@ -229,6 +234,7 @@ message ThpEndResponse {}
  message ThpCredentialMetadata {
     option (internal_only) = true;
     optional string host_name = 1;     // Human-readable host name
+    optional bool autoconnect = 2;     // Whether host is allowed to autoconnect without user confirmation
 }
 
 /**
diff --git a/core/src/apps/debug/__init__.py b/core/src/apps/debug/__init__.py
index 71c5745eaa..d7364f14f2 100644
--- a/core/src/apps/debug/__init__.py
+++ b/core/src/apps/debug/__init__.py
@@ -301,9 +301,7 @@ if __debug__:
             if ctx is not None and isinstance(ctx, PairingContext):
                 thp_pairing_code_entry_code = ctx.display_data.code_code_entry
                 thp_pairing_code_qr_code = ctx.display_data.code_qr_code
-                thp_pairing_code_nfc_unidirectional = (
-                    ctx.display_data.code_nfc_unidirectional
-                )
+                thp_pairing_code_nfc_unidirectional = ctx.display_data.code_nfc
 
         if msg.wait_layout == DebugWaitType.IMMEDIATE:
             return _state(
diff --git a/core/src/apps/thp/pairing.py b/core/src/apps/thp/pairing.py
index 0f47e6b967..221b44edf6 100644
--- a/core/src/apps/thp/pairing.py
+++ b/core/src/apps/thp/pairing.py
@@ -2,30 +2,32 @@ from typing import TYPE_CHECKING
 from ubinascii import hexlify
 
 from trezor import loop, protobuf
+from trezor.crypto import random
 from trezor.crypto.hashlib import sha256
 from trezor.enums import ThpMessageType, ThpPairingMethod
 from trezor.messages import (
     Cancel,
     ThpCodeEntryChallenge,
     ThpCodeEntryCommitment,
-    ThpCodeEntryCpaceHost,
+    ThpCodeEntryCpaceHostTag,
     ThpCodeEntryCpaceTrezor,
     ThpCodeEntrySecret,
-    ThpCodeEntryTag,
     ThpCredentialMetadata,
     ThpCredentialRequest,
     ThpCredentialResponse,
     ThpEndRequest,
     ThpEndResponse,
-    ThpNfcUnidirectionalSecret,
-    ThpNfcUnidirectionalTag,
+    ThpNfcTagHost,
+    ThpNfcTagTrezor,
     ThpPairingPreparationsFinished,
+    ThpPairingRequest,
+    ThpPairingRequestAck,
     ThpQrCodeSecret,
     ThpQrCodeTag,
-    ThpStartPairingRequest,
+    ThpSelectMethod,
 )
 from trezor.wire.errors import ActionCancelled, SilentError, UnexpectedMessage
-from trezor.wire.thp import ChannelState, ThpError, crypto
+from trezor.wire.thp import ChannelState, ThpError, crypto, get_enabled_pairing_methods
 from trezor.wire.thp.pairing_context import PairingContext
 
 from .credential_manager import issue_credential
@@ -64,12 +66,13 @@ def check_state_and_log(
     return decorator
 
 
-def check_method_is_allowed(
+def check_method_is_allowed_and_selected(
     pairing_method: ThpPairingMethod,
 ) -> Callable[[FuncWithContext], FuncWithContext]:
     def decorator(f: FuncWithContext) -> FuncWithContext:
         def inner(context: PairingContext, *args: P.args, **kwargs: P.kwargs) -> object:
             _check_method_is_allowed(context, pairing_method)
+            _check_method_is_selected(context, pairing_method)
             return f(context, *args, **kwargs)
 
         return inner
@@ -81,31 +84,47 @@ def check_method_is_allowed(
 # Pairing handlers
 
 
-@check_state_and_log(ChannelState.TP1)
+@check_state_and_log(ChannelState.TP0)
 async def handle_pairing_request(
     ctx: PairingContext, message: protobuf.MessageType
 ) -> ThpEndResponse:
 
-    if not ThpStartPairingRequest.is_type_of(message):
+    if not ThpPairingRequest.is_type_of(message):
         raise UnexpectedMessage("Unexpected message")
 
     ctx.host_name = message.host_name or ""
 
-    skip_pairing = _is_method_included(ctx, ThpPairingMethod.NoMethod)
-    if skip_pairing:
+    # TODO show dialog
+
+    select_method_msg: ThpSelectMethod = await ctx.call(
+        ThpPairingRequestAck(), ThpSelectMethod
+    )
+    assert select_method_msg.selected_pairing_method is not None
+
+    ctx.set_selected_method(select_method_msg.selected_pairing_method)
+
+    if ctx.selected_method == ThpPairingMethod.SkipPairing:
         return await _end_pairing(ctx)
 
-    await _prepare_pairing(ctx)
-    await ctx.write(ThpPairingPreparationsFinished())
-    ctx.channel_ctx.set_channel_state(ChannelState.TP3)
-    response = await show_display_data(
-        ctx, _get_possible_pairing_methods_and_cancel(ctx)
-    )
+    while True:
 
-    if Cancel.is_type_of(response):
-        ctx.channel_ctx.clear()
-        raise SilentError("Action was cancelled by the Host")
-    # TODO disable NFC (if enabled)
+        await _prepare_pairing(ctx)
+
+        ctx.channel_ctx.set_channel_state(ChannelState.TP3)
+        response = await show_display_data(ctx, _get_accepted_messages(ctx))
+
+        if Cancel.is_type_of(response):
+            ctx.channel_ctx.clear()
+            raise SilentError("Action was cancelled by the Host")
+
+        if ThpSelectMethod.is_type_of(response):
+            assert response.selected_pairing_method is not None
+            ctx.set_selected_method(response.selected_pairing_method)
+            ctx.channel_ctx.set_channel_state(ChannelState.TP1)
+        else:
+            break
+
+        # TODO disable NFC (if enabled)
     response = await _handle_different_pairing_methods(ctx, response)
 
     while ThpCredentialRequest.is_type_of(response):
@@ -115,15 +134,16 @@ async def handle_pairing_request(
 
 
 async def _prepare_pairing(ctx: PairingContext) -> None:
+    ctx.channel_ctx.set_channel_state(ChannelState.TP1)
 
-    if _is_method_included(ctx, ThpPairingMethod.CodeEntry):
-        await _handle_code_entry_is_included(ctx)
-
-    if _is_method_included(ctx, ThpPairingMethod.QrCode):
-        _handle_qr_code_is_included(ctx)
-
-    if _is_method_included(ctx, ThpPairingMethod.NFC_Unidirectional):
-        _handle_nfc_unidirectional_is_included(ctx)
+    if ctx.selected_method == ThpPairingMethod.CodeEntry:
+        await _handle_code_entry_is_selected(ctx)
+    elif ctx.selected_method == ThpPairingMethod.NFC:
+        _handle_nfc_is_selected(ctx)
+    elif ctx.selected_method == ThpPairingMethod.QrCode:
+        _handle_qr_code_is_selected(ctx)
+    else:
+        raise Exception()  # TODO unknown pairing method
 
 
 async def show_display_data(
@@ -143,10 +163,20 @@ async def show_display_data(
 
 
 @check_state_and_log(ChannelState.TP1)
-async def _handle_code_entry_is_included(ctx: PairingContext) -> None:
-    commitment = sha256(ctx.secret).digest()
+async def _handle_code_entry_is_selected(ctx: PairingContext) -> None:
+    if ctx.code_entry_secret is None:
+        await _handle_code_entry_is_selected_first_time(ctx)
+    else:
+        await ctx.write(ThpPairingPreparationsFinished())
 
-    challenge_message = await ctx.call(  # noqa: F841
+
+async def _handle_code_entry_is_selected_first_time(ctx: PairingContext):
+    from trezor.wire.thp.cpace import Cpace
+
+    ctx.code_entry_secret = random.bytes(16)
+    commitment = sha256(ctx.code_entry_secret).digest()
+
+    challenge_message = await ctx.call(
         ThpCodeEntryCommitment(commitment=commitment), ThpCodeEntryChallenge
     )
     ctx.channel_ctx.set_channel_state(ChannelState.TP2)
@@ -157,84 +187,76 @@ async def _handle_code_entry_is_included(ctx: PairingContext) -> None:
     if challenge_message.challenge is None:
         raise Exception("Invalid message")
     sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
-    sha_ctx.update(ctx.secret)
+    sha_ctx.update(ctx.code_entry_secret)
     sha_ctx.update(challenge_message.challenge)
     sha_ctx.update(bytes("PairingMethod_CodeEntry", "utf-8"))
     code_code_entry_hash = sha_ctx.digest()
     ctx.display_data.code_code_entry = (
         int.from_bytes(code_code_entry_hash, "big") % 1000000
     )
-
-
-@check_state_and_log(ChannelState.TP1, ChannelState.TP2)
-def _handle_qr_code_is_included(ctx: PairingContext) -> None:
-    sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
-    sha_ctx.update(ctx.secret)
-    sha_ctx.update(bytes("PairingMethod_QrCode", "utf-8"))
-    ctx.display_data.code_qr_code = sha_ctx.digest()[:16]
-
-
-@check_state_and_log(ChannelState.TP1, ChannelState.TP2)
-def _handle_nfc_unidirectional_is_included(ctx: PairingContext) -> None:
-    sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
-    sha_ctx.update(ctx.secret)
-    sha_ctx.update(bytes("PairingMethod_NfcUnidirectional", "utf-8"))
-    ctx.display_data.code_nfc_unidirectional = sha_ctx.digest()[:16]
-
-
-@check_state_and_log(ChannelState.TP3)
-async def _handle_different_pairing_methods(
-    ctx: PairingContext, response: protobuf.MessageType
-) -> protobuf.MessageType:
-    if ThpCodeEntryCpaceHost.is_type_of(response):
-        return await _handle_code_entry_cpace(ctx, response)
-    if ThpQrCodeTag.is_type_of(response):
-        return await _handle_qr_code_tag(ctx, response)
-    if ThpNfcUnidirectionalTag.is_type_of(response):
-        return await _handle_nfc_unidirectional_tag(ctx, response)
-    raise UnexpectedMessage("Unexpected message")
-
-
-@check_state_and_log(ChannelState.TP3)
-@check_method_is_allowed(ThpPairingMethod.CodeEntry)
-async def _handle_code_entry_cpace(
-    ctx: PairingContext, message: protobuf.MessageType
-) -> protobuf.MessageType:
-    from trezor.wire.thp.cpace import Cpace
-
-    # TODO check that ThpCodeEntryCpaceHost message is valid
-
-    if TYPE_CHECKING:
-        assert isinstance(message, ThpCodeEntryCpaceHost)
-    if message.cpace_host_public_key is None:
-        raise ThpError("Message ThpCodeEntryCpaceHost has no public key")
-
     ctx.cpace = Cpace(
-        message.cpace_host_public_key,
         ctx.channel_ctx.get_handshake_hash(),
     )
     assert ctx.display_data.code_code_entry is not None
     ctx.cpace.generate_keys_and_secret(
         ctx.display_data.code_code_entry.to_bytes(6, "big")
     )
-
-    ctx.channel_ctx.set_channel_state(ChannelState.TP4)
-    response = await ctx.call(
-        ThpCodeEntryCpaceTrezor(cpace_trezor_public_key=ctx.cpace.trezor_public_key),
-        ThpCodeEntryTag,
+    await ctx.write(
+        ThpCodeEntryCpaceTrezor(cpace_trezor_public_key=ctx.cpace.trezor_public_key)
     )
-    return await _handle_code_entry_tag(ctx, response)
 
 
-@check_state_and_log(ChannelState.TP4)
-@check_method_is_allowed(ThpPairingMethod.CodeEntry)
-async def _handle_code_entry_tag(
+@check_state_and_log(ChannelState.TP1)
+async def _handle_nfc_is_selected(ctx: PairingContext) -> None:
+    ctx.nfc_secret = random.bytes(16)
+    sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
+    sha_ctx.update(ctx.nfc_secret)
+    sha_ctx.update(bytes("PairingMethod_NfcUnidirectional", "utf-8"))
+    ctx.display_data.code_nfc = sha_ctx.digest()[:16]
+    await ctx.write(ThpPairingPreparationsFinished())
+
+
+@check_state_and_log(ChannelState.TP1)
+async def _handle_qr_code_is_selected(ctx: PairingContext) -> None:
+    ctx.qr_code_secret = random.bytes(16)
+
+    sha_ctx = sha256(ThpPairingMethod.QrCode.to_bytes(1, "big"))
+    sha_ctx.update(ctx.channel_ctx.get_handshake_hash())
+    sha_ctx.update(ctx.qr_code_secret)
+
+    ctx.display_data.code_qr_code = sha_ctx.digest()[:16]
+    await ctx.write(ThpPairingPreparationsFinished())
+
+
+@check_state_and_log(ChannelState.TP3)
+async def _handle_different_pairing_methods(
+    ctx: PairingContext, response: protobuf.MessageType
+) -> protobuf.MessageType:
+    if ThpCodeEntryCpaceHostTag.is_type_of(response):
+        return await _handle_code_entry_cpace(ctx, response)
+    if ThpQrCodeTag.is_type_of(response):
+        return await _handle_qr_code_tag(ctx, response)
+    if ThpNfcTagHost.is_type_of(response):
+        return await _handle_nfc_tag(ctx, response)
+    raise UnexpectedMessage("Unexpected message")
+
+
+@check_state_and_log(ChannelState.TP3)
+@check_method_is_allowed_and_selected(ThpPairingMethod.CodeEntry)
+async def _handle_code_entry_cpace(
     ctx: PairingContext, message: protobuf.MessageType
 ) -> protobuf.MessageType:
 
     if TYPE_CHECKING:
-        assert isinstance(message, ThpCodeEntryTag)
+        assert isinstance(message, ThpCodeEntryCpaceHostTag)
+    if message.cpace_host_public_key is None:
+        raise ThpError(
+            "Message ThpCodeEntryCpaceHostTag is missing cpace_host_public_key"
+        )
+    if message.tag is None:
+        raise ThpError("Message ThpCodeEntryCpaceHostTag is missing tag")
 
+    ctx.cpace.compute_shared_secret(message.cpace_host_public_key)
     expected_tag = sha256(ctx.cpace.shared_secret).digest()
     if expected_tag != message.tag:
         print(
@@ -248,19 +270,21 @@ async def _handle_code_entry_tag(
 
     return await _handle_secret_reveal(
         ctx,
-        msg=ThpCodeEntrySecret(secret=ctx.secret),
+        msg=ThpCodeEntrySecret(secret=ctx.code_entry_secret),
     )
 
 
 @check_state_and_log(ChannelState.TP3)
-@check_method_is_allowed(ThpPairingMethod.QrCode)
+@check_method_is_allowed_and_selected(ThpPairingMethod.QrCode)
 async def _handle_qr_code_tag(
     ctx: PairingContext, message: protobuf.MessageType
 ) -> protobuf.MessageType:
     if TYPE_CHECKING:
         assert isinstance(message, ThpQrCodeTag)
     assert ctx.display_data.code_qr_code is not None
-    expected_tag = sha256(ctx.display_data.code_qr_code).digest()
+    sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
+    sha_ctx.update(ctx.display_data.code_qr_code)
+    expected_tag = sha_ctx.digest()
     if expected_tag != message.tag:
         print(
             "expected qr code tag:", hexlify(expected_tag).decode()
@@ -276,28 +300,35 @@ async def _handle_qr_code_tag(
 
     return await _handle_secret_reveal(
         ctx,
-        msg=ThpQrCodeSecret(secret=ctx.secret),
+        msg=ThpQrCodeSecret(secret=ctx.qr_code_secret),
     )
 
 
 @check_state_and_log(ChannelState.TP3)
-@check_method_is_allowed(ThpPairingMethod.NFC_Unidirectional)
-async def _handle_nfc_unidirectional_tag(
+@check_method_is_allowed_and_selected(ThpPairingMethod.NFC)
+async def _handle_nfc_tag(
     ctx: PairingContext, message: protobuf.MessageType
 ) -> protobuf.MessageType:
     if TYPE_CHECKING:
-        assert isinstance(message, ThpNfcUnidirectionalTag)
-
-    expected_tag = sha256(ctx.display_data.code_nfc_unidirectional).digest()
+        assert isinstance(message, ThpNfcTagHost)
+    sha_ctx = sha256(ThpPairingMethod.NFC.to_bytes(1, "big"))
+    sha_ctx.update(ctx.channel_ctx.get_handshake_hash())
+    sha_ctx.update(ctx.nfc_secret)
+    expected_tag = sha_ctx.digest()
     if expected_tag != message.tag:
         print(
             "expected nfc tag:", hexlify(expected_tag).decode()
         )  # TODO remove after testing
         raise ThpError("Unexpected NFC Unidirectional Tag")
 
+    sha_ctx = sha256(ThpPairingMethod.NFC.to_bytes(1, "big"))
+    sha_ctx.update(ctx.channel_ctx.get_handshake_hash())
+    # TODO add Host's secret from NFC message transferred over NFC
+    # sha_ctx.update(host's secret)
+    trezor_tag = sha_ctx.digest()
     return await _handle_secret_reveal(
         ctx,
-        msg=ThpNfcUnidirectionalSecret(secret=ctx.secret),
+        msg=ThpNfcTagTrezor(tag=trezor_tag),
     )
 
 
@@ -318,7 +349,6 @@ async def _handle_secret_reveal(
 async def _handle_credential_request(
     ctx: PairingContext, message: protobuf.MessageType
 ) -> protobuf.MessageType:
-    ctx.secret
 
     if not ThpCredentialRequest.is_type_of(message):
         raise UnexpectedMessage("Unexpected message")
@@ -362,42 +392,39 @@ def _check_state(ctx: PairingContext, *allowed_states: ChannelState) -> None:
 
 
 def _check_method_is_allowed(ctx: PairingContext, method: ThpPairingMethod) -> None:
-    if not _is_method_included(ctx, method):
+    if method not in get_enabled_pairing_methods(ctx.iface):
         raise ThpError("Unexpected pairing method")
 
 
-def _is_method_included(ctx: PairingContext, method: ThpPairingMethod) -> bool:
-    return method in ctx.channel_ctx.selected_pairing_methods
+def _check_method_is_selected(ctx: PairingContext, method: ThpPairingMethod) -> None:
+    if method is not ctx.selected_method:
+        raise ThpError("Not selected pairing method")
 
 
 #
 # Helpers - getters
 
 
-def _get_possible_pairing_methods_and_cancel(ctx: PairingContext) -> Tuple[int, ...]:
+def _get_accepted_messages(ctx: PairingContext) -> Tuple[int, ...]:
     r = _get_possible_pairing_methods(ctx)
     mtype = Cancel.MESSAGE_WIRE_TYPE
-    return r + ((mtype,) if mtype is not None else ())
+    r += (mtype,) if mtype is not None else ()
+    mtype = ThpSelectMethod.MESSAGE_WIRE_TYPE
+    r += (mtype,) if mtype is not None else ()
+
+    return r
 
 
 def _get_possible_pairing_methods(ctx: PairingContext) -> Tuple[int, ...]:
-    r = tuple(
-        _get_message_type_for_method(method)
-        for method in ctx.channel_ctx.selected_pairing_methods
-    )
-    if __debug__:
-        from trezor.messages import DebugLinkGetState
-
-        mtype = DebugLinkGetState.MESSAGE_WIRE_TYPE
-        return r + ((mtype,) if mtype is not None else ())
+    r = tuple(_get_message_type_for_method(ctx.selected_method))
     return r
 
 
 def _get_message_type_for_method(method: int) -> int:
     if method is ThpPairingMethod.CodeEntry:
-        return ThpMessageType.ThpCodeEntryCpaceHost
-    if method is ThpPairingMethod.NFC_Unidirectional:
-        return ThpMessageType.ThpNfcUnidirectionalTag
+        return ThpMessageType.ThpCodeEntryCpaceHostTag
+    if method is ThpPairingMethod.NFC:
+        return ThpMessageType.ThpNfcTagHost
     if method is ThpPairingMethod.QrCode:
         return ThpMessageType.ThpQrCodeTag
     raise ValueError("Unexpected pairing method - no message type available")
diff --git a/core/src/trezor/enums/ThpMessageType.py b/core/src/trezor/enums/ThpMessageType.py
index 45a34120e5..77a4e9d652 100644
--- a/core/src/trezor/enums/ThpMessageType.py
+++ b/core/src/trezor/enums/ThpMessageType.py
@@ -3,8 +3,9 @@
 # isort:skip_file
 
 ThpCreateNewSession = 1000
-ThpNewSession = 1001
-ThpStartPairingRequest = 1008
+ThpPairingRequest = 1006
+ThpPairingRequestAck = 1007
+ThpSelectMethod = 1008
 ThpPairingPreparationsFinished = 1009
 ThpCredentialRequest = 1010
 ThpCredentialResponse = 1011
@@ -12,11 +13,10 @@ ThpEndRequest = 1012
 ThpEndResponse = 1013
 ThpCodeEntryCommitment = 1016
 ThpCodeEntryChallenge = 1017
-ThpCodeEntryCpaceHost = 1018
-ThpCodeEntryCpaceTrezor = 1019
-ThpCodeEntryTag = 1020
-ThpCodeEntrySecret = 1021
+ThpCodeEntryCpaceTrezor = 1018
+ThpCodeEntryCpaceHostTag = 1019
+ThpCodeEntrySecret = 1020
 ThpQrCodeTag = 1024
 ThpQrCodeSecret = 1025
-ThpNfcUnidirectionalTag = 1032
-ThpNfcUnidirectionalSecret = 1033
+ThpNfcTagHost = 1032
+ThpNfcTagTrezor = 1033
diff --git a/core/src/trezor/enums/ThpPairingMethod.py b/core/src/trezor/enums/ThpPairingMethod.py
index b356cdf470..0af2487182 100644
--- a/core/src/trezor/enums/ThpPairingMethod.py
+++ b/core/src/trezor/enums/ThpPairingMethod.py
@@ -2,7 +2,7 @@
 # fmt: off
 # isort:skip_file
 
-NoMethod = 1
+SkipPairing = 1
 CodeEntry = 2
 QrCode = 3
-NFC_Unidirectional = 4
+NFC = 4
diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py
index 059882ccac..7809bea849 100644
--- a/core/src/trezor/enums/__init__.py
+++ b/core/src/trezor/enums/__init__.py
@@ -353,8 +353,9 @@ if TYPE_CHECKING:
 
     class ThpMessageType(IntEnum):
         ThpCreateNewSession = 1000
-        ThpNewSession = 1001
-        ThpStartPairingRequest = 1008
+        ThpPairingRequest = 1006
+        ThpPairingRequestAck = 1007
+        ThpSelectMethod = 1008
         ThpPairingPreparationsFinished = 1009
         ThpCredentialRequest = 1010
         ThpCredentialResponse = 1011
@@ -362,20 +363,19 @@ if TYPE_CHECKING:
         ThpEndResponse = 1013
         ThpCodeEntryCommitment = 1016
         ThpCodeEntryChallenge = 1017
-        ThpCodeEntryCpaceHost = 1018
-        ThpCodeEntryCpaceTrezor = 1019
-        ThpCodeEntryTag = 1020
-        ThpCodeEntrySecret = 1021
+        ThpCodeEntryCpaceTrezor = 1018
+        ThpCodeEntryCpaceHostTag = 1019
+        ThpCodeEntrySecret = 1020
         ThpQrCodeTag = 1024
         ThpQrCodeSecret = 1025
-        ThpNfcUnidirectionalTag = 1032
-        ThpNfcUnidirectionalSecret = 1033
+        ThpNfcTagHost = 1032
+        ThpNfcTagTrezor = 1033
 
     class ThpPairingMethod(IntEnum):
-        NoMethod = 1
+        SkipPairing = 1
         CodeEntry = 2
         QrCode = 3
-        NFC_Unidirectional = 4
+        NFC = 4
 
     class MessageType(IntEnum):
         Initialize = 0
diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py
index 0c64aae3c0..bf0e38a162 100644
--- a/core/src/trezor/messages.py
+++ b/core/src/trezor/messages.py
@@ -6175,8 +6175,8 @@ if TYPE_CHECKING:
     class ThpDeviceProperties(protobuf.MessageType):
         internal_model: "str | None"
         model_variant: "int | None"
-        bootloader_mode: "bool | None"
-        protocol_version: "int | None"
+        protocol_version_major: "int | None"
+        protocol_version_minor: "int | None"
         pairing_methods: "list[ThpPairingMethod]"
 
         def __init__(
@@ -6185,8 +6185,8 @@ if TYPE_CHECKING:
             pairing_methods: "list[ThpPairingMethod] | None" = None,
             internal_model: "str | None" = None,
             model_variant: "int | None" = None,
-            bootloader_mode: "bool | None" = None,
-            protocol_version: "int | None" = None,
+            protocol_version_major: "int | None" = None,
+            protocol_version_minor: "int | None" = None,
         ) -> None:
             pass
 
@@ -6196,12 +6196,10 @@ if TYPE_CHECKING:
 
     class ThpHandshakeCompletionReqNoisePayload(protobuf.MessageType):
         host_pairing_credential: "bytes | None"
-        pairing_methods: "list[ThpPairingMethod]"
 
         def __init__(
             self,
             *,
-            pairing_methods: "list[ThpPairingMethod] | None" = None,
             host_pairing_credential: "bytes | None" = None,
         ) -> None:
             pass
@@ -6228,21 +6226,7 @@ if TYPE_CHECKING:
         def is_type_of(cls, msg: Any) -> TypeGuard["ThpCreateNewSession"]:
             return isinstance(msg, cls)
 
-    class ThpNewSession(protobuf.MessageType):
-        new_session_id: "int | None"
-
-        def __init__(
-            self,
-            *,
-            new_session_id: "int | None" = None,
-        ) -> None:
-            pass
-
-        @classmethod
-        def is_type_of(cls, msg: Any) -> TypeGuard["ThpNewSession"]:
-            return isinstance(msg, cls)
-
-    class ThpStartPairingRequest(protobuf.MessageType):
+    class ThpPairingRequest(protobuf.MessageType):
         host_name: "str | None"
 
         def __init__(
@@ -6253,7 +6237,27 @@ if TYPE_CHECKING:
             pass
 
         @classmethod
-        def is_type_of(cls, msg: Any) -> TypeGuard["ThpStartPairingRequest"]:
+        def is_type_of(cls, msg: Any) -> TypeGuard["ThpPairingRequest"]:
+            return isinstance(msg, cls)
+
+    class ThpPairingRequestAck(protobuf.MessageType):
+
+        @classmethod
+        def is_type_of(cls, msg: Any) -> TypeGuard["ThpPairingRequestAck"]:
+            return isinstance(msg, cls)
+
+    class ThpSelectMethod(protobuf.MessageType):
+        selected_pairing_method: "ThpPairingMethod | None"
+
+        def __init__(
+            self,
+            *,
+            selected_pairing_method: "ThpPairingMethod | None" = None,
+        ) -> None:
+            pass
+
+        @classmethod
+        def is_type_of(cls, msg: Any) -> TypeGuard["ThpSelectMethod"]:
             return isinstance(msg, cls)
 
     class ThpPairingPreparationsFinished(protobuf.MessageType):
@@ -6290,20 +6294,6 @@ if TYPE_CHECKING:
         def is_type_of(cls, msg: Any) -> TypeGuard["ThpCodeEntryChallenge"]:
             return isinstance(msg, cls)
 
-    class ThpCodeEntryCpaceHost(protobuf.MessageType):
-        cpace_host_public_key: "bytes | None"
-
-        def __init__(
-            self,
-            *,
-            cpace_host_public_key: "bytes | None" = None,
-        ) -> None:
-            pass
-
-        @classmethod
-        def is_type_of(cls, msg: Any) -> TypeGuard["ThpCodeEntryCpaceHost"]:
-            return isinstance(msg, cls)
-
     class ThpCodeEntryCpaceTrezor(protobuf.MessageType):
         cpace_trezor_public_key: "bytes | None"
 
@@ -6318,18 +6308,20 @@ if TYPE_CHECKING:
         def is_type_of(cls, msg: Any) -> TypeGuard["ThpCodeEntryCpaceTrezor"]:
             return isinstance(msg, cls)
 
-    class ThpCodeEntryTag(protobuf.MessageType):
+    class ThpCodeEntryCpaceHostTag(protobuf.MessageType):
+        cpace_host_public_key: "bytes | None"
         tag: "bytes | None"
 
         def __init__(
             self,
             *,
+            cpace_host_public_key: "bytes | None" = None,
             tag: "bytes | None" = None,
         ) -> None:
             pass
 
         @classmethod
-        def is_type_of(cls, msg: Any) -> TypeGuard["ThpCodeEntryTag"]:
+        def is_type_of(cls, msg: Any) -> TypeGuard["ThpCodeEntryCpaceHostTag"]:
             return isinstance(msg, cls)
 
     class ThpCodeEntrySecret(protobuf.MessageType):
@@ -6374,7 +6366,7 @@ if TYPE_CHECKING:
         def is_type_of(cls, msg: Any) -> TypeGuard["ThpQrCodeSecret"]:
             return isinstance(msg, cls)
 
-    class ThpNfcUnidirectionalTag(protobuf.MessageType):
+    class ThpNfcTagHost(protobuf.MessageType):
         tag: "bytes | None"
 
         def __init__(
@@ -6385,30 +6377,32 @@ if TYPE_CHECKING:
             pass
 
         @classmethod
-        def is_type_of(cls, msg: Any) -> TypeGuard["ThpNfcUnidirectionalTag"]:
+        def is_type_of(cls, msg: Any) -> TypeGuard["ThpNfcTagHost"]:
             return isinstance(msg, cls)
 
-    class ThpNfcUnidirectionalSecret(protobuf.MessageType):
-        secret: "bytes | None"
+    class ThpNfcTagTrezor(protobuf.MessageType):
+        tag: "bytes | None"
 
         def __init__(
             self,
             *,
-            secret: "bytes | None" = None,
+            tag: "bytes | None" = None,
         ) -> None:
             pass
 
         @classmethod
-        def is_type_of(cls, msg: Any) -> TypeGuard["ThpNfcUnidirectionalSecret"]:
+        def is_type_of(cls, msg: Any) -> TypeGuard["ThpNfcTagTrezor"]:
             return isinstance(msg, cls)
 
     class ThpCredentialRequest(protobuf.MessageType):
         host_static_pubkey: "bytes | None"
+        autoconnect: "bool | None"
 
         def __init__(
             self,
             *,
             host_static_pubkey: "bytes | None" = None,
+            autoconnect: "bool | None" = None,
         ) -> None:
             pass
 
@@ -6446,11 +6440,13 @@ if TYPE_CHECKING:
 
     class ThpCredentialMetadata(protobuf.MessageType):
         host_name: "str | None"
+        autoconnect: "bool | None"
 
         def __init__(
             self,
             *,
             host_name: "str | None" = None,
+            autoconnect: "bool | None" = None,
         ) -> None:
             pass
 
diff --git a/core/src/trezor/wire/thp/__init__.py b/core/src/trezor/wire/thp/__init__.py
index 3250b5aad9..4eee9280a8 100644
--- a/core/src/trezor/wire/thp/__init__.py
+++ b/core/src/trezor/wire/thp/__init__.py
@@ -66,13 +66,14 @@ class ChannelState(IntEnum):
     UNALLOCATED = 0
     TH1 = 1
     TH2 = 2
-    TP1 = 3
-    TP2 = 4
-    TP3 = 5
-    TP4 = 6
-    TC1 = 7
-    ENCRYPTED_TRANSPORT = 8
-    INVALIDATED = 9
+    TP0 = 3
+    TP1 = 4
+    TP2 = 5
+    TP3 = 6
+    TP4 = 7
+    TC1 = 8
+    ENCRYPTED_TRANSPORT = 9
+    INVALIDATED = 10
 
 
 class SessionState(IntEnum):
@@ -134,7 +135,7 @@ class PacketHeader:
 _DEFAULT_ENABLED_PAIRING_METHODS = [
     ThpPairingMethod.CodeEntry,
     ThpPairingMethod.QrCode,
-    ThpPairingMethod.NFC_Unidirectional,
+    ThpPairingMethod.NFC,
 ]
 
 
@@ -149,7 +150,7 @@ def get_enabled_pairing_methods(
 
     methods = _DEFAULT_ENABLED_PAIRING_METHODS.copy()
     if iface is not None and iface is usb.iface_wire:
-        methods.append(ThpPairingMethod.NoMethod)
+        methods.append(ThpPairingMethod.SkipPairing)
     return methods
 
 
@@ -159,8 +160,8 @@ def _get_device_properties(iface: WireInterface) -> ThpDeviceProperties:
         pairing_methods=get_enabled_pairing_methods(iface),
         internal_model=utils.INTERNAL_MODEL,
         model_variant=0,
-        bootloader_mode=False,
-        protocol_version=2,
+        protocol_version_major=2,
+        protocol_version_minor=0,
     )
 
 
diff --git a/core/src/trezor/wire/thp/channel.py b/core/src/trezor/wire/thp/channel.py
index 6ed01c7318..4913c93bd5 100644
--- a/core/src/trezor/wire/thp/channel.py
+++ b/core/src/trezor/wire/thp/channel.py
@@ -69,7 +69,6 @@ class Channel:
         self.bytes_read: int = 0
         self.expected_payload_length: int = 0
         self.is_cont_packet_expected: bool = False
-        self.selected_pairing_methods = []
         self.sessions: dict[int, GenericSessionContext] = {}
 
         # Objects for writing a message to a wire
diff --git a/core/src/trezor/wire/thp/cpace.py b/core/src/trezor/wire/thp/cpace.py
index 302dd3e5e3..5592b5f9f4 100644
--- a/core/src/trezor/wire/thp/cpace.py
+++ b/core/src/trezor/wire/thp/cpace.py
@@ -11,9 +11,8 @@ class Cpace:
     CPace, a balanced composable PAKE: https://datatracker.ietf.org/doc/draft-irtf-cfrg-cpace/
     """
 
-    def __init__(self, cpace_host_public_key: bytes, handshake_hash: bytes) -> None:
+    def __init__(self, handshake_hash: bytes) -> None:
         self.handshake_hash: bytes = handshake_hash
-        self.host_public_key: bytes = cpace_host_public_key
         self.shared_secret: bytes
         self.trezor_private_key: bytes
         self.trezor_public_key: bytes
@@ -34,3 +33,8 @@ class Cpace:
         self.shared_secret = curve25519.multiply(
             self.trezor_private_key, self.host_public_key
         )
+
+    def compute_shared_secret(self, host_public_key: bytes):
+        self.shared_secret = curve25519.multiply(
+            self.trezor_private_key, host_public_key
+        )
diff --git a/core/src/trezor/wire/thp/pairing_context.py b/core/src/trezor/wire/thp/pairing_context.py
index 02f8db3a8a..e185a9dd44 100644
--- a/core/src/trezor/wire/thp/pairing_context.py
+++ b/core/src/trezor/wire/thp/pairing_context.py
@@ -1,4 +1,5 @@
 from typing import TYPE_CHECKING
+from trezor.wire.thp import get_enabled_pairing_methods
 from ubinascii import hexlify
 
 import trezorui_api
@@ -13,6 +14,7 @@ if TYPE_CHECKING:
     from typing import Container
 
     from trezor import ui
+    from trezor.enums import ThpPairingMethod
 
     from .channel import Channel
     from .cpace import Cpace
@@ -28,7 +30,7 @@ class PairingDisplayData:
     def __init__(self) -> None:
         self.code_code_entry: int | None = None
         self.code_qr_code: bytes | None = None
-        self.code_nfc_unidirectional: bytes | None = None
+        self.code_nfc: bytes | None = None
 
     def get_display_layout(self) -> ui.Layout:
         from trezor import ui
@@ -77,20 +79,16 @@ class PairingContext(Context):
         super().__init__(channel_ctx.iface, channel_ctx.channel_id)
         self.channel_ctx: Channel = channel_ctx
         self.incoming_message = loop.mailbox()
-        self.secret: bytes = random.bytes(16)
+        self.nfc_secret: bytes
+        self.qr_code_secret: bytes
+        self.code_entry_secret: bytes | None = None
+        self.selected_method: ThpPairingMethod
 
         self.display_data: PairingDisplayData = PairingDisplayData()
         self.cpace: Cpace
         self.host_name: str
 
-    async def handle(self, is_debug_session: bool = False) -> None:
-        # if __debug__:
-        #     log.debug(__name__, "handle - start")
-        #     if is_debug_session:
-        #         import apps.debug
-
-        #         apps.debug.DEBUG_CONTEXT = self
-
+    async def handle(self) -> None:
         next_message: Message | None = None
 
         while True:
@@ -189,6 +187,11 @@ class PairingContext(Context):
         del msg
         return await self.read(expected_types)
 
+    def set_selected_method(self, selected_method: ThpPairingMethod) -> None:
+        if selected_method not in get_enabled_pairing_methods(self.iface):
+            raise Exception("Not allowed to set this method")
+        self.selected_method = selected_method
+
 
 async def handle_pairing_request_message(
     pairing_ctx: PairingContext,
diff --git a/core/src/trezor/wire/thp/received_message_handler.py b/core/src/trezor/wire/thp/received_message_handler.py
index c357e586ea..c40b7a4d5e 100644
--- a/core/src/trezor/wire/thp/received_message_handler.py
+++ b/core/src/trezor/wire/thp/received_message_handler.py
@@ -315,12 +315,7 @@ async def _handle_state_TH2(ctx: Channel, message_length: int, ctrl_byte: int) -
     )
     if TYPE_CHECKING:
         assert ThpHandshakeCompletionReqNoisePayload.is_type_of(noise_payload)
-    enabled_methods = get_enabled_pairing_methods(ctx.iface)
-    for method in noise_payload.pairing_methods:
-        if method not in enabled_methods:
-            raise ThpInvalidDataError()
-        if method not in ctx.selected_pairing_methods:
-            ctx.selected_pairing_methods.append(method)
+
     if __debug__ and utils.ALLOW_DEBUG_MESSAGES:
         log.debug(
             __name__,
@@ -357,9 +352,9 @@ async def _handle_state_TH2(ctx: Channel, message_length: int, ctrl_byte: int) -
     ctx.handshake = None
 
     if paired:
-        ctx.set_channel_state(ChannelState.ENCRYPTED_TRANSPORT)
+        ctx.set_channel_state(ChannelState.TC1)
     else:
-        ctx.set_channel_state(ChannelState.TP1)
+        ctx.set_channel_state(ChannelState.TP0)
 
 
 async def _handle_state_ENCRYPTED_TRANSPORT(ctx: Channel, message_length: int) -> None:
@@ -457,6 +452,7 @@ def _decode_message(
 
 def _is_channel_state_pairing(state: int) -> bool:
     if state in (
+        ChannelState.TP0,
         ChannelState.TP1,
         ChannelState.TP2,
         ChannelState.TP3,
diff --git a/core/tests/test_trezor.wire.thp.py b/core/tests/test_trezor.wire.thp.py
index 6078d7698c..48c48c711a 100644
--- a/core/tests/test_trezor.wire.thp.py
+++ b/core/tests/test_trezor.wire.thp.py
@@ -27,7 +27,7 @@ if utils.USE_THP:
         ThpCodeEntryTag,
         ThpCredentialRequest,
         ThpEndRequest,
-        ThpStartPairingRequest,
+        ThpPairingRequest,
     )
     from trezor.wire.thp import (
         ChannelState,
@@ -280,13 +280,13 @@ class TestTrezorHostProtocol(unittest.TestCase):
         config.wipe()
         channel = next(iter(thp_main._CHANNELS.values()))
         channel.selected_pairing_methods = [
-            ThpPairingMethod.NoMethod,
+            ThpPairingMethod.SkipPairing,
             ThpPairingMethod.CodeEntry,
             ThpPairingMethod.NFC_Unidirectional,
             ThpPairingMethod.QrCode,
         ]
         pairing_ctx = PairingContext(channel)
-        request_message = ThpStartPairingRequest()
+        request_message = ThpPairingRequest()
         channel.set_channel_state(ChannelState.TP1)
         gen = pairing.handle_pairing_request(pairing_ctx, request_message)
 
@@ -310,7 +310,7 @@ class TestTrezorHostProtocol(unittest.TestCase):
             ThpPairingMethod.QrCode,
         ]
         pairing_ctx = PairingContext(channel)
-        request_message = ThpStartPairingRequest()
+        request_message = ThpPairingRequest()
         with self.assertRaises(UnexpectedMessage) as e:
             pairing.handle_pairing_request(pairing_ctx, request_message)
         print(e.value.message)
@@ -346,7 +346,7 @@ class TestTrezorHostProtocol(unittest.TestCase):
         msg = ThpCodeEntryCpaceHost(cpace_host_public_key=cpace_host_public_key)
 
         # msg = ThpQrCodeTag(tag=tag_qrc)
-        # msg = ThpNfcUnidirectionalTag(tag=tag_nfc)
+        # msg = ThpNfcTagHost(tag=tag_nfc)
         buffer: bytearray = bytearray(protobuf.encoded_length(msg))
 
         protobuf.encode(buffer, msg)
diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py
index 2e4390fff0..66db8799e8 100644
--- a/python/src/trezorlib/messages.py
+++ b/python/src/trezorlib/messages.py
@@ -406,8 +406,9 @@ class TezosBallotType(IntEnum):
 
 class ThpMessageType(IntEnum):
     ThpCreateNewSession = 1000
-    ThpNewSession = 1001
-    ThpStartPairingRequest = 1008
+    ThpPairingRequest = 1006
+    ThpPairingRequestAck = 1007
+    ThpSelectMethod = 1008
     ThpPairingPreparationsFinished = 1009
     ThpCredentialRequest = 1010
     ThpCredentialResponse = 1011
@@ -415,21 +416,20 @@ class ThpMessageType(IntEnum):
     ThpEndResponse = 1013
     ThpCodeEntryCommitment = 1016
     ThpCodeEntryChallenge = 1017
-    ThpCodeEntryCpaceHost = 1018
-    ThpCodeEntryCpaceTrezor = 1019
-    ThpCodeEntryTag = 1020
-    ThpCodeEntrySecret = 1021
+    ThpCodeEntryCpaceTrezor = 1018
+    ThpCodeEntryCpaceHostTag = 1019
+    ThpCodeEntrySecret = 1020
     ThpQrCodeTag = 1024
     ThpQrCodeSecret = 1025
-    ThpNfcUnidirectionalTag = 1032
-    ThpNfcUnidirectionalSecret = 1033
+    ThpNfcTagHost = 1032
+    ThpNfcTagTrezor = 1033
 
 
 class ThpPairingMethod(IntEnum):
-    NoMethod = 1
+    SkipPairing = 1
     CodeEntry = 2
     QrCode = 3
-    NFC_Unidirectional = 4
+    NFC = 4
 
 
 class MessageType(IntEnum):
@@ -7909,8 +7909,8 @@ class ThpDeviceProperties(protobuf.MessageType):
     FIELDS = {
         1: protobuf.Field("internal_model", "string", repeated=False, required=False, default=None),
         2: protobuf.Field("model_variant", "uint32", repeated=False, required=False, default=None),
-        3: protobuf.Field("bootloader_mode", "bool", repeated=False, required=False, default=None),
-        4: protobuf.Field("protocol_version", "uint32", repeated=False, required=False, default=None),
+        3: protobuf.Field("protocol_version_major", "uint32", repeated=False, required=False, default=None),
+        4: protobuf.Field("protocol_version_minor", "uint32", repeated=False, required=False, default=None),
         5: protobuf.Field("pairing_methods", "ThpPairingMethod", repeated=True, required=False, default=None),
     }
 
@@ -7920,30 +7920,27 @@ class ThpDeviceProperties(protobuf.MessageType):
         pairing_methods: Optional[Sequence["ThpPairingMethod"]] = None,
         internal_model: Optional["str"] = None,
         model_variant: Optional["int"] = None,
-        bootloader_mode: Optional["bool"] = None,
-        protocol_version: Optional["int"] = None,
+        protocol_version_major: Optional["int"] = None,
+        protocol_version_minor: Optional["int"] = None,
     ) -> None:
         self.pairing_methods: Sequence["ThpPairingMethod"] = pairing_methods if pairing_methods is not None else []
         self.internal_model = internal_model
         self.model_variant = model_variant
-        self.bootloader_mode = bootloader_mode
-        self.protocol_version = protocol_version
+        self.protocol_version_major = protocol_version_major
+        self.protocol_version_minor = protocol_version_minor
 
 
 class ThpHandshakeCompletionReqNoisePayload(protobuf.MessageType):
     MESSAGE_WIRE_TYPE = None
     FIELDS = {
         1: protobuf.Field("host_pairing_credential", "bytes", repeated=False, required=False, default=None),
-        2: protobuf.Field("pairing_methods", "ThpPairingMethod", repeated=True, required=False, default=None),
     }
 
     def __init__(
         self,
         *,
-        pairing_methods: Optional[Sequence["ThpPairingMethod"]] = None,
         host_pairing_credential: Optional["bytes"] = None,
     ) -> None:
-        self.pairing_methods: Sequence["ThpPairingMethod"] = pairing_methods if pairing_methods is not None else []
         self.host_pairing_credential = host_pairing_credential
 
 
@@ -7967,22 +7964,8 @@ class ThpCreateNewSession(protobuf.MessageType):
         self.derive_cardano = derive_cardano
 
 
-class ThpNewSession(protobuf.MessageType):
-    MESSAGE_WIRE_TYPE = 1001
-    FIELDS = {
-        1: protobuf.Field("new_session_id", "uint32", repeated=False, required=False, default=None),
-    }
-
-    def __init__(
-        self,
-        *,
-        new_session_id: Optional["int"] = None,
-    ) -> None:
-        self.new_session_id = new_session_id
-
-
-class ThpStartPairingRequest(protobuf.MessageType):
-    MESSAGE_WIRE_TYPE = 1008
+class ThpPairingRequest(protobuf.MessageType):
+    MESSAGE_WIRE_TYPE = 1006
     FIELDS = {
         1: protobuf.Field("host_name", "string", repeated=False, required=False, default=None),
     }
@@ -7995,6 +7978,24 @@ class ThpStartPairingRequest(protobuf.MessageType):
         self.host_name = host_name
 
 
+class ThpPairingRequestAck(protobuf.MessageType):
+    MESSAGE_WIRE_TYPE = 1007
+
+
+class ThpSelectMethod(protobuf.MessageType):
+    MESSAGE_WIRE_TYPE = 1008
+    FIELDS = {
+        1: protobuf.Field("selected_pairing_method", "ThpPairingMethod", repeated=False, required=False, default=None),
+    }
+
+    def __init__(
+        self,
+        *,
+        selected_pairing_method: Optional["ThpPairingMethod"] = None,
+    ) -> None:
+        self.selected_pairing_method = selected_pairing_method
+
+
 class ThpPairingPreparationsFinished(protobuf.MessageType):
     MESSAGE_WIRE_TYPE = 1009
 
@@ -8027,22 +8028,8 @@ class ThpCodeEntryChallenge(protobuf.MessageType):
         self.challenge = challenge
 
 
-class ThpCodeEntryCpaceHost(protobuf.MessageType):
-    MESSAGE_WIRE_TYPE = 1018
-    FIELDS = {
-        1: protobuf.Field("cpace_host_public_key", "bytes", repeated=False, required=False, default=None),
-    }
-
-    def __init__(
-        self,
-        *,
-        cpace_host_public_key: Optional["bytes"] = None,
-    ) -> None:
-        self.cpace_host_public_key = cpace_host_public_key
-
-
 class ThpCodeEntryCpaceTrezor(protobuf.MessageType):
-    MESSAGE_WIRE_TYPE = 1019
+    MESSAGE_WIRE_TYPE = 1018
     FIELDS = {
         1: protobuf.Field("cpace_trezor_public_key", "bytes", repeated=False, required=False, default=None),
     }
@@ -8055,22 +8042,25 @@ class ThpCodeEntryCpaceTrezor(protobuf.MessageType):
         self.cpace_trezor_public_key = cpace_trezor_public_key
 
 
-class ThpCodeEntryTag(protobuf.MessageType):
-    MESSAGE_WIRE_TYPE = 1020
+class ThpCodeEntryCpaceHostTag(protobuf.MessageType):
+    MESSAGE_WIRE_TYPE = 1019
     FIELDS = {
+        1: protobuf.Field("cpace_host_public_key", "bytes", repeated=False, required=False, default=None),
         2: protobuf.Field("tag", "bytes", repeated=False, required=False, default=None),
     }
 
     def __init__(
         self,
         *,
+        cpace_host_public_key: Optional["bytes"] = None,
         tag: Optional["bytes"] = None,
     ) -> None:
+        self.cpace_host_public_key = cpace_host_public_key
         self.tag = tag
 
 
 class ThpCodeEntrySecret(protobuf.MessageType):
-    MESSAGE_WIRE_TYPE = 1021
+    MESSAGE_WIRE_TYPE = 1020
     FIELDS = {
         1: protobuf.Field("secret", "bytes", repeated=False, required=False, default=None),
     }
@@ -8111,7 +8101,7 @@ class ThpQrCodeSecret(protobuf.MessageType):
         self.secret = secret
 
 
-class ThpNfcUnidirectionalTag(protobuf.MessageType):
+class ThpNfcTagHost(protobuf.MessageType):
     MESSAGE_WIRE_TYPE = 1032
     FIELDS = {
         1: protobuf.Field("tag", "bytes", repeated=False, required=False, default=None),
@@ -8125,32 +8115,35 @@ class ThpNfcUnidirectionalTag(protobuf.MessageType):
         self.tag = tag
 
 
-class ThpNfcUnidirectionalSecret(protobuf.MessageType):
+class ThpNfcTagTrezor(protobuf.MessageType):
     MESSAGE_WIRE_TYPE = 1033
     FIELDS = {
-        1: protobuf.Field("secret", "bytes", repeated=False, required=False, default=None),
+        1: protobuf.Field("tag", "bytes", repeated=False, required=False, default=None),
     }
 
     def __init__(
         self,
         *,
-        secret: Optional["bytes"] = None,
+        tag: Optional["bytes"] = None,
     ) -> None:
-        self.secret = secret
+        self.tag = tag
 
 
 class ThpCredentialRequest(protobuf.MessageType):
     MESSAGE_WIRE_TYPE = 1010
     FIELDS = {
         1: protobuf.Field("host_static_pubkey", "bytes", repeated=False, required=False, default=None),
+        2: protobuf.Field("autoconnect", "bool", repeated=False, required=False, default=None),
     }
 
     def __init__(
         self,
         *,
         host_static_pubkey: Optional["bytes"] = None,
+        autoconnect: Optional["bool"] = None,
     ) -> None:
         self.host_static_pubkey = host_static_pubkey
+        self.autoconnect = autoconnect
 
 
 class ThpCredentialResponse(protobuf.MessageType):
@@ -8182,14 +8175,17 @@ class ThpCredentialMetadata(protobuf.MessageType):
     MESSAGE_WIRE_TYPE = None
     FIELDS = {
         1: protobuf.Field("host_name", "string", repeated=False, required=False, default=None),
+        2: protobuf.Field("autoconnect", "bool", repeated=False, required=False, default=None),
     }
 
     def __init__(
         self,
         *,
         host_name: Optional["str"] = None,
+        autoconnect: Optional["bool"] = None,
     ) -> None:
         self.host_name = host_name
+        self.autoconnect = autoconnect
 
 
 class ThpPairingCredential(protobuf.MessageType):
diff --git a/python/src/trezorlib/transport/thp/protocol_v2.py b/python/src/trezorlib/transport/thp/protocol_v2.py
index 945dde6893..ccb2400cab 100644
--- a/python/src/trezorlib/transport/thp/protocol_v2.py
+++ b/python/src/trezorlib/transport/thp/protocol_v2.py
@@ -306,7 +306,7 @@ class ProtocolV2(ProtocolAndChannel):
 
     def _do_pairing(self):
         # Send StartPairingReqest message
-        message = messages.ThpStartPairingRequest()
+        message = messages.ThpPairingRequest()
         message_type, message_data = self.mapping.encode(message)
 
         self._encrypt_and_write(MANAGEMENT_SESSION_ID, message_type, message_data)
diff --git a/rust/trezor-client/src/protos/generated/messages_thp.rs b/rust/trezor-client/src/protos/generated/messages_thp.rs
index 9bd5e40d3d..334a652415 100644
--- a/rust/trezor-client/src/protos/generated/messages_thp.rs
+++ b/rust/trezor-client/src/protos/generated/messages_thp.rs
@@ -33,10 +33,10 @@ pub struct ThpDeviceProperties {
     pub internal_model: ::std::option::Option<::std::string::String>,
     // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpDeviceProperties.model_variant)
     pub model_variant: ::std::option::Option<u32>,
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpDeviceProperties.bootloader_mode)
-    pub bootloader_mode: ::std::option::Option<bool>,
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpDeviceProperties.protocol_version)
-    pub protocol_version: ::std::option::Option<u32>,
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpDeviceProperties.protocol_version_major)
+    pub protocol_version_major: ::std::option::Option<u32>,
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpDeviceProperties.protocol_version_minor)
+    pub protocol_version_minor: ::std::option::Option<u32>,
     // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpDeviceProperties.pairing_methods)
     pub pairing_methods: ::std::vec::Vec<::protobuf::EnumOrUnknown<ThpPairingMethod>>,
     // special fields
@@ -110,42 +110,42 @@ impl ThpDeviceProperties {
         self.model_variant = ::std::option::Option::Some(v);
     }
 
-    // optional bool bootloader_mode = 3;
+    // optional uint32 protocol_version_major = 3;
 
-    pub fn bootloader_mode(&self) -> bool {
-        self.bootloader_mode.unwrap_or(false)
+    pub fn protocol_version_major(&self) -> u32 {
+        self.protocol_version_major.unwrap_or(0)
     }
 
-    pub fn clear_bootloader_mode(&mut self) {
-        self.bootloader_mode = ::std::option::Option::None;
+    pub fn clear_protocol_version_major(&mut self) {
+        self.protocol_version_major = ::std::option::Option::None;
     }
 
-    pub fn has_bootloader_mode(&self) -> bool {
-        self.bootloader_mode.is_some()
+    pub fn has_protocol_version_major(&self) -> bool {
+        self.protocol_version_major.is_some()
     }
 
     // Param is passed by value, moved
-    pub fn set_bootloader_mode(&mut self, v: bool) {
-        self.bootloader_mode = ::std::option::Option::Some(v);
+    pub fn set_protocol_version_major(&mut self, v: u32) {
+        self.protocol_version_major = ::std::option::Option::Some(v);
     }
 
-    // optional uint32 protocol_version = 4;
+    // optional uint32 protocol_version_minor = 4;
 
-    pub fn protocol_version(&self) -> u32 {
-        self.protocol_version.unwrap_or(0)
+    pub fn protocol_version_minor(&self) -> u32 {
+        self.protocol_version_minor.unwrap_or(0)
     }
 
-    pub fn clear_protocol_version(&mut self) {
-        self.protocol_version = ::std::option::Option::None;
+    pub fn clear_protocol_version_minor(&mut self) {
+        self.protocol_version_minor = ::std::option::Option::None;
     }
 
-    pub fn has_protocol_version(&self) -> bool {
-        self.protocol_version.is_some()
+    pub fn has_protocol_version_minor(&self) -> bool {
+        self.protocol_version_minor.is_some()
     }
 
     // Param is passed by value, moved
-    pub fn set_protocol_version(&mut self, v: u32) {
-        self.protocol_version = ::std::option::Option::Some(v);
+    pub fn set_protocol_version_minor(&mut self, v: u32) {
+        self.protocol_version_minor = ::std::option::Option::Some(v);
     }
 
     fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
@@ -162,14 +162,14 @@ impl ThpDeviceProperties {
             |m: &mut ThpDeviceProperties| { &mut m.model_variant },
         ));
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
-            "bootloader_mode",
-            |m: &ThpDeviceProperties| { &m.bootloader_mode },
-            |m: &mut ThpDeviceProperties| { &mut m.bootloader_mode },
+            "protocol_version_major",
+            |m: &ThpDeviceProperties| { &m.protocol_version_major },
+            |m: &mut ThpDeviceProperties| { &mut m.protocol_version_major },
         ));
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
-            "protocol_version",
-            |m: &ThpDeviceProperties| { &m.protocol_version },
-            |m: &mut ThpDeviceProperties| { &mut m.protocol_version },
+            "protocol_version_minor",
+            |m: &ThpDeviceProperties| { &m.protocol_version_minor },
+            |m: &mut ThpDeviceProperties| { &mut m.protocol_version_minor },
         ));
         fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
             "pairing_methods",
@@ -201,10 +201,10 @@ impl ::protobuf::Message for ThpDeviceProperties {
                     self.model_variant = ::std::option::Option::Some(is.read_uint32()?);
                 },
                 24 => {
-                    self.bootloader_mode = ::std::option::Option::Some(is.read_bool()?);
+                    self.protocol_version_major = ::std::option::Option::Some(is.read_uint32()?);
                 },
                 32 => {
-                    self.protocol_version = ::std::option::Option::Some(is.read_uint32()?);
+                    self.protocol_version_minor = ::std::option::Option::Some(is.read_uint32()?);
                 },
                 40 => {
                     self.pairing_methods.push(is.read_enum_or_unknown()?);
@@ -230,10 +230,10 @@ impl ::protobuf::Message for ThpDeviceProperties {
         if let Some(v) = self.model_variant {
             my_size += ::protobuf::rt::uint32_size(2, v);
         }
-        if let Some(v) = self.bootloader_mode {
-            my_size += 1 + 1;
+        if let Some(v) = self.protocol_version_major {
+            my_size += ::protobuf::rt::uint32_size(3, v);
         }
-        if let Some(v) = self.protocol_version {
+        if let Some(v) = self.protocol_version_minor {
             my_size += ::protobuf::rt::uint32_size(4, v);
         }
         for value in &self.pairing_methods {
@@ -251,10 +251,10 @@ impl ::protobuf::Message for ThpDeviceProperties {
         if let Some(v) = self.model_variant {
             os.write_uint32(2, v)?;
         }
-        if let Some(v) = self.bootloader_mode {
-            os.write_bool(3, v)?;
+        if let Some(v) = self.protocol_version_major {
+            os.write_uint32(3, v)?;
         }
-        if let Some(v) = self.protocol_version {
+        if let Some(v) = self.protocol_version_minor {
             os.write_uint32(4, v)?;
         }
         for v in &self.pairing_methods {
@@ -279,8 +279,8 @@ impl ::protobuf::Message for ThpDeviceProperties {
     fn clear(&mut self) {
         self.internal_model = ::std::option::Option::None;
         self.model_variant = ::std::option::Option::None;
-        self.bootloader_mode = ::std::option::Option::None;
-        self.protocol_version = ::std::option::Option::None;
+        self.protocol_version_major = ::std::option::Option::None;
+        self.protocol_version_minor = ::std::option::Option::None;
         self.pairing_methods.clear();
         self.special_fields.clear();
     }
@@ -289,8 +289,8 @@ impl ::protobuf::Message for ThpDeviceProperties {
         static instance: ThpDeviceProperties = ThpDeviceProperties {
             internal_model: ::std::option::Option::None,
             model_variant: ::std::option::Option::None,
-            bootloader_mode: ::std::option::Option::None,
-            protocol_version: ::std::option::Option::None,
+            protocol_version_major: ::std::option::Option::None,
+            protocol_version_minor: ::std::option::Option::None,
             pairing_methods: ::std::vec::Vec::new(),
             special_fields: ::protobuf::SpecialFields::new(),
         };
@@ -321,8 +321,6 @@ pub struct ThpHandshakeCompletionReqNoisePayload {
     // message fields
     // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpHandshakeCompletionReqNoisePayload.host_pairing_credential)
     pub host_pairing_credential: ::std::option::Option<::std::vec::Vec<u8>>,
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpHandshakeCompletionReqNoisePayload.pairing_methods)
-    pub pairing_methods: ::std::vec::Vec<::protobuf::EnumOrUnknown<ThpPairingMethod>>,
     // special fields
     // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpHandshakeCompletionReqNoisePayload.special_fields)
     pub special_fields: ::protobuf::SpecialFields,
@@ -376,18 +374,13 @@ impl ThpHandshakeCompletionReqNoisePayload {
     }
 
     fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
-        let mut fields = ::std::vec::Vec::with_capacity(2);
+        let mut fields = ::std::vec::Vec::with_capacity(1);
         let mut oneofs = ::std::vec::Vec::with_capacity(0);
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
             "host_pairing_credential",
             |m: &ThpHandshakeCompletionReqNoisePayload| { &m.host_pairing_credential },
             |m: &mut ThpHandshakeCompletionReqNoisePayload| { &mut m.host_pairing_credential },
         ));
-        fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
-            "pairing_methods",
-            |m: &ThpHandshakeCompletionReqNoisePayload| { &m.pairing_methods },
-            |m: &mut ThpHandshakeCompletionReqNoisePayload| { &mut m.pairing_methods },
-        ));
         ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpHandshakeCompletionReqNoisePayload>(
             "ThpHandshakeCompletionReqNoisePayload",
             fields,
@@ -409,12 +402,6 @@ impl ::protobuf::Message for ThpHandshakeCompletionReqNoisePayload {
                 10 => {
                     self.host_pairing_credential = ::std::option::Option::Some(is.read_bytes()?);
                 },
-                16 => {
-                    self.pairing_methods.push(is.read_enum_or_unknown()?);
-                },
-                18 => {
-                    ::protobuf::rt::read_repeated_packed_enum_or_unknown_into(is, &mut self.pairing_methods)?
-                },
                 tag => {
                     ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
                 },
@@ -430,9 +417,6 @@ impl ::protobuf::Message for ThpHandshakeCompletionReqNoisePayload {
         if let Some(v) = self.host_pairing_credential.as_ref() {
             my_size += ::protobuf::rt::bytes_size(1, &v);
         }
-        for value in &self.pairing_methods {
-            my_size += ::protobuf::rt::int32_size(2, value.value());
-        };
         my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
         self.special_fields.cached_size().set(my_size as u32);
         my_size
@@ -442,9 +426,6 @@ impl ::protobuf::Message for ThpHandshakeCompletionReqNoisePayload {
         if let Some(v) = self.host_pairing_credential.as_ref() {
             os.write_bytes(1, v)?;
         }
-        for v in &self.pairing_methods {
-            os.write_enum(2, ::protobuf::EnumOrUnknown::value(v))?;
-        };
         os.write_unknown_fields(self.special_fields.unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -463,14 +444,12 @@ impl ::protobuf::Message for ThpHandshakeCompletionReqNoisePayload {
 
     fn clear(&mut self) {
         self.host_pairing_credential = ::std::option::Option::None;
-        self.pairing_methods.clear();
         self.special_fields.clear();
     }
 
     fn default_instance() -> &'static ThpHandshakeCompletionReqNoisePayload {
         static instance: ThpHandshakeCompletionReqNoisePayload = ThpHandshakeCompletionReqNoisePayload {
             host_pairing_credential: ::std::option::Option::None,
-            pairing_methods: ::std::vec::Vec::new(),
             special_fields: ::protobuf::SpecialFields::new(),
         };
         &instance
@@ -726,166 +705,25 @@ impl ::protobuf::reflect::ProtobufValue for ThpCreateNewSession {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
-// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpNewSession)
+// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpPairingRequest)
 #[derive(PartialEq,Clone,Default,Debug)]
-pub struct ThpNewSession {
+pub struct ThpPairingRequest {
     // message fields
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpNewSession.new_session_id)
-    pub new_session_id: ::std::option::Option<u32>,
-    // special fields
-    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpNewSession.special_fields)
-    pub special_fields: ::protobuf::SpecialFields,
-}
-
-impl<'a> ::std::default::Default for &'a ThpNewSession {
-    fn default() -> &'a ThpNewSession {
-        <ThpNewSession as ::protobuf::Message>::default_instance()
-    }
-}
-
-impl ThpNewSession {
-    pub fn new() -> ThpNewSession {
-        ::std::default::Default::default()
-    }
-
-    // optional uint32 new_session_id = 1;
-
-    pub fn new_session_id(&self) -> u32 {
-        self.new_session_id.unwrap_or(0)
-    }
-
-    pub fn clear_new_session_id(&mut self) {
-        self.new_session_id = ::std::option::Option::None;
-    }
-
-    pub fn has_new_session_id(&self) -> bool {
-        self.new_session_id.is_some()
-    }
-
-    // Param is passed by value, moved
-    pub fn set_new_session_id(&mut self, v: u32) {
-        self.new_session_id = ::std::option::Option::Some(v);
-    }
-
-    fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
-        let mut fields = ::std::vec::Vec::with_capacity(1);
-        let mut oneofs = ::std::vec::Vec::with_capacity(0);
-        fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
-            "new_session_id",
-            |m: &ThpNewSession| { &m.new_session_id },
-            |m: &mut ThpNewSession| { &mut m.new_session_id },
-        ));
-        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpNewSession>(
-            "ThpNewSession",
-            fields,
-            oneofs,
-        )
-    }
-}
-
-impl ::protobuf::Message for ThpNewSession {
-    const NAME: &'static str = "ThpNewSession";
-
-    fn is_initialized(&self) -> bool {
-        true
-    }
-
-    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
-        while let Some(tag) = is.read_raw_tag_or_eof()? {
-            match tag {
-                8 => {
-                    self.new_session_id = ::std::option::Option::Some(is.read_uint32()?);
-                },
-                tag => {
-                    ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
-                },
-            };
-        }
-        ::std::result::Result::Ok(())
-    }
-
-    // Compute sizes of nested messages
-    #[allow(unused_variables)]
-    fn compute_size(&self) -> u64 {
-        let mut my_size = 0;
-        if let Some(v) = self.new_session_id {
-            my_size += ::protobuf::rt::uint32_size(1, v);
-        }
-        my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
-        self.special_fields.cached_size().set(my_size as u32);
-        my_size
-    }
-
-    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
-        if let Some(v) = self.new_session_id {
-            os.write_uint32(1, v)?;
-        }
-        os.write_unknown_fields(self.special_fields.unknown_fields())?;
-        ::std::result::Result::Ok(())
-    }
-
-    fn special_fields(&self) -> &::protobuf::SpecialFields {
-        &self.special_fields
-    }
-
-    fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
-        &mut self.special_fields
-    }
-
-    fn new() -> ThpNewSession {
-        ThpNewSession::new()
-    }
-
-    fn clear(&mut self) {
-        self.new_session_id = ::std::option::Option::None;
-        self.special_fields.clear();
-    }
-
-    fn default_instance() -> &'static ThpNewSession {
-        static instance: ThpNewSession = ThpNewSession {
-            new_session_id: ::std::option::Option::None,
-            special_fields: ::protobuf::SpecialFields::new(),
-        };
-        &instance
-    }
-}
-
-impl ::protobuf::MessageFull for ThpNewSession {
-    fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
-        static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
-        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpNewSession").unwrap()).clone()
-    }
-}
-
-impl ::std::fmt::Display for ThpNewSession {
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-        ::protobuf::text_format::fmt(self, f)
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for ThpNewSession {
-    type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
-}
-
-// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpStartPairingRequest)
-#[derive(PartialEq,Clone,Default,Debug)]
-pub struct ThpStartPairingRequest {
-    // message fields
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpStartPairingRequest.host_name)
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpPairingRequest.host_name)
     pub host_name: ::std::option::Option<::std::string::String>,
     // special fields
-    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpStartPairingRequest.special_fields)
+    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpPairingRequest.special_fields)
     pub special_fields: ::protobuf::SpecialFields,
 }
 
-impl<'a> ::std::default::Default for &'a ThpStartPairingRequest {
-    fn default() -> &'a ThpStartPairingRequest {
-        <ThpStartPairingRequest as ::protobuf::Message>::default_instance()
+impl<'a> ::std::default::Default for &'a ThpPairingRequest {
+    fn default() -> &'a ThpPairingRequest {
+        <ThpPairingRequest as ::protobuf::Message>::default_instance()
     }
 }
 
-impl ThpStartPairingRequest {
-    pub fn new() -> ThpStartPairingRequest {
+impl ThpPairingRequest {
+    pub fn new() -> ThpPairingRequest {
         ::std::default::Default::default()
     }
 
@@ -930,19 +768,19 @@ impl ThpStartPairingRequest {
         let mut oneofs = ::std::vec::Vec::with_capacity(0);
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
             "host_name",
-            |m: &ThpStartPairingRequest| { &m.host_name },
-            |m: &mut ThpStartPairingRequest| { &mut m.host_name },
+            |m: &ThpPairingRequest| { &m.host_name },
+            |m: &mut ThpPairingRequest| { &mut m.host_name },
         ));
-        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpStartPairingRequest>(
-            "ThpStartPairingRequest",
+        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpPairingRequest>(
+            "ThpPairingRequest",
             fields,
             oneofs,
         )
     }
 }
 
-impl ::protobuf::Message for ThpStartPairingRequest {
-    const NAME: &'static str = "ThpStartPairingRequest";
+impl ::protobuf::Message for ThpPairingRequest {
+    const NAME: &'static str = "ThpPairingRequest";
 
     fn is_initialized(&self) -> bool {
         true
@@ -990,8 +828,8 @@ impl ::protobuf::Message for ThpStartPairingRequest {
         &mut self.special_fields
     }
 
-    fn new() -> ThpStartPairingRequest {
-        ThpStartPairingRequest::new()
+    fn new() -> ThpPairingRequest {
+        ThpPairingRequest::new()
     }
 
     fn clear(&mut self) {
@@ -999,8 +837,8 @@ impl ::protobuf::Message for ThpStartPairingRequest {
         self.special_fields.clear();
     }
 
-    fn default_instance() -> &'static ThpStartPairingRequest {
-        static instance: ThpStartPairingRequest = ThpStartPairingRequest {
+    fn default_instance() -> &'static ThpPairingRequest {
+        static instance: ThpPairingRequest = ThpPairingRequest {
             host_name: ::std::option::Option::None,
             special_fields: ::protobuf::SpecialFields::new(),
         };
@@ -1008,20 +846,267 @@ impl ::protobuf::Message for ThpStartPairingRequest {
     }
 }
 
-impl ::protobuf::MessageFull for ThpStartPairingRequest {
+impl ::protobuf::MessageFull for ThpPairingRequest {
     fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
         static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
-        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpStartPairingRequest").unwrap()).clone()
+        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpPairingRequest").unwrap()).clone()
     }
 }
 
-impl ::std::fmt::Display for ThpStartPairingRequest {
+impl ::std::fmt::Display for ThpPairingRequest {
     fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
         ::protobuf::text_format::fmt(self, f)
     }
 }
 
-impl ::protobuf::reflect::ProtobufValue for ThpStartPairingRequest {
+impl ::protobuf::reflect::ProtobufValue for ThpPairingRequest {
+    type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
+}
+
+// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpPairingRequestAck)
+#[derive(PartialEq,Clone,Default,Debug)]
+pub struct ThpPairingRequestAck {
+    // special fields
+    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpPairingRequestAck.special_fields)
+    pub special_fields: ::protobuf::SpecialFields,
+}
+
+impl<'a> ::std::default::Default for &'a ThpPairingRequestAck {
+    fn default() -> &'a ThpPairingRequestAck {
+        <ThpPairingRequestAck as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ThpPairingRequestAck {
+    pub fn new() -> ThpPairingRequestAck {
+        ::std::default::Default::default()
+    }
+
+    fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
+        let mut fields = ::std::vec::Vec::with_capacity(0);
+        let mut oneofs = ::std::vec::Vec::with_capacity(0);
+        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpPairingRequestAck>(
+            "ThpPairingRequestAck",
+            fields,
+            oneofs,
+        )
+    }
+}
+
+impl ::protobuf::Message for ThpPairingRequestAck {
+    const NAME: &'static str = "ThpPairingRequestAck";
+
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
+        while let Some(tag) = is.read_raw_tag_or_eof()? {
+            match tag {
+                tag => {
+                    ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u64 {
+        let mut my_size = 0;
+        my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
+        self.special_fields.cached_size().set(my_size as u32);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
+        os.write_unknown_fields(self.special_fields.unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn special_fields(&self) -> &::protobuf::SpecialFields {
+        &self.special_fields
+    }
+
+    fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
+        &mut self.special_fields
+    }
+
+    fn new() -> ThpPairingRequestAck {
+        ThpPairingRequestAck::new()
+    }
+
+    fn clear(&mut self) {
+        self.special_fields.clear();
+    }
+
+    fn default_instance() -> &'static ThpPairingRequestAck {
+        static instance: ThpPairingRequestAck = ThpPairingRequestAck {
+            special_fields: ::protobuf::SpecialFields::new(),
+        };
+        &instance
+    }
+}
+
+impl ::protobuf::MessageFull for ThpPairingRequestAck {
+    fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
+        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpPairingRequestAck").unwrap()).clone()
+    }
+}
+
+impl ::std::fmt::Display for ThpPairingRequestAck {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ThpPairingRequestAck {
+    type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
+}
+
+// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpSelectMethod)
+#[derive(PartialEq,Clone,Default,Debug)]
+pub struct ThpSelectMethod {
+    // message fields
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpSelectMethod.selected_pairing_method)
+    pub selected_pairing_method: ::std::option::Option<::protobuf::EnumOrUnknown<ThpPairingMethod>>,
+    // special fields
+    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpSelectMethod.special_fields)
+    pub special_fields: ::protobuf::SpecialFields,
+}
+
+impl<'a> ::std::default::Default for &'a ThpSelectMethod {
+    fn default() -> &'a ThpSelectMethod {
+        <ThpSelectMethod as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ThpSelectMethod {
+    pub fn new() -> ThpSelectMethod {
+        ::std::default::Default::default()
+    }
+
+    // optional .hw.trezor.messages.thp.ThpPairingMethod selected_pairing_method = 1;
+
+    pub fn selected_pairing_method(&self) -> ThpPairingMethod {
+        match self.selected_pairing_method {
+            Some(e) => e.enum_value_or(ThpPairingMethod::SkipPairing),
+            None => ThpPairingMethod::SkipPairing,
+        }
+    }
+
+    pub fn clear_selected_pairing_method(&mut self) {
+        self.selected_pairing_method = ::std::option::Option::None;
+    }
+
+    pub fn has_selected_pairing_method(&self) -> bool {
+        self.selected_pairing_method.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_selected_pairing_method(&mut self, v: ThpPairingMethod) {
+        self.selected_pairing_method = ::std::option::Option::Some(::protobuf::EnumOrUnknown::new(v));
+    }
+
+    fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
+        let mut fields = ::std::vec::Vec::with_capacity(1);
+        let mut oneofs = ::std::vec::Vec::with_capacity(0);
+        fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+            "selected_pairing_method",
+            |m: &ThpSelectMethod| { &m.selected_pairing_method },
+            |m: &mut ThpSelectMethod| { &mut m.selected_pairing_method },
+        ));
+        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpSelectMethod>(
+            "ThpSelectMethod",
+            fields,
+            oneofs,
+        )
+    }
+}
+
+impl ::protobuf::Message for ThpSelectMethod {
+    const NAME: &'static str = "ThpSelectMethod";
+
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
+        while let Some(tag) = is.read_raw_tag_or_eof()? {
+            match tag {
+                8 => {
+                    self.selected_pairing_method = ::std::option::Option::Some(is.read_enum_or_unknown()?);
+                },
+                tag => {
+                    ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u64 {
+        let mut my_size = 0;
+        if let Some(v) = self.selected_pairing_method {
+            my_size += ::protobuf::rt::int32_size(1, v.value());
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
+        self.special_fields.cached_size().set(my_size as u32);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
+        if let Some(v) = self.selected_pairing_method {
+            os.write_enum(1, ::protobuf::EnumOrUnknown::value(&v))?;
+        }
+        os.write_unknown_fields(self.special_fields.unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn special_fields(&self) -> &::protobuf::SpecialFields {
+        &self.special_fields
+    }
+
+    fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
+        &mut self.special_fields
+    }
+
+    fn new() -> ThpSelectMethod {
+        ThpSelectMethod::new()
+    }
+
+    fn clear(&mut self) {
+        self.selected_pairing_method = ::std::option::Option::None;
+        self.special_fields.clear();
+    }
+
+    fn default_instance() -> &'static ThpSelectMethod {
+        static instance: ThpSelectMethod = ThpSelectMethod {
+            selected_pairing_method: ::std::option::Option::None,
+            special_fields: ::protobuf::SpecialFields::new(),
+        };
+        &instance
+    }
+}
+
+impl ::protobuf::MessageFull for ThpSelectMethod {
+    fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
+        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpSelectMethod").unwrap()).clone()
+    }
+}
+
+impl ::std::fmt::Display for ThpSelectMethod {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ThpSelectMethod {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
@@ -1444,164 +1529,6 @@ impl ::protobuf::reflect::ProtobufValue for ThpCodeEntryChallenge {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
-// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpCodeEntryCpaceHost)
-#[derive(PartialEq,Clone,Default,Debug)]
-pub struct ThpCodeEntryCpaceHost {
-    // message fields
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCodeEntryCpaceHost.cpace_host_public_key)
-    pub cpace_host_public_key: ::std::option::Option<::std::vec::Vec<u8>>,
-    // special fields
-    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpCodeEntryCpaceHost.special_fields)
-    pub special_fields: ::protobuf::SpecialFields,
-}
-
-impl<'a> ::std::default::Default for &'a ThpCodeEntryCpaceHost {
-    fn default() -> &'a ThpCodeEntryCpaceHost {
-        <ThpCodeEntryCpaceHost as ::protobuf::Message>::default_instance()
-    }
-}
-
-impl ThpCodeEntryCpaceHost {
-    pub fn new() -> ThpCodeEntryCpaceHost {
-        ::std::default::Default::default()
-    }
-
-    // optional bytes cpace_host_public_key = 1;
-
-    pub fn cpace_host_public_key(&self) -> &[u8] {
-        match self.cpace_host_public_key.as_ref() {
-            Some(v) => v,
-            None => &[],
-        }
-    }
-
-    pub fn clear_cpace_host_public_key(&mut self) {
-        self.cpace_host_public_key = ::std::option::Option::None;
-    }
-
-    pub fn has_cpace_host_public_key(&self) -> bool {
-        self.cpace_host_public_key.is_some()
-    }
-
-    // Param is passed by value, moved
-    pub fn set_cpace_host_public_key(&mut self, v: ::std::vec::Vec<u8>) {
-        self.cpace_host_public_key = ::std::option::Option::Some(v);
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_cpace_host_public_key(&mut self) -> &mut ::std::vec::Vec<u8> {
-        if self.cpace_host_public_key.is_none() {
-            self.cpace_host_public_key = ::std::option::Option::Some(::std::vec::Vec::new());
-        }
-        self.cpace_host_public_key.as_mut().unwrap()
-    }
-
-    // Take field
-    pub fn take_cpace_host_public_key(&mut self) -> ::std::vec::Vec<u8> {
-        self.cpace_host_public_key.take().unwrap_or_else(|| ::std::vec::Vec::new())
-    }
-
-    fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
-        let mut fields = ::std::vec::Vec::with_capacity(1);
-        let mut oneofs = ::std::vec::Vec::with_capacity(0);
-        fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
-            "cpace_host_public_key",
-            |m: &ThpCodeEntryCpaceHost| { &m.cpace_host_public_key },
-            |m: &mut ThpCodeEntryCpaceHost| { &mut m.cpace_host_public_key },
-        ));
-        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpCodeEntryCpaceHost>(
-            "ThpCodeEntryCpaceHost",
-            fields,
-            oneofs,
-        )
-    }
-}
-
-impl ::protobuf::Message for ThpCodeEntryCpaceHost {
-    const NAME: &'static str = "ThpCodeEntryCpaceHost";
-
-    fn is_initialized(&self) -> bool {
-        true
-    }
-
-    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
-        while let Some(tag) = is.read_raw_tag_or_eof()? {
-            match tag {
-                10 => {
-                    self.cpace_host_public_key = ::std::option::Option::Some(is.read_bytes()?);
-                },
-                tag => {
-                    ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
-                },
-            };
-        }
-        ::std::result::Result::Ok(())
-    }
-
-    // Compute sizes of nested messages
-    #[allow(unused_variables)]
-    fn compute_size(&self) -> u64 {
-        let mut my_size = 0;
-        if let Some(v) = self.cpace_host_public_key.as_ref() {
-            my_size += ::protobuf::rt::bytes_size(1, &v);
-        }
-        my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
-        self.special_fields.cached_size().set(my_size as u32);
-        my_size
-    }
-
-    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
-        if let Some(v) = self.cpace_host_public_key.as_ref() {
-            os.write_bytes(1, v)?;
-        }
-        os.write_unknown_fields(self.special_fields.unknown_fields())?;
-        ::std::result::Result::Ok(())
-    }
-
-    fn special_fields(&self) -> &::protobuf::SpecialFields {
-        &self.special_fields
-    }
-
-    fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
-        &mut self.special_fields
-    }
-
-    fn new() -> ThpCodeEntryCpaceHost {
-        ThpCodeEntryCpaceHost::new()
-    }
-
-    fn clear(&mut self) {
-        self.cpace_host_public_key = ::std::option::Option::None;
-        self.special_fields.clear();
-    }
-
-    fn default_instance() -> &'static ThpCodeEntryCpaceHost {
-        static instance: ThpCodeEntryCpaceHost = ThpCodeEntryCpaceHost {
-            cpace_host_public_key: ::std::option::Option::None,
-            special_fields: ::protobuf::SpecialFields::new(),
-        };
-        &instance
-    }
-}
-
-impl ::protobuf::MessageFull for ThpCodeEntryCpaceHost {
-    fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
-        static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
-        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpCodeEntryCpaceHost").unwrap()).clone()
-    }
-}
-
-impl ::std::fmt::Display for ThpCodeEntryCpaceHost {
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-        ::protobuf::text_format::fmt(self, f)
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for ThpCodeEntryCpaceHost {
-    type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
-}
-
 // @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpCodeEntryCpaceTrezor)
 #[derive(PartialEq,Clone,Default,Debug)]
 pub struct ThpCodeEntryCpaceTrezor {
@@ -1760,28 +1687,66 @@ impl ::protobuf::reflect::ProtobufValue for ThpCodeEntryCpaceTrezor {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
-// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpCodeEntryTag)
+// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpCodeEntryCpaceHostTag)
 #[derive(PartialEq,Clone,Default,Debug)]
-pub struct ThpCodeEntryTag {
+pub struct ThpCodeEntryCpaceHostTag {
     // message fields
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCodeEntryTag.tag)
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCodeEntryCpaceHostTag.cpace_host_public_key)
+    pub cpace_host_public_key: ::std::option::Option<::std::vec::Vec<u8>>,
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCodeEntryCpaceHostTag.tag)
     pub tag: ::std::option::Option<::std::vec::Vec<u8>>,
     // special fields
-    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpCodeEntryTag.special_fields)
+    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpCodeEntryCpaceHostTag.special_fields)
     pub special_fields: ::protobuf::SpecialFields,
 }
 
-impl<'a> ::std::default::Default for &'a ThpCodeEntryTag {
-    fn default() -> &'a ThpCodeEntryTag {
-        <ThpCodeEntryTag as ::protobuf::Message>::default_instance()
+impl<'a> ::std::default::Default for &'a ThpCodeEntryCpaceHostTag {
+    fn default() -> &'a ThpCodeEntryCpaceHostTag {
+        <ThpCodeEntryCpaceHostTag as ::protobuf::Message>::default_instance()
     }
 }
 
-impl ThpCodeEntryTag {
-    pub fn new() -> ThpCodeEntryTag {
+impl ThpCodeEntryCpaceHostTag {
+    pub fn new() -> ThpCodeEntryCpaceHostTag {
         ::std::default::Default::default()
     }
 
+    // optional bytes cpace_host_public_key = 1;
+
+    pub fn cpace_host_public_key(&self) -> &[u8] {
+        match self.cpace_host_public_key.as_ref() {
+            Some(v) => v,
+            None => &[],
+        }
+    }
+
+    pub fn clear_cpace_host_public_key(&mut self) {
+        self.cpace_host_public_key = ::std::option::Option::None;
+    }
+
+    pub fn has_cpace_host_public_key(&self) -> bool {
+        self.cpace_host_public_key.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_cpace_host_public_key(&mut self, v: ::std::vec::Vec<u8>) {
+        self.cpace_host_public_key = ::std::option::Option::Some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_cpace_host_public_key(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.cpace_host_public_key.is_none() {
+            self.cpace_host_public_key = ::std::option::Option::Some(::std::vec::Vec::new());
+        }
+        self.cpace_host_public_key.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_cpace_host_public_key(&mut self) -> ::std::vec::Vec<u8> {
+        self.cpace_host_public_key.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    }
+
     // optional bytes tag = 2;
 
     pub fn tag(&self) -> &[u8] {
@@ -1819,23 +1784,28 @@ impl ThpCodeEntryTag {
     }
 
     fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
-        let mut fields = ::std::vec::Vec::with_capacity(1);
+        let mut fields = ::std::vec::Vec::with_capacity(2);
         let mut oneofs = ::std::vec::Vec::with_capacity(0);
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
-            "tag",
-            |m: &ThpCodeEntryTag| { &m.tag },
-            |m: &mut ThpCodeEntryTag| { &mut m.tag },
+            "cpace_host_public_key",
+            |m: &ThpCodeEntryCpaceHostTag| { &m.cpace_host_public_key },
+            |m: &mut ThpCodeEntryCpaceHostTag| { &mut m.cpace_host_public_key },
         ));
-        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpCodeEntryTag>(
-            "ThpCodeEntryTag",
+        fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+            "tag",
+            |m: &ThpCodeEntryCpaceHostTag| { &m.tag },
+            |m: &mut ThpCodeEntryCpaceHostTag| { &mut m.tag },
+        ));
+        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpCodeEntryCpaceHostTag>(
+            "ThpCodeEntryCpaceHostTag",
             fields,
             oneofs,
         )
     }
 }
 
-impl ::protobuf::Message for ThpCodeEntryTag {
-    const NAME: &'static str = "ThpCodeEntryTag";
+impl ::protobuf::Message for ThpCodeEntryCpaceHostTag {
+    const NAME: &'static str = "ThpCodeEntryCpaceHostTag";
 
     fn is_initialized(&self) -> bool {
         true
@@ -1844,6 +1814,9 @@ impl ::protobuf::Message for ThpCodeEntryTag {
     fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
         while let Some(tag) = is.read_raw_tag_or_eof()? {
             match tag {
+                10 => {
+                    self.cpace_host_public_key = ::std::option::Option::Some(is.read_bytes()?);
+                },
                 18 => {
                     self.tag = ::std::option::Option::Some(is.read_bytes()?);
                 },
@@ -1859,6 +1832,9 @@ impl ::protobuf::Message for ThpCodeEntryTag {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u64 {
         let mut my_size = 0;
+        if let Some(v) = self.cpace_host_public_key.as_ref() {
+            my_size += ::protobuf::rt::bytes_size(1, &v);
+        }
         if let Some(v) = self.tag.as_ref() {
             my_size += ::protobuf::rt::bytes_size(2, &v);
         }
@@ -1868,6 +1844,9 @@ impl ::protobuf::Message for ThpCodeEntryTag {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
+        if let Some(v) = self.cpace_host_public_key.as_ref() {
+            os.write_bytes(1, v)?;
+        }
         if let Some(v) = self.tag.as_ref() {
             os.write_bytes(2, v)?;
         }
@@ -1883,17 +1862,19 @@ impl ::protobuf::Message for ThpCodeEntryTag {
         &mut self.special_fields
     }
 
-    fn new() -> ThpCodeEntryTag {
-        ThpCodeEntryTag::new()
+    fn new() -> ThpCodeEntryCpaceHostTag {
+        ThpCodeEntryCpaceHostTag::new()
     }
 
     fn clear(&mut self) {
+        self.cpace_host_public_key = ::std::option::Option::None;
         self.tag = ::std::option::Option::None;
         self.special_fields.clear();
     }
 
-    fn default_instance() -> &'static ThpCodeEntryTag {
-        static instance: ThpCodeEntryTag = ThpCodeEntryTag {
+    fn default_instance() -> &'static ThpCodeEntryCpaceHostTag {
+        static instance: ThpCodeEntryCpaceHostTag = ThpCodeEntryCpaceHostTag {
+            cpace_host_public_key: ::std::option::Option::None,
             tag: ::std::option::Option::None,
             special_fields: ::protobuf::SpecialFields::new(),
         };
@@ -1901,20 +1882,20 @@ impl ::protobuf::Message for ThpCodeEntryTag {
     }
 }
 
-impl ::protobuf::MessageFull for ThpCodeEntryTag {
+impl ::protobuf::MessageFull for ThpCodeEntryCpaceHostTag {
     fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
         static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
-        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpCodeEntryTag").unwrap()).clone()
+        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpCodeEntryCpaceHostTag").unwrap()).clone()
     }
 }
 
-impl ::std::fmt::Display for ThpCodeEntryTag {
+impl ::std::fmt::Display for ThpCodeEntryCpaceHostTag {
     fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
         ::protobuf::text_format::fmt(self, f)
     }
 }
 
-impl ::protobuf::reflect::ProtobufValue for ThpCodeEntryTag {
+impl ::protobuf::reflect::ProtobufValue for ThpCodeEntryCpaceHostTag {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
@@ -2392,25 +2373,25 @@ impl ::protobuf::reflect::ProtobufValue for ThpQrCodeSecret {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
-// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpNfcUnidirectionalTag)
+// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpNfcTagHost)
 #[derive(PartialEq,Clone,Default,Debug)]
-pub struct ThpNfcUnidirectionalTag {
+pub struct ThpNfcTagHost {
     // message fields
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpNfcUnidirectionalTag.tag)
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpNfcTagHost.tag)
     pub tag: ::std::option::Option<::std::vec::Vec<u8>>,
     // special fields
-    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpNfcUnidirectionalTag.special_fields)
+    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpNfcTagHost.special_fields)
     pub special_fields: ::protobuf::SpecialFields,
 }
 
-impl<'a> ::std::default::Default for &'a ThpNfcUnidirectionalTag {
-    fn default() -> &'a ThpNfcUnidirectionalTag {
-        <ThpNfcUnidirectionalTag as ::protobuf::Message>::default_instance()
+impl<'a> ::std::default::Default for &'a ThpNfcTagHost {
+    fn default() -> &'a ThpNfcTagHost {
+        <ThpNfcTagHost as ::protobuf::Message>::default_instance()
     }
 }
 
-impl ThpNfcUnidirectionalTag {
-    pub fn new() -> ThpNfcUnidirectionalTag {
+impl ThpNfcTagHost {
+    pub fn new() -> ThpNfcTagHost {
         ::std::default::Default::default()
     }
 
@@ -2455,19 +2436,19 @@ impl ThpNfcUnidirectionalTag {
         let mut oneofs = ::std::vec::Vec::with_capacity(0);
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
             "tag",
-            |m: &ThpNfcUnidirectionalTag| { &m.tag },
-            |m: &mut ThpNfcUnidirectionalTag| { &mut m.tag },
+            |m: &ThpNfcTagHost| { &m.tag },
+            |m: &mut ThpNfcTagHost| { &mut m.tag },
         ));
-        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpNfcUnidirectionalTag>(
-            "ThpNfcUnidirectionalTag",
+        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpNfcTagHost>(
+            "ThpNfcTagHost",
             fields,
             oneofs,
         )
     }
 }
 
-impl ::protobuf::Message for ThpNfcUnidirectionalTag {
-    const NAME: &'static str = "ThpNfcUnidirectionalTag";
+impl ::protobuf::Message for ThpNfcTagHost {
+    const NAME: &'static str = "ThpNfcTagHost";
 
     fn is_initialized(&self) -> bool {
         true
@@ -2515,8 +2496,8 @@ impl ::protobuf::Message for ThpNfcUnidirectionalTag {
         &mut self.special_fields
     }
 
-    fn new() -> ThpNfcUnidirectionalTag {
-        ThpNfcUnidirectionalTag::new()
+    fn new() -> ThpNfcTagHost {
+        ThpNfcTagHost::new()
     }
 
     fn clear(&mut self) {
@@ -2524,8 +2505,8 @@ impl ::protobuf::Message for ThpNfcUnidirectionalTag {
         self.special_fields.clear();
     }
 
-    fn default_instance() -> &'static ThpNfcUnidirectionalTag {
-        static instance: ThpNfcUnidirectionalTag = ThpNfcUnidirectionalTag {
+    fn default_instance() -> &'static ThpNfcTagHost {
+        static instance: ThpNfcTagHost = ThpNfcTagHost {
             tag: ::std::option::Option::None,
             special_fields: ::protobuf::SpecialFields::new(),
         };
@@ -2533,99 +2514,99 @@ impl ::protobuf::Message for ThpNfcUnidirectionalTag {
     }
 }
 
-impl ::protobuf::MessageFull for ThpNfcUnidirectionalTag {
+impl ::protobuf::MessageFull for ThpNfcTagHost {
     fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
         static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
-        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpNfcUnidirectionalTag").unwrap()).clone()
+        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpNfcTagHost").unwrap()).clone()
     }
 }
 
-impl ::std::fmt::Display for ThpNfcUnidirectionalTag {
+impl ::std::fmt::Display for ThpNfcTagHost {
     fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
         ::protobuf::text_format::fmt(self, f)
     }
 }
 
-impl ::protobuf::reflect::ProtobufValue for ThpNfcUnidirectionalTag {
+impl ::protobuf::reflect::ProtobufValue for ThpNfcTagHost {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
-// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpNfcUnidirectionalSecret)
+// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpNfcTagTrezor)
 #[derive(PartialEq,Clone,Default,Debug)]
-pub struct ThpNfcUnidirectionalSecret {
+pub struct ThpNfcTagTrezor {
     // message fields
-    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpNfcUnidirectionalSecret.secret)
-    pub secret: ::std::option::Option<::std::vec::Vec<u8>>,
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpNfcTagTrezor.tag)
+    pub tag: ::std::option::Option<::std::vec::Vec<u8>>,
     // special fields
-    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpNfcUnidirectionalSecret.special_fields)
+    // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpNfcTagTrezor.special_fields)
     pub special_fields: ::protobuf::SpecialFields,
 }
 
-impl<'a> ::std::default::Default for &'a ThpNfcUnidirectionalSecret {
-    fn default() -> &'a ThpNfcUnidirectionalSecret {
-        <ThpNfcUnidirectionalSecret as ::protobuf::Message>::default_instance()
+impl<'a> ::std::default::Default for &'a ThpNfcTagTrezor {
+    fn default() -> &'a ThpNfcTagTrezor {
+        <ThpNfcTagTrezor as ::protobuf::Message>::default_instance()
     }
 }
 
-impl ThpNfcUnidirectionalSecret {
-    pub fn new() -> ThpNfcUnidirectionalSecret {
+impl ThpNfcTagTrezor {
+    pub fn new() -> ThpNfcTagTrezor {
         ::std::default::Default::default()
     }
 
-    // optional bytes secret = 1;
+    // optional bytes tag = 1;
 
-    pub fn secret(&self) -> &[u8] {
-        match self.secret.as_ref() {
+    pub fn tag(&self) -> &[u8] {
+        match self.tag.as_ref() {
             Some(v) => v,
             None => &[],
         }
     }
 
-    pub fn clear_secret(&mut self) {
-        self.secret = ::std::option::Option::None;
+    pub fn clear_tag(&mut self) {
+        self.tag = ::std::option::Option::None;
     }
 
-    pub fn has_secret(&self) -> bool {
-        self.secret.is_some()
+    pub fn has_tag(&self) -> bool {
+        self.tag.is_some()
     }
 
     // Param is passed by value, moved
-    pub fn set_secret(&mut self, v: ::std::vec::Vec<u8>) {
-        self.secret = ::std::option::Option::Some(v);
+    pub fn set_tag(&mut self, v: ::std::vec::Vec<u8>) {
+        self.tag = ::std::option::Option::Some(v);
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_secret(&mut self) -> &mut ::std::vec::Vec<u8> {
-        if self.secret.is_none() {
-            self.secret = ::std::option::Option::Some(::std::vec::Vec::new());
+    pub fn mut_tag(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if self.tag.is_none() {
+            self.tag = ::std::option::Option::Some(::std::vec::Vec::new());
         }
-        self.secret.as_mut().unwrap()
+        self.tag.as_mut().unwrap()
     }
 
     // Take field
-    pub fn take_secret(&mut self) -> ::std::vec::Vec<u8> {
-        self.secret.take().unwrap_or_else(|| ::std::vec::Vec::new())
+    pub fn take_tag(&mut self) -> ::std::vec::Vec<u8> {
+        self.tag.take().unwrap_or_else(|| ::std::vec::Vec::new())
     }
 
     fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
         let mut fields = ::std::vec::Vec::with_capacity(1);
         let mut oneofs = ::std::vec::Vec::with_capacity(0);
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
-            "secret",
-            |m: &ThpNfcUnidirectionalSecret| { &m.secret },
-            |m: &mut ThpNfcUnidirectionalSecret| { &mut m.secret },
+            "tag",
+            |m: &ThpNfcTagTrezor| { &m.tag },
+            |m: &mut ThpNfcTagTrezor| { &mut m.tag },
         ));
-        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpNfcUnidirectionalSecret>(
-            "ThpNfcUnidirectionalSecret",
+        ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpNfcTagTrezor>(
+            "ThpNfcTagTrezor",
             fields,
             oneofs,
         )
     }
 }
 
-impl ::protobuf::Message for ThpNfcUnidirectionalSecret {
-    const NAME: &'static str = "ThpNfcUnidirectionalSecret";
+impl ::protobuf::Message for ThpNfcTagTrezor {
+    const NAME: &'static str = "ThpNfcTagTrezor";
 
     fn is_initialized(&self) -> bool {
         true
@@ -2635,7 +2616,7 @@ impl ::protobuf::Message for ThpNfcUnidirectionalSecret {
         while let Some(tag) = is.read_raw_tag_or_eof()? {
             match tag {
                 10 => {
-                    self.secret = ::std::option::Option::Some(is.read_bytes()?);
+                    self.tag = ::std::option::Option::Some(is.read_bytes()?);
                 },
                 tag => {
                     ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
@@ -2649,7 +2630,7 @@ impl ::protobuf::Message for ThpNfcUnidirectionalSecret {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u64 {
         let mut my_size = 0;
-        if let Some(v) = self.secret.as_ref() {
+        if let Some(v) = self.tag.as_ref() {
             my_size += ::protobuf::rt::bytes_size(1, &v);
         }
         my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
@@ -2658,7 +2639,7 @@ impl ::protobuf::Message for ThpNfcUnidirectionalSecret {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
-        if let Some(v) = self.secret.as_ref() {
+        if let Some(v) = self.tag.as_ref() {
             os.write_bytes(1, v)?;
         }
         os.write_unknown_fields(self.special_fields.unknown_fields())?;
@@ -2673,38 +2654,38 @@ impl ::protobuf::Message for ThpNfcUnidirectionalSecret {
         &mut self.special_fields
     }
 
-    fn new() -> ThpNfcUnidirectionalSecret {
-        ThpNfcUnidirectionalSecret::new()
+    fn new() -> ThpNfcTagTrezor {
+        ThpNfcTagTrezor::new()
     }
 
     fn clear(&mut self) {
-        self.secret = ::std::option::Option::None;
+        self.tag = ::std::option::Option::None;
         self.special_fields.clear();
     }
 
-    fn default_instance() -> &'static ThpNfcUnidirectionalSecret {
-        static instance: ThpNfcUnidirectionalSecret = ThpNfcUnidirectionalSecret {
-            secret: ::std::option::Option::None,
+    fn default_instance() -> &'static ThpNfcTagTrezor {
+        static instance: ThpNfcTagTrezor = ThpNfcTagTrezor {
+            tag: ::std::option::Option::None,
             special_fields: ::protobuf::SpecialFields::new(),
         };
         &instance
     }
 }
 
-impl ::protobuf::MessageFull for ThpNfcUnidirectionalSecret {
+impl ::protobuf::MessageFull for ThpNfcTagTrezor {
     fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
         static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
-        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpNfcUnidirectionalSecret").unwrap()).clone()
+        descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpNfcTagTrezor").unwrap()).clone()
     }
 }
 
-impl ::std::fmt::Display for ThpNfcUnidirectionalSecret {
+impl ::std::fmt::Display for ThpNfcTagTrezor {
     fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
         ::protobuf::text_format::fmt(self, f)
     }
 }
 
-impl ::protobuf::reflect::ProtobufValue for ThpNfcUnidirectionalSecret {
+impl ::protobuf::reflect::ProtobufValue for ThpNfcTagTrezor {
     type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
 }
 
@@ -2714,6 +2695,8 @@ pub struct ThpCredentialRequest {
     // message fields
     // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCredentialRequest.host_static_pubkey)
     pub host_static_pubkey: ::std::option::Option<::std::vec::Vec<u8>>,
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCredentialRequest.autoconnect)
+    pub autoconnect: ::std::option::Option<bool>,
     // special fields
     // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpCredentialRequest.special_fields)
     pub special_fields: ::protobuf::SpecialFields,
@@ -2766,14 +2749,38 @@ impl ThpCredentialRequest {
         self.host_static_pubkey.take().unwrap_or_else(|| ::std::vec::Vec::new())
     }
 
+    // optional bool autoconnect = 2;
+
+    pub fn autoconnect(&self) -> bool {
+        self.autoconnect.unwrap_or(false)
+    }
+
+    pub fn clear_autoconnect(&mut self) {
+        self.autoconnect = ::std::option::Option::None;
+    }
+
+    pub fn has_autoconnect(&self) -> bool {
+        self.autoconnect.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_autoconnect(&mut self, v: bool) {
+        self.autoconnect = ::std::option::Option::Some(v);
+    }
+
     fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
-        let mut fields = ::std::vec::Vec::with_capacity(1);
+        let mut fields = ::std::vec::Vec::with_capacity(2);
         let mut oneofs = ::std::vec::Vec::with_capacity(0);
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
             "host_static_pubkey",
             |m: &ThpCredentialRequest| { &m.host_static_pubkey },
             |m: &mut ThpCredentialRequest| { &mut m.host_static_pubkey },
         ));
+        fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+            "autoconnect",
+            |m: &ThpCredentialRequest| { &m.autoconnect },
+            |m: &mut ThpCredentialRequest| { &mut m.autoconnect },
+        ));
         ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpCredentialRequest>(
             "ThpCredentialRequest",
             fields,
@@ -2795,6 +2802,9 @@ impl ::protobuf::Message for ThpCredentialRequest {
                 10 => {
                     self.host_static_pubkey = ::std::option::Option::Some(is.read_bytes()?);
                 },
+                16 => {
+                    self.autoconnect = ::std::option::Option::Some(is.read_bool()?);
+                },
                 tag => {
                     ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
                 },
@@ -2810,6 +2820,9 @@ impl ::protobuf::Message for ThpCredentialRequest {
         if let Some(v) = self.host_static_pubkey.as_ref() {
             my_size += ::protobuf::rt::bytes_size(1, &v);
         }
+        if let Some(v) = self.autoconnect {
+            my_size += 1 + 1;
+        }
         my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
         self.special_fields.cached_size().set(my_size as u32);
         my_size
@@ -2819,6 +2832,9 @@ impl ::protobuf::Message for ThpCredentialRequest {
         if let Some(v) = self.host_static_pubkey.as_ref() {
             os.write_bytes(1, v)?;
         }
+        if let Some(v) = self.autoconnect {
+            os.write_bool(2, v)?;
+        }
         os.write_unknown_fields(self.special_fields.unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -2837,12 +2853,14 @@ impl ::protobuf::Message for ThpCredentialRequest {
 
     fn clear(&mut self) {
         self.host_static_pubkey = ::std::option::Option::None;
+        self.autoconnect = ::std::option::Option::None;
         self.special_fields.clear();
     }
 
     fn default_instance() -> &'static ThpCredentialRequest {
         static instance: ThpCredentialRequest = ThpCredentialRequest {
             host_static_pubkey: ::std::option::Option::None,
+            autoconnect: ::std::option::Option::None,
             special_fields: ::protobuf::SpecialFields::new(),
         };
         &instance
@@ -3290,6 +3308,8 @@ pub struct ThpCredentialMetadata {
     // message fields
     // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCredentialMetadata.host_name)
     pub host_name: ::std::option::Option<::std::string::String>,
+    // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCredentialMetadata.autoconnect)
+    pub autoconnect: ::std::option::Option<bool>,
     // special fields
     // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpCredentialMetadata.special_fields)
     pub special_fields: ::protobuf::SpecialFields,
@@ -3342,14 +3362,38 @@ impl ThpCredentialMetadata {
         self.host_name.take().unwrap_or_else(|| ::std::string::String::new())
     }
 
+    // optional bool autoconnect = 2;
+
+    pub fn autoconnect(&self) -> bool {
+        self.autoconnect.unwrap_or(false)
+    }
+
+    pub fn clear_autoconnect(&mut self) {
+        self.autoconnect = ::std::option::Option::None;
+    }
+
+    pub fn has_autoconnect(&self) -> bool {
+        self.autoconnect.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_autoconnect(&mut self, v: bool) {
+        self.autoconnect = ::std::option::Option::Some(v);
+    }
+
     fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
-        let mut fields = ::std::vec::Vec::with_capacity(1);
+        let mut fields = ::std::vec::Vec::with_capacity(2);
         let mut oneofs = ::std::vec::Vec::with_capacity(0);
         fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
             "host_name",
             |m: &ThpCredentialMetadata| { &m.host_name },
             |m: &mut ThpCredentialMetadata| { &mut m.host_name },
         ));
+        fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+            "autoconnect",
+            |m: &ThpCredentialMetadata| { &m.autoconnect },
+            |m: &mut ThpCredentialMetadata| { &mut m.autoconnect },
+        ));
         ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpCredentialMetadata>(
             "ThpCredentialMetadata",
             fields,
@@ -3371,6 +3415,9 @@ impl ::protobuf::Message for ThpCredentialMetadata {
                 10 => {
                     self.host_name = ::std::option::Option::Some(is.read_string()?);
                 },
+                16 => {
+                    self.autoconnect = ::std::option::Option::Some(is.read_bool()?);
+                },
                 tag => {
                     ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
                 },
@@ -3386,6 +3433,9 @@ impl ::protobuf::Message for ThpCredentialMetadata {
         if let Some(v) = self.host_name.as_ref() {
             my_size += ::protobuf::rt::string_size(1, &v);
         }
+        if let Some(v) = self.autoconnect {
+            my_size += 1 + 1;
+        }
         my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
         self.special_fields.cached_size().set(my_size as u32);
         my_size
@@ -3395,6 +3445,9 @@ impl ::protobuf::Message for ThpCredentialMetadata {
         if let Some(v) = self.host_name.as_ref() {
             os.write_string(1, v)?;
         }
+        if let Some(v) = self.autoconnect {
+            os.write_bool(2, v)?;
+        }
         os.write_unknown_fields(self.special_fields.unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -3413,12 +3466,14 @@ impl ::protobuf::Message for ThpCredentialMetadata {
 
     fn clear(&mut self) {
         self.host_name = ::std::option::Option::None;
+        self.autoconnect = ::std::option::Option::None;
         self.special_fields.clear();
     }
 
     fn default_instance() -> &'static ThpCredentialMetadata {
         static instance: ThpCredentialMetadata = ThpCredentialMetadata {
             host_name: ::std::option::Option::None,
+            autoconnect: ::std::option::Option::None,
             special_fields: ::protobuf::SpecialFields::new(),
         };
         &instance
@@ -3801,10 +3856,12 @@ impl ::protobuf::reflect::ProtobufValue for ThpAuthenticatedCredentialData {
 pub enum ThpMessageType {
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCreateNewSession)
     ThpMessageType_ThpCreateNewSession = 1000,
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpNewSession)
-    ThpMessageType_ThpNewSession = 1001,
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpStartPairingRequest)
-    ThpMessageType_ThpStartPairingRequest = 1008,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpPairingRequest)
+    ThpMessageType_ThpPairingRequest = 1006,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpPairingRequestAck)
+    ThpMessageType_ThpPairingRequestAck = 1007,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpSelectMethod)
+    ThpMessageType_ThpSelectMethod = 1008,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpPairingPreparationsFinished)
     ThpMessageType_ThpPairingPreparationsFinished = 1009,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCredentialRequest)
@@ -3819,22 +3876,20 @@ pub enum ThpMessageType {
     ThpMessageType_ThpCodeEntryCommitment = 1016,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCodeEntryChallenge)
     ThpMessageType_ThpCodeEntryChallenge = 1017,
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCodeEntryCpaceHost)
-    ThpMessageType_ThpCodeEntryCpaceHost = 1018,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCodeEntryCpaceTrezor)
-    ThpMessageType_ThpCodeEntryCpaceTrezor = 1019,
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCodeEntryTag)
-    ThpMessageType_ThpCodeEntryTag = 1020,
+    ThpMessageType_ThpCodeEntryCpaceTrezor = 1018,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCodeEntryCpaceHostTag)
+    ThpMessageType_ThpCodeEntryCpaceHostTag = 1019,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpCodeEntrySecret)
-    ThpMessageType_ThpCodeEntrySecret = 1021,
+    ThpMessageType_ThpCodeEntrySecret = 1020,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpQrCodeTag)
     ThpMessageType_ThpQrCodeTag = 1024,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpQrCodeSecret)
     ThpMessageType_ThpQrCodeSecret = 1025,
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpNfcUnidirectionalTag)
-    ThpMessageType_ThpNfcUnidirectionalTag = 1032,
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpNfcUnidirectionalSecret)
-    ThpMessageType_ThpNfcUnidirectionalSecret = 1033,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpNfcTagHost)
+    ThpMessageType_ThpNfcTagHost = 1032,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpMessageType.ThpMessageType_ThpNfcTagTrezor)
+    ThpMessageType_ThpNfcTagTrezor = 1033,
 }
 
 impl ::protobuf::Enum for ThpMessageType {
@@ -3847,8 +3902,9 @@ impl ::protobuf::Enum for ThpMessageType {
     fn from_i32(value: i32) -> ::std::option::Option<ThpMessageType> {
         match value {
             1000 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCreateNewSession),
-            1001 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNewSession),
-            1008 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpStartPairingRequest),
+            1006 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpPairingRequest),
+            1007 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpPairingRequestAck),
+            1008 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpSelectMethod),
             1009 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpPairingPreparationsFinished),
             1010 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCredentialRequest),
             1011 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCredentialResponse),
@@ -3856,14 +3912,13 @@ impl ::protobuf::Enum for ThpMessageType {
             1013 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpEndResponse),
             1016 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCommitment),
             1017 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryChallenge),
-            1018 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHost),
-            1019 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCpaceTrezor),
-            1020 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryTag),
-            1021 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntrySecret),
+            1018 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCpaceTrezor),
+            1019 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHostTag),
+            1020 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntrySecret),
             1024 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpQrCodeTag),
             1025 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpQrCodeSecret),
-            1032 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcUnidirectionalTag),
-            1033 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcUnidirectionalSecret),
+            1032 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcTagHost),
+            1033 => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcTagTrezor),
             _ => ::std::option::Option::None
         }
     }
@@ -3871,8 +3926,9 @@ impl ::protobuf::Enum for ThpMessageType {
     fn from_str(str: &str) -> ::std::option::Option<ThpMessageType> {
         match str {
             "ThpMessageType_ThpCreateNewSession" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCreateNewSession),
-            "ThpMessageType_ThpNewSession" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNewSession),
-            "ThpMessageType_ThpStartPairingRequest" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpStartPairingRequest),
+            "ThpMessageType_ThpPairingRequest" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpPairingRequest),
+            "ThpMessageType_ThpPairingRequestAck" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpPairingRequestAck),
+            "ThpMessageType_ThpSelectMethod" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpSelectMethod),
             "ThpMessageType_ThpPairingPreparationsFinished" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpPairingPreparationsFinished),
             "ThpMessageType_ThpCredentialRequest" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCredentialRequest),
             "ThpMessageType_ThpCredentialResponse" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCredentialResponse),
@@ -3880,22 +3936,22 @@ impl ::protobuf::Enum for ThpMessageType {
             "ThpMessageType_ThpEndResponse" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpEndResponse),
             "ThpMessageType_ThpCodeEntryCommitment" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCommitment),
             "ThpMessageType_ThpCodeEntryChallenge" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryChallenge),
-            "ThpMessageType_ThpCodeEntryCpaceHost" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHost),
             "ThpMessageType_ThpCodeEntryCpaceTrezor" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCpaceTrezor),
-            "ThpMessageType_ThpCodeEntryTag" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryTag),
+            "ThpMessageType_ThpCodeEntryCpaceHostTag" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHostTag),
             "ThpMessageType_ThpCodeEntrySecret" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpCodeEntrySecret),
             "ThpMessageType_ThpQrCodeTag" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpQrCodeTag),
             "ThpMessageType_ThpQrCodeSecret" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpQrCodeSecret),
-            "ThpMessageType_ThpNfcUnidirectionalTag" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcUnidirectionalTag),
-            "ThpMessageType_ThpNfcUnidirectionalSecret" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcUnidirectionalSecret),
+            "ThpMessageType_ThpNfcTagHost" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcTagHost),
+            "ThpMessageType_ThpNfcTagTrezor" => ::std::option::Option::Some(ThpMessageType::ThpMessageType_ThpNfcTagTrezor),
             _ => ::std::option::Option::None
         }
     }
 
     const VALUES: &'static [ThpMessageType] = &[
         ThpMessageType::ThpMessageType_ThpCreateNewSession,
-        ThpMessageType::ThpMessageType_ThpNewSession,
-        ThpMessageType::ThpMessageType_ThpStartPairingRequest,
+        ThpMessageType::ThpMessageType_ThpPairingRequest,
+        ThpMessageType::ThpMessageType_ThpPairingRequestAck,
+        ThpMessageType::ThpMessageType_ThpSelectMethod,
         ThpMessageType::ThpMessageType_ThpPairingPreparationsFinished,
         ThpMessageType::ThpMessageType_ThpCredentialRequest,
         ThpMessageType::ThpMessageType_ThpCredentialResponse,
@@ -3903,14 +3959,13 @@ impl ::protobuf::Enum for ThpMessageType {
         ThpMessageType::ThpMessageType_ThpEndResponse,
         ThpMessageType::ThpMessageType_ThpCodeEntryCommitment,
         ThpMessageType::ThpMessageType_ThpCodeEntryChallenge,
-        ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHost,
         ThpMessageType::ThpMessageType_ThpCodeEntryCpaceTrezor,
-        ThpMessageType::ThpMessageType_ThpCodeEntryTag,
+        ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHostTag,
         ThpMessageType::ThpMessageType_ThpCodeEntrySecret,
         ThpMessageType::ThpMessageType_ThpQrCodeTag,
         ThpMessageType::ThpMessageType_ThpQrCodeSecret,
-        ThpMessageType::ThpMessageType_ThpNfcUnidirectionalTag,
-        ThpMessageType::ThpMessageType_ThpNfcUnidirectionalSecret,
+        ThpMessageType::ThpMessageType_ThpNfcTagHost,
+        ThpMessageType::ThpMessageType_ThpNfcTagTrezor,
     ];
 }
 
@@ -3923,23 +3978,23 @@ impl ::protobuf::EnumFull for ThpMessageType {
     fn descriptor(&self) -> ::protobuf::reflect::EnumValueDescriptor {
         let index = match self {
             ThpMessageType::ThpMessageType_ThpCreateNewSession => 0,
-            ThpMessageType::ThpMessageType_ThpNewSession => 1,
-            ThpMessageType::ThpMessageType_ThpStartPairingRequest => 2,
-            ThpMessageType::ThpMessageType_ThpPairingPreparationsFinished => 3,
-            ThpMessageType::ThpMessageType_ThpCredentialRequest => 4,
-            ThpMessageType::ThpMessageType_ThpCredentialResponse => 5,
-            ThpMessageType::ThpMessageType_ThpEndRequest => 6,
-            ThpMessageType::ThpMessageType_ThpEndResponse => 7,
-            ThpMessageType::ThpMessageType_ThpCodeEntryCommitment => 8,
-            ThpMessageType::ThpMessageType_ThpCodeEntryChallenge => 9,
-            ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHost => 10,
+            ThpMessageType::ThpMessageType_ThpPairingRequest => 1,
+            ThpMessageType::ThpMessageType_ThpPairingRequestAck => 2,
+            ThpMessageType::ThpMessageType_ThpSelectMethod => 3,
+            ThpMessageType::ThpMessageType_ThpPairingPreparationsFinished => 4,
+            ThpMessageType::ThpMessageType_ThpCredentialRequest => 5,
+            ThpMessageType::ThpMessageType_ThpCredentialResponse => 6,
+            ThpMessageType::ThpMessageType_ThpEndRequest => 7,
+            ThpMessageType::ThpMessageType_ThpEndResponse => 8,
+            ThpMessageType::ThpMessageType_ThpCodeEntryCommitment => 9,
+            ThpMessageType::ThpMessageType_ThpCodeEntryChallenge => 10,
             ThpMessageType::ThpMessageType_ThpCodeEntryCpaceTrezor => 11,
-            ThpMessageType::ThpMessageType_ThpCodeEntryTag => 12,
+            ThpMessageType::ThpMessageType_ThpCodeEntryCpaceHostTag => 12,
             ThpMessageType::ThpMessageType_ThpCodeEntrySecret => 13,
             ThpMessageType::ThpMessageType_ThpQrCodeTag => 14,
             ThpMessageType::ThpMessageType_ThpQrCodeSecret => 15,
-            ThpMessageType::ThpMessageType_ThpNfcUnidirectionalTag => 16,
-            ThpMessageType::ThpMessageType_ThpNfcUnidirectionalSecret => 17,
+            ThpMessageType::ThpMessageType_ThpNfcTagHost => 16,
+            ThpMessageType::ThpMessageType_ThpNfcTagTrezor => 17,
         };
         Self::enum_descriptor().value_by_index(index)
     }
@@ -3961,14 +4016,14 @@ impl ThpMessageType {
 #[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
 // @@protoc_insertion_point(enum:hw.trezor.messages.thp.ThpPairingMethod)
 pub enum ThpPairingMethod {
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpPairingMethod.NoMethod)
-    NoMethod = 1,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpPairingMethod.SkipPairing)
+    SkipPairing = 1,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpPairingMethod.CodeEntry)
     CodeEntry = 2,
     // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpPairingMethod.QrCode)
     QrCode = 3,
-    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpPairingMethod.NFC_Unidirectional)
-    NFC_Unidirectional = 4,
+    // @@protoc_insertion_point(enum_value:hw.trezor.messages.thp.ThpPairingMethod.NFC)
+    NFC = 4,
 }
 
 impl ::protobuf::Enum for ThpPairingMethod {
@@ -3980,29 +4035,29 @@ impl ::protobuf::Enum for ThpPairingMethod {
 
     fn from_i32(value: i32) -> ::std::option::Option<ThpPairingMethod> {
         match value {
-            1 => ::std::option::Option::Some(ThpPairingMethod::NoMethod),
+            1 => ::std::option::Option::Some(ThpPairingMethod::SkipPairing),
             2 => ::std::option::Option::Some(ThpPairingMethod::CodeEntry),
             3 => ::std::option::Option::Some(ThpPairingMethod::QrCode),
-            4 => ::std::option::Option::Some(ThpPairingMethod::NFC_Unidirectional),
+            4 => ::std::option::Option::Some(ThpPairingMethod::NFC),
             _ => ::std::option::Option::None
         }
     }
 
     fn from_str(str: &str) -> ::std::option::Option<ThpPairingMethod> {
         match str {
-            "NoMethod" => ::std::option::Option::Some(ThpPairingMethod::NoMethod),
+            "SkipPairing" => ::std::option::Option::Some(ThpPairingMethod::SkipPairing),
             "CodeEntry" => ::std::option::Option::Some(ThpPairingMethod::CodeEntry),
             "QrCode" => ::std::option::Option::Some(ThpPairingMethod::QrCode),
-            "NFC_Unidirectional" => ::std::option::Option::Some(ThpPairingMethod::NFC_Unidirectional),
+            "NFC" => ::std::option::Option::Some(ThpPairingMethod::NFC),
             _ => ::std::option::Option::None
         }
     }
 
     const VALUES: &'static [ThpPairingMethod] = &[
-        ThpPairingMethod::NoMethod,
+        ThpPairingMethod::SkipPairing,
         ThpPairingMethod::CodeEntry,
         ThpPairingMethod::QrCode,
-        ThpPairingMethod::NFC_Unidirectional,
+        ThpPairingMethod::NFC,
     ];
 }
 
@@ -4014,10 +4069,10 @@ impl ::protobuf::EnumFull for ThpPairingMethod {
 
     fn descriptor(&self) -> ::protobuf::reflect::EnumValueDescriptor {
         let index = match self {
-            ThpPairingMethod::NoMethod => 0,
+            ThpPairingMethod::SkipPairing => 0,
             ThpPairingMethod::CodeEntry => 1,
             ThpPairingMethod::QrCode => 2,
-            ThpPairingMethod::NFC_Unidirectional => 3,
+            ThpPairingMethod::NFC => 3,
         };
         Self::enum_descriptor().value_by_index(index)
     }
@@ -4026,7 +4081,7 @@ impl ::protobuf::EnumFull for ThpPairingMethod {
 // Note, `Default` is implemented although default value is not 0
 impl ::std::default::Default for ThpPairingMethod {
     fn default() -> Self {
-        ThpPairingMethod::NoMethod
+        ThpPairingMethod::SkipPairing
     }
 }
 
@@ -4038,70 +4093,70 @@ impl ThpPairingMethod {
 
 static file_descriptor_proto_data: &'static [u8] = b"\
     \n\x12messages-thp.proto\x12\x16hw.trezor.messages.thp\x1a\roptions.prot\
-    o\"\x88\x02\n\x13ThpDeviceProperties\x12%\n\x0einternal_model\x18\x01\
+    o\"\xa0\x02\n\x13ThpDeviceProperties\x12%\n\x0einternal_model\x18\x01\
     \x20\x01(\tR\rinternalModel\x12#\n\rmodel_variant\x18\x02\x20\x01(\rR\
-    \x0cmodelVariant\x12'\n\x0fbootloader_mode\x18\x03\x20\x01(\x08R\x0eboot\
-    loaderMode\x12)\n\x10protocol_version\x18\x04\x20\x01(\rR\x0fprotocolVer\
-    sion\x12Q\n\x0fpairing_methods\x18\x05\x20\x03(\x0e2(.hw.trezor.messages\
-    .thp.ThpPairingMethodR\x0epairingMethods\"\xb2\x01\n%ThpHandshakeComplet\
-    ionReqNoisePayload\x126\n\x17host_pairing_credential\x18\x01\x20\x01(\
-    \x0cR\x15hostPairingCredential\x12Q\n\x0fpairing_methods\x18\x02\x20\x03\
-    (\x0e2(.hw.trezor.messages.thp.ThpPairingMethodR\x0epairingMethods\"y\n\
-    \x13ThpCreateNewSession\x12\x1e\n\npassphrase\x18\x01\x20\x01(\tR\npassp\
-    hrase\x12\x1b\n\ton_device\x18\x02\x20\x01(\x08R\x08onDevice\x12%\n\x0ed\
-    erive_cardano\x18\x03\x20\x01(\x08R\rderiveCardano\"5\n\rThpNewSession\
-    \x12$\n\x0enew_session_id\x18\x01\x20\x01(\rR\x0cnewSessionId\"5\n\x16Th\
-    pStartPairingRequest\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostNam\
-    e\"\x20\n\x1eThpPairingPreparationsFinished\"8\n\x16ThpCodeEntryCommitme\
-    nt\x12\x1e\n\ncommitment\x18\x01\x20\x01(\x0cR\ncommitment\"5\n\x15ThpCo\
-    deEntryChallenge\x12\x1c\n\tchallenge\x18\x01\x20\x01(\x0cR\tchallenge\"\
-    J\n\x15ThpCodeEntryCpaceHost\x121\n\x15cpace_host_public_key\x18\x01\x20\
-    \x01(\x0cR\x12cpaceHostPublicKey\"P\n\x17ThpCodeEntryCpaceTrezor\x125\n\
-    \x17cpace_trezor_public_key\x18\x01\x20\x01(\x0cR\x14cpaceTrezorPublicKe\
-    y\"#\n\x0fThpCodeEntryTag\x12\x10\n\x03tag\x18\x02\x20\x01(\x0cR\x03tag\
-    \",\n\x12ThpCodeEntrySecret\x12\x16\n\x06secret\x18\x01\x20\x01(\x0cR\
-    \x06secret\"\x20\n\x0cThpQrCodeTag\x12\x10\n\x03tag\x18\x01\x20\x01(\x0c\
-    R\x03tag\")\n\x0fThpQrCodeSecret\x12\x16\n\x06secret\x18\x01\x20\x01(\
-    \x0cR\x06secret\"+\n\x17ThpNfcUnidirectionalTag\x12\x10\n\x03tag\x18\x01\
-    \x20\x01(\x0cR\x03tag\"4\n\x1aThpNfcUnidirectionalSecret\x12\x16\n\x06se\
-    cret\x18\x01\x20\x01(\x0cR\x06secret\"D\n\x14ThpCredentialRequest\x12,\n\
-    \x12host_static_pubkey\x18\x01\x20\x01(\x0cR\x10hostStaticPubkey\"i\n\
-    \x15ThpCredentialResponse\x120\n\x14trezor_static_pubkey\x18\x01\x20\x01\
-    (\x0cR\x12trezorStaticPubkey\x12\x1e\n\ncredential\x18\x02\x20\x01(\x0cR\
-    \ncredential\"\x0f\n\rThpEndRequest\"\x10\n\x0eThpEndResponse\":\n\x15Th\
-    pCredentialMetadata\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostName\
-    :\x04\x98\xb2\x19\x01\"\x82\x01\n\x14ThpPairingCredential\x12R\n\rcred_m\
-    etadata\x18\x01\x20\x01(\x0b2-.hw.trezor.messages.thp.ThpCredentialMetad\
-    ataR\x0ccredMetadata\x12\x10\n\x03mac\x18\x02\x20\x01(\x0cR\x03mac:\x04\
-    \x98\xb2\x19\x01\"\xa8\x01\n\x1eThpAuthenticatedCredentialData\x12,\n\
-    \x12host_static_pubkey\x18\x01\x20\x01(\x0cR\x10hostStaticPubkey\x12R\n\
-    \rcred_metadata\x18\x02\x20\x01(\x0b2-.hw.trezor.messages.thp.ThpCredent\
-    ialMetadataR\x0ccredMetadata:\x04\x98\xb2\x19\x01*\xf6\x06\n\x0eThpMessa\
-    geType\x12-\n\"ThpMessageType_ThpCreateNewSession\x10\xe8\x07\x1a\x04\
-    \x80\xa6\x1d\x01\x12'\n\x1cThpMessageType_ThpNewSession\x10\xe9\x07\x1a\
-    \x04\x80\xa6\x1d\x01\x120\n%ThpMessageType_ThpStartPairingRequest\x10\
-    \xf0\x07\x1a\x04\x80\xa6\x1d\x01\x128\n-ThpMessageType_ThpPairingPrepara\
-    tionsFinished\x10\xf1\x07\x1a\x04\x80\xa6\x1d\x01\x12.\n#ThpMessageType_\
-    ThpCredentialRequest\x10\xf2\x07\x1a\x04\x80\xa6\x1d\x01\x12/\n$ThpMessa\
-    geType_ThpCredentialResponse\x10\xf3\x07\x1a\x04\x80\xa6\x1d\x01\x12'\n\
-    \x1cThpMessageType_ThpEndRequest\x10\xf4\x07\x1a\x04\x80\xa6\x1d\x01\x12\
-    (\n\x1dThpMessageType_ThpEndResponse\x10\xf5\x07\x1a\x04\x80\xa6\x1d\x01\
-    \x120\n%ThpMessageType_ThpCodeEntryCommitment\x10\xf8\x07\x1a\x04\x80\
-    \xa6\x1d\x01\x12/\n$ThpMessageType_ThpCodeEntryChallenge\x10\xf9\x07\x1a\
-    \x04\x80\xa6\x1d\x01\x12/\n$ThpMessageType_ThpCodeEntryCpaceHost\x10\xfa\
+    \x0cmodelVariant\x124\n\x16protocol_version_major\x18\x03\x20\x01(\rR\
+    \x14protocolVersionMajor\x124\n\x16protocol_version_minor\x18\x04\x20\
+    \x01(\rR\x14protocolVersionMinor\x12Q\n\x0fpairing_methods\x18\x05\x20\
+    \x03(\x0e2(.hw.trezor.messages.thp.ThpPairingMethodR\x0epairingMethods\"\
+    _\n%ThpHandshakeCompletionReqNoisePayload\x126\n\x17host_pairing_credent\
+    ial\x18\x01\x20\x01(\x0cR\x15hostPairingCredential\"y\n\x13ThpCreateNewS\
+    ession\x12\x1e\n\npassphrase\x18\x01\x20\x01(\tR\npassphrase\x12\x1b\n\t\
+    on_device\x18\x02\x20\x01(\x08R\x08onDevice\x12%\n\x0ederive_cardano\x18\
+    \x03\x20\x01(\x08R\rderiveCardano\"0\n\x11ThpPairingRequest\x12\x1b\n\th\
+    ost_name\x18\x01\x20\x01(\tR\x08hostName\"\x16\n\x14ThpPairingRequestAck\
+    \"s\n\x0fThpSelectMethod\x12`\n\x17selected_pairing_method\x18\x01\x20\
+    \x01(\x0e2(.hw.trezor.messages.thp.ThpPairingMethodR\x15selectedPairingM\
+    ethod\"\x20\n\x1eThpPairingPreparationsFinished\"8\n\x16ThpCodeEntryComm\
+    itment\x12\x1e\n\ncommitment\x18\x01\x20\x01(\x0cR\ncommitment\"5\n\x15T\
+    hpCodeEntryChallenge\x12\x1c\n\tchallenge\x18\x01\x20\x01(\x0cR\tchallen\
+    ge\"P\n\x17ThpCodeEntryCpaceTrezor\x125\n\x17cpace_trezor_public_key\x18\
+    \x01\x20\x01(\x0cR\x14cpaceTrezorPublicKey\"_\n\x18ThpCodeEntryCpaceHost\
+    Tag\x121\n\x15cpace_host_public_key\x18\x01\x20\x01(\x0cR\x12cpaceHostPu\
+    blicKey\x12\x10\n\x03tag\x18\x02\x20\x01(\x0cR\x03tag\",\n\x12ThpCodeEnt\
+    rySecret\x12\x16\n\x06secret\x18\x01\x20\x01(\x0cR\x06secret\"\x20\n\x0c\
+    ThpQrCodeTag\x12\x10\n\x03tag\x18\x01\x20\x01(\x0cR\x03tag\")\n\x0fThpQr\
+    CodeSecret\x12\x16\n\x06secret\x18\x01\x20\x01(\x0cR\x06secret\"!\n\rThp\
+    NfcTagHost\x12\x10\n\x03tag\x18\x01\x20\x01(\x0cR\x03tag\"#\n\x0fThpNfcT\
+    agTrezor\x12\x10\n\x03tag\x18\x01\x20\x01(\x0cR\x03tag\"f\n\x14ThpCreden\
+    tialRequest\x12,\n\x12host_static_pubkey\x18\x01\x20\x01(\x0cR\x10hostSt\
+    aticPubkey\x12\x20\n\x0bautoconnect\x18\x02\x20\x01(\x08R\x0bautoconnect\
+    \"i\n\x15ThpCredentialResponse\x120\n\x14trezor_static_pubkey\x18\x01\
+    \x20\x01(\x0cR\x12trezorStaticPubkey\x12\x1e\n\ncredential\x18\x02\x20\
+    \x01(\x0cR\ncredential\"\x0f\n\rThpEndRequest\"\x10\n\x0eThpEndResponse\
+    \"\\\n\x15ThpCredentialMetadata\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\
+    \x08hostName\x12\x20\n\x0bautoconnect\x18\x02\x20\x01(\x08R\x0bautoconne\
+    ct:\x04\x98\xb2\x19\x01\"\x82\x01\n\x14ThpPairingCredential\x12R\n\rcred\
+    _metadata\x18\x01\x20\x01(\x0b2-.hw.trezor.messages.thp.ThpCredentialMet\
+    adataR\x0ccredMetadata\x12\x10\n\x03mac\x18\x02\x20\x01(\x0cR\x03mac:\
+    \x04\x98\xb2\x19\x01\"\xa8\x01\n\x1eThpAuthenticatedCredentialData\x12,\
+    \n\x12host_static_pubkey\x18\x01\x20\x01(\x0cR\x10hostStaticPubkey\x12R\
+    \n\rcred_metadata\x18\x02\x20\x01(\x0b2-.hw.trezor.messages.thp.ThpCrede\
+    ntialMetadataR\x0ccredMetadata:\x04\x98\xb2\x19\x01*\xe6\x06\n\x0eThpMes\
+    sageType\x12-\n\"ThpMessageType_ThpCreateNewSession\x10\xe8\x07\x1a\x04\
+    \x80\xa6\x1d\x01\x12+\n\x20ThpMessageType_ThpPairingRequest\x10\xee\x07\
+    \x1a\x04\x80\xa6\x1d\x01\x12.\n#ThpMessageType_ThpPairingRequestAck\x10\
+    \xef\x07\x1a\x04\x80\xa6\x1d\x01\x12)\n\x1eThpMessageType_ThpSelectMetho\
+    d\x10\xf0\x07\x1a\x04\x80\xa6\x1d\x01\x128\n-ThpMessageType_ThpPairingPr\
+    eparationsFinished\x10\xf1\x07\x1a\x04\x80\xa6\x1d\x01\x12.\n#ThpMessage\
+    Type_ThpCredentialRequest\x10\xf2\x07\x1a\x04\x80\xa6\x1d\x01\x12/\n$Thp\
+    MessageType_ThpCredentialResponse\x10\xf3\x07\x1a\x04\x80\xa6\x1d\x01\
+    \x12'\n\x1cThpMessageType_ThpEndRequest\x10\xf4\x07\x1a\x04\x80\xa6\x1d\
+    \x01\x12(\n\x1dThpMessageType_ThpEndResponse\x10\xf5\x07\x1a\x04\x80\xa6\
+    \x1d\x01\x120\n%ThpMessageType_ThpCodeEntryCommitment\x10\xf8\x07\x1a\
+    \x04\x80\xa6\x1d\x01\x12/\n$ThpMessageType_ThpCodeEntryChallenge\x10\xf9\
     \x07\x1a\x04\x80\xa6\x1d\x01\x121\n&ThpMessageType_ThpCodeEntryCpaceTrez\
-    or\x10\xfb\x07\x1a\x04\x80\xa6\x1d\x01\x12)\n\x1eThpMessageType_ThpCodeE\
-    ntryTag\x10\xfc\x07\x1a\x04\x80\xa6\x1d\x01\x12,\n!ThpMessageType_ThpCod\
-    eEntrySecret\x10\xfd\x07\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1bThpMessageTyp\
-    e_ThpQrCodeTag\x10\x80\x08\x1a\x04\x80\xa6\x1d\x01\x12)\n\x1eThpMessageT\
-    ype_ThpQrCodeSecret\x10\x81\x08\x1a\x04\x80\xa6\x1d\x01\x121\n&ThpMessag\
-    eType_ThpNfcUnidirectionalTag\x10\x88\x08\x1a\x04\x80\xa6\x1d\x01\x124\n\
-    )ThpMessageType_ThpNfcUnidirectionalSecret\x10\x89\x08\x1a\x04\x80\xa6\
-    \x1d\x01\"\x05\x08\0\x10\xe7\x07\"\t\x08\xcc\x08\x10\xff\xff\xff\xff\x07\
-    *S\n\x10ThpPairingMethod\x12\x0c\n\x08NoMethod\x10\x01\x12\r\n\tCodeEntr\
-    y\x10\x02\x12\n\n\x06QrCode\x10\x03\x12\x16\n\x12NFC_Unidirectional\x10\
-    \x04B;\n#com.satoshilabs.trezor.lib.protobufB\x10TrezorMessageThp\x80\
-    \xa6\x1d\x01\
+    or\x10\xfa\x07\x1a\x04\x80\xa6\x1d\x01\x122\n'ThpMessageType_ThpCodeEntr\
+    yCpaceHostTag\x10\xfb\x07\x1a\x04\x80\xa6\x1d\x01\x12,\n!ThpMessageType_\
+    ThpCodeEntrySecret\x10\xfc\x07\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1bThpMess\
+    ageType_ThpQrCodeTag\x10\x80\x08\x1a\x04\x80\xa6\x1d\x01\x12)\n\x1eThpMe\
+    ssageType_ThpQrCodeSecret\x10\x81\x08\x1a\x04\x80\xa6\x1d\x01\x12'\n\x1c\
+    ThpMessageType_ThpNfcTagHost\x10\x88\x08\x1a\x04\x80\xa6\x1d\x01\x12)\n\
+    \x1eThpMessageType_ThpNfcTagTrezor\x10\x89\x08\x1a\x04\x80\xa6\x1d\x01\"\
+    \x05\x08\0\x10\xe7\x07\"\t\x08\xcc\x08\x10\xff\xff\xff\xff\x07*G\n\x10Th\
+    pPairingMethod\x12\x0f\n\x0bSkipPairing\x10\x01\x12\r\n\tCodeEntry\x10\
+    \x02\x12\n\n\x06QrCode\x10\x03\x12\x07\n\x03NFC\x10\x04B;\n#com.satoshil\
+    abs.trezor.lib.protobufB\x10TrezorMessageThp\x80\xa6\x1d\x01\
 ";
 
 /// `FileDescriptorProto` object which was a source for this generated file
@@ -4124,19 +4179,19 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
             messages.push(ThpDeviceProperties::generated_message_descriptor_data());
             messages.push(ThpHandshakeCompletionReqNoisePayload::generated_message_descriptor_data());
             messages.push(ThpCreateNewSession::generated_message_descriptor_data());
-            messages.push(ThpNewSession::generated_message_descriptor_data());
-            messages.push(ThpStartPairingRequest::generated_message_descriptor_data());
+            messages.push(ThpPairingRequest::generated_message_descriptor_data());
+            messages.push(ThpPairingRequestAck::generated_message_descriptor_data());
+            messages.push(ThpSelectMethod::generated_message_descriptor_data());
             messages.push(ThpPairingPreparationsFinished::generated_message_descriptor_data());
             messages.push(ThpCodeEntryCommitment::generated_message_descriptor_data());
             messages.push(ThpCodeEntryChallenge::generated_message_descriptor_data());
-            messages.push(ThpCodeEntryCpaceHost::generated_message_descriptor_data());
             messages.push(ThpCodeEntryCpaceTrezor::generated_message_descriptor_data());
-            messages.push(ThpCodeEntryTag::generated_message_descriptor_data());
+            messages.push(ThpCodeEntryCpaceHostTag::generated_message_descriptor_data());
             messages.push(ThpCodeEntrySecret::generated_message_descriptor_data());
             messages.push(ThpQrCodeTag::generated_message_descriptor_data());
             messages.push(ThpQrCodeSecret::generated_message_descriptor_data());
-            messages.push(ThpNfcUnidirectionalTag::generated_message_descriptor_data());
-            messages.push(ThpNfcUnidirectionalSecret::generated_message_descriptor_data());
+            messages.push(ThpNfcTagHost::generated_message_descriptor_data());
+            messages.push(ThpNfcTagTrezor::generated_message_descriptor_data());
             messages.push(ThpCredentialRequest::generated_message_descriptor_data());
             messages.push(ThpCredentialResponse::generated_message_descriptor_data());
             messages.push(ThpEndRequest::generated_message_descriptor_data());