feat(common): introduce `BackupMethod` protobuf enum
What changed, and why it matters
This commit adds a new 'BackupMethod' setting to Trezor's device communication protocol. It lets the wallet software tell the device how to handle backup or recovery of the secret recovery words. The change only defines the new enum and wires it into three messages (ResetDevice, BackupDevice, RecoveryDevice); it does not add any actual backup/recovery behavior. There is no security fix or vulnerability visible in this patch.
No immediate security action required. Treat as a normal feature commit. Monitor follow-up commits that implement the N4W1 backup method for actual security implications.
Security signals we found
New protobuf enum and message fields only
No validation, parsing, or cryptographic logic changed
No memory-unsafe code modified
No privilege boundary or access-control change
No vendor disclosure of security relevance
Evidence from the diff
The commit introduces a protobuf enum BackupMethod with values Display (0) and N4W1 (1), and adds an optional method field to ResetDevice, BackupDevice, and RecoveryDevice in common/protob/messages-management.proto. Generated bindings are updated for MicroPython, Python trezorlib, and Rust. The only runtime logic change is adding method to DRY_RUN_ALLOWED_FIELDS in core/src/apps/management/recovery_device/init.py and in a matching test file. No implementation of the N4W1 method is present in the diff, and no security-sensitive logic is modified.
Changed components
common/protob/messages-management.protocore/src/trezor/enums/BackupMethod.pycore/src/trezor/enums/__init__.pycore/src/trezor/messages.pycore/src/apps/management/recovery_device/__init__.pypython/src/trezorlib/messages.pyrust/trezor-client/src/protos/generated/messages_management.rstests/device_tests/reset_recovery/test_recovery_bip39_dryrun.pyInspect captured patch +286 / −46
diff --git a/common/protob/messages-management.proto b/common/protob/messages-management.proto
index dfc12a92..bd1ed586 100644
--- a/common/protob/messages-management.proto
+++ b/common/protob/messages-management.proto
@@ -22,6 +22,14 @@ enum BackupType {
Slip39_Advanced_Extendable = 5; // extendable multi-share Shamir backup with groups
}
+/**
+ * Backup method of the mnemonic shares.
+ */
+enum BackupMethod {
+ Display = 0; // the share words are displayed on the device screen
+ N4W1 = 1;
+}
+
/**
* Level of safety checks for unsafe actions like spending from invalid path namespace or setting high transaction fee.
*/
@@ -450,6 +458,7 @@ message ResetDevice {
optional bool no_backup = 9; // indicate that no backup is going to be made
optional BackupType backup_type = 10 [default = Bip39]; // type of the mnemonic backup
optional bool entropy_check = 11; // run with entropy check protocol
+ optional BackupMethod method = 12 [default = Display]; // how the mnemonic shares should be backed up
}
/**
@@ -464,6 +473,7 @@ message BackupDevice {
required uint32 member_count = 2;
}
repeated Slip39Group groups = 2;
+ optional BackupMethod method = 3 [default = Display]; // how the mnemonic shares should be backed up
}
/**
@@ -518,6 +528,7 @@ message RecoveryDevice {
optional RecoveryDeviceInputMethod input_method = 8; // supported recovery input method (T1 only)
optional uint32 u2f_counter = 9; // U2F counter
optional RecoveryType type = 10 [default = NormalRecovery]; // the type of recovery to perform
+ optional BackupMethod method = 11 [default = Display]; // how the shares should be recovered from backup
/**
* Type of recovery procedure. These should be used as bitmask, e.g.,
* `RecoveryDeviceInputMethod_ScrambledWords | RecoveryDeviceInputMethod_Matrix`
diff --git a/core/embed/upymod/qstrdefsport.h b/core/embed/upymod/qstrdefsport.h
index 390e888e..fbbb62cc 100644
--- a/core/embed/upymod/qstrdefsport.h
+++ b/core/embed/upymod/qstrdefsport.h
@@ -23,6 +23,7 @@
Q(AmountUnit)
Q(BackupAvailability)
+Q(BackupMethod)
Q(BackupType)
Q(BootCommand)
Q(ButtonRequestType)
@@ -336,6 +337,7 @@ Q(trezor.crypto.slip39)
Q(trezor.enums)
Q(trezor.enums.AmountUnit)
Q(trezor.enums.BackupAvailability)
+Q(trezor.enums.BackupMethod)
Q(trezor.enums.BackupType)
Q(trezor.enums.BootCommand)
Q(trezor.enums.ButtonRequestType)
diff --git a/core/src/apps/management/recovery_device/__init__.py b/core/src/apps/management/recovery_device/__init__.py
index 908493b8..b187900b 100644
--- a/core/src/apps/management/recovery_device/__init__.py
+++ b/core/src/apps/management/recovery_device/__init__.py
@@ -8,7 +8,14 @@ if TYPE_CHECKING:
# List of RecoveryDevice fields that can be set when doing dry-run recovery.
# All except `type` are allowed for T1 compatibility, but their values are ignored.
# If set, `enforce_wordlist` must be True, because we do not support non-enforcing.
-DRY_RUN_ALLOWED_FIELDS = ("type", "word_count", "enforce_wordlist", "input_method")
+# `method` allows choosing between different ways to input the shares (on Core devices).
+DRY_RUN_ALLOWED_FIELDS = (
+ "type",
+ "word_count",
+ "enforce_wordlist",
+ "input_method",
+ "method",
+)
async def recovery_device(msg: RecoveryDevice) -> Success:
diff --git a/core/src/trezor/enums/BackupMethod.py b/core/src/trezor/enums/BackupMethod.py
new file mode 100644
index 00000000..607ed181
--- /dev/null
+++ b/core/src/trezor/enums/BackupMethod.py
@@ -0,0 +1,6 @@
+# Automatically generated by pb2py
+# fmt: off
+# isort:skip_file
+
+Display = 0
+N4W1 = 1
diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py
index dcfa7fe3..2f60ae3e 100644
--- a/core/src/trezor/enums/__init__.py
+++ b/core/src/trezor/enums/__init__.py
@@ -179,6 +179,10 @@ if TYPE_CHECKING:
Slip39_Basic_Extendable = 4
Slip39_Advanced_Extendable = 5
+ class BackupMethod(IntEnum):
+ Display = 0
+ N4W1 = 1
+
class SafetyCheckLevel(IntEnum):
Strict = 0
PromptAlways = 1
diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py
index f7892804..54e89a94 100644
--- a/core/src/trezor/messages.py
+++ b/core/src/trezor/messages.py
@@ -19,6 +19,7 @@ if TYPE_CHECKING:
from typing import TypeGuard
from trezor.enums import AmountUnit # noqa: F401
from trezor.enums import BackupAvailability # noqa: F401
+ from trezor.enums import BackupMethod # noqa: F401
from trezor.enums import BackupType # noqa: F401
from trezor.enums import BootCommand # noqa: F401
from trezor.enums import ButtonRequestType # noqa: F401
@@ -2487,6 +2488,7 @@ if TYPE_CHECKING:
no_backup: "bool | None"
backup_type: "BackupType"
entropy_check: "bool | None"
+ method: "BackupMethod"
def __init__(
self,
@@ -2500,6 +2502,7 @@ if TYPE_CHECKING:
no_backup: "bool | None" = None,
backup_type: "BackupType | None" = None,
entropy_check: "bool | None" = None,
+ method: "BackupMethod | None" = None,
) -> None:
pass
@@ -2510,12 +2513,14 @@ if TYPE_CHECKING:
class BackupDevice(protobuf.MessageType):
group_threshold: "int | None"
groups: "list[Slip39Group]"
+ method: "BackupMethod"
def __init__(
self,
*,
groups: "list[Slip39Group] | None" = None,
group_threshold: "int | None" = None,
+ method: "BackupMethod | None" = None,
) -> None:
pass
@@ -2582,6 +2587,7 @@ if TYPE_CHECKING:
input_method: "RecoveryDeviceInputMethod | None"
u2f_counter: "int | None"
type: "RecoveryType"
+ method: "BackupMethod"
def __init__(
self,
@@ -2594,6 +2600,7 @@ if TYPE_CHECKING:
input_method: "RecoveryDeviceInputMethod | None" = None,
u2f_counter: "int | None" = None,
type: "RecoveryType | None" = None,
+ method: "BackupMethod | None" = None,
) -> None:
pass
diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py
index 3bd98673..5ea34399 100644
--- a/python/src/trezorlib/messages.py
+++ b/python/src/trezorlib/messages.py
@@ -202,6 +202,11 @@ class BackupType(IntEnum):
Slip39_Advanced_Extendable = 5
+class BackupMethod(IntEnum):
+ Display = 0
+ N4W1 = 1
+
+
class SafetyCheckLevel(IntEnum):
Strict = 0
PromptAlways = 1
@@ -3765,6 +3770,7 @@ class ResetDevice(protobuf.MessageType):
9: protobuf.Field("no_backup", "bool", repeated=False, required=False, default=None),
10: protobuf.Field("backup_type", "BackupType", repeated=False, required=False, default=BackupType.Bip39),
11: protobuf.Field("entropy_check", "bool", repeated=False, required=False, default=None),
+ 12: protobuf.Field("method", "BackupMethod", repeated=False, required=False, default=BackupMethod.Display),
}
def __init__(
@@ -3780,6 +3786,7 @@ class ResetDevice(protobuf.MessageType):
no_backup: Optional["bool"] = None,
backup_type: Optional["BackupType"] = BackupType.Bip39,
entropy_check: Optional["bool"] = None,
+ method: Optional["BackupMethod"] = BackupMethod.Display,
) -> None:
self.strength = strength
self.passphrase_protection = passphrase_protection
@@ -3791,6 +3798,7 @@ class ResetDevice(protobuf.MessageType):
self.no_backup = no_backup
self.backup_type = backup_type
self.entropy_check = entropy_check
+ self.method = method
class BackupDevice(protobuf.MessageType):
@@ -3798,6 +3806,7 @@ class BackupDevice(protobuf.MessageType):
FIELDS = {
1: protobuf.Field("group_threshold", "uint32", repeated=False, required=False, default=None),
2: protobuf.Field("groups", "Slip39Group", repeated=True, required=False, default=None),
+ 3: protobuf.Field("method", "BackupMethod", repeated=False, required=False, default=BackupMethod.Display),
}
def __init__(
@@ -3805,9 +3814,11 @@ class BackupDevice(protobuf.MessageType):
*,
groups: Optional[Sequence["Slip39Group"]] = None,
group_threshold: Optional["int"] = None,
+ method: Optional["BackupMethod"] = BackupMethod.Display,
) -> None:
self.groups: Sequence["Slip39Group"] = groups if groups is not None else []
self.group_threshold = group_threshold
+ self.method = method
class EntropyRequest(protobuf.MessageType):
@@ -3871,6 +3882,7 @@ class RecoveryDevice(protobuf.MessageType):
8: protobuf.Field("input_method", "RecoveryDeviceInputMethod", repeated=False, required=False, default=None),
9: protobuf.Field("u2f_counter", "uint32", repeated=False, required=False, default=None),
10: protobuf.Field("type", "RecoveryType", repeated=False, required=False, default=RecoveryType.NormalRecovery),
+ 11: protobuf.Field("method", "BackupMethod", repeated=False, required=False, default=BackupMethod.Display),
}
def __init__(
@@ -3885,6 +3897,7 @@ class RecoveryDevice(protobuf.MessageType):
input_method: Optional["RecoveryDeviceInputMethod"] = None,
u2f_counter: Optional["int"] = None,
type: Optional["RecoveryType"] = RecoveryType.NormalRecovery,
+ method: Optional["BackupMethod"] = BackupMethod.Display,
) -> None:
self.word_count = word_count
self.passphrase_protection = passphrase_protection
@@ -3895,6 +3908,7 @@ class RecoveryDevice(protobuf.MessageType):
self.input_method = input_method
self.u2f_counter = u2f_counter
self.type = type
+ self.method = method
class WordRequest(protobuf.MessageType):
diff --git a/rust/trezor-client/src/protos/generated/messages_management.rs b/rust/trezor-client/src/protos/generated/messages_management.rs
index dd7dbdf2..c4443db8 100644
--- a/rust/trezor-client/src/protos/generated/messages_management.rs
+++ b/rust/trezor-client/src/protos/generated/messages_management.rs
@@ -7364,6 +7364,8 @@ pub struct ResetDevice {
pub backup_type: ::std::option::Option<::protobuf::EnumOrUnknown<BackupType>>,
// @@protoc_insertion_point(field:hw.trezor.messages.management.ResetDevice.entropy_check)
pub entropy_check: ::std::option::Option<bool>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.management.ResetDevice.method)
+ pub method: ::std::option::Option<::protobuf::EnumOrUnknown<BackupMethod>>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.management.ResetDevice.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@@ -7607,8 +7609,30 @@ impl ResetDevice {
self.entropy_check = ::std::option::Option::Some(v);
}
+ // optional .hw.trezor.messages.management.BackupMethod method = 12;
+
+ pub fn method(&self) -> BackupMethod {
+ match self.method {
+ Some(e) => e.enum_value_or(BackupMethod::Display),
+ None => BackupMethod::Display,
+ }
+ }
+
+ pub fn clear_method(&mut self) {
+ self.method = ::std::option::Option::None;
+ }
+
+ pub fn has_method(&self) -> bool {
+ self.method.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_method(&mut self, v: BackupMethod) {
+ self.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(10);
+ let mut fields = ::std::vec::Vec::with_capacity(11);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"strength",
@@ -7660,6 +7684,11 @@ impl ResetDevice {
|m: &ResetDevice| { &m.entropy_check },
|m: &mut ResetDevice| { &mut m.entropy_check },
));
+ fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+ "method",
+ |m: &ResetDevice| { &m.method },
+ |m: &mut ResetDevice| { &mut m.method },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ResetDevice>(
"ResetDevice",
fields,
@@ -7708,6 +7737,9 @@ impl ::protobuf::Message for ResetDevice {
88 => {
self.entropy_check = ::std::option::Option::Some(is.read_bool()?);
},
+ 96 => {
+ self.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())?;
},
@@ -7750,6 +7782,9 @@ impl ::protobuf::Message for ResetDevice {
if let Some(v) = self.entropy_check {
my_size += 1 + 1;
}
+ if let Some(v) = self.method {
+ my_size += ::protobuf::rt::int32_size(12, 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
@@ -7786,6 +7821,9 @@ impl ::protobuf::Message for ResetDevice {
if let Some(v) = self.entropy_check {
os.write_bool(11, v)?;
}
+ if let Some(v) = self.method {
+ os.write_enum(12, ::protobuf::EnumOrUnknown::value(&v))?;
+ }
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -7813,6 +7851,7 @@ impl ::protobuf::Message for ResetDevice {
self.no_backup = ::std::option::Option::None;
self.backup_type = ::std::option::Option::None;
self.entropy_check = ::std::option::Option::None;
+ self.method = ::std::option::Option::None;
self.special_fields.clear();
}
@@ -7828,6 +7867,7 @@ impl ::protobuf::Message for ResetDevice {
no_backup: ::std::option::Option::None,
backup_type: ::std::option::Option::None,
entropy_check: ::std::option::Option::None,
+ method: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -7859,6 +7899,8 @@ pub struct BackupDevice {
pub group_threshold: ::std::option::Option<u32>,
// @@protoc_insertion_point(field:hw.trezor.messages.management.BackupDevice.groups)
pub groups: ::std::vec::Vec<backup_device::Slip39Group>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.management.BackupDevice.method)
+ pub method: ::std::option::Option<::protobuf::EnumOrUnknown<BackupMethod>>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.management.BackupDevice.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@@ -7894,8 +7936,30 @@ impl BackupDevice {
self.group_threshold = ::std::option::Option::Some(v);
}
+ // optional .hw.trezor.messages.management.BackupMethod method = 3;
+
+ pub fn method(&self) -> BackupMethod {
+ match self.method {
+ Some(e) => e.enum_value_or(BackupMethod::Display),
+ None => BackupMethod::Display,
+ }
+ }
+
+ pub fn clear_method(&mut self) {
+ self.method = ::std::option::Option::None;
+ }
+
+ pub fn has_method(&self) -> bool {
+ self.method.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_method(&mut self, v: BackupMethod) {
+ self.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(2);
+ let mut fields = ::std::vec::Vec::with_capacity(3);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"group_threshold",
@@ -7907,6 +7971,11 @@ impl BackupDevice {
|m: &BackupDevice| { &m.groups },
|m: &mut BackupDevice| { &mut m.groups },
));
+ fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+ "method",
+ |m: &BackupDevice| { &m.method },
+ |m: &mut BackupDevice| { &mut m.method },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<BackupDevice>(
"BackupDevice",
fields,
@@ -7936,6 +8005,9 @@ impl ::protobuf::Message for BackupDevice {
18 => {
self.groups.push(is.read_message()?);
},
+ 24 => {
+ self.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())?;
},
@@ -7955,6 +8027,9 @@ impl ::protobuf::Message for BackupDevice {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
};
+ if let Some(v) = self.method {
+ my_size += ::protobuf::rt::int32_size(3, 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
@@ -7967,6 +8042,9 @@ impl ::protobuf::Message for BackupDevice {
for v in &self.groups {
::protobuf::rt::write_message_field_with_cached_size(2, v, os)?;
};
+ if let Some(v) = self.method {
+ os.write_enum(3, ::protobuf::EnumOrUnknown::value(&v))?;
+ }
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -7986,6 +8064,7 @@ impl ::protobuf::Message for BackupDevice {
fn clear(&mut self) {
self.group_threshold = ::std::option::Option::None;
self.groups.clear();
+ self.method = ::std::option::Option::None;
self.special_fields.clear();
}
@@ -7993,6 +8072,7 @@ impl ::protobuf::Message for BackupDevice {
static instance: BackupDevice = BackupDevice {
group_threshold: ::std::option::Option::None,
groups: ::std::vec::Vec::new(),
+ method: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -8842,6 +8922,8 @@ pub struct RecoveryDevice {
pub u2f_counter: ::std::option::Option<u32>,
// @@protoc_insertion_point(field:hw.trezor.messages.management.RecoveryDevice.type)
pub type_: ::std::option::Option<::protobuf::EnumOrUnknown<RecoveryType>>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.management.RecoveryDevice.method)
+ pub method: ::std::option::Option<::protobuf::EnumOrUnknown<BackupMethod>>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.management.RecoveryDevice.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@@ -9069,8 +9151,30 @@ impl RecoveryDevice {
self.type_ = ::std::option::Option::Some(::protobuf::EnumOrUnknown::new(v));
}
+ // optional .hw.trezor.messages.management.BackupMethod method = 11;
+
+ pub fn method(&self) -> BackupMethod {
+ match self.method {
+ Some(e) => e.enum_value_or(BackupMethod::Display),
+ None => BackupMethod::Display,
+ }
+ }
+
+ pub fn clear_method(&mut self) {
+ self.method = ::std::option::Option::None;
+ }
+
+ pub fn has_method(&self) -> bool {
+ self.method.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_method(&mut self, v: BackupMethod) {
+ self.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(9);
+ let mut fields = ::std::vec::Vec::with_capacity(10);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"word_count",
@@ -9117,6 +9221,11 @@ impl RecoveryDevice {
|m: &RecoveryDevice| { &m.type_ },
|m: &mut RecoveryDevice| { &mut m.type_ },
));
+ fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+ "method",
+ |m: &RecoveryDevice| { &m.method },
+ |m: &mut RecoveryDevice| { &mut m.method },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<RecoveryDevice>(
"RecoveryDevice",
fields,
@@ -9162,6 +9271,9 @@ impl ::protobuf::Message for RecoveryDevice {
80 => {
self.type_ = ::std::option::Option::Some(is.read_enum_or_unknown()?);
},
+ 88 => {
+ self.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())?;
},
@@ -9201,6 +9313,9 @@ impl ::protobuf::Message for RecoveryDevice {
if let Some(v) = self.type_ {
my_size += ::protobuf::rt::int32_size(10, v.value());
}
+ if let Some(v) = self.method {
+ my_size += ::protobuf::rt::int32_size(11, 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
@@ -9234,6 +9349,9 @@ impl ::protobuf::Message for RecoveryDevice {
if let Some(v) = self.type_ {
os.write_enum(10, ::protobuf::EnumOrUnknown::value(&v))?;
}
+ if let Some(v) = self.method {
+ os.write_enum(11, ::protobuf::EnumOrUnknown::value(&v))?;
+ }
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -9260,6 +9378,7 @@ impl ::protobuf::Message for RecoveryDevice {
self.input_method = ::std::option::Option::None;
self.u2f_counter = ::std::option::Option::None;
self.type_ = ::std::option::Option::None;
+ self.method = ::std::option::Option::None;
self.special_fields.clear();
}
@@ -9274,6 +9393,7 @@ impl ::protobuf::Message for RecoveryDevice {
input_method: ::std::option::Option::None,
u2f_counter: ::std::option::Option::None,
type_: ::std::option::Option::None,
+ method: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -12000,6 +12120,68 @@ impl BackupType {
}
}
+#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
+// @@protoc_insertion_point(enum:hw.trezor.messages.management.BackupMethod)
+pub enum BackupMethod {
+ // @@protoc_insertion_point(enum_value:hw.trezor.messages.management.BackupMethod.Display)
+ Display = 0,
+ // @@protoc_insertion_point(enum_value:hw.trezor.messages.management.BackupMethod.N4W1)
+ N4W1 = 1,
+}
+
+impl ::protobuf::Enum for BackupMethod {
+ const NAME: &'static str = "BackupMethod";
+
+ fn value(&self) -> i32 {
+ *self as i32
+ }
+
+ fn from_i32(value: i32) -> ::std::option::Option<BackupMethod> {
+ match value {
+ 0 => ::std::option::Option::Some(BackupMethod::Display),
+ 1 => ::std::option::Option::Some(BackupMethod::N4W1),
+ _ => ::std::option::Option::None
+ }
+ }
+
+ fn from_str(str: &str) -> ::std::option::Option<BackupMethod> {
+ match str {
+ "Display" => ::std::option::Option::Some(BackupMethod::Display),
+ "N4W1" => ::std::option::Option::Some(BackupMethod::N4W1),
+ _ => ::std::option::Option::None
+ }
+ }
+
+ const VALUES: &'static [BackupMethod] = &[
+ BackupMethod::Display,
+ BackupMethod::N4W1,
+ ];
+}
+
+impl ::protobuf::EnumFull for BackupMethod {
+ fn enum_descriptor() -> ::protobuf::reflect::EnumDescriptor {
+ static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::Lazy::new();
+ descriptor.get(|| file_descriptor().enum_by_package_relative_name("BackupMethod").unwrap()).clone()
+ }
+
+ fn descriptor(&self) -> ::protobuf::reflect::EnumValueDescriptor {
+ let index = *self as usize;
+ Self::enum_descriptor().value_by_index(index)
+ }
+}
+
+impl ::std::default::Default for BackupMethod {
+ fn default() -> Self {
+ BackupMethod::Display
+ }
+}
+
+impl BackupMethod {
+ fn generated_enum_descriptor_data() -> ::protobuf::reflect::GeneratedEnumDescriptorData {
+ ::protobuf::reflect::GeneratedEnumDescriptorData::new::<BackupMethod>("BackupMethod")
+ }
+}
+
#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
// @@protoc_insertion_point(enum:hw.trezor.messages.management.SafetyCheckLevel)
pub enum SafetyCheckLevel {
@@ -12415,7 +12597,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\
f_counter\x18\x08\x20\x01(\rR\nu2fCounter\x12!\n\x0cneeds_backup\x18\t\
\x20\x01(\x08R\x0bneedsBackup\x12\x1b\n\tno_backup\x18\n\x20\x01(\x08R\
\x08noBackup\x12+\n\x11unfinished_backup\x18\x0b\x20\x01(\x08R\x10unfini\
- shedBackup\"\x9d\x03\n\x0bResetDevice\x12\x1f\n\x08strength\x18\x02\x20\
+ shedBackup\"\xeb\x03\n\x0bResetDevice\x12\x1f\n\x08strength\x18\x02\x20\
\x01(\r:\x03256R\x08strength\x123\n\x15passphrase_protection\x18\x03\x20\
\x01(\x08R\x14passphraseProtection\x12%\n\x0epin_protection\x18\x04\x20\
\x01(\x08R\rpinProtection\x12\x1e\n\x08language\x18\x05\x20\x01(\tR\x08l\
@@ -12424,17 +12606,20 @@ static file_descriptor_proto_data: &'static [u8] = b"\
backup\x18\x08\x20\x01(\x08R\nskipBackup\x12\x1b\n\tno_backup\x18\t\x20\
\x01(\x08R\x08noBackup\x12Q\n\x0bbackup_type\x18\n\x20\x01(\x0e2).hw.tre\
zor.messages.management.BackupType:\x05Bip39R\nbackupType\x12#\n\rentrop\
- y_check\x18\x0b\x20\x01(\x08R\x0centropyCheckJ\x04\x08\x01\x10\x02\"\xe5\
- \x01\n\x0cBackupDevice\x12'\n\x0fgroup_threshold\x18\x01\x20\x01(\rR\x0e\
- groupThreshold\x12O\n\x06groups\x18\x02\x20\x03(\x0b27.hw.trezor.message\
- s.management.BackupDevice.Slip39GroupR\x06groups\x1a[\n\x0bSlip39Group\
+ y_check\x18\x0b\x20\x01(\x08R\x0centropyCheck\x12L\n\x06method\x18\x0c\
+ \x20\x01(\x0e2+.hw.trezor.messages.management.BackupMethod:\x07DisplayR\
+ \x06methodJ\x04\x08\x01\x10\x02\"\xb3\x02\n\x0cBackupDevice\x12'\n\x0fgr\
+ oup_threshold\x18\x01\x20\x01(\rR\x0egroupThreshold\x12O\n\x06groups\x18\
+ \x02\x20\x03(\x0b27.hw.trezor.messages.management.BackupDevice.Slip39Gro\
+ upR\x06groups\x12L\n\x06method\x18\x03\x20\x01(\x0e2+.hw.trezor.messages\
+ .management.BackupMethod:\x07DisplayR\x06method\x1a[\n\x0bSlip39Group\
\x12)\n\x10member_threshold\x18\x01\x20\x02(\rR\x0fmemberThreshold\x12!\
\n\x0cmember_count\x18\x02\x20\x02(\rR\x0bmemberCount\"b\n\x0eEntropyReq\
uest\x12-\n\x12entropy_commitment\x18\x01\x20\x01(\x0cR\x11entropyCommit\
ment\x12!\n\x0cprev_entropy\x18\x02\x20\x01(\x0cR\x0bprevEntropy\"&\n\nE\
ntropyAck\x12\x18\n\x07entropy\x18\x01\x20\x02(\x0cR\x07entropy\"\x13\n\
\x11EntropyCheckReady\"5\n\x14EntropyCheckContinue\x12\x1d\n\x06finish\
- \x18\x01\x20\x01(\x08:\x05falseR\x06finish\"\x8d\x04\n\x0eRecoveryDevice\
+ \x18\x01\x20\x01(\x08:\x05falseR\x06finish\"\xdb\x04\n\x0eRecoveryDevice\
\x12\x1d\n\nword_count\x18\x01\x20\x01(\rR\twordCount\x123\n\x15passphra\
se_protection\x18\x02\x20\x01(\x08R\x14passphraseProtection\x12%\n\x0epi\
n_protection\x18\x03\x20\x01(\x08R\rpinProtection\x12\x1e\n\x08language\
@@ -12444,41 +12629,43 @@ static file_descriptor_proto_data: &'static [u8] = b"\
zor.messages.management.RecoveryDevice.RecoveryDeviceInputMethodR\x0binp\
utMethod\x12\x1f\n\x0bu2f_counter\x18\t\x20\x01(\rR\nu2fCounter\x12O\n\
\x04type\x18\n\x20\x01(\x0e2+.hw.trezor.messages.management.RecoveryType\
- :\x0eNormalRecoveryR\x04type\";\n\x19RecoveryDeviceInputMethod\x12\x12\n\
- \x0eScrambledWords\x10\0\x12\n\n\x06Matrix\x10\x01J\x04\x08\x07\x10\x08\
- \"\xc5\x01\n\x0bWordRequest\x12N\n\x04type\x18\x01\x20\x02(\x0e2:.hw.tre\
- zor.messages.management.WordRequest.WordRequestTypeR\x04type\"f\n\x0fWor\
- dRequestType\x12\x19\n\x15WordRequestType_Plain\x10\0\x12\x1b\n\x17WordR\
- equestType_Matrix9\x10\x01\x12\x1b\n\x17WordRequestType_Matrix6\x10\x02\
- \"\x1d\n\x07WordAck\x12\x12\n\x04word\x18\x01\x20\x02(\tR\x04word\"0\n\r\
- SetU2FCounter\x12\x1f\n\x0bu2f_counter\x18\x01\x20\x02(\rR\nu2fCounter\"\
- \x13\n\x11GetNextU2FCounter\"1\n\x0eNextU2FCounter\x12\x1f\n\x0bu2f_coun\
- ter\x18\x01\x20\x02(\rR\nu2fCounter\"\x11\n\x0fDoPreauthorized\"\x16\n\
- \x14PreauthorizedRequest\"\x15\n\x13CancelAuthorization\"\xeb\x01\n\x12R\
- ebootToBootloader\x12o\n\x0cboot_command\x18\x01\x20\x01(\x0e2=.hw.trezo\
- r.messages.management.RebootToBootloader.BootCommand:\rSTOP_AND_WAITR\
- \x0bbootCommand\x12'\n\x0ffirmware_header\x18\x02\x20\x01(\x0cR\x0efirmw\
- areHeader\"5\n\x0bBootCommand\x12\x11\n\rSTOP_AND_WAIT\x10\0\x12\x13\n\
- \x0fINSTALL_UPGRADE\x10\x01J\x04\x08\x03\x10\x04\"\n\n\x08GetNonce\"\x1d\
- \n\x05Nonce\x12\x14\n\x05nonce\x18\x01\x20\x02(\x0cR\x05nonce\";\n\nUnlo\
- ckPath\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x10\n\
- \x03mac\x18\x02\x20\x01(\x0cR\x03mac\"'\n\x13UnlockedPathRequest\x12\x10\
- \n\x03mac\x18\x01\x20\x02(\x0cR\x03mac\"\x14\n\x12ShowDeviceTutorial\"\
- \x12\n\x10UnlockBootloader\"%\n\rSetBrightness\x12\x14\n\x05value\x18\
- \x01\x20\x01(\rR\x05value\"\x11\n\x0fGetSerialNumber\"3\n\x0cSerialNumbe\
- r\x12#\n\rserial_number\x18\x01\x20\x02(\tR\x0cserialNumber*\x99\x01\n\n\
- BackupType\x12\t\n\x05Bip39\x10\0\x12\x10\n\x0cSlip39_Basic\x10\x01\x12\
- \x13\n\x0fSlip39_Advanced\x10\x02\x12\x1c\n\x18Slip39_Single_Extendable\
- \x10\x03\x12\x1b\n\x17Slip39_Basic_Extendable\x10\x04\x12\x1e\n\x1aSlip3\
- 9_Advanced_Extendable\x10\x05*G\n\x10SafetyCheckLevel\x12\n\n\x06Strict\
- \x10\0\x12\x10\n\x0cPromptAlways\x10\x01\x12\x15\n\x11PromptTemporarily\
- \x10\x02*=\n\x0fDisplayRotation\x12\t\n\x05North\x10\0\x12\x08\n\x04East\
- \x10Z\x12\n\n\x05South\x10\xb4\x01\x12\t\n\x04West\x10\x8e\x02*0\n\x10Ho\
- mescreenFormat\x12\x08\n\x04Toif\x10\x01\x12\x08\n\x04Jpeg\x10\x02\x12\
- \x08\n\x04ToiG\x10\x03*H\n\x0cRecoveryType\x12\x12\n\x0eNormalRecovery\
- \x10\0\x12\n\n\x06DryRun\x10\x01\x12\x18\n\x14UnlockRepeatedBackup\x10\
- \x02BB\n#com.satoshilabs.trezor.lib.protobufB\x17TrezorMessageManagement\
- \x80\xa6\x1d\x01\
+ :\x0eNormalRecoveryR\x04type\x12L\n\x06method\x18\x0b\x20\x01(\x0e2+.hw.\
+ trezor.messages.management.BackupMethod:\x07DisplayR\x06method\";\n\x19R\
+ ecoveryDeviceInputMethod\x12\x12\n\x0eScrambledWords\x10\0\x12\n\n\x06Ma\
+ trix\x10\x01J\x04\x08\x07\x10\x08\"\xc5\x01\n\x0bWordRequest\x12N\n\x04t\
+ ype\x18\x01\x20\x02(\x0e2:.hw.trezor.messages.management.WordRequest.Wor\
+ dRequestTypeR\x04type\"f\n\x0fWordRequestType\x12\x19\n\x15WordRequestTy\
+ pe_Plain\x10\0\x12\x1b\n\x17WordRequestType_Matrix9\x10\x01\x12\x1b\n\
+ \x17WordRequestType_Matrix6\x10\x02\"\x1d\n\x07WordAck\x12\x12\n\x04word\
+ \x18\x01\x20\x02(\tR\x04word\"0\n\rSetU2FCounter\x12\x1f\n\x0bu2f_counte\
+ r\x18\x01\x20\x02(\rR\nu2fCounter\"\x13\n\x11GetNextU2FCounter\"1\n\x0eN\
+ extU2FCounter\x12\x1f\n\x0bu2f_counter\x18\x01\x20\x02(\rR\nu2fCounter\"\
+ \x11\n\x0fDoPreauthorized\"\x16\n\x14PreauthorizedRequest\"\x15\n\x13Can\
+ celAuthorization\"\xeb\x01\n\x12RebootToBootloader\x12o\n\x0cboot_comman\
+ d\x18\x01\x20\x01(\x0e2=.hw.trezor.messages.management.RebootToBootloade\
+ r.BootCommand:\rSTOP_AND_WAITR\x0bbootCommand\x12'\n\x0ffirmware_header\
+ \x18\x02\x20\x01(\x0cR\x0efirmwareHeader\"5\n\x0bBootCommand\x12\x11\n\r\
+ STOP_AND_WAIT\x10\0\x12\x13\n\x0fINSTALL_UPGRADE\x10\x01J\x04\x08\x03\
+ \x10\x04\"\n\n\x08GetNonce\"\x1d\n\x05Nonce\x12\x14\n\x05nonce\x18\x01\
+ \x20\x02(\x0cR\x05nonce\";\n\nUnlockPath\x12\x1b\n\taddress_n\x18\x01\
+ \x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\x02\x20\x01(\x0cR\x03mac\"\
+ '\n\x13UnlockedPathRequest\x12\x10\n\x03mac\x18\x01\x20\x02(\x0cR\x03mac\
+ \"\x14\n\x12ShowDeviceTutorial\"\x12\n\x10UnlockBootloader\"%\n\rSetBrig\
+ htness\x12\x14\n\x05value\x18\x01\x20\x01(\rR\x05value\"\x11\n\x0fGetSer\
+ ialNumber\"3\n\x0cSerialNumber\x12#\n\rserial_number\x18\x01\x20\x02(\tR\
+ \x0cserialNumber*\x99\x01\n\nBackupType\x12\t\n\x05Bip39\x10\0\x12\x10\n\
+ \x0cSlip39_Basic\x10\x01\x12\x13\n\x0fSlip39_Advanced\x10\x02\x12\x1c\n\
+ \x18Slip39_Single_Extendable\x10\x03\x12\x1b\n\x17Slip39_Basic_Extendabl\
+ e\x10\x04\x12\x1e\n\x1aSlip39_Advanced_Extendable\x10\x05*%\n\x0cBackupM\
+ ethod\x12\x0b\n\x07Display\x10\0\x12\x08\n\x04N4W1\x10\x01*G\n\x10Safety\
+ CheckLevel\x12\n\n\x06Strict\x10\0\x12\x10\n\x0cPromptAlways\x10\x01\x12\
+ \x15\n\x11PromptTemporarily\x10\x02*=\n\x0fDisplayRotation\x12\t\n\x05No\
+ rth\x10\0\x12\x08\n\x04East\x10Z\x12\n\n\x05South\x10\xb4\x01\x12\t\n\
+ \x04West\x10\x8e\x02*0\n\x10HomescreenFormat\x12\x08\n\x04Toif\x10\x01\
+ \x12\x08\n\x04Jpeg\x10\x02\x12\x08\n\x04ToiG\x10\x03*H\n\x0cRecoveryType\
+ \x12\x12\n\x0eNormalRecovery\x10\0\x12\n\n\x06DryRun\x10\x01\x12\x18\n\
+ \x14UnlockRepeatedBackup\x10\x02BB\n#com.satoshilabs.trezor.lib.protobuf\
+ B\x17TrezorMessageManagement\x80\xa6\x1d\x01\
";
/// `FileDescriptorProto` object which was a source for this generated file
@@ -12548,8 +12735,9 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
messages.push(GetSerialNumber::generated_message_descriptor_data());
messages.push(SerialNumber::generated_message_descriptor_data());
messages.push(backup_device::Slip39Group::generated_message_descriptor_data());
- let mut enums = ::std::vec::Vec::with_capacity(12);
+ let mut enums = ::std::vec::Vec::with_capacity(13);
enums.push(BackupType::generated_enum_descriptor_data());
+ enums.push(BackupMethod::generated_enum_descriptor_data());
enums.push(SafetyCheckLevel::generated_enum_descriptor_data());
enums.push(DisplayRotation::generated_enum_descriptor_data());
enums.push(HomescreenFormat::generated_enum_descriptor_data());
diff --git a/tests/device_tests/reset_recovery/test_recovery_bip39_dryrun.py b/tests/device_tests/reset_recovery/test_recovery_bip39_dryrun.py
index f853209d..a97e0615 100644
--- a/tests/device_tests/reset_recovery/test_recovery_bip39_dryrun.py
+++ b/tests/device_tests/reset_recovery/test_recovery_bip39_dryrun.py
@@ -117,6 +117,7 @@ DRY_RUN_ALLOWED_FIELDS = (
"enforce_wordlist",
"input_method",
"show_tutorial",
+ "method",
)
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.