feat(core): generate SLIP-21 node for Evolu
What changed, and why it matters
This commit adds a new Trezor feature that lets users derive a special cryptographic key (a SLIP-21 node) for a third-party storage framework called Evolu. The device will show an on-screen confirmation before releasing the key. It is a feature addition, not a fix for a known vulnerability. The main security consideration is that any host application able to send the new message type can request this key, but only after the user confirms on the device. The key is tied to a fixed path ("TREZOR"/"Evolu"), so it cannot be used to steal cryptocurrency directly, but if a user is tricked into approving it, the key could be leaked to a malicious application.
Review whether the new message type should be gated behind an application policy or session authorization beyond a single user confirmation. Verify that the confirm_action prompt cannot be silently approved by a compromised host or debuglink in production. Confirm that the fixed SLIP-21 path does not overlap with any other cryptographic usage. Treat this as a routine feature review rather than an incident response.
Security signals we found
New wire message type added to an existing privileged interface
User confirmation required before key derivation
Fixed SLIP-21 derivation path limits key scope
Legacy firmware skips the new messages, reducing attack surface on legacy devices
No input validation issues visible in the handler because the request message carries no fields
TODO comment indicates UI copy is not final
Evidence from the diff
The change introduces new protobuf messages EvoluGetNode (2100) and EvoluNode (2101), a core handler apps/misc/get_evolu_node.py, and client support in python/trezorlib and rust/trezor-client. The handler checks that the device is initialized, prompts the user with confirm_action(“Derive SLIP-21 node for Evolu?”), derives a Slip21Node from the seed along the hardcoded path [b”TREZOR”, b”Evolu”], and returns node.data. The legacy firmware build explicitly skips these messages. There is no evidence in the commit of a vulnerability, bypass, or security fix; it is a new feature. The TODO comment notes that the on-device copy may be adjusted when exposed via Trezor Suite.
Changed components
core/src/apps/misc/get_evolu_node.pycore/src/apps/workflow_handlers.pycommon/protob/messages-evolu.protocommon/protob/messages.protocore/src/trezor/messages.pycore/src/trezor/enums/MessageType.pypython/src/trezorlib/evolu.pypython/src/trezorlib/cli/evolu.pyrust/trezor-client/src/messages/generated.rsrust/trezor-client/src/protos/generated/messages_evolu.rsInspect captured patch +597 / −7
diff --git a/common/protob/messages-evolu.proto b/common/protob/messages-evolu.proto
new file mode 100644
index 00000000..457b7a0a
--- /dev/null
+++ b/common/protob/messages-evolu.proto
@@ -0,0 +1,24 @@
+
+syntax = "proto2";
+package hw.trezor.messages.evolu;
+
+// Sugar for easier handling in Java
+option java_package = "com.satoshilabs.trezor.lib.protobuf";
+option java_outer_classname = "TrezorMessageEvolu";
+
+/**
+ * Request: Ask the device for the SLIP-21 node for Evolu, a local first storage
+ * framework. See https://github.com/evoluhq/evolu
+ * @start
+ * @next EvoluNode
+ */
+message EvoluGetNode {
+}
+
+/**
+ * Response: Evolu SLIP-21 node
+ * @end
+ */
+message EvoluNode {
+ required bytes data = 1;
+}
diff --git a/common/protob/messages.proto b/common/protob/messages.proto
index 6df7e20b..c27235e2 100644
--- a/common/protob/messages.proto
+++ b/common/protob/messages.proto
@@ -337,6 +337,10 @@ enum MessageType {
MessageType_NostrSignEvent = 2003 [(wire_in) = true];
MessageType_NostrEventSignature = 2004 [(wire_out) = true];
+ // Evolu
+ MessageType_EvoluGetNode = 2100 [(wire_in) = true];
+ MessageType_EvoluNode = 2101 [(wire_out) = true];
+
// Benchmark
MessageType_BenchmarkListNames = 9100 [(bitcoin_only) = true];
MessageType_BenchmarkNames = 9101 [(bitcoin_only) = true];
diff --git a/core/.changelog.d/5220.added b/core/.changelog.d/5220.added
new file mode 100644
index 00000000..adb39cbc
--- /dev/null
+++ b/core/.changelog.d/5220.added
@@ -0,0 +1 @@
+Generation of SLIP-21 node for a new way of storing labels (using Evolu).
diff --git a/core/embed/upymod/qstrdefsport.h b/core/embed/upymod/qstrdefsport.h
index 9a94deef..d246c927 100644
--- a/core/embed/upymod/qstrdefsport.h
+++ b/core/embed/upymod/qstrdefsport.h
@@ -153,6 +153,7 @@ Q(apps.misc)
Q(apps.misc.cipher_key_value)
Q(apps.misc.get_ecdh_session_key)
Q(apps.misc.get_entropy)
+Q(apps.misc.get_evolu_node)
Q(apps.misc.get_firmware_hash)
Q(apps.misc.payment_notification)
Q(apps.misc.sign_identity)
@@ -218,6 +219,7 @@ Q(fido2)
Q(get_address)
Q(get_ecdh_session_key)
Q(get_entropy)
+Q(get_evolu_node)
Q(get_firmware_hash)
Q(get_next_u2f_counter)
Q(get_nonce)
diff --git a/core/src/apps/misc/get_evolu_node.py b/core/src/apps/misc/get_evolu_node.py
new file mode 100644
index 00000000..3df5bb32
--- /dev/null
+++ b/core/src/apps/misc/get_evolu_node.py
@@ -0,0 +1,31 @@
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+ from trezor.messages import EvoluGetNode, EvoluNode
+
+_EVOLU_KEY_PATH_PREFIX = [b"TREZOR", b"Evolu"]
+
+
+async def get_evolu_node(_msg: EvoluGetNode) -> EvoluNode:
+ from storage.device import is_initialized
+ from trezor.messages import EvoluNode
+ from trezor.ui.layouts import confirm_action
+ from trezor.wire import NotInitialized
+
+ from apps.common.seed import Slip21Node, get_seed
+
+ if not is_initialized():
+ raise NotInitialized("Device is not initialized")
+
+ # TODO: adjust copy when the usage is exposed via Trezor Suite
+ await confirm_action(
+ "get_evolu_keys",
+ "Evolu node",
+ action="Derive SLIP-21 node for Evolu?",
+ prompt_screen=True,
+ )
+ seed = await get_seed()
+ node = Slip21Node(seed)
+ node.derive_path(_EVOLU_KEY_PATH_PREFIX)
+
+ return EvoluNode(data=node.data)
diff --git a/core/src/apps/workflow_handlers.py b/core/src/apps/workflow_handlers.py
index eda64dda..488de35b 100644
--- a/core/src/apps/workflow_handlers.py
+++ b/core/src/apps/workflow_handlers.py
@@ -104,6 +104,8 @@ def _find_message_handler_module(msg_type: int) -> str:
return "apps.misc.cipher_key_value"
if msg_type == MessageType.GetFirmwareHash:
return "apps.misc.get_firmware_hash"
+ if msg_type == MessageType.EvoluGetNode:
+ return "apps.misc.get_evolu_node"
if not utils.BITCOIN_ONLY:
# When promoting the Nostr app to production-level
diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py
index b344db95..7d011aff 100644
--- a/core/src/trezor/enums/MessageType.py
+++ b/core/src/trezor/enums/MessageType.py
@@ -259,3 +259,5 @@ if not utils.BITCOIN_ONLY:
NostrPubkey = 2002
NostrSignEvent = 2003
NostrEventSignature = 2004
+ EvoluGetNode = 2100
+ EvoluNode = 2101
diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py
index f3293d15..b1cd239b 100644
--- a/core/src/trezor/enums/__init__.py
+++ b/core/src/trezor/enums/__init__.py
@@ -621,6 +621,8 @@ if TYPE_CHECKING:
NostrPubkey = 2002
NostrSignEvent = 2003
NostrEventSignature = 2004
+ EvoluGetNode = 2100
+ EvoluNode = 2101
BenchmarkListNames = 9100
BenchmarkNames = 9101
BenchmarkRun = 9102
diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py
index 52fe198e..f5dbc194 100644
--- a/core/src/trezor/messages.py
+++ b/core/src/trezor/messages.py
@@ -4062,6 +4062,26 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["EthereumFieldType"]:
return isinstance(msg, cls)
+ class EvoluGetNode(protobuf.MessageType):
+
+ @classmethod
+ def is_type_of(cls, msg: Any) -> TypeGuard["EvoluGetNode"]:
+ return isinstance(msg, cls)
+
+ class EvoluNode(protobuf.MessageType):
+ data: "bytes"
+
+ def __init__(
+ self,
+ *,
+ data: "bytes",
+ ) -> None:
+ pass
+
+ @classmethod
+ def is_type_of(cls, msg: Any) -> TypeGuard["EvoluNode"]:
+ return isinstance(msg, cls)
+
class MoneroTransactionSourceEntry(protobuf.MessageType):
outputs: "list[MoneroOutputEntry]"
real_output: "int | None"
diff --git a/legacy/firmware/protob/Makefile b/legacy/firmware/protob/Makefile
index 5f5a9400..081cbcca 100644
--- a/legacy/firmware/protob/Makefile
+++ b/legacy/firmware/protob/Makefile
@@ -15,7 +15,7 @@ SKIPPED_MESSAGES := Cardano DebugMonero Eos Monero Ontology Ripple SdProtect Tez
SetBrightness DebugLinkOptigaSetSecMax \
BenchmarkListNames BenchmarkRun BenchmarkNames BenchmarkResult \
NostrGetPubkey NostrPubkey NostrSignEvent NostrEventSignature \
- BleUnpair PaymentNotification
+ BleUnpair PaymentNotification EvoluGetNode EvoluNode
ifeq ($(BITCOIN_ONLY), 1)
SKIPPED_MESSAGES += Ethereum NEM Stellar
diff --git a/python/.changelog.d/5220.added b/python/.changelog.d/5220.added
new file mode 100644
index 00000000..adb39cbc
--- /dev/null
+++ b/python/.changelog.d/5220.added
@@ -0,0 +1 @@
+Generation of SLIP-21 node for a new way of storing labels (using Evolu).
diff --git a/python/src/trezorlib/cli/evolu.py b/python/src/trezorlib/cli/evolu.py
new file mode 100644
index 00000000..092ca702
--- /dev/null
+++ b/python/src/trezorlib/cli/evolu.py
@@ -0,0 +1,47 @@
+# This file is part of the Trezor project.
+#
+# Copyright (C) 2012-2025 SatoshiLabs and contributors
+#
+# This library is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the License along with this library.
+# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
+
+from __future__ import annotations
+
+import typing as t
+
+import click
+
+from .. import evolu, messages
+from . import with_session
+
+if t.TYPE_CHECKING:
+ from ..transport.session import Session
+
+
+@click.group(name="evolu")
+def cli() -> None:
+ """Evolu commands. Evolu is a local first storage framework. See https://github.com/evoluhq/evolu"""
+
+
+@cli.command()
+@with_session
+def get_node(
+ session: "Session",
+) -> dict[str, str]:
+ """Return the SLIP-21 node for Evolu."""
+
+ node: messages.EvoluNode = evolu.get_evolu_node(
+ session,
+ )
+ return {
+ "data": node.data.hex(),
+ }
diff --git a/python/src/trezorlib/cli/trezorctl.py b/python/src/trezorlib/cli/trezorctl.py
index 024ccd0b..2fd52bf6 100755
--- a/python/src/trezorlib/cli/trezorctl.py
+++ b/python/src/trezorlib/cli/trezorctl.py
@@ -40,6 +40,7 @@ from . import (
device,
eos,
ethereum,
+ evolu,
fido,
firmware,
monero,
@@ -410,6 +411,7 @@ cli.add_command(crypto.cli)
cli.add_command(device.cli)
cli.add_command(eos.cli)
cli.add_command(ethereum.cli)
+cli.add_command(evolu.cli)
cli.add_command(fido.cli)
cli.add_command(monero.cli)
cli.add_command(nem.cli)
diff --git a/python/src/trezorlib/evolu.py b/python/src/trezorlib/evolu.py
new file mode 100644
index 00000000..e139c12e
--- /dev/null
+++ b/python/src/trezorlib/evolu.py
@@ -0,0 +1,30 @@
+# This file is part of the Trezor project.
+#
+# Copyright (C) 2012-2025 SatoshiLabs and contributors
+#
+# This library is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the License along with this library.
+# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
+
+
+from typing import TYPE_CHECKING
+
+from . import messages
+
+if TYPE_CHECKING:
+ from .transport.session import Session
+
+
+def get_evolu_node(session: "Session") -> messages.EvoluNode:
+ return session.call(
+ messages.EvoluGetNode(),
+ expect=messages.EvoluNode,
+ )
diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py
index 1e30cb7b..15c6503b 100644
--- a/python/src/trezorlib/messages.py
+++ b/python/src/trezorlib/messages.py
@@ -674,6 +674,8 @@ class MessageType(IntEnum):
NostrPubkey = 2002
NostrSignEvent = 2003
NostrEventSignature = 2004
+ EvoluGetNode = 2100
+ EvoluNode = 2101
BenchmarkListNames = 9100
BenchmarkNames = 9101
BenchmarkRun = 9102
@@ -5499,6 +5501,24 @@ class EthereumFieldType(protobuf.MessageType):
self.struct_name = struct_name
+class EvoluGetNode(protobuf.MessageType):
+ MESSAGE_WIRE_TYPE = 2100
+
+
+class EvoluNode(protobuf.MessageType):
+ MESSAGE_WIRE_TYPE = 2101
+ FIELDS = {
+ 1: protobuf.Field("data", "bytes", repeated=False, required=True),
+ }
+
+ def __init__(
+ self,
+ *,
+ data: "bytes",
+ ) -> None:
+ self.data = data
+
+
class MoneroTransactionSourceEntry(protobuf.MessageType):
MESSAGE_WIRE_TYPE = None
FIELDS = {
diff --git a/rust/trezor-client/scripts/build_messages b/rust/trezor-client/scripts/build_messages
index d1c25d0d..707830e8 100755
--- a/rust/trezor-client/scripts/build_messages
+++ b/rust/trezor-client/scripts/build_messages
@@ -21,6 +21,7 @@ FEATURES = {
#
"Cardano": "cardano",
"EOS": "eos",
+ "Evolu": "evolu",
"Monero": "monero",
"NEM": "nem",
"Nostr": "nostr",
diff --git a/rust/trezor-client/src/messages/generated.rs b/rust/trezor-client/src/messages/generated.rs
index b825d592..bb4439ed 100644
--- a/rust/trezor-client/src/messages/generated.rs
+++ b/rust/trezor-client/src/messages/generated.rs
@@ -186,6 +186,12 @@ trezor_message_impl! {
EthereumSignTypedHash => MessageType_EthereumSignTypedHash,
}
+#[cfg(feature = "evolu")]
+trezor_message_impl! {
+ EvoluGetNode => MessageType_EvoluGetNode,
+ EvoluNode => MessageType_EvoluNode,
+}
+
#[cfg(feature = "monero")]
trezor_message_impl! {
MoneroTransactionInitRequest => MessageType_MoneroTransactionInitRequest,
diff --git a/rust/trezor-client/src/protos/generated/messages.rs b/rust/trezor-client/src/protos/generated/messages.rs
index face0452..48eed602 100644
--- a/rust/trezor-client/src/protos/generated/messages.rs
+++ b/rust/trezor-client/src/protos/generated/messages.rs
@@ -527,6 +527,10 @@ pub enum MessageType {
MessageType_NostrSignEvent = 2003,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_NostrEventSignature)
MessageType_NostrEventSignature = 2004,
+ // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_EvoluGetNode)
+ MessageType_EvoluGetNode = 2100,
+ // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_EvoluNode)
+ MessageType_EvoluNode = 2101,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_BenchmarkListNames)
MessageType_BenchmarkListNames = 9100,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_BenchmarkNames)
@@ -796,6 +800,8 @@ impl ::protobuf::Enum for MessageType {
2002 => ::std::option::Option::Some(MessageType::MessageType_NostrPubkey),
2003 => ::std::option::Option::Some(MessageType::MessageType_NostrSignEvent),
2004 => ::std::option::Option::Some(MessageType::MessageType_NostrEventSignature),
+ 2100 => ::std::option::Option::Some(MessageType::MessageType_EvoluGetNode),
+ 2101 => ::std::option::Option::Some(MessageType::MessageType_EvoluNode),
9100 => ::std::option::Option::Some(MessageType::MessageType_BenchmarkListNames),
9101 => ::std::option::Option::Some(MessageType::MessageType_BenchmarkNames),
9102 => ::std::option::Option::Some(MessageType::MessageType_BenchmarkRun),
@@ -1056,6 +1062,8 @@ impl ::protobuf::Enum for MessageType {
"MessageType_NostrPubkey" => ::std::option::Option::Some(MessageType::MessageType_NostrPubkey),
"MessageType_NostrSignEvent" => ::std::option::Option::Some(MessageType::MessageType_NostrSignEvent),
"MessageType_NostrEventSignature" => ::std::option::Option::Some(MessageType::MessageType_NostrEventSignature),
+ "MessageType_EvoluGetNode" => ::std::option::Option::Some(MessageType::MessageType_EvoluGetNode),
+ "MessageType_EvoluNode" => ::std::option::Option::Some(MessageType::MessageType_EvoluNode),
"MessageType_BenchmarkListNames" => ::std::option::Option::Some(MessageType::MessageType_BenchmarkListNames),
"MessageType_BenchmarkNames" => ::std::option::Option::Some(MessageType::MessageType_BenchmarkNames),
"MessageType_BenchmarkRun" => ::std::option::Option::Some(MessageType::MessageType_BenchmarkRun),
@@ -1315,6 +1323,8 @@ impl ::protobuf::Enum for MessageType {
MessageType::MessageType_NostrPubkey,
MessageType::MessageType_NostrSignEvent,
MessageType::MessageType_NostrEventSignature,
+ MessageType::MessageType_EvoluGetNode,
+ MessageType::MessageType_EvoluNode,
MessageType::MessageType_BenchmarkListNames,
MessageType::MessageType_BenchmarkNames,
MessageType::MessageType_BenchmarkRun,
@@ -1580,10 +1590,12 @@ impl ::protobuf::EnumFull for MessageType {
MessageType::MessageType_NostrPubkey => 247,
MessageType::MessageType_NostrSignEvent => 248,
MessageType::MessageType_NostrEventSignature => 249,
- MessageType::MessageType_BenchmarkListNames => 250,
- MessageType::MessageType_BenchmarkNames => 251,
- MessageType::MessageType_BenchmarkRun => 252,
- MessageType::MessageType_BenchmarkResult => 253,
+ MessageType::MessageType_EvoluGetNode => 250,
+ MessageType::MessageType_EvoluNode => 251,
+ MessageType::MessageType_BenchmarkListNames => 252,
+ MessageType::MessageType_BenchmarkNames => 253,
+ MessageType::MessageType_BenchmarkRun => 254,
+ MessageType::MessageType_BenchmarkResult => 255,
};
Self::enum_descriptor().value_by_index(index)
}
@@ -1602,7 +1614,7 @@ impl MessageType {
}
static file_descriptor_proto_data: &'static [u8] = b"\
- \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\xd4X\
+ \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\x9bY\
\n\x0bMessageType\x12(\n\x16MessageType_Initialize\x10\0\x1a\x0c\x80\xa6\
\x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\x10MessageType_Ping\
\x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12%\n\x13MessageType_S\
@@ -1887,7 +1899,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\
sageType_NostrGetPubkey\x10\xd1\x0f\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17M\
essageType_NostrPubkey\x10\xd2\x0f\x1a\x04\x98\xb5\x18\x01\x12%\n\x1aMes\
sageType_NostrSignEvent\x10\xd3\x0f\x1a\x04\x90\xb5\x18\x01\x12*\n\x1fMe\
- ssageType_NostrEventSignature\x10\xd4\x0f\x1a\x04\x98\xb5\x18\x01\x12)\n\
+ ssageType_NostrEventSignature\x10\xd4\x0f\x1a\x04\x98\xb5\x18\x01\x12#\n\
+ \x18MessageType_EvoluGetNode\x10\xb4\x10\x1a\x04\x90\xb5\x18\x01\x12\x20\
+ \n\x15MessageType_EvoluNode\x10\xb5\x10\x1a\x04\x98\xb5\x18\x01\x12)\n\
\x1eMessageType_BenchmarkListNames\x10\x8cG\x1a\x04\x80\xa6\x1d\x01\x12%\
\n\x1aMessageType_BenchmarkNames\x10\x8dG\x1a\x04\x80\xa6\x1d\x01\x12#\n\
\x18MessageType_BenchmarkRun\x10\x8eG\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1b\
diff --git a/rust/trezor-client/src/protos/generated/messages_evolu.rs b/rust/trezor-client/src/protos/generated/messages_evolu.rs
new file mode 100644
index 00000000..ffeefbb3
--- /dev/null
+++ b/rust/trezor-client/src/protos/generated/messages_evolu.rs
@@ -0,0 +1,325 @@
+// This file is generated by rust-protobuf 3.7.2. Do not edit
+// .proto file is parsed by protoc 3.19.6
+// @generated
+
+// https://github.com/rust-lang/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![allow(unused_attributes)]
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unused_results)]
+#![allow(unused_mut)]
+
+//! Generated file from `messages-evolu.proto`
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_7_2;
+
+// @@protoc_insertion_point(message:hw.trezor.messages.evolu.EvoluGetNode)
+#[derive(PartialEq,Clone,Default,Debug)]
+pub struct EvoluGetNode {
+ // special fields
+ // @@protoc_insertion_point(special_field:hw.trezor.messages.evolu.EvoluGetNode.special_fields)
+ pub special_fields: ::protobuf::SpecialFields,
+}
+
+impl<'a> ::std::default::Default for &'a EvoluGetNode {
+ fn default() -> &'a EvoluGetNode {
+ <EvoluGetNode as ::protobuf::Message>::default_instance()
+ }
+}
+
+impl EvoluGetNode {
+ pub fn new() -> EvoluGetNode {
+ ::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::<EvoluGetNode>(
+ "EvoluGetNode",
+ fields,
+ oneofs,
+ )
+ }
+}
+
+impl ::protobuf::Message for EvoluGetNode {
+ const NAME: &'static str = "EvoluGetNode";
+
+ 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() -> EvoluGetNode {
+ EvoluGetNode::new()
+ }
+
+ fn clear(&mut self) {
+ self.special_fields.clear();
+ }
+
+ fn default_instance() -> &'static EvoluGetNode {
+ static instance: EvoluGetNode = EvoluGetNode {
+ special_fields: ::protobuf::SpecialFields::new(),
+ };
+ &instance
+ }
+}
+
+impl ::protobuf::MessageFull for EvoluGetNode {
+ 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("EvoluGetNode").unwrap()).clone()
+ }
+}
+
+impl ::std::fmt::Display for EvoluGetNode {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::protobuf::text_format::fmt(self, f)
+ }
+}
+
+impl ::protobuf::reflect::ProtobufValue for EvoluGetNode {
+ type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
+}
+
+// @@protoc_insertion_point(message:hw.trezor.messages.evolu.EvoluNode)
+#[derive(PartialEq,Clone,Default,Debug)]
+pub struct EvoluNode {
+ // message fields
+ // @@protoc_insertion_point(field:hw.trezor.messages.evolu.EvoluNode.data)
+ pub data: ::std::option::Option<::std::vec::Vec<u8>>,
+ // special fields
+ // @@protoc_insertion_point(special_field:hw.trezor.messages.evolu.EvoluNode.special_fields)
+ pub special_fields: ::protobuf::SpecialFields,
+}
+
+impl<'a> ::std::default::Default for &'a EvoluNode {
+ fn default() -> &'a EvoluNode {
+ <EvoluNode as ::protobuf::Message>::default_instance()
+ }
+}
+
+impl EvoluNode {
+ pub fn new() -> EvoluNode {
+ ::std::default::Default::default()
+ }
+
+ // required bytes data = 1;
+
+ pub fn data(&self) -> &[u8] {
+ match self.data.as_ref() {
+ Some(v) => v,
+ None => &[],
+ }
+ }
+
+ pub fn clear_data(&mut self) {
+ self.data = ::std::option::Option::None;
+ }
+
+ pub fn has_data(&self) -> bool {
+ self.data.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_data(&mut self, v: ::std::vec::Vec<u8>) {
+ self.data = ::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_data(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.data.is_none() {
+ self.data = ::std::option::Option::Some(::std::vec::Vec::new());
+ }
+ self.data.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
+ self.data.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::<_, _>(
+ "data",
+ |m: &EvoluNode| { &m.data },
+ |m: &mut EvoluNode| { &mut m.data },
+ ));
+ ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<EvoluNode>(
+ "EvoluNode",
+ fields,
+ oneofs,
+ )
+ }
+}
+
+impl ::protobuf::Message for EvoluNode {
+ const NAME: &'static str = "EvoluNode";
+
+ fn is_initialized(&self) -> bool {
+ if self.data.is_none() {
+ return false;
+ }
+ 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.data = ::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.data.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.data.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() -> EvoluNode {
+ EvoluNode::new()
+ }
+
+ fn clear(&mut self) {
+ self.data = ::std::option::Option::None;
+ self.special_fields.clear();
+ }
+
+ fn default_instance() -> &'static EvoluNode {
+ static instance: EvoluNode = EvoluNode {
+ data: ::std::option::Option::None,
+ special_fields: ::protobuf::SpecialFields::new(),
+ };
+ &instance
+ }
+}
+
+impl ::protobuf::MessageFull for EvoluNode {
+ 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("EvoluNode").unwrap()).clone()
+ }
+}
+
+impl ::std::fmt::Display for EvoluNode {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::protobuf::text_format::fmt(self, f)
+ }
+}
+
+impl ::protobuf::reflect::ProtobufValue for EvoluNode {
+ type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+ \n\x14messages-evolu.proto\x12\x18hw.trezor.messages.evolu\"\x0e\n\x0cEv\
+ oluGetNode\"\x1f\n\tEvoluNode\x12\x12\n\x04data\x18\x01\x20\x02(\x0cR\
+ \x04dataB9\n#com.satoshilabs.trezor.lib.protobufB\x12TrezorMessageEvolu\
+";
+
+/// `FileDescriptorProto` object which was a source for this generated file
+fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+ static file_descriptor_proto_lazy: ::protobuf::rt::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::Lazy::new();
+ file_descriptor_proto_lazy.get(|| {
+ ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
+ })
+}
+
+/// `FileDescriptor` object which allows dynamic access to files
+pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
+ static generated_file_descriptor_lazy: ::protobuf::rt::Lazy<::protobuf::reflect::GeneratedFileDescriptor> = ::protobuf::rt::Lazy::new();
+ static file_descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::FileDescriptor> = ::protobuf::rt::Lazy::new();
+ file_descriptor.get(|| {
+ let generated_file_descriptor = generated_file_descriptor_lazy.get(|| {
+ let mut deps = ::std::vec::Vec::with_capacity(0);
+ let mut messages = ::std::vec::Vec::with_capacity(2);
+ messages.push(EvoluGetNode::generated_message_descriptor_data());
+ messages.push(EvoluNode::generated_message_descriptor_data());
+ let mut enums = ::std::vec::Vec::with_capacity(0);
+ ::protobuf::reflect::GeneratedFileDescriptor::new_generated(
+ file_descriptor_proto(),
+ deps,
+ messages,
+ enums,
+ )
+ });
+ ::protobuf::reflect::FileDescriptor::new_generated_2(generated_file_descriptor)
+ })
+}
diff --git a/rust/trezor-client/src/protos/mod.rs b/rust/trezor-client/src/protos/mod.rs
index 4c029c36..70d1b5fe 100644
--- a/rust/trezor-client/src/protos/mod.rs
+++ b/rust/trezor-client/src/protos/mod.rs
@@ -32,6 +32,7 @@ mod generated {
"ethereum" => messages_ethereum_eip712
"cardano" => messages_cardano
"eos" => messages_eos
+ "evolu" => messages_evolu
"monero" => messages_monero
"nem" => messages_nem
"nostr" => messages_nostr
diff --git a/tests/device_tests/misc/test_msg_getevolunode.py b/tests/device_tests/misc/test_msg_getevolunode.py
new file mode 100644
index 00000000..e2dc6fba
--- /dev/null
+++ b/tests/device_tests/misc/test_msg_getevolunode.py
@@ -0,0 +1,31 @@
+# This file is part of the Trezor project.
+#
+# Copyright (C) 2012-2025 SatoshiLabs and contributors
+#
+# This library is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the License along with this library.
+# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
+
+import pytest
+
+from trezorlib import evolu
+from trezorlib.debuglink import SessionDebugWrapper as Session
+
+pytestmark = [pytest.mark.altcoin, pytest.mark.models("core")]
+
+EXPECTED_SLIP21_NODE_DATA = "a81aaf51997b6ddfa33d11c038d6aba5f711754a2c823823ff8b777825cdbb32b0e71c301fa381c75081bd3bcc134b63306aa6fc9a9f52d835ad4df8cd507be6"
+
+
+def test_get_evolu_node(session: Session):
+ """Test Evolu key derivation against known test vectors."""
+ res = evolu.get_evolu_node(session)
+
+ assert res.data.hex() == EXPECTED_SLIP21_NODE_DATA
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index 8d0fd6e8..01b9cb26 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -2209,6 +2209,7 @@
"T2T1_cs_misc-test_msg_getentropy.py::test_entropy[65]": "4a967a7981f89b3165f2e1e7d7a6c46335865ee41d417d945497ed1fd767d8c4",
"T2T1_cs_misc-test_msg_getentropy.py::test_entropy[8]": "4a967a7981f89b3165f2e1e7d7a6c46335865ee41d417d945497ed1fd767d8c4",
"T2T1_cs_misc-test_msg_getentropy.py::test_entropy[9]": "4a967a7981f89b3165f2e1e7d7a6c46335865ee41d417d945497ed1fd767d8c4",
+"T2T1_cs_misc-test_msg_getevolunode.py::test_get_evolu_node": "a186c37d0686ee8245d2da263bd8a8f49fa1cca70a490bcaaa45d7a17400a235",
"T2T1_cs_misc-test_msg_signidentity.py::test_sign": "6f8e13fc2b5b1705a581a44023fbf48a01462be1ff2381c89db3e6be2f384d80",
"T2T1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "e00a2c45559d463ca2364110479c3e630fb1798e94cf460a4341ff64802975bc",
"T2T1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "5cc2673aeac3e4e217f648b0452a5b76927f5e3328ec46293628e0b079473980",
@@ -3747,6 +3748,7 @@
"T2T1_de_misc-test_msg_getentropy.py::test_entropy[65]": "e99f3a6f32e6a12e0311ced039f5aa028a3b36a323ba771c8e39df6ed774a886",
"T2T1_de_misc-test_msg_getentropy.py::test_entropy[8]": "e99f3a6f32e6a12e0311ced039f5aa028a3b36a323ba771c8e39df6ed774a886",
"T2T1_de_misc-test_msg_getentropy.py::test_entropy[9]": "e99f3a6f32e6a12e0311ced039f5aa028a3b36a323ba771c8e39df6ed774a886",
+"T2T1_de_misc-test_msg_getevolunode.py::test_get_evolu_node": "26d1022169bb3c41ee8ba9af4544b7d1cb5a5ee20732820487cd2968c468a71f",
"T2T1_de_misc-test_msg_signidentity.py::test_sign": "54fec7bfcadcf777f7d36753eb1b2b14a448c75ebd32dfa3df1a172891797ad9",
"T2T1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "9611b1c2ca257ed6c4aaf4d3eda15db53571c1b123daaf90ee2890124839f64f",
"T2T1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "6b99792ab806fe1edaa04c98470ea6133f3f3b6316585959f83a08e68e96ac92",
@@ -5285,6 +5287,7 @@
"T2T1_en_misc-test_msg_getentropy.py::test_entropy[65]": "051aa888948148f00166656771c8237baaf2496b65ee2f2fb4a924457a132154",
"T2T1_en_misc-test_msg_getentropy.py::test_entropy[8]": "051aa888948148f00166656771c8237baaf2496b65ee2f2fb4a924457a132154",
"T2T1_en_misc-test_msg_getentropy.py::test_entropy[9]": "051aa888948148f00166656771c8237baaf2496b65ee2f2fb4a924457a132154",
+"T2T1_en_misc-test_msg_getevolunode.py::test_get_evolu_node": "44dc09f3d866403d4062221f39bb88d42619e9e5bf8c4ae060c76b72e18d278b",
"T2T1_en_misc-test_msg_signidentity.py::test_sign": "f6e9e33a08e6e11b7b2524c3838a3a1a79e8f87c9ce8fcff69fc746c016164b7",
"T2T1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "dcae755fb9c1f2fdd9f253ecdb8e0f02dc2d2f114479d1e85c08dde3eb17a368",
"T2T1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "e64de616c2b7ee35912ad8c148cc27b4c340217615aefec98a58777a1d975217",
@@ -6841,6 +6844,7 @@
"T2T1_es_misc-test_msg_getentropy.py::test_entropy[65]": "ce02927690b468e91267845870fa17fcf8a504968b2a1b66990f9b0801bca412",
"T2T1_es_misc-test_msg_getentropy.py::test_entropy[8]": "ce02927690b468e91267845870fa17fcf8a504968b2a1b66990f9b0801bca412",
"T2T1_es_misc-test_msg_getentropy.py::test_entropy[9]": "ce02927690b468e91267845870fa17fcf8a504968b2a1b66990f9b0801bca412",
+"T2T1_es_misc-test_msg_getevolunode.py::test_get_evolu_node": "1841370c73c1a3401a97de916f0bc6c582fb7cb895bacce1cf1667dc128b4e83",
"T2T1_es_misc-test_msg_signidentity.py::test_sign": "67444c2839712225e9c53502a3ba1a5b867f66c1e1b0831241665e0f1d177a15",
"T2T1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "082be2f36f05247cda02a9909b93f994f169c66dcf3bed3819fd5f22a79d27eb",
"T2T1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "1ad9a562dc8155aac49ba33e53b27da80425034205519174c19cb09533b6dba4",
@@ -8379,6 +8383,7 @@
"T2T1_fr_misc-test_msg_getentropy.py::test_entropy[65]": "97765004d869c9dbcc9bb5fc916cb7e6be0ba00b1861e3cedc579f360ef3cc01",
"T2T1_fr_misc-test_msg_getentropy.py::test_entropy[8]": "97765004d869c9dbcc9bb5fc916cb7e6be0ba00b1861e3cedc579f360ef3cc01",
"T2T1_fr_misc-test_msg_getentropy.py::test_entropy[9]": "97765004d869c9dbcc9bb5fc916cb7e6be0ba00b1861e3cedc579f360ef3cc01",
+"T2T1_fr_misc-test_msg_getevolunode.py::test_get_evolu_node": "b67212498d9ac1e2ff65d67a200cd7ba2c61958a04dd0eb652ec36032fa84709",
"T2T1_fr_misc-test_msg_signidentity.py::test_sign": "08910d0a9b2ad7024e17aaf5de14f9c4250c0e7ff422df41c1a21d27e0733acf",
"T2T1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "de3b2b1395227a816371efdabe2d54d380e9c435f26f24f96b4910b5f0d46239",
"T2T1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "06e10e0e6aa1430219583aeef9265e22146f5e9e4351bad33df611c15a2c914b",
@@ -9917,6 +9922,7 @@
"T2T1_pt_misc-test_msg_getentropy.py::test_entropy[65]": "a1f14befac1eb1035e0ea2ae20c40631ca082c6112ddfbe7e544b1fac13b143c",
"T2T1_pt_misc-test_msg_getentropy.py::test_entropy[8]": "a1f14befac1eb1035e0ea2ae20c40631ca082c6112ddfbe7e544b1fac13b143c",
"T2T1_pt_misc-test_msg_getentropy.py::test_entropy[9]": "a1f14befac1eb1035e0ea2ae20c40631ca082c6112ddfbe7e544b1fac13b143c",
+"T2T1_pt_misc-test_msg_getevolunode.py::test_get_evolu_node": "09eb0befd94cd56ad27479460f49ace537f67125de9ff5120a2a1f884c4dd008",
"T2T1_pt_misc-test_msg_signidentity.py::test_sign": "f789ab3bb813b0686c7d0ca4b3cf65ff0f309ea2f83c3bc9bd2988c0ed1d093d",
"T2T1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "8c1727ff726a29de9185ec8e0a69983ad6189aa761f9cc2d74b4c5bba27ac458",
"T2T1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "beca034cea321adca5db0f2e7bf58c5f9d3b8d6a6aa7d11be5672ef04b91dc45",
@@ -11706,6 +11712,7 @@
"T3B1_cs_misc-test_msg_getentropy.py::test_entropy[65]": "755144ba31bea3230796491b91205d770707810be22b069376d5fd75f07989ac",
"T3B1_cs_misc-test_msg_getentropy.py::test_entropy[8]": "755144ba31bea3230796491b91205d770707810be22b069376d5fd75f07989ac",
"T3B1_cs_misc-test_msg_getentropy.py::test_entropy[9]": "755144ba31bea3230796491b91205d770707810be22b069376d5fd75f07989ac",
+"T3B1_cs_misc-test_msg_getevolunode.py::test_get_evolu_node": "e99c36c3af53571b6d17774461a1a7b8232d7147c96c8c005a5bb42c77c32969",
"T3B1_cs_misc-test_msg_signidentity.py::test_sign": "d034f3b7fff9f90d25ae5f84c27690f65f314a72b1d541569d4722a301bd1bb7",
"T3B1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "9888a62c956c2ba0272038f92e74ea1ea5abf28f5dde455f56b066e59dfa39e3",
"T3B1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "ee2e8d64333c166fdc308142ba13b553e448b7f80d588e5325b8731d93605702",
@@ -13161,6 +13168,7 @@
"T3B1_de_misc-test_msg_getentropy.py::test_entropy[65]": "9f8671705cc2c47582ae67f76c111a4bffec5c35849733595134a18aadd1804e",
"T3B1_de_misc-test_msg_getentropy.py::test_entropy[8]": "9f8671705cc2c47582ae67f76c111a4bffec5c35849733595134a18aadd1804e",
"T3B1_de_misc-test_msg_getentropy.py::test_entropy[9]": "9f8671705cc2c47582ae67f76c111a4bffec5c35849733595134a18aadd1804e",
+"T3B1_de_misc-test_msg_getevolunode.py::test_get_evolu_node": "8862af62d5d4cba3470ba18b7f350c889162c1045fd3e869fcf6d3233dc98700",
"T3B1_de_misc-test_msg_signidentity.py::test_sign": "6b8d0cca2f6208a5030e7639c6a8f86579faa539df6c6e750bd98838b04fa202",
"T3B1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "e7e29a72c4e3dc28ea88d31efd53b6847dbf6b5a05854faa1edb86c545d8cbe0",
"T3B1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "f126a55c4b152ac9da410555f64d7afee4523af2382ff21f93f1b7606a7b93fc",
@@ -14616,6 +14624,7 @@
"T3B1_en_misc-test_msg_getentropy.py::test_entropy[65]": "5c5cf562f789ae5fad9e3dd028878dcb91273d46281f06a910e0c875eb520d4c",
"T3B1_en_misc-test_msg_getentropy.py::test_entropy[8]": "5c5cf562f789ae5fad9e3dd028878dcb91273d46281f06a910e0c875eb520d4c",
"T3B1_en_misc-test_msg_getentropy.py::test_entropy[9]": "5c5cf562f789ae5fad9e3dd028878dcb91273d46281f06a910e0c875eb520d4c",
+"T3B1_en_misc-test_msg_getevolunode.py::test_get_evolu_node": "79559f55560fe12085e1fb3dcfd40a3a422063819da4a7b222d90f51c2cd91a7",
"T3B1_en_misc-test_msg_signidentity.py::test_sign": "4f574bb5257b37230f549220819d177cdafa8e4603aa8fef825e7c7701790d90",
"T3B1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "c538a84a0885cac4b19ae8f97fad83947d3fdec3735efdbb6e730e33244196a0",
"T3B1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "538af80590917bf41313091bc11617044444c9ae5978209b0a74332d390234dc",
@@ -16071,6 +16080,7 @@
"T3B1_es_misc-test_msg_getentropy.py::test_entropy[65]": "e692ba3e9f449dde4e9eec614342e4fdf7548953e45959dfd90d83836c5bdf21",
"T3B1_es_misc-test_msg_getentropy.py::test_entropy[8]": "e692ba3e9f449dde4e9eec614342e4fdf7548953e45959dfd90d83836c5bdf21",
"T3B1_es_misc-test_msg_getentropy.py::test_entropy[9]": "e692ba3e9f449dde4e9eec614342e4fdf7548953e45959dfd90d83836c5bdf21",
+"T3B1_es_misc-test_msg_getevolunode.py::test_get_evolu_node": "06a413855d8bbc29e09cbe1de646480189d8a684c8d355fb962d90b2c23d3ef7",
"T3B1_es_misc-test_msg_signidentity.py::test_sign": "75ada42bef7a931d7c331b57e1a8e20e617f17fd7c12f4651efb54645b8b2bae",
"T3B1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "b4a7baaa1f75a9110ad8683bba4f4b8e406bd0ad233482755d508eb0d4b45e28",
"T3B1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "981d01d4370a3851574931b2122ea75b20ca20bd08c14966e507604fe7a9fb92",
@@ -17526,6 +17536,7 @@
"T3B1_fr_misc-test_msg_getentropy.py::test_entropy[65]": "1b02691176d74e16c048f174d3e71a9bc24a0ced4b4b08d02ac1f86000f789c7",
"T3B1_fr_misc-test_msg_getentropy.py::test_entropy[8]": "1b02691176d74e16c048f174d3e71a9bc24a0ced4b4b08d02ac1f86000f789c7",
"T3B1_fr_misc-test_msg_getentropy.py::test_entropy[9]": "1b02691176d74e16c048f174d3e71a9bc24a0ced4b4b08d02ac1f86000f789c7",
+"T3B1_fr_misc-test_msg_getevolunode.py::test_get_evolu_node": "9720291d66656c9e21bf35bdf47ed9591bc69c09bf003438b4a32dfee3de6371",
"T3B1_fr_misc-test_msg_signidentity.py::test_sign": "948949a41dedf7771d9fb1443706557429774639ed8a655a54cbdf8f634d2a2a",
"T3B1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "01d74a67df59141513f048abcfbda73c66ffd6f3fc3f350deb42ee8a0b17930f",
"T3B1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "fb93cda619f0183c16cfc4fc8b789c3fa96ccd7cfb97c2024739e22e8cb5587e",
@@ -18981,6 +18992,7 @@
"T3B1_pt_misc-test_msg_getentropy.py::test_entropy[65]": "3611d94998d9d15b67baae7a134fa92f892f466e04318b5179fbaff9bf17d1cd",
"T3B1_pt_misc-test_msg_getentropy.py::test_entropy[8]": "3611d94998d9d15b67baae7a134fa92f892f466e04318b5179fbaff9bf17d1cd",
"T3B1_pt_misc-test_msg_getentropy.py::test_entropy[9]": "3611d94998d9d15b67baae7a134fa92f892f466e04318b5179fbaff9bf17d1cd",
+"T3B1_pt_misc-test_msg_getevolunode.py::test_get_evolu_node": "a584c97638a81d0bdb8559ab476ff0100a80af1ac05cc7dd947d7ad68ec54773",
"T3B1_pt_misc-test_msg_signidentity.py::test_sign": "60e8329571b2f80b6fcea6a8e90cefb272bca5e04253cff66bbb7c171550900b",
"T3B1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "096328ac069b519df177e94d3f488ca8befb5010d2c177796578c25fd118eeb3",
"T3B1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "fd922301a13d8cf396f10afbbb42e83b8fcd3bd5a8ecf09a5544c309890512f0",
@@ -20828,6 +20840,7 @@
"T3T1_cs_misc-test_msg_getentropy.py::test_entropy[65]": "5ea75a999a80dcf159e7a8d09a6cb0d425da1c3137350c7d241b301d8e0b8993",
"T3T1_cs_misc-test_msg_getentropy.py::test_entropy[8]": "5ea75a999a80dcf159e7a8d09a6cb0d425da1c3137350c7d241b301d8e0b8993",
"T3T1_cs_misc-test_msg_getentropy.py::test_entropy[9]": "5ea75a999a80dcf159e7a8d09a6cb0d425da1c3137350c7d241b301d8e0b8993",
+"T3T1_cs_misc-test_msg_getevolunode.py::test_get_evolu_node": "d370635c265d0117d2212ab904bbc50aeea89bd36578349d5f9c7af32d1605c4",
"T3T1_cs_misc-test_msg_signidentity.py::test_sign": "373769071ec21460a8cb0fa961a0c860a7f18f048d7cd02dae6f60039df11e16",
"T3T1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "384a6e24249e7272dcf0c35956ef74fafb48c6311026afd4c7f01c9dcfa8e429",
"T3T1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "27243e7368c51c5407296d211b393de207a211ed2640333f63165403d6f706a9",
@@ -22314,6 +22327,7 @@
"T3T1_de_misc-test_msg_getentropy.py::test_entropy[65]": "38eeddd6b6a6755d89fd89b5e84292cd9caf914aac0000c8ff5c66048278becc",
"T3T1_de_misc-test_msg_getentropy.py::test_entropy[8]": "38eeddd6b6a6755d89fd89b5e84292cd9caf914aac0000c8ff5c66048278becc",
"T3T1_de_misc-test_msg_getentropy.py::test_entropy[9]": "38eeddd6b6a6755d89fd89b5e84292cd9caf914aac0000c8ff5c66048278becc",
+"T3T1_de_misc-test_msg_getevolunode.py::test_get_evolu_node": "563c3ecd0fedd9f4c15c38bbb470c514a4527d53d96622913f835ce2cbd95a6d",
"T3T1_de_misc-test_msg_signidentity.py::test_sign": "bf4d89fcc8a4c33e1985d23d35132d845d60d868c4d130987143c583229a8e96",
"T3T1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "f12269e30eb4ed99a23cb5ed3d830b96134b01d2f25505dbae93550b75febdeb",
"T3T1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "eb927bbaa7af4c0c49505814a4691055497e85a15b7a739e2d4a6e15df1b6c53",
@@ -23800,6 +23814,7 @@
"T3T1_en_misc-test_msg_getentropy.py::test_entropy[65]": "d28c3abf9359ebd67789ac99e3f91299e126c507c8c49cec063a1014ac51f8bf",
"T3T1_en_misc-test_msg_getentropy.py::test_entropy[8]": "d28c3abf9359ebd67789ac99e3f91299e126c507c8c49cec063a1014ac51f8bf",
"T3T1_en_misc-test_msg_getentropy.py::test_entropy[9]": "d28c3abf9359ebd67789ac99e3f91299e126c507c8c49cec063a1014ac51f8bf",
+"T3T1_en_misc-test_msg_getevolunode.py::test_get_evolu_node": "6e513eceafa48c21da892b9265059739742e33084ef05f312d9ccb0090751fc2",
"T3T1_en_misc-test_msg_signidentity.py::test_sign": "5307725e663ce2da2fbbbcab377888048e0f92f0605ce30a3c730d33c26ad0a2",
"T3T1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "2ec7ee0cfca13cc950c666b4f0c5aed71b0fa6f4f59650d141af556e61a6514f",
"T3T1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "9340fc0d18de49a7d41d44029f4a2eac62ac8e2755cc2db3143e60740344c38f",
@@ -25286,6 +25301,7 @@
"T3T1_es_misc-test_msg_getentropy.py::test_entropy[65]": "a557ba0f31b5dabe2202b373791dbbbfadb07fe1cb0f0a7b591988a23d190099",
"T3T1_es_misc-test_msg_getentropy.py::test_entropy[8]": "a557ba0f31b5dabe2202b373791dbbbfadb07fe1cb0f0a7b591988a23d190099",
"T3T1_es_misc-test_msg_getentropy.py::test_entropy[9]": "a557ba0f31b5dabe2202b373791dbbbfadb07fe1cb0f0a7b591988a23d190099",
+"T3T1_es_misc-test_msg_getevolunode.py::test_get_evolu_node": "7bfa600f7556eed41c58162f685f8db00ae4e881f095cc1c8b85b52944171dee",
"T3T1_es_misc-test_msg_signidentity.py::test_sign": "73881aee342aaa76929b8c977da01ba5a9213f39fd0a7e0026e223dab78e3425",
"T3T1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "d90d7c2a03396f62465be6e0aab40291090d553b60890918985248d228f90485",
"T3T1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "fd673024b4bf4b05ba058cbf107d27079032b2109fcada935f95baf805a226f2",
@@ -26772,6 +26788,7 @@
"T3T1_fr_misc-test_msg_getentropy.py::test_entropy[65]": "a9bd063b9aa7827df4aa54e1228f44d0b465e6e8d88792f5849e1d9a0543967f",
"T3T1_fr_misc-test_msg_getentropy.py::test_entropy[8]": "a9bd063b9aa7827df4aa54e1228f44d0b465e6e8d88792f5849e1d9a0543967f",
"T3T1_fr_misc-test_msg_getentropy.py::test_entropy[9]": "a9bd063b9aa7827df4aa54e1228f44d0b465e6e8d88792f5849e1d9a0543967f",
+"T3T1_fr_misc-test_msg_getevolunode.py::test_get_evolu_node": "9f204e771de5d8f1a920e342f7fe3d14e1c88e240cdc82acd9b96f82d2323736",
"T3T1_fr_misc-test_msg_signidentity.py::test_sign": "65c3ca98c8576cb8d2b15b2385904ccae0110aff0ef909459486d8c508ca37bb",
"T3T1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "389b633232262380b98df4302b57f4e4447f30098b7a44e303889d534a1418e3",
"T3T1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "ea46d33df520e5e5dc3ba35ee54857f7691c92d19510cb96c341e302f241ce93",
@@ -28258,6 +28275,7 @@
"T3T1_pt_misc-test_msg_getentropy.py::test_entropy[65]": "53e872921809db75cc98867a01bc93495d51128ef1842675b406c3d95c81769a",
"T3T1_pt_misc-test_msg_getentropy.py::test_entropy[8]": "53e872921809db75cc98867a01bc93495d51128ef1842675b406c3d95c81769a",
"T3T1_pt_misc-test_msg_getentropy.py::test_entropy[9]": "53e872921809db75cc98867a01bc93495d51128ef1842675b406c3d95c81769a",
+"T3T1_pt_misc-test_msg_getevolunode.py::test_get_evolu_node": "e482c1d6c292938a4b42033032d14549765611cb27455423174652792f674886",
"T3T1_pt_misc-test_msg_signidentity.py::test_sign": "7cf8536da9b1294b3a962a16d853bf08db532110a3e93d3a3d41cf502c7de86e",
"T3T1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "0bb7c2f9fe9fe5827c0b60d697bfdf21632d2611e6193fa162e0d4206581817a",
"T3T1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "4bbc4fe9da2b9e0f7e34779a1c2e87b6b4f4fcad6278ddfd22bda9e186d2a5cc",
@@ -30108,6 +30126,7 @@
"T3W1_cs_misc-test_msg_getentropy.py::test_entropy[65]": "33c7ab1dd87bc3ac872d54303150a7a8ff7d60467b74c2710f952798b53b19cc",
"T3W1_cs_misc-test_msg_getentropy.py::test_entropy[8]": "33c7ab1dd87bc3ac872d54303150a7a8ff7d60467b74c2710f952798b53b19cc",
"T3W1_cs_misc-test_msg_getentropy.py::test_entropy[9]": "33c7ab1dd87bc3ac872d54303150a7a8ff7d60467b74c2710f952798b53b19cc",
+"T3W1_cs_misc-test_msg_getevolunode.py::test_get_evolu_node": "591a8974ba93914396a48c9ad473a56ffaf761b652588951fbf4b7cb67b4f2a9",
"T3W1_cs_misc-test_msg_signidentity.py::test_sign": "7870072b38e070d9215aa5395186757594362443e6f71168d4d8e2330d3f16ac",
"T3W1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "e0d835fe5317501c2bd5f83ce3c3d36db2ae7e4771ebf90e964c83a57024251c",
"T3W1_cs_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "25e7721f20ee8a8c4f79e2e81669435f409e6aa9dd5f05ed1a7807ed818dee33",
@@ -31583,6 +31602,7 @@
"T3W1_de_misc-test_msg_getentropy.py::test_entropy[65]": "c5b6acd4a1f53ac3e7a351c353368a714db910281f968e869959132672e7e464",
"T3W1_de_misc-test_msg_getentropy.py::test_entropy[8]": "c5b6acd4a1f53ac3e7a351c353368a714db910281f968e869959132672e7e464",
"T3W1_de_misc-test_msg_getentropy.py::test_entropy[9]": "c5b6acd4a1f53ac3e7a351c353368a714db910281f968e869959132672e7e464",
+"T3W1_de_misc-test_msg_getevolunode.py::test_get_evolu_node": "70fb842a64bc7b990d0a7fefd0aba44a8073dee1cee98cf930b21d815c415e7b",
"T3W1_de_misc-test_msg_signidentity.py::test_sign": "9cdb523d7c5f541eb0d2ae7c4cbc0fa17abf18844a2c77a8633f1e333d6f8c3b",
"T3W1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "ed3bd15e81983f1a732bb9d90e64a07a78031133ccb3c0e605ffe0c96a49640e",
"T3W1_de_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "26bda9fd27032d1fc1deb92854f6881c66e9e89d6939953d7e8d56e54589768b",
@@ -33058,6 +33078,7 @@
"T3W1_en_misc-test_msg_getentropy.py::test_entropy[65]": "96eafa5894542675617159b2ebdb415134afb685b679fda31f4a38b26a6212df",
"T3W1_en_misc-test_msg_getentropy.py::test_entropy[8]": "96eafa5894542675617159b2ebdb415134afb685b679fda31f4a38b26a6212df",
"T3W1_en_misc-test_msg_getentropy.py::test_entropy[9]": "96eafa5894542675617159b2ebdb415134afb685b679fda31f4a38b26a6212df",
+"T3W1_en_misc-test_msg_getevolunode.py::test_get_evolu_node": "b87fad27817c51a12897f5232588c60919f674f3795c5ec1783971d4a4f7f213",
"T3W1_en_misc-test_msg_signidentity.py::test_sign": "2507f5a2e70f4389bb9a4a251b99fd120837de595af085ae61b8b85fb730f159",
"T3W1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "9ffb559eafdf4ff4eba6288a895d45fff20e769d573bf802fe5594ccb61d1303",
"T3W1_en_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "eb083cdbcf1ffea5a2c0eea343900e4d0f4990323d2f8318ccbd150ef0ffb398",
@@ -34533,6 +34554,7 @@
"T3W1_es_misc-test_msg_getentropy.py::test_entropy[65]": "d3d816013c4e0dec92ebb480f1a102a5245326cbec7e740acbf28593893af6e6",
"T3W1_es_misc-test_msg_getentropy.py::test_entropy[8]": "d3d816013c4e0dec92ebb480f1a102a5245326cbec7e740acbf28593893af6e6",
"T3W1_es_misc-test_msg_getentropy.py::test_entropy[9]": "d3d816013c4e0dec92ebb480f1a102a5245326cbec7e740acbf28593893af6e6",
+"T3W1_es_misc-test_msg_getevolunode.py::test_get_evolu_node": "69c1bb07d8d7c850fc71f6f0ab6f541c89412466faafa07f375f054238a855df",
"T3W1_es_misc-test_msg_signidentity.py::test_sign": "3567e92c1c5418cb71af7e0d48e3e2009f7bde0f3e73ed3871fef93b421aab81",
"T3W1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "d417732ff45f0fe788bb742282ccedeb6613d140646ef98b64f62b321d65c6ec",
"T3W1_es_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "26c3f5b0f8a285de380df16c727abe16051e2eed9cad3059c68ce13afaec2f3d",
@@ -36008,6 +36030,7 @@
"T3W1_fr_misc-test_msg_getentropy.py::test_entropy[65]": "b46fe2890c5535a4bec737cffe489941818ce02708c734e225119d52d3d8325b",
"T3W1_fr_misc-test_msg_getentropy.py::test_entropy[8]": "b46fe2890c5535a4bec737cffe489941818ce02708c734e225119d52d3d8325b",
"T3W1_fr_misc-test_msg_getentropy.py::test_entropy[9]": "b46fe2890c5535a4bec737cffe489941818ce02708c734e225119d52d3d8325b",
+"T3W1_fr_misc-test_msg_getevolunode.py::test_get_evolu_node": "16dc07b50ac47657d5da8f7e926d4c610e20cbe851e6a6395b71dfaf913c744f",
"T3W1_fr_misc-test_msg_signidentity.py::test_sign": "2a47af381d1cea32395674457dedb44c39dd113db304802685744b245330b41a",
"T3W1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "39af730e2ee0e9972a1dcbb812e4a636adff3187426695e8e1c8e9ad7156775e",
"T3W1_fr_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "61e2cd05b477eee4e65e1c517c28ba89a30860c9f83470260e0a905118dba67f",
@@ -37483,6 +37506,7 @@
"T3W1_pt_misc-test_msg_getentropy.py::test_entropy[65]": "7e984a4f79c9beabd2a39be1fb18bae60876a71af0119ece6c2ed5dd13898e8d",
"T3W1_pt_misc-test_msg_getentropy.py::test_entropy[8]": "7e984a4f79c9beabd2a39be1fb18bae60876a71af0119ece6c2ed5dd13898e8d",
"T3W1_pt_misc-test_msg_getentropy.py::test_entropy[9]": "7e984a4f79c9beabd2a39be1fb18bae60876a71af0119ece6c2ed5dd13898e8d",
+"T3W1_pt_misc-test_msg_getevolunode.py::test_get_evolu_node": "75bcd530fc2f1a3d69928c1755816ca32a23e0106afb2b8f927c1ca27973e446",
"T3W1_pt_misc-test_msg_signidentity.py::test_sign": "57bcfabbf8f8f83e1c5fb2386c7033895355a17a145ce1f18027927e87fde469",
"T3W1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-0h-4Ahp23WfMrMFK3wYL2hLWQFGt87-f8cc3746": "3fe993ce700c452e48db6bc2b9b532e2da1b1dd5dfe998672a64f821bc00a909",
"T3W1_pt_monero-test_getaddress.py::test_monero_getaddress[m-44h-128h-1h-44iAazhoAkv5a5RqLNVyh82a1n3-1cc72b15": "427e36c65aec54a8dc4f28f8f4084a5cb2b1b818d4bdac5ca4fd67c7391a1473",
Why this scored 33/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.