feat(core): hide chars in passphrase input
What changed, and why it matters
This commit changes how Trezor hardware wallets display passphrase entry on screen. Previously, the passphrase characters were shown in plain text as the user typed them. After this change, already-typed characters are hidden (shown as dots or asterisks), with only the most recently typed character briefly visible. The user can press and hold in the input area to reveal the full passphrase for verification. This is a security/usability improvement to reduce shoulder-surfing risk, not a fix for an exploitable vulnerability.
No immediate security action required. Treat as a normal privacy-hardening UI improvement. Reviewers may want to verify that the reveal gesture does not accidentally persist on screen after touch release, and that the masking behavior does not interfere with accessibility or user confirmation flows.
Security signals we found
UI change masks sensitive passphrase input to mitigate shoulder-surfing
Adds time-bounded reveal of last character and touch-to-reveal full passphrase
Disables keypad interaction while passphrase is fully revealed
Updates UI test fixtures indicating behavior change is intentional and tested
No cryptographic, memory-safety, or authentication logic changed
Evidence from the diff
The patch modifies the passphrase keyboard UI components for the Bolt (T2T1), Delizia (T3T1), and Eckhart layouts. It introduces a DisplayStyle state machine (Hidden, LastOnly, LastWithMarker, Shown) and a one-second timer. Typed characters are masked: single-tap keys show only the last character briefly, multi-tap keys show the pending character with a marker, and completed characters revert to hidden. A touch-and-hold gesture in the input field switches to DisplayStyle::Shown, rendering the full passphrase in a multi-line overlay; releasing or dragging outside the overlay hides it again. The change also updates UI test fixtures to reflect the new rendered screens. A minor theme color tweak for Delizia keyboard icons is included.
Changed components
core/embed/rust/src/ui/layout_bolt/component/keyboard/passphrase.rscore/embed/rust/src/ui/layout_delizia/component/keyboard/passphrase.rscore/embed/rust/src/ui/layout_delizia/theme/mod.rscore/embed/rust/src/ui/layout_eckhart/firmware/keyboard/passphrase.rstests/ui_tests/fixtures.jsonInspect captured patch +674 / −276
diff --git a/core/.changelog.d/6342.fixed b/core/.changelog.d/6342.fixed
new file mode 100644
index 00000000..d6a67592
--- /dev/null
+++ b/core/.changelog.d/6342.fixed
@@ -0,0 +1 @@
+[T2T1,T3T1] Hide written characters in passphrase keyboard.
diff --git a/core/embed/rust/src/ui/layout_bolt/component/keyboard/passphrase.rs b/core/embed/rust/src/ui/layout_bolt/component/keyboard/passphrase.rs
index 64073bde..2763d7ea 100644
--- a/core/embed/rust/src/ui/layout_bolt/component/keyboard/passphrase.rs
+++ b/core/embed/rust/src/ui/layout_bolt/component/keyboard/passphrase.rs
@@ -1,18 +1,26 @@
use crate::{
- strutil::TString,
+ strutil::{ShortString, TString},
+ time::Duration,
ui::{
component::{
- base::ComponentExt, text::common::TextBox, Child, Component, Event, EventCtx, Never,
- Paginate,
+ base::ComponentExt,
+ text::{
+ common::TextBox,
+ layout::{LayoutFit, LineBreaking},
+ TextStyle,
+ },
+ Child, Component, Event, EventCtx, Never, Pad, Paginate, TextLayout, Timer,
},
display,
- geometry::{Grid, Offset, Rect},
- shape::{self, Renderer},
- util::{long_line_content_with_ellipsis, Pager},
+ event::TouchEvent,
+ geometry::{Alignment, Grid, Insets, Offset, Rect},
+ shape::{Bar, Renderer, Text},
+ util::{DisplayStyle, Pager},
},
};
use super::super::{
+ super::constant::SCREEN,
button::{Button, ButtonContent, ButtonMsg},
keyboard::common::{render_pending_marker, MultiTapKeyboard},
swipe::{Swipe, SwipeDirection},
@@ -134,9 +142,15 @@ impl PassphraseKeyboard {
};
self.scrollbar.set_pager(pager);
- // Clear the pending state.
- self.input
- .mutate(ctx, |ctx, i| i.multi_tap.clear_pending_state(ctx));
+ // Clear the pending state. If there was a pending character, it has been
+ // committed; show it briefly then hide.
+ self.input.mutate(ctx, |ctx, i| {
+ if i.multi_tap.pending_key().is_some() {
+ i.multi_tap.clear_pending_state(ctx);
+ i.display_style = DisplayStyle::LastOnly;
+ i.last_char_timer.start(ctx, Input::LAST_DIGIT_TIMEOUT);
+ }
+ });
// Update buttons.
self.replace_button_content(ctx, pager.current().into());
// Reset backlight to normal level on next paint.
@@ -219,18 +233,19 @@ impl Component for PassphraseKeyboard {
fn place(&mut self, bounds: Rect) -> Rect {
let bounds = bounds.inset(theme::borders());
- let (input_area, key_grid_area) =
+ let (top_area, key_grid_area) =
bounds.split_bottom(4 * theme::PIN_BUTTON_HEIGHT + 3 * theme::BUTTON_SPACING);
- let (input_area, scroll_area) = input_area.split_bottom(INPUT_AREA_HEIGHT);
+ let (input_area, scroll_area) = top_area.split_bottom(INPUT_AREA_HEIGHT);
let (scroll_area, _) = scroll_area.split_top(ScrollBar::DOT_SIZE);
let key_grid = Grid::new(key_grid_area, 4, 3).with_spacing(theme::BUTTON_SPACING);
let confirm_btn_area = key_grid.cell(11);
let back_btn_area = key_grid.cell(9);
- self.page_swipe.place(bounds);
+ self.page_swipe.place(key_grid_area);
self.input.place(input_area);
+ self.input.inner().reveal_area.set(top_area);
self.confirm.place(confirm_btn_area);
self.back.place(back_btn_area);
self.scrollbar.place(scroll_area);
@@ -255,17 +270,32 @@ impl Component for PassphraseKeyboard {
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
+ // Handle multi-tap timeout: commit the pending character and show it briefly
let multitap_timeout = self.input.mutate(ctx, |ctx, i| {
if i.multi_tap.timeout_event(event) {
i.multi_tap.clear_pending_state(ctx);
+ i.display_style = DisplayStyle::LastOnly;
+ i.last_char_timer.start(ctx, Input::LAST_DIGIT_TIMEOUT);
true
} else {
false
}
});
if multitap_timeout {
+ // Disable keypad when the passphrase reached the max length
+ if self.input.inner().textbox.len() >= self.max_len {
+ self.update_input_btns_state(ctx);
+ }
+ return None;
+ }
+
+ self.input.event(ctx, event);
+
+ // When passphrase is shown in full, disable all keypad interaction
+ if self.input.inner().display_style == DisplayStyle::Shown {
return None;
}
+
if let Some(swipe) = self.page_swipe.event(ctx, event) {
// We have detected a horizontal swipe. Change the keyboard page.
self.on_page_swipe(ctx, swipe);
@@ -286,6 +316,7 @@ impl Component for PassphraseKeyboard {
self.input.mutate(ctx, |ctx, i| {
i.multi_tap.clear_pending_state(ctx);
i.textbox.delete_last(ctx);
+ i.display_style = DisplayStyle::Hidden;
});
self.after_edit(ctx);
None
@@ -295,6 +326,7 @@ impl Component for PassphraseKeyboard {
self.input.mutate(ctx, |ctx, i| {
i.multi_tap.clear_pending_state(ctx);
i.textbox.clear(ctx);
+ i.display_style = DisplayStyle::Hidden;
});
self.after_edit(ctx);
return None;
@@ -319,6 +351,15 @@ impl Component for PassphraseKeyboard {
self.input.mutate(ctx, |ctx, i| {
let edit = text.map(|c| i.multi_tap.click_key(ctx, key, c));
i.textbox.apply(ctx, edit);
+ if text.len() == 1 {
+ // Single-char key: immediately applied, show last char briefly
+ i.display_style = DisplayStyle::LastOnly;
+ i.last_char_timer.start(ctx, Input::LAST_DIGIT_TIMEOUT);
+ } else {
+ // Multi-tap key: pending state, show char with marker
+ i.last_char_timer.stop();
+ i.display_style = DisplayStyle::LastWithMarker;
+ }
});
self.after_edit(ctx);
return None;
@@ -328,16 +369,21 @@ impl Component for PassphraseKeyboard {
}
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
- self.input.render(target);
- self.scrollbar.render(target);
- self.confirm.render(target);
- self.back.render(target);
- for btn in &self.keys {
- btn.render(target);
- }
- if self.fade.take() {
- // Note that this is blocking and takes some time.
- display::fade_backlight(theme::backlight::get_backlight_normal());
+ if self.input.inner().display_style == DisplayStyle::Shown {
+ // When passphrase is revealed, render only the shown overlay
+ self.input.render(target);
+ } else {
+ self.input.render(target);
+ self.scrollbar.render(target);
+ self.confirm.render(target);
+ self.back.render(target);
+ for btn in &self.keys {
+ btn.render(target);
+ }
+ if self.fade.take() {
+ // Note that this is blocking and takes some time.
+ display::fade_backlight(theme::backlight::get_backlight_normal());
+ }
}
}
}
@@ -346,14 +392,133 @@ struct Input {
area: Rect,
textbox: TextBox,
multi_tap: MultiTapKeyboard,
+ display_style: DisplayStyle,
+ last_char_timer: Timer,
+ pad: Pad,
+ /// Area in which a touch start triggers the passphrase reveal
+ reveal_area: Cell<Rect>,
+ /// Area in which the passphrase reveal window appears
+ shown_area: Rect,
}
impl Input {
+ const TWITCH: i16 = 4;
+ const LAST_DIGIT_TIMEOUT: Duration = Duration::from_secs(1);
+ const STYLE: TextStyle =
+ theme::label_keyboard().with_line_breaking(LineBreaking::BreakWordsNoHyphen);
+ const SHOWN_INSETS: Insets = Insets::new(8, 10, 8, 10);
+ const SHOWN_TOUCH_OUTSET: Insets = Insets::bottom(80);
+
fn new(max_len: usize) -> Self {
Self {
area: Rect::zero(),
+ reveal_area: Cell::new(Rect::zero()),
textbox: TextBox::empty(max_len),
multi_tap: MultiTapKeyboard::new(),
+ display_style: DisplayStyle::Hidden,
+ last_char_timer: Timer::new(),
+ pad: Pad::with_background(theme::BG),
+ shown_area: Rect::zero(),
+ }
+ }
+
+ fn update_shown_area(&mut self) {
+ let line_height = Self::STYLE.text_font.line_height();
+
+ // Start with full screen width, positioned at the input area top
+ let initial_height = line_height + Self::SHOWN_INSETS.top + Self::SHOWN_INSETS.bottom;
+ let mut shown_area = SCREEN.inset(Self::SHOWN_INSETS).with_height(initial_height);
+
+ // Extend the shown area until the text fits
+ while let LayoutFit::OutOfBounds { .. } = TextLayout::new(Self::STYLE)
+ .with_align(Alignment::Start)
+ .with_bounds(shown_area.inset(Self::SHOWN_INSETS))
+ .fit_text(self.textbox.content())
+ {
+ shown_area = shown_area.outset(Insets::bottom(line_height));
+ }
+
+ self.shown_area = shown_area;
+ }
+
+ fn render_shown<'s>(&self, target: &mut impl Renderer<'s>) {
+ debug_assert_eq!(self.display_style, DisplayStyle::Shown);
+
+ Bar::new(self.shown_area)
+ .with_bg(theme::GREY_DARK)
+ .with_radius(theme::RADIUS as i16)
+ .render(target);
+
+ TextLayout::new(Self::STYLE)
+ .with_bounds(self.shown_area.inset(Self::SHOWN_INSETS))
+ .with_align(Alignment::Start)
+ .render_text(self.textbox.content(), target, true);
+ }
+
+ fn render_hidden<'s>(&self, target: &mut impl Renderer<'s>) {
+ debug_assert_ne!(self.display_style, DisplayStyle::Shown);
+
+ let style = theme::label_keyboard();
+ let pp_len = self.textbox.count();
+ if pp_len == 0 {
+ return;
+ }
+
+ let last_char_visible = self.display_style == DisplayStyle::LastOnly
+ || self.display_style == DisplayStyle::LastWithMarker;
+
+ // Compute how many characters fit in the available width. Account for the
+ // pending marker, which draws itself one pixel longer than the last char.
+ let available_width = self.area.width() - 1;
+ let asterisk_width = style.text_font.char_width('*').max(1);
+ let max_visible = (available_width / asterisk_width).max(1) as usize;
+ let visible_count = pp_len.min(max_visible);
+ let asterisk_count = visible_count.saturating_sub(last_char_visible as usize);
+
+ // Build asterisks string
+ let mut asterisks = ShortString::new();
+ for _ in 0..asterisk_count {
+ let _ = asterisks.push('*');
+ }
+
+ let mut text_baseline = self.area.top_left() + Offset::y(style.text_font.text_height())
+ - Offset::y(style.text_font.text_baseline());
+
+ // Twitch when overflowed (alternates so user sees feedback when typing past
+ // what fits)
+ if pp_len > max_visible && pp_len % 2 == 1 {
+ text_baseline.x += Self::TWITCH;
+ }
+
+ // Render asterisks in GREY_LIGHT
+ if !asterisks.is_empty() {
+ Text::new(text_baseline, &asterisks, style.text_font)
+ .with_align(Alignment::Start)
+ .with_fg(theme::GREY_LIGHT)
+ .render(target);
+ }
+
+ // Render the visible last character in the regular text color
+ if last_char_visible {
+ if let Some(last) = self.textbox.last_char_str() {
+ let last_baseline =
+ text_baseline + Offset::x(style.text_font.text_width(&asterisks));
+
+ Text::new(last_baseline, last, style.text_font)
+ .with_align(Alignment::Start)
+ .with_fg(style.text_color)
+ .render(target);
+
+ if self.display_style == DisplayStyle::LastWithMarker {
+ render_pending_marker(
+ target,
+ last_baseline,
+ last,
+ style.text_font,
+ style.text_color,
+ );
+ }
+ }
}
}
}
@@ -362,44 +527,66 @@ impl Component for Input {
type Msg = Never;
fn place(&mut self, bounds: Rect) -> Rect {
+ self.pad.place(bounds);
self.area = bounds;
+ self.reveal_area.set(bounds);
self.area
}
- fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option<Self::Msg> {
+ fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
+ if self.textbox.is_empty() {
+ return None;
+ }
+
+ let extended_shown_area = self
+ .shown_area
+ .outset(Self::SHOWN_TOUCH_OUTSET)
+ .clamp(SCREEN);
+
+ match event {
+ // Reveal on touch start within the extended input area
+ Event::Touch(TouchEvent::TouchStart(pos)) if self.reveal_area.get().contains(pos) => {
+ self.multi_tap.clear_pending_state(ctx);
+ self.last_char_timer.stop();
+ self.display_style = DisplayStyle::Shown;
+ self.update_shown_area();
+ self.pad.clear();
+ ctx.request_paint();
+ }
+ Event::Touch(TouchEvent::TouchEnd(_)) if self.display_style == DisplayStyle::Shown => {
+ self.display_style = DisplayStyle::Hidden;
+ self.pad.clear();
+ ctx.request_paint();
+ }
+ Event::Touch(TouchEvent::TouchMove(pos))
+ if !extended_shown_area.contains(pos)
+ && self.display_style == DisplayStyle::Shown =>
+ {
+ self.display_style = DisplayStyle::Hidden;
+ self.pad.clear();
+ ctx.request_paint();
+ }
+ // Timeout for showing the last char
+ Event::Timer(_) if self.last_char_timer.expire(event) => {
+ self.display_style = DisplayStyle::Hidden;
+ self.request_complete_repaint(ctx);
+ ctx.request_paint();
+ }
+ _ => {}
+ }
None
}
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
- let style = theme::label_keyboard();
+ self.pad.render(target);
- let text_baseline = self.area.top_left() + Offset::y(style.text_font.text_height())
- - Offset::y(style.text_font.text_baseline());
-
- let text = self.textbox.content();
-
- shape::Bar::new(self.area).with_bg(theme::BG).render(target);
-
- // Find out how much text can fit into the textbox.
- // Accounting for the pending marker, which draws itself one pixel longer than
- // the last character
- let available_area_width = self.area.width() - 1;
- let text_to_display =
- long_line_content_with_ellipsis(text, "...", style.text_font, available_area_width);
-
- shape::Text::new(text_baseline, &text_to_display, style.text_font)
- .with_fg(style.text_color)
- .render(target);
+ if self.textbox.is_empty() {
+ return;
+ }
- // Paint the pending marker.
- if self.multi_tap.pending_key().is_some() {
- render_pending_marker(
- target,
- text_baseline,
- &text_to_display,
- style.text_font,
- style.text_color,
- );
+ match self.display_style {
+ DisplayStyle::Shown => self.render_shown(target),
+ _ => self.render_hidden(target),
}
}
}
@@ -410,8 +597,10 @@ impl crate::trace::Trace for PassphraseKeyboard {
let page = self.scrollbar.pager().current();
debug_assert!(page < PAGE_COUNT as u16);
let active_layout = uformat!("{:?}", KeyboardLayout::from_page_unchecked(page.into()));
+ let display_style = uformat!("{:?}", self.input.inner().display_style);
t.component("PassphraseKeyboard");
t.string("active_layout", active_layout.as_str().into());
t.string("passphrase", self.passphrase().into());
+ t.string("display_style", display_style.as_str().into());
}
}
diff --git a/core/embed/rust/src/ui/layout_delizia/component/keyboard/passphrase.rs b/core/embed/rust/src/ui/layout_delizia/component/keyboard/passphrase.rs
index 2e6ef527..59610ef8 100644
--- a/core/embed/rust/src/ui/layout_delizia/component/keyboard/passphrase.rs
+++ b/core/embed/rust/src/ui/layout_delizia/component/keyboard/passphrase.rs
@@ -1,14 +1,22 @@
use crate::{
strutil::{ShortString, TString},
+ time::Duration,
ui::{
component::{
- base::ComponentExt, swipe_detect::SwipeConfig, text::common::TextBox, Component, Event,
- EventCtx, Label, Maybe, Never, Swipe,
+ base::ComponentExt,
+ swipe_detect::SwipeConfig,
+ text::{
+ common::TextBox,
+ layout::{LayoutFit, LineBreaking},
+ TextStyle,
+ },
+ Component, Event, EventCtx, Label, Maybe, Never, Pad, Swipe, TextLayout, Timer,
},
display,
- geometry::{Alignment, Direction, Grid, Insets, Offset, Rect},
- shape::{self, Renderer},
- util::{long_line_content_with_ellipsis, Pager},
+ event::TouchEvent,
+ geometry::{Alignment, Alignment2D, Direction, Grid, Insets, Rect},
+ shape::{Bar, Renderer, Text, ToifImage},
+ util::{DisplayStyle, Pager},
},
};
@@ -18,6 +26,7 @@ use super::super::super::{
keyboard::common::{render_pending_marker, MultiTapKeyboard},
theme,
},
+ constant::SCREEN,
cshape,
};
@@ -182,7 +191,14 @@ impl PassphraseKeyboard {
_ => self.active_layout,
};
// Clear the pending state.
- self.input.multi_tap.clear_pending_state(ctx);
+ if self.input.multi_tap.pending_key().is_some() {
+ self.input.multi_tap.clear_pending_state(ctx);
+ // The character has been committed, show it briefly then hide
+ self.input.display_style = DisplayStyle::LastOnly;
+ self.input
+ .last_char_timer
+ .start(ctx, Input::LAST_DIGIT_TIMEOUT);
+ }
// Update keys.
self.replace_keys_contents(ctx);
// Reset backlight to normal level on next paint.
@@ -218,6 +234,7 @@ impl PassphraseKeyboard {
self.cancel_btn.inner_mut().enable_if(ctx, is_empty);
self.update_input_btns_state(ctx);
+ self.input.request_complete_repaint(ctx);
}
/// When the input has reached max length, disable all the input buttons.
@@ -269,7 +286,6 @@ impl Component for PassphraseKeyboard {
const CONFIRM_EMPTY_BTN_WIDTH: i16 = 32;
const INPUT_INSETS: Insets = Insets::new(10, 2, 10, 4);
- let bounds = bounds.inset(theme::borders());
let (top_area, keypad_area) =
bounds.split_bottom(4 * theme::PASSPHRASE_BUTTON_HEIGHT + 3 * theme::BUTTON_SPACING);
self.keypad_area = keypad_area;
@@ -316,10 +332,28 @@ impl Component for PassphraseKeyboard {
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
+ // Handle multi-tap timeout: commit the pending character
if self.input.multi_tap.timeout_event(event) {
self.input.multi_tap.clear_pending_state(ctx);
+ self.input
+ .last_char_timer
+ .start(ctx, Input::LAST_DIGIT_TIMEOUT);
+ self.input.display_style = DisplayStyle::LastOnly;
+ // Disable keypad when the passphrase reached the max length
+ if self.input.textbox.len() >= self.max_len {
+ self.update_input_btns_state(ctx);
+ }
return None;
}
+
+ // Handle input touch events (reveal/hide passphrase)
+ self.input.event(ctx, event);
+
+ // When passphrase is shown in full, disable all keypad interaction
+ if self.input.display_style == DisplayStyle::Shown {
+ return None;
+ }
+
if let Some(swipe) = self.page_swipe.event(ctx, event) {
// We have detected a horizontal swipe. Change the keyboard page.
self.on_page_change(ctx, swipe);
@@ -349,12 +383,14 @@ impl Component for PassphraseKeyboard {
Some(ButtonMsg::Clicked) => {
self.input.multi_tap.clear_pending_state(ctx);
self.input.textbox.delete_last(ctx);
+ self.input.display_style = DisplayStyle::Hidden;
self.after_edit(ctx);
return None;
}
Some(ButtonMsg::LongPressed) => {
self.input.multi_tap.clear_pending_state(ctx);
self.input.textbox.clear(ctx);
+ self.input.display_style = DisplayStyle::Hidden;
self.after_edit(ctx);
return None;
}
@@ -377,6 +413,17 @@ impl Component for PassphraseKeyboard {
let text = Self::key_text(btn.content());
let edit = text.map(|c| self.input.multi_tap.click_key(ctx, key, c));
self.input.textbox.apply(ctx, edit);
+ if text.len() == 1 {
+ // Single-char key: immediately applied, show last char briefly
+ self.input.display_style = DisplayStyle::LastOnly;
+ self.input
+ .last_char_timer
+ .start(ctx, Input::LAST_DIGIT_TIMEOUT);
+ } else {
+ // Multi-tap key: pending state, show char with marker
+ self.input.last_char_timer.stop();
+ self.input.display_style = DisplayStyle::LastWithMarker;
+ }
self.after_edit(ctx);
return None;
}
@@ -385,25 +432,30 @@ impl Component for PassphraseKeyboard {
}
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
- self.input.render(target);
- self.next_btn.render(target);
- if self.input.textbox.is_empty() {
- self.confirm_empty_btn.render(target);
- self.cancel_btn.render(target);
- self.input_prompt.render(target);
+ if self.input.display_style == DisplayStyle::Shown {
+ // When passphrase is revealed, render only the shown overlay
+ self.input.render(target);
} else {
- self.confirm_btn.render(target);
- self.erase_btn.render(target);
- }
- for btn in &self.keys {
- btn.render(target);
- }
- if self.fade.take() {
- // Note that this is blocking and takes some time.
- display::fade_backlight(theme::backlight::get_backlight_normal());
- }
+ self.input.render(target);
+ self.next_btn.render(target);
+ if self.input.textbox.is_empty() {
+ self.confirm_empty_btn.render(target);
+ self.cancel_btn.render(target);
+ self.input_prompt.render(target);
+ } else {
+ self.confirm_btn.render(target);
+ self.erase_btn.render(target);
+ }
+ for btn in &self.keys {
+ btn.render(target);
+ }
+ if self.fade.take() {
+ // Note that this is blocking and takes some time.
+ display::fade_backlight(theme::backlight::get_backlight_normal());
+ }
- cshape::KeyboardOverlay::new(self.keypad_area).render(target);
+ cshape::KeyboardOverlay::new(self.keypad_area).render(target);
+ }
}
}
@@ -411,14 +463,151 @@ struct Input {
area: Rect,
textbox: TextBox,
multi_tap: MultiTapKeyboard,
+ display_style: DisplayStyle,
+ last_char_timer: Timer,
+ pad: Pad,
+ shown_area: Rect,
}
impl Input {
+ const DOT_ICON_WIDTH: i16 = theme::DOT_ACTIVE.toif.width();
+ const DOT_ICON_SPACING: i16 = 7;
+ const TWITCH: i16 = 4;
+ const LAST_DIGIT_TIMEOUT: Duration = Duration::from_secs(1);
+ const STYLE: TextStyle =
+ theme::label_keyboard().with_line_breaking(LineBreaking::BreakWordsNoHyphen);
+ const SHOWN_INSETS: Insets = Insets::new(8, 10, 8, 10);
+ const SHOWN_TOUCH_OUTSET: Insets = Insets::bottom(80);
+
fn new(max_len: usize) -> Self {
Self {
area: Rect::zero(),
textbox: TextBox::empty(max_len),
multi_tap: MultiTapKeyboard::new(),
+ display_style: DisplayStyle::Hidden,
+ last_char_timer: Timer::new(),
+ pad: Pad::with_background(theme::BG),
+ shown_area: Rect::zero(),
+ }
+ }
+
+ /// Maximum number of dots that fit in the input area (accounting for the
+ /// confirm button taking the right portion of the row).
+ fn max_shown_dots(&self) -> usize {
+ let step = Self::DOT_ICON_WIDTH + Self::DOT_ICON_SPACING;
+ let dots_space = (self.area.width() + Self::DOT_ICON_SPACING) / step;
+ // reduce by one to create more space between the written dots and `confirm_btn`
+ let dots_space = dots_space - 1;
+ (dots_space).max(1) as usize
+ }
+
+ fn update_shown_area(&mut self) {
+ let line_height = Self::STYLE.text_font.line_height();
+
+ // Start with full screen width
+ let initial_height = line_height + Self::SHOWN_INSETS.top + Self::SHOWN_INSETS.bottom;
+ let mut shown_area = SCREEN.inset(Self::SHOWN_INSETS).with_height(initial_height);
+
+ // Extend the shown area until the text fits
+ while let LayoutFit::OutOfBounds { .. } = TextLayout::new(Self::STYLE)
+ .with_align(Alignment::Start)
+ .with_bounds(shown_area.inset(Self::SHOWN_INSETS))
+ .fit_text(self.textbox.content())
+ {
+ shown_area = shown_area.outset(Insets::bottom(line_height));
+ }
+
+ self.shown_area = shown_area;
+ }
+
+ fn render_shown<'s>(&self, target: &mut impl Renderer<'s>) {
+ debug_assert_eq!(self.display_style, DisplayStyle::Shown);
+
+ Bar::new(self.shown_area)
+ .with_bg(theme::GREY_EXTRA_DARK)
+ .with_radius(12)
+ .render(target);
+
+ TextLayout::new(Self::STYLE)
+ .with_align(Alignment::Start)
+ .with_bounds(self.shown_area.inset(Self::SHOWN_INSETS))
+ .render_text(self.textbox.content(), target, true);
+ }
+
+ fn render_hidden<'s>(&self, target: &mut impl Renderer<'s>) {
+ debug_assert_ne!(self.display_style, DisplayStyle::Shown);
+
+ let style = theme::label_keyboard();
+ let mut cursor = self.area.left_center();
+
+ let pp_len = self.textbox.count();
+ let last_char = self.display_style == DisplayStyle::LastOnly
+ || self.display_style == DisplayStyle::LastWithMarker;
+ let step = Self::DOT_ICON_WIDTH + Self::DOT_ICON_SPACING;
+ let max_dots = self.max_shown_dots();
+
+ if pp_len == 0 {
+ return;
+ }
+
+ let visible_len = pp_len.min(max_dots);
+ let visible_icons = visible_len - last_char as usize;
+
+ // Jiggle when overflowed
+ if pp_len > visible_len && pp_len % 2 == 1 && self.display_style != DisplayStyle::Shown {
+ cursor.x += Self::TWITCH;
+ }
+
+ let mut char_idx = 0;
+
+ // Small leftmost dot (fading indicator for overflow)
+ if pp_len > max_dots + 1 {
+ ToifImage::new(cursor, theme::DOT_ACTIVE.toif)
+ .with_align(Alignment2D::CENTER_LEFT)
+ .with_fg(theme::GREY_DARK)
+ .render(target);
+ cursor.x += step;
+ char_idx += 1;
+ }
+
+ // Greyed out dot
+ if pp_len > max_dots {
+ ToifImage::new(cursor, theme::DOT_ACTIVE.toif)
+ .with_align(Alignment2D::CENTER_LEFT)
+ .with_fg(theme::GREY)
+ .render(target);
+ cursor.x += step;
+ char_idx += 1;
+ }
+
+ // Normal dots
+ if visible_icons > 0 {
+ for _ in char_idx..visible_icons {
+ ToifImage::new(cursor, theme::DOT_ACTIVE.toif)
+ .with_align(Alignment2D::CENTER_LEFT)
+ .with_fg(style.text_color)
+ .render(target);
+ cursor.x += step;
+ }
+ }
+
+ // Last character (if visible)
+ if last_char {
+ if let Some(last) = self.textbox.last_char_str() {
+ // Adapt y position for the character
+ cursor.y =
+ self.area.left_center().y + (style.text_font.visible_text_height("1") / 2);
+
+ Text::new(cursor, last, style.text_font)
+ .with_align(Alignment::Start)
+ .with_fg(style.text_color)
+ .render(target);
+
+ // Paint the pending marker
+ if self.display_style == DisplayStyle::LastWithMarker {
+ render_pending_marker(target, cursor, last, style.text_font, style.text_color);
+ }
+ }
}
}
}
@@ -427,44 +616,64 @@ impl Component for Input {
type Msg = Never;
fn place(&mut self, bounds: Rect) -> Rect {
+ self.pad.place(bounds);
self.area = bounds;
self.area
}
- fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option<Self::Msg> {
+ fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
+ if self.textbox.is_empty() {
+ return None;
+ }
+
+ let extended_shown_area = self
+ .shown_area
+ .outset(Self::SHOWN_TOUCH_OUTSET)
+ .clamp(SCREEN);
+
+ match event {
+ Event::Touch(TouchEvent::TouchStart(pos)) if self.area.contains(pos) => {
+ self.multi_tap.clear_pending_state(ctx);
+ self.last_char_timer.stop();
+ self.display_style = DisplayStyle::Shown;
+ self.update_shown_area();
+ self.pad.clear();
+ ctx.request_paint();
+ }
+ Event::Touch(TouchEvent::TouchEnd(_)) if self.display_style == DisplayStyle::Shown => {
+ self.display_style = DisplayStyle::Hidden;
+ self.pad.clear();
+ ctx.request_paint();
+ }
+ Event::Touch(TouchEvent::TouchMove(pos))
+ if !extended_shown_area.contains(pos)
+ && self.display_style == DisplayStyle::Shown =>
+ {
+ self.display_style = DisplayStyle::Hidden;
+ self.pad.clear();
+ ctx.request_paint();
+ }
+ // Timeout for showing the last char
+ Event::Timer(_) if self.last_char_timer.expire(event) => {
+ self.display_style = DisplayStyle::Hidden;
+ self.request_complete_repaint(ctx);
+ ctx.request_paint();
+ }
+ _ => {}
+ }
None
}
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
- let style = theme::label_keyboard();
-
- let text_baseline = self.area.top_left() + Offset::y(style.text_font.text_height())
- - Offset::y(style.text_font.text_baseline());
-
- let text = self.textbox.content();
+ self.pad.render(target);
- shape::Bar::new(self.area).with_bg(theme::BG).render(target);
-
- // Find out how much text can fit into the textbox.
- // Accounting for the pending marker, which draws itself one pixel longer than
- // the last character
- let available_area_width = self.area.width() - 1;
- let text_to_display =
- long_line_content_with_ellipsis(text, "...", style.text_font, available_area_width);
-
- shape::Text::new(text_baseline, &text_to_display, style.text_font)
- .with_fg(style.text_color)
- .render(target);
+ if self.textbox.is_empty() {
+ return;
+ }
- // Paint the pending marker.
- if self.multi_tap.pending_key().is_some() {
- render_pending_marker(
- target,
- text_baseline,
- &text_to_display,
- style.text_font,
- style.text_color,
- );
+ match self.display_style {
+ DisplayStyle::Shown => self.render_shown(target),
+ _ => self.render_hidden(target),
}
}
}
@@ -484,8 +693,10 @@ impl crate::ui::flow::Swipable for PassphraseKeyboard {
impl crate::trace::Trace for PassphraseKeyboard {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
let active_layout = uformat!("{:?}", self.active_layout);
+ let display_style = uformat!("{:?}", self.input.display_style);
t.component("PassphraseKeyboard");
t.string("passphrase", self.passphrase().into());
t.string("active_layout", active_layout.as_str().into());
+ t.string("display_style", display_style.as_str().into());
}
}
diff --git a/core/embed/rust/src/ui/layout_delizia/theme/mod.rs b/core/embed/rust/src/ui/layout_delizia/theme/mod.rs
index ad8373df..3083beff 100644
--- a/core/embed/rust/src/ui/layout_delizia/theme/mod.rs
+++ b/core/embed/rust/src/ui/layout_delizia/theme/mod.rs
@@ -400,7 +400,7 @@ pub const fn button_keyboard() -> ButtonStyleSheet {
font: fonts::FONT_DEMIBOLD,
text_color: GREY_DARK,
button_color: BG, // so there is no "button" itself, just the text
- icon_color: GREY_LIGHT,
+ icon_color: GREY_DARK,
background_color: BG,
},
}
diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/keyboard/passphrase.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/keyboard/passphrase.rs
index fb20b2be..7a941305 100644
--- a/core/embed/rust/src/ui/layout_eckhart/firmware/keyboard/passphrase.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/firmware/keyboard/passphrase.rs
@@ -326,11 +326,8 @@ impl Component for PassphraseInput {
self.update_shown_area();
return Some(StringInputMsg::UpdateKeypad);
}
- // Return touch end if the touch end is detected inside the visible area
- Event::Touch(TouchEvent::TouchEnd(pos))
- if extended_shown_area.contains(pos)
- && self.display_style == DisplayStyle::Shown =>
- {
+ // Return touch end if the touch end is detected
+ Event::Touch(TouchEvent::TouchEnd(_)) if self.display_style == DisplayStyle::Shown => {
self.multi_tap.clear_pending_state(ctx);
self.display_style = DisplayStyle::Hidden;
return Some(StringInputMsg::UpdateKeypad);
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index f2297842..b2bb2f12 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -862,9 +862,9 @@
"click_tests": {
"T2T1_cs_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "fc431d91ffcecee2468e4edf5994b0abcebac03b12635401b0176c8e1400182b",
"T2T1_cs_test_autolock.py::test_autolock_does_not_interrupt_signing": "ffd34dd7b96178fdd779eeb89aea698af1079b4c31cd774e96837544eeaae557",
-"T2T1_cs_test_autolock.py::test_autolock_interrupts_passphrase": "b935ad8f2b31825e750b9467921af4b9a57f2cb6da293913e7720e9d9d22036e",
+"T2T1_cs_test_autolock.py::test_autolock_interrupts_passphrase": "c4f2846ca30babdd0a855a01dfb27987934df97f2141580a766154146759845b",
"T2T1_cs_test_autolock.py::test_autolock_interrupts_signing": "833046857a0a3a58ee258139187a005c1fc6fed648cd184baba1461047deb36f",
-"T2T1_cs_test_autolock.py::test_autolock_passphrase_keyboard": "e872b63c26f74c98e1bdc57c72dcfc256658ad2617d62d8521e96dfcca36862e",
+"T2T1_cs_test_autolock.py::test_autolock_passphrase_keyboard": "daff600788e49fc5145ca6249258e5f6485cc3768680378d04d7199ade02c1fc",
"T2T1_cs_test_autolock.py::test_dryrun_enter_word_slowly": "7db55aa9c30a23d304a07db2df8ba8e5062a757e18bdffad10d60955fbc9cc01",
"T2T1_cs_test_autolock.py::test_dryrun_locks_at_number_of_words": "82ff5727a438e1f984179c802dcf86abf6aa5fe7cf0489c0bc9692a67072d911",
"T2T1_cs_test_autolock.py::test_dryrun_locks_at_word_entry": "0ae9b37b6944f8956fa68efc8f3c7e67b97176f0c715f0b6a484b69b1ae7941f",
@@ -872,18 +872,18 @@
"T2T1_cs_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "9fcccbce86879304fce00a56973eecaf61718b21914fbd5e6f31513ce4a6d106",
"T2T1_cs_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "882de24cca08f44be2f21c298a6b6c97994686456f5e998315b710700271bec7",
"T2T1_cs_test_lock.py::test_hold_to_lock": "b625c90d4d1e24643cdcbf2677fe8a6bd68a595a97ac8929375c639aab5d7cd4",
-"T2T1_cs_test_passphrase_bde.py::test_cycle_through_last_character": "a0225a7bd97bed6054fa8d7d6d3488caaa0ff8b58d4b8eccc930ae22e7f08b0d",
+"T2T1_cs_test_passphrase_bde.py::test_cycle_through_last_character": "ca98277865e3368ed9908338e0f42f38ec551940d62db97baa73a12dbda771a2",
"T2T1_cs_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "0f9b254f1dcbdc53feed7b240e42f0443d49e387da694b57b71980616e00b149",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_delete": "e382cf8956cc731398961e0854cefe925dda645396ba08110b1ca4c87bce0819",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_delete_all": "d4b775ae922df9ce14ae07d776d4d5098afda04a50bb975c95b49a63dacfe4dd",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "c5276899d65286d194e498b297b288810a89029b45d2c8f9072fba07a3a47e23",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "1b2f289aa83ae590e6a5638b35df43a012190fea2a9b8cd33eb518c20800b00a",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "906a34aa58487ad632ff24a9d26078c1ad823989412c0d005567caf00d7bb471",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "86aa65f2d3e583d51cc302d9b61889ff322f506456995f53efdc14899a2ede9c",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "4553c56ba4c1d8b1e14f66885b45e8d42771699134737fee006a42ba3512758a",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "a0feb3c8e5b2bb6b27ad571a2f021df124e7383fc4b90b3a4708ff105d79d5c6",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "4553c56ba4c1d8b1e14f66885b45e8d42771699134737fee006a42ba3512758a",
-"T2T1_cs_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "17f2aec5ca7f8d5c2fff70a5e10a43180140c5c08688baaa559a7f80d48daeae",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_delete": "410eef22a31fe0c839eb120e9abeda468a87b223542dcb9d19389e21185a1369",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_delete_all": "82fde88e683f0fcd7e24c3a60edc674c32a194d112596d96e98156beee84708e",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "d086d15770a3c743dd8898b6854c9df1014626bd7929ae42ee8bea60e6b6ee21",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "9dd6ccb1b75c34b98606de3b07f6db818a69f9816d2008e6007a156864411513",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "10f0ebbf48a1eaf9ce0b5a73919a8e586856a543926229224bff2edfb59ea34c",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "45889981cf0b6febbc1ab30aedd21583ecd670e3400732adcf721bb77b5fedb9",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "15dda028913d85efcc02188e63b3f30c60017fb37c9044ec1e6fa9059a2f54b9",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "0e3e7b52cc92885db81708838ed3869a6614157dcd1d5652868c8602969c84a7",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "15dda028913d85efcc02188e63b3f30c60017fb37c9044ec1e6fa9059a2f54b9",
+"T2T1_cs_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "f174867b72cb1590f1a91bc00da94ee79069126bbdf901ada58b21d5f4d8560a",
"T2T1_cs_test_passphrase_bde.py::test_passphrase_loop_all_characters": "5db7e4cc0ade16364a63d335095f23f8e04b5d3309fb55913cb67aded403d396",
"T2T1_cs_test_passphrase_bde.py::test_passphrase_prompt_disappears": "f8ff949ad62592c2e8e7034c538ec071444d850f51a0644477a0c892a5448818",
"T2T1_cs_test_pin.py::test_last_digit_timeout": "0a3d934c34a774eb6be44ea101198d3c9458f197b965480d15a2afc52e770b88",
@@ -917,9 +917,9 @@
"T2T1_cs_test_reset_slip39_basic.py::test_reset_slip39_basic[1of1]": "8a129f94127ae58fbbd87e0458b6193ddeadeedaf949d4a61e5d834fa9a396ff",
"T2T1_de_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "067fc0ee31f4eeac9cdf3b1c8263b42c30689f1887781ff38b6dc1b768c42243",
"T2T1_de_test_autolock.py::test_autolock_does_not_interrupt_signing": "a1587ee96455556ad5e50304fc8629b313dcc13df48fb63f328f9a37f4b09e07",
-"T2T1_de_test_autolock.py::test_autolock_interrupts_passphrase": "fa07fe4b11c588cbb910cb0a4bb4a78e892b28b4a384f56e3ae606312538e0e0",
+"T2T1_de_test_autolock.py::test_autolock_interrupts_passphrase": "bed207808bd4a97c565e6c97308aedf1bb74f26e0e3fa9d76aabcbc01b912b2d",
"T2T1_de_test_autolock.py::test_autolock_interrupts_signing": "ee49a3b1eb2f3baff27c2c40025b111878c818e0dd2b38b055bbc8e7c7afd51e",
-"T2T1_de_test_autolock.py::test_autolock_passphrase_keyboard": "b5eb152453a1a34b876dbc438cb5c2012ded0604784441a9eb087ff130991138",
+"T2T1_de_test_autolock.py::test_autolock_passphrase_keyboard": "36c8858020ab766c63cef2aedc430173a428f96b9b1eb4d209a10fb6fe2851ac",
"T2T1_de_test_autolock.py::test_dryrun_enter_word_slowly": "4f170580001f28824a4cb40d8d5048ac8a4d39818a0d4910138a79d8855cc473",
"T2T1_de_test_autolock.py::test_dryrun_locks_at_number_of_words": "962640bc1b4c0611de26ea38fa978e4273ab60d6748d7258c2adc8154d602774",
"T2T1_de_test_autolock.py::test_dryrun_locks_at_word_entry": "41d36b632ae32793eb8c11288b9559bab3682c13364e0adb83a0c9620443be9d",
@@ -927,18 +927,18 @@
"T2T1_de_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "1c9cd12f1f09515eeefe0c5bdcc4a7b9e64d2c2ad40253c816fba214eb4babfe",
"T2T1_de_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "d395b5a20071837f50836f4d050d780b55625798d554f6b46a75d33c4280f8fe",
"T2T1_de_test_lock.py::test_hold_to_lock": "fa23e325a30fd6a25473b386ed96dc3c7f9390a3acfb0bd697e17cd9b2daeab3",
-"T2T1_de_test_passphrase_bde.py::test_cycle_through_last_character": "5f5e21949f3028b9f9097210759ee04bf4c79a0ab60b966d43d2d7c21c357eb4",
+"T2T1_de_test_passphrase_bde.py::test_cycle_through_last_character": "d277385e7b13ccc1a8aa62becea0ac8e00ac8752e1173f7e9a62c1bd7fa08679",
"T2T1_de_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "5de87b65a526e45b4ad0fa9fcb64e0902705dc115f6f36ff913b41c8a76e10b2",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_delete": "ae2145256411ca4e4a8c5d433df37ea9dc57f1886ecb143e7a7915b2ed851405",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_delete_all": "39b2fbf383f185877acaebaebab44140fa8c5aa652fc7cb097ce215fec19d197",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "0e46c0a7cb077cdbbf01cd842e58471ea41a47263d741849fc86e8b7f9a75454",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "89101c2f0b2e784c626385153aa12aadf637f4f1ad9cd5bcf0637306fb077d05",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "9effd1c68e1eed89e713436e5bc0a10429c24acfc0076eb2d408a33ffcd1c93e",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "eb851a6b2cb6d23024abe7d6ff6fd9bcebceaae4a604a02f5673dfff4bee2c6a",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "bdd92fd6165288932b54b35238a603bf439a0cff327341e1c9f79cbd1c8d2383",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "a6476c07ecffb7ea78129702441f4d4f4daad279712cfc271950a8fd57427a85",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "bdd92fd6165288932b54b35238a603bf439a0cff327341e1c9f79cbd1c8d2383",
-"T2T1_de_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "fd18f4483aeeeaa0eeb566b179f1afffa81662f7db65761c7a9e5c352b381474",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_delete": "1b59c8ed47dc24889a2619225e204273aacf575a0c017fe5e4d81dd4b4a649a3",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_delete_all": "7ebebbe80a0e65fb0a95b3bb70dd13bc8706035ad7643cde444bed0d752ad490",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "0230f865046581ab79916f4ec76b14d4461ca53e425b94168a97ab368bf129de",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "08d9f18db55878f7ae02c6e9c53dec6591038d89882d7df556bddb38dd12d6ba",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "a4c22f67a091425327517c0e78ab4ac5038b61c7999959f0b588213738ccc7dc",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "c38e54a5772db14e672e1ff0373f176500e9386273e7cc432c326488087e3f8c",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "208f5779a95bb0ab49c7ab32d56b766affde236e8fbfadc4c9559f842e148459",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "33bd3ba7f992fd8bd4eb9984805a7430cdeaf9dd55f7fff01fe1db37db1d14e1",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "208f5779a95bb0ab49c7ab32d56b766affde236e8fbfadc4c9559f842e148459",
+"T2T1_de_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "435ae4c40dd347426244dac5b2a0b1500ae120544895df6c7427c84bc0a2b8ac",
"T2T1_de_test_passphrase_bde.py::test_passphrase_loop_all_characters": "51fd70ffd16f5c4d554376a45501b5c051648398ee97f1baf2030dbbcd169d4a",
"T2T1_de_test_passphrase_bde.py::test_passphrase_prompt_disappears": "5a9f803b8252df5ca01557ef1c9b0162775708dc340214e0f0964396af057fd1",
"T2T1_de_test_pin.py::test_last_digit_timeout": "892b5959c689361e58c9d996567ddebcca24390f70da2f87623851c7b5628d24",
@@ -972,9 +972,9 @@
"T2T1_de_test_reset_slip39_basic.py::test_reset_slip39_basic[1of1]": "db42e55a3345145517873b9351856c49aa9a5e019d1a96292b0b49d89ece65a0",
"T2T1_en_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "5aab49633bdfdee2ce4e00576b548b5d4a106c8c0a36c266f605cd0e44ae7d04",
"T2T1_en_test_autolock.py::test_autolock_does_not_interrupt_signing": "2539591ae1646bb0915c6ca1bf18b5ccdbca2d24ebb9f9be5cbcdfad5b55e3fe",
-"T2T1_en_test_autolock.py::test_autolock_interrupts_passphrase": "31c05b4d0b0cdd2a30b06f1da61900eb35b8dbe1565a33f34ae2dad52aa30dd9",
+"T2T1_en_test_autolock.py::test_autolock_interrupts_passphrase": "b5b3647c2c2043fd7e87f536141acd7ff6a43a7f38aab4ae6720a02f4e928018",
"T2T1_en_test_autolock.py::test_autolock_interrupts_signing": "bf7406f5c8849af60e06e8bab6cd21bac4b606c87bb8ab64ec53f1f3b7a3447a",
-"T2T1_en_test_autolock.py::test_autolock_passphrase_keyboard": "98186552bd08bf42b1b22983bf595cb70949aa3d4a04f46f2c604c5e0d1dcf6f",
+"T2T1_en_test_autolock.py::test_autolock_passphrase_keyboard": "42ec9a071d3adae1d0fb9ee56b81abef03ba582bf90e695468dccf43bb1555a2",
"T2T1_en_test_autolock.py::test_dryrun_enter_word_slowly": "87eb1a46d20226bf7d0fb709c88f6c91dd9881080354fe0f75db8c883f3d7a55",
"T2T1_en_test_autolock.py::test_dryrun_locks_at_number_of_words": "306484b82ca45f3c66a1c7986a3dfaa14427458a64ce187b01b3440de92ae902",
"T2T1_en_test_autolock.py::test_dryrun_locks_at_word_entry": "c3374b0ee2066dff4a383d6aa9414a3b7181fd6857102f16c766febaa31966b5",
@@ -982,18 +982,18 @@
"T2T1_en_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "d80b7f6652b5df55e737b0dec997292ef78b438288b9a4d2e4310264b1f714ae",
"T2T1_en_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "1222aa45ced0446f0fe1b135289c3e0d350c3851f8b2da765d69092e8b83adaf",
"T2T1_en_test_lock.py::test_hold_to_lock": "87f851971afd5551709a6dcbf0755dc04df42bd36167748c2bb4bb39cee5d0e8",
-"T2T1_en_test_passphrase_bde.py::test_cycle_through_last_character": "8d23de2465d239615298c4472335a755d30ab8e4ff22f741ac367cc55c24b3df",
+"T2T1_en_test_passphrase_bde.py::test_cycle_through_last_character": "a59ed9089884cdb735809d1ab81efdaf5e2ec837137659c76b015147c50c8425",
"T2T1_en_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "4f3bcc8e5b7d71dd8243f8efbbfc23cfce4b1744fb1cfa5879e2f1a990176d29",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_delete": "155f00a32151acb9419f5cfa0d5f0c1837afa32ada135742a7c1fd567af08b11",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_delete_all": "5040ddd98a029d4c82a6c0bff5a528ddf35cf460cea1e0b5e96c42e53739ff0f",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "b007f8c17046fd422f307d19250d9ebeab07b583bbef0ffefec21604fe1514c0",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "b31288d67ae633cefab82893d843bf6c7e3d9d4706e66c341c711c144ceeb185",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "d127fce4d74b042da335aec34389a3b8779099df8db239547b7f6a8ddb7761e5",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "bab4aa1b19b97c23c77ec66de45bf809b983d8c4c9000cb40e581d4c0248601b",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "a5e77616a3ac0f122293430b8a17777a893bf9327bc01f2f0437fb54c8634520",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "7e003c6e898d0ad1842b40378b8a44e095644d7b4ea58f66c767d9b14a43ee63",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "a5e77616a3ac0f122293430b8a17777a893bf9327bc01f2f0437fb54c8634520",
-"T2T1_en_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "6442b75f6699a0dcc00cc1cfab4c48006334921e6756d50fe78a2b9c99e50478",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_delete": "945b209dd85d58c0b79b971f5000b3020b689a006a7662ad79d3996ba11215b5",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_delete_all": "12ea8a2cdb8adf89fbcae2f657632102bd0754b8cc2c4343abf92c70e2db4176",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "b4e56ca799e8a4ef5d7f0134563a24434595f3536ee9c351d99b3c714bdb551c",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "cf71834eae3c0b75e836f34911cea83715fe7e1a87c8d1945260bb44d11b7a46",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "8f5d7e1f94abfa2f6a3f9df92507c85f1cfe9309d3fd193908dfc3a8bdb80ac9",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "8f31fff04db754c0420ec261618a4a895bcd2f1d0c3b9e529b9a5bdf8415b4d2",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "356eb0af7a8a8f01772a39ef7f0f7111d1bc819ea69fa9120fc540ba700b5ba2",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "76b5b52ea9efbf77cbb27b86391317a8661052f0b1535598a4c4e605613fd1d8",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "356eb0af7a8a8f01772a39ef7f0f7111d1bc819ea69fa9120fc540ba700b5ba2",
+"T2T1_en_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "9f00f8f53a9195601f2afb2e77d3e8f45189cb2355fc64eb1df2e09744f7d107",
"T2T1_en_test_passphrase_bde.py::test_passphrase_loop_all_characters": "ba039e0e04fe932c8497f9073f119e84b114ddabe27f2dd258b82836f8aae0ca",
"T2T1_en_test_passphrase_bde.py::test_passphrase_prompt_disappears": "888767326ba692427077a717c0169a903d1eae77150a0052897c2296ebc9860f",
"T2T1_en_test_pin.py::test_last_digit_timeout": "6ca215c2f62c4d97c923f68c4a7293e55eaadc03df1ff089d6972d301ecfde56",
@@ -1027,9 +1027,9 @@
"T2T1_en_test_reset_slip39_basic.py::test_reset_slip39_basic[1of1]": "543dfc46f90b84fc3308a5e9229677d5c078de0164d01c27330c782cfd774f2e",
"T2T1_es_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "4730114c46a6b3a488c226d35557079f9655c0f4a78d274499628548bda31eaf",
"T2T1_es_test_autolock.py::test_autolock_does_not_interrupt_signing": "4af66af637d8adb80a1eaf6bbb47709f3c7da2bf2d164519e73e209c3211cd21",
-"T2T1_es_test_autolock.py::test_autolock_interrupts_passphrase": "e7f3fbf687e100e4bbfad53fbead55bb20a1dec8c0d1955017bd415a7e5a1cbf",
+"T2T1_es_test_autolock.py::test_autolock_interrupts_passphrase": "beb01500969b68a735d4b3b1e5fc33c5be56778b48207a046b829b4949262911",
"T2T1_es_test_autolock.py::test_autolock_interrupts_signing": "66e3c1bfcdd79d6653768c09a1b3798d28fcbece37a80c7382074dcddf04f276",
-"T2T1_es_test_autolock.py::test_autolock_passphrase_keyboard": "ab3e9f261ce7aab5eda7ee264f8906ed639ce1932679f26d6b67960ec2bf2243",
+"T2T1_es_test_autolock.py::test_autolock_passphrase_keyboard": "778d86193a8be4c808edeca95a6af4f9c1a9fe6f980e47bb04333b82351eef72",
"T2T1_es_test_autolock.py::test_dryrun_enter_word_slowly": "d2de8b96bd17cdc30c42a6f8c63829844967ac1ef24ac3c93897ae18f271d068",
"T2T1_es_test_autolock.py::test_dryrun_locks_at_number_of_words": "70432a660aded6c9265a7a9d754cf78b90bd2388774b2e4399ab21e4b9caf250",
"T2T1_es_test_autolock.py::test_dryrun_locks_at_word_entry": "866445b2400749d562fb0876860e047c8f13b8cb94c749401be8cffafa8e1923",
@@ -1037,18 +1037,18 @@
"T2T1_es_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "22043283de96683e7f00809d11301da8b5a04901b4e34453be033bafbed15921",
"T2T1_es_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "39d7fcd1f7476c20d1441d14a5ab7f180e72d3d61ef9725514752ebca33f1431",
"T2T1_es_test_lock.py::test_hold_to_lock": "52dae436fa80528400745fc9c585ddd8e7e8f363d7161dc46c72b912ab006995",
-"T2T1_es_test_passphrase_bde.py::test_cycle_through_last_character": "b3cb6bf3c5ca8d07e8f60ab160b785a0ec138140edd2043488c136a686ba7da1",
+"T2T1_es_test_passphrase_bde.py::test_cycle_through_last_character": "d837343540f9ed0e40d9f7de911d2edb649447d88571d1717cfec0bc32188dd1",
"T2T1_es_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "cca754991d170de9c411880689f48f9de4e65badaa0a3dff0abfdec1f0e6b0fb",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_delete": "1d1a1595d1436ebcde1b65c8178e4e41b8192b4caa9fdcbc6671cb1d39786867",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_delete_all": "d07eb6a9a2d5c12fc1c3cdf5049c6bc643e81035eaaf1ad88ce0143a34540ae1",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "06282999b3f7c6087fe74520e5da117862782b0a27f7dc89de8d5e7e498ce2aa",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "daa1c80bb25cf70585717e04884968b13e1fa0bd96dc969c56e942d761b0b251",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "4a003d704eff18152a4d210566d3107ecc55bf6b187b6eeaeb5ff41a282f0c6a",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "dada89204cf5b69194dbd9fc4d7bf8617e9a2ac81635df50c6afb2c6cd2ee3f9",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "91ec63b9ceef57c08a8ac15d7547717389345e6f085ef628176b5f26ee9ff0e7",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "3a6951e1a8a11451a969eb1557f8e41a0ec02938cc08555f71f7a3eaee11e05a",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "91ec63b9ceef57c08a8ac15d7547717389345e6f085ef628176b5f26ee9ff0e7",
-"T2T1_es_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "42d61f2a3bf52d596c51eacba11ca15e87b826537274333bf5b1bd086fee64e6",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_delete": "660086e008b2e411ab1133377be1ed6fa27d8f6b3b78b931fe13a3cf18055fc1",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_delete_all": "b786cd4109d146460045cffe1a2269e931977c5627cb79817f11be44bbaa0478",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "837dd67c445a343abaafe688ecee83ec73022378aaa748342b7c41be6add6937",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "1dc27c87d4b96fef66d5ff36e2e64695ad90dbc4eee3905eef9b94265558c5ad",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "c5f1b9edbfd5a870d42781d22a1ade26eacc019d4319fbdf125ede5daecc49da",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "5542a506eb92f1685e7124b6c4519c760da6c45e469ce1714a856c4d9b6cf21b",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "7c3caea5d6660bc60c8a69d0a27c7d9a2fbaeb0899248ba7b278855bcebb6e46",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "bada79e295bc5a2abbab5acaa0054b1f23b0f7c49d5a1c740d06114ca008af06",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "7c3caea5d6660bc60c8a69d0a27c7d9a2fbaeb0899248ba7b278855bcebb6e46",
+"T2T1_es_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "62f627c33065d6020c13e2a68a0c76a9ed33dbd293074f66696696caaa6ca973",
"T2T1_es_test_passphrase_bde.py::test_passphrase_loop_all_characters": "a0bafb16e1a7a54d7b84695ba8e9d7af600d445fecb987c01a46189235896073",
"T2T1_es_test_passphrase_bde.py::test_passphrase_prompt_disappears": "0cb973a9787b3ca94f0768c03e06437d4668f9edc4909dceaa96fbbe53b4de2d",
"T2T1_es_test_pin.py::test_last_digit_timeout": "45a0ee9056abacb9b46de8413cf870c03756014ffe9a762800b366c44bbea38f",
@@ -1082,9 +1082,9 @@
"T2T1_es_test_reset_slip39_basic.py::test_reset_slip39_basic[1of1]": "4a24a73a71840d70904cdc0f56765bc61417f592efff31e400d3f26799e4f175",
"T2T1_fr_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "21c5d3b4dbd56f83c70ed612dd0286eb428a78ed4b9cefe66abb5b5315903323",
"T2T1_fr_test_autolock.py::test_autolock_does_not_interrupt_signing": "cbf8ae6e80c138911c40972fe82927465942f338a7b2989585244d549660cae0",
-"T2T1_fr_test_autolock.py::test_autolock_interrupts_passphrase": "76f91db2ff708967bbaf1dccfcb3613cec80d42919ed1d2d3896e4c4cca4ac51",
+"T2T1_fr_test_autolock.py::test_autolock_interrupts_passphrase": "d52d1b9452ef5c6320e86fded0bb36079b6f7ce4801a686eb8d5ea4f8ef2de74",
"T2T1_fr_test_autolock.py::test_autolock_interrupts_signing": "a7c22ae049d23ce74ec58c5215309c8b808afb05e18dec89393cfae505b83bee",
-"T2T1_fr_test_autolock.py::test_autolock_passphrase_keyboard": "83690260fecd4466a765936b88c39949af895cafb2c52c688f229539186ee467",
+"T2T1_fr_test_autolock.py::test_autolock_passphrase_keyboard": "36bc5f2cf47f0d9a05c5a21182e00914639a247a8422e7c481fd42a009e55c5c",
"T2T1_fr_test_autolock.py::test_dryrun_enter_word_slowly": "3d68b03f92025f1707cc800f2a2a2a13f768351ca73fbaa035e92be9602a6eb0",
"T2T1_fr_test_autolock.py::test_dryrun_locks_at_number_of_words": "caa40719948b744d45e7429cb5825249abe4eef43f6aaaf0f5dabae8d5aec80a",
"T2T1_fr_test_autolock.py::test_dryrun_locks_at_word_entry": "368efe5962c2618c4ff895663ca22806c08135a878ffcb28a9253bfd59c5531b",
@@ -1092,18 +1092,18 @@
"T2T1_fr_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "5ac3d80a5aa1255ccdf21baf2632b73c6c5918a8605bc4b1faf2ec876f713343",
"T2T1_fr_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "6ecfabec38382ec131f2b191e1e1eae6a11b065386576cfb4098a1a7738802e1",
"T2T1_fr_test_lock.py::test_hold_to_lock": "f3ee9a75666c201f9dbeae0780fc43dd9b8437c1ded87681b2048b48eba0cb62",
-"T2T1_fr_test_passphrase_bde.py::test_cycle_through_last_character": "d33a0c36b01b040e7f78500e5dc44facaed909bfaa6a57946855ea17dc3a6ef2",
+"T2T1_fr_test_passphrase_bde.py::test_cycle_through_last_character": "7779acf7cafa7f8f00e92e486eb9a25f11af5c6e30a36c72cf5f10d493ba363a",
"T2T1_fr_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "7acf71f5d4f5a581eebce3bda22d5757433a1cf1d35ddc9e4220ba0da876d756",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_delete": "98ced5d7a7f1f175d85aad71c64e7ad12615c717f11bf8f7d9c79b326912f65a",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_delete_all": "f9cb665a1059427d3efbfea6b68254b6c07cbef2decc9d6ec579fbadf1af84b6",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "b3a50b7b93f9814f355442e093d32fb385bbee5c3cfe40baa43c0b4687132a8e",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "37c502fd18de568f83d664d8b88c0ebf3346cab6f56166700973a651fe4c8d55",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "3bdfdd663d1be35f342bbc85e689b46666d3b85d951db8333eefca40c27d6b34",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "02c9e7987aba71135435aff62c84559ff4d7192d548e56a5aa2120b9445b0d72",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "9f6dcaf30463351d59a2e275e1c708a6d47d0363f44ac2c60dfcbad12811b0d0",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "0fc84164415556738233a3cd6350bd0f64697f002022a6969191730f3e1e19f0",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "9f6dcaf30463351d59a2e275e1c708a6d47d0363f44ac2c60dfcbad12811b0d0",
-"T2T1_fr_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "594ea4504234c24753b4ee401869aca64749a5f8e3443f9083707ba544bef2bd",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_delete": "e2e837f05afcfd0b51a0b3bedd3923283e5467eada3ce40e6141390e21b01ed6",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_delete_all": "e510c515658323157a7303705badc296911f3dd883d16779c8c803b8b0996eea",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "f790f6fddb0ebda1def6442833463aa9776854afb90f5dea29a6e96efc7a7944",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "a5bbca2d151fdd22233fe466f1a95d22aa8573a2fd701005c4588c2f96252339",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "78e3663d0c87dd85e0b2dbb7c8fa94fdd6d4ea4eac52546436d15571c6c0dea3",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "c4c2f12706c1343d362472912ffbb2d1ba6b55d0224e2cbf768b4ab32454aab0",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "9e58d8a0f7e1286a71e5150caff17b7f6018002e063a075dafa61e9a60657e7e",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "b9ec2fdefcae1f8f067be1df9f6d4254329b31182d0f371a5e1c899026db0bb2",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "9e58d8a0f7e1286a71e5150caff17b7f6018002e063a075dafa61e9a60657e7e",
+"T2T1_fr_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "26bbe9cfc6c1a8fb26302f9b800aec23152e4e7d6e12403f6baf3dffd244f0fb",
"T2T1_fr_test_passphrase_bde.py::test_passphrase_loop_all_characters": "3f6d02bbe902eac61f144242ff3e7e59b6db7d337fc3743ff3777e78ea4f5923",
"T2T1_fr_test_passphrase_bde.py::test_passphrase_prompt_disappears": "0e6b209df1421cb051d97c220c568405bb60bc815fe24d198f07b0a5ed52c4f7",
"T2T1_fr_test_pin.py::test_last_digit_timeout": "2d4b28e21e918be930665ef738e9af4240271069f36ccbda7cf9f5250a8aeea8",
@@ -1137,9 +1137,9 @@
"T2T1_fr_test_reset_slip39_basic.py::test_reset_slip39_basic[1of1]": "46e4cf04c08336274c4a3e60c58238a4a284e9086663f414b20c183df52edfa1",
"T2T1_pt_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "2d00c4dc73eacc723815e377bdadbbb92626916917381447028a4c037cccdb16",
"T2T1_pt_test_autolock.py::test_autolock_does_not_interrupt_signing": "79a3ddc6f0063bf3b066ed5ddf6329af57e8ee829ed809fca44ea5fc5fa8293b",
-"T2T1_pt_test_autolock.py::test_autolock_interrupts_passphrase": "786117bb205984125d3baa84ec68024cefe9f9fb481cefcdbfebc8e9e86e2faa",
+"T2T1_pt_test_autolock.py::test_autolock_interrupts_passphrase": "fc6d4dde6c62d05efc035c09c595a230b0c4520237dddd084940a3e65d7485d2",
"T2T1_pt_test_autolock.py::test_autolock_interrupts_signing": "8c99829e68319e3af844c9f4f60ffb399b97de3b7d89d493e4569da50214b6d3",
-"T2T1_pt_test_autolock.py::test_autolock_passphrase_keyboard": "32976fde75931516301e45271ccbf8ce0654054d88bf36b90ce1fa564becf001",
+"T2T1_pt_test_autolock.py::test_autolock_passphrase_keyboard": "752325540404d8cbac05408849bd4ae995382248f1abb27e1300090e9f1dad0e",
"T2T1_pt_test_autolock.py::test_dryrun_enter_word_slowly": "e9de5b0958e74891529daeb2e39007cee1ccf6cb5de72427aacfa7f7dcbf38a1",
"T2T1_pt_test_autolock.py::test_dryrun_locks_at_number_of_words": "ac51c6cd8113d9c605760e0385aa6c47fcee0539080a3034ee2a283db8c2bd3b",
"T2T1_pt_test_autolock.py::test_dryrun_locks_at_word_entry": "06775863da637a27e9d95156c92b07c77cec0729f8facdb699d8f1df6f4c1bb5",
@@ -1147,18 +1147,18 @@
"T2T1_pt_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "61d25599ca8d9d551e9bcf3e636048e38715f683e9f5b82862d3003158cfea40",
"T2T1_pt_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "099d14f2da67d34a1886958916752fbd8f67d27ad57c549124d2205c2380b2c7",
"T2T1_pt_test_lock.py::test_hold_to_lock": "5113e0c4403df13022260a014fa41014016ccd88769235bcf4c8c7a6358c333e",
-"T2T1_pt_test_passphrase_bde.py::test_cycle_through_last_character": "1e8c32243308c01b98fe91e065f984542f1277e955b71e47aa964ee1ca6f0823",
+"T2T1_pt_test_passphrase_bde.py::test_cycle_through_last_character": "34f32726bc5d6cc7ab00e2e8e5e2d8eb7fb34e7df38e8c20cdd9b2c6c11b6bcf",
"T2T1_pt_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "be1c7cc1f706a361af14a03c9fb06470c41a27d61818532f0687f58da204be5d",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_delete": "51651db44ba9564824ef0a6f18de47642a6ac1d17e94beef73a9cbd2c08f0ee0",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_delete_all": "d69f15cb95a0af424897a723b02f284881602626abd3defff37b8762543b6fbf",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "498b94b32ade7fa84f50a5af51e857c7248788b5f3f687b0b3691eccfcd63fcc",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "97f23c1c79a44ba1ce3ed9b8a7d0d6220178324ca1c290ae894c9fd0209171f1",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "3b5aa51f19db71ad2374095c4dff34ecd57c1ff964e8d3d1b072c308b392dc2c",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "caadfed3481c4d62d4e8081951d4c2a12dd917b2ec5b23e3c341fbe04dadd269",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "09138553fcf77a7c9511071554b8fb74ce75236243b1a604d35494a22a773a93",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "3f47abbd4140c3903c0a23083ec7d206dc48210c2c1c0b90fa64ebddfb230535",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "09138553fcf77a7c9511071554b8fb74ce75236243b1a604d35494a22a773a93",
-"T2T1_pt_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "bf84eefc32978ea7de80805a1caa5bf11d91d15978dacf52831a49eff839e601",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_delete": "bf42ec15b8ccfe3156400aa3d8b8059dd1855163f4c89879f475b74569f5963b",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_delete_all": "d5edb83a7d0fdf0f9ba07fdd236f7db56ec6840868b0dbeae49a720d9a783ab5",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "5cf61d9e671b6fd5fbe468b3886395d294b1defeed255bd63cef40f4c7478f19",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "72680641024c3b729cf92c68085de4822337ee29a8276fbabbc2870547ea6bd5",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "58c0262ff519ad37aa3cfec6d7afde283a3fb54e34cf0d6679367cb21d1d3904",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "eb368f4035faac61ee8e29663b2d681a8e29b18db0bf6d68712911b818eb8a28",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "d6d453fe0f7943876b9c484cfcc55d0ceed0f507d3ac3769c98d8280a1c0b2ed",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "ef6dd5c7830c2bf1ce3c705346befdcb6d4330a7e85574bb60b936d31507973c",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "d6d453fe0f7943876b9c484cfcc55d0ceed0f507d3ac3769c98d8280a1c0b2ed",
+"T2T1_pt_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "a30ee159daffe6af488c2ca5bbf67859fb523d37da77f5199e5e9a8e84e815fe",
"T2T1_pt_test_passphrase_bde.py::test_passphrase_loop_all_characters": "39cb0e23418500fcc9b36e5a7fb81fa152b154774664b7ef5cbcdac57a1a64d2",
"T2T1_pt_test_passphrase_bde.py::test_passphrase_prompt_disappears": "a9f60f9d7f3cd8a1daded5709366211a5a12d172057d00a1202779f21b115e3f",
"T2T1_pt_test_pin.py::test_last_digit_timeout": "32a938a05c0c009c2232515452caa8d31791414483063c5ef5377fa174a003ff",
@@ -21956,9 +21956,9 @@
"click_tests": {
"T3T1_cs_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "6418eb7bb5301713c4f7747047c5aa92810eab066910d3ac46de9ee6e68e5d45",
"T3T1_cs_test_autolock.py::test_autolock_does_not_interrupt_signing": "0d5dde751dcd4fb14a485438850c8cd50d022738cbc2aaf0c0bb3d4c16071182",
-"T3T1_cs_test_autolock.py::test_autolock_interrupts_passphrase": "fbea90e8a0ab1585b5857590d5cecc4fcf5020cb5e7e685f8e76b474bae1cf34",
+"T3T1_cs_test_autolock.py::test_autolock_interrupts_passphrase": "5970e6a42d7f3b3aea4ccffdac4ce3ab8479d9fc4d9695e57c170599c7c99aca",
"T3T1_cs_test_autolock.py::test_autolock_interrupts_signing": "401b45ea6afff6edd18eb34fc404f9967d4d13ab1a85941c1f589af8ab797a09",
-"T3T1_cs_test_autolock.py::test_autolock_passphrase_keyboard": "14f2707496000bc435bbe007c83ebf6412d004b26e144546b3b1dddfced59b13",
+"T3T1_cs_test_autolock.py::test_autolock_passphrase_keyboard": "c8564ce6703ec3a2b741071043b24b3807522088c02a8fe6d0630d3c84ae490e",
"T3T1_cs_test_autolock.py::test_dryrun_enter_word_slowly": "cc0b06d2a697f68411fbc7112593d80305cb0c68d61a479cf13cd6183e2460d1",
"T3T1_cs_test_autolock.py::test_dryrun_locks_at_number_of_words": "80d859a2831cac63399ab48d8b2d2f60115885e4c504b64c947f576641e36ec1",
"T3T1_cs_test_autolock.py::test_dryrun_locks_at_word_entry": "a4794c130b14edd44495f93644469c7edb2d96fd4277b7e8bc55197b6ceb1ddd",
@@ -21966,20 +21966,20 @@
"T3T1_cs_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "1d1b1ad7b848d3316a8257dae85b32dee964f06dc9dd714cce41f54ad3d15433",
"T3T1_cs_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "4b827a2a1a94b6d4fc667c504434fa3ca9122f6feb050e91d4961fdf17dfe1b8",
"T3T1_cs_test_lock.py::test_hold_to_lock": "c854a34398b0d17b3466ff2fc63bcc231ddab6ffb76d569f1f64848019532f8b",
-"T3T1_cs_test_passphrase_bde.py::test_cycle_through_last_character": "655dd2132ca060239c503506f4e2ab7bcde91dd3413bb76e167abec7f034d9e2",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "0e42f0e973f2e6379ea737f009c050f8fa64c60914e1f57cb5881fa1cfcff9ff",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_delete": "3750028c0c2435be1795aa110b5d9212c59fb11b40ccc7689e5f4393d14aa6c0",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_delete_all": "f48243f4aba1fbf110beaeabf27ee60cc60eca420ffe7db02399dd36531aef7c",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "17f2814cb925477b16fb68ab851015b842972b1ff0c777d46303035967ff6514",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "f66ebdb0cbf8229cbf27d1e123dc8ca0b8f083e2b1e51c5ce653a2dac61a24c3",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "26949fb6560dfbe07a5b8ffc595839709c5767232dc80e1d49602173126dceb9",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "0be23229cce5c4d4998d61812470ca79edf91a27394b9030ff176fb4813458c4",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "3a4510027ef7d72bd5fa15abd6f441dc64e806815af5f8c938e49997947f44b6",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "2cf6c226906f083280220d733d3f92a3d4244578252c576b2145be42d5bf35cf",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "3a4510027ef7d72bd5fa15abd6f441dc64e806815af5f8c938e49997947f44b6",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "aa640d74accc7280e6d27894f2309775aa57cd3d7cd3644644f1c35843b8c206",
+"T3T1_cs_test_passphrase_bde.py::test_cycle_through_last_character": "f1b79f1f3019497168246cb3f030036ebf7318312bc7f56c6bfab36244a5fb51",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "919b47eb45fd433c80bd842b998c6d42d95942b016399fcd702eab112d020fd7",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_delete": "1fb27b3a0f2740fafd7d51849a992b37361077a4e661b72956b4836ce6f38ef3",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_delete_all": "36fd3a80e1e4892e41648fe2ca5acb010fe0d3223ff308309d4c13e7ee483112",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "a8974a45b7571d1123e8250329cb683d983f3d53cd5e2dccb31316972846c14e",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "99612eaf9ead4fd77e639316affff6213a61c22242a127dbdbdb97455980bee3",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "69b44fbe730f8f05daeb8b57f6a5855a4a9765d9d552522c5f4400e0d4082c27",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "d8c126750876b10576ce1aad80996dd309a6e4d457f114bf2b2088297b5312fc",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "96e7cbafde1bbe5a52ac4bf6b3d6a3cfc07de636f2bc3c9ba88122154e3af207",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "9380bcc2b19c3d61dcc44bb07552955661d5368c4f89857fbf7cf37899680726",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "96e7cbafde1bbe5a52ac4bf6b3d6a3cfc07de636f2bc3c9ba88122154e3af207",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "77b34aee3b1808b674d52b0ce257204e8b38c55b71d9d7c27b68fd948dedbfe5",
"T3T1_cs_test_passphrase_bde.py::test_passphrase_loop_all_characters": "1bf84961e4466aec570baefd00ffe5272e5489de40d23f248e7e45357e0997bb",
-"T3T1_cs_test_passphrase_bde.py::test_passphrase_prompt_disappears": "a566dd804f77e3aa25a058cde89963c0fadd788834367220189dc3b945737224",
+"T3T1_cs_test_passphrase_bde.py::test_passphrase_prompt_disappears": "50e1a15c29f846f737b85f82ca5e639f0fcb5a70b5e2ae751e4e45071df71d35",
"T3T1_cs_test_pin.py::test_last_digit_timeout": "1cf670438e9e1ce2986a8dac9dcbdd343e10a33b57ed7db1bc7721f6619ba010",
"T3T1_cs_test_pin.py::test_long_press_digit": "9960cc9f38fc463e08ddf19c0bb9c8d162b61944fa4b65d9a94a424169a0c161",
"T3T1_cs_test_pin.py::test_pin_cancel": "727cc6defe6c69f5d16da4b9347e4a6dda4f4352420bb2ace220686d5f87a655",
@@ -22016,9 +22016,9 @@
"T3T1_cs_test_tutorial_delizia.py::test_tutorial_menu_repeat": "85a686ade5d7156d01b8409ad364193a333295ce872626a151fe5c5b9808afe5",
"T3T1_de_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "df21ab1304eef83aff6a7b594ff0e50dd6cf753bd53f51ba5bda8e210203234e",
"T3T1_de_test_autolock.py::test_autolock_does_not_interrupt_signing": "c2eab2fe3dece1d75d9e2b0311a66bfc22818d3ee7b209e39cd84882d6954e5e",
-"T3T1_de_test_autolock.py::test_autolock_interrupts_passphrase": "90cd3811c490644cacd1de2058563fbf688bc2b8e404538a1aa65d20846f7d76",
+"T3T1_de_test_autolock.py::test_autolock_interrupts_passphrase": "aafd75f059ed2c9d9c61adbfc83c203cd17f2942859cc6a03493886a0eec39f3",
"T3T1_de_test_autolock.py::test_autolock_interrupts_signing": "fb31276532b9d1a9f64ed74aa74d7f49e198d07f8561d5f32e23c8f8350a3d11",
-"T3T1_de_test_autolock.py::test_autolock_passphrase_keyboard": "3e2bfba0fc15eeb938b91f6f9459e56e1ce3ece82bb4ec82c4ea25c0b43e5b14",
+"T3T1_de_test_autolock.py::test_autolock_passphrase_keyboard": "8c1faa9bde00362b49847c93c364999de31ea11544a5b3b0809e1cf9556bcb34",
"T3T1_de_test_autolock.py::test_dryrun_enter_word_slowly": "816defd3873b93700750451cb2710b8d20b4a0e5809564dcf0a89df8f5597527",
"T3T1_de_test_autolock.py::test_dryrun_locks_at_number_of_words": "e61c9252a9fcb68d68d600439f07c425746b3001cca2def33ef32b9e43bba294",
"T3T1_de_test_autolock.py::test_dryrun_locks_at_word_entry": "067689093ebc46cdd951625ebedb873916bd0af72f85d740b7a90ffa8ddadd28",
@@ -22026,20 +22026,20 @@
"T3T1_de_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "211c75dd9417521352152c216fcc81492cbbf8bdce7ecf6cf470c6613316275c",
"T3T1_de_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "cd3a2618bcccd3368ee663ce0a3c338bb0a0a9188675b250556bebbc1d441f41",
"T3T1_de_test_lock.py::test_hold_to_lock": "bbe7272442f2e587d638d1737fbbcf9a05f62cd8363ced13aa0700dc65e996e8",
-"T3T1_de_test_passphrase_bde.py::test_cycle_through_last_character": "7945b5059cb3bcf6567776eeede9287d910c6696bd657e5fd68adb0a2b8e5d7d",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "c076e67cdef0c2387e7fdb0d331f37332aca049aa4bf34d49fc0d300b78c1e9a",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_delete": "6c560929f96d101143076889702003849593b17015c70152db0d3073df2b0e2d",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_delete_all": "7889269b7e3fdb79faa0947fef4c2bbd44ff0e5df02dbe801b441d324a6d6d03",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "93507a84255630c1bff8d568c1f8ba56accd245326adf7036866f25ec71dce78",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "88e1d3267a9d40afc4a66f97e00a3da9b6697ed4e2b1838a7e747ca9ff11a380",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "4590d6e58eabeb3d5ce1ce6ff710ea1b31e359cb2d193d2ed2e1cf5c29c202ca",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "f8fc73489ac424718dd607aa849cc53efea12c70eca1fd3d61b9fc0d7c661e5f",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "1d127c122622994f036914170548447e19c7dc3a04f4434b80a5522bcbeac47e",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "f01b50af80e431d6b47341160b77ddc30796a51a8bde9c5e15abfd06fdf43c30",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "1d127c122622994f036914170548447e19c7dc3a04f4434b80a5522bcbeac47e",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "aa7678477e55205759954aee8230f7a3b5bb5d2ea84d6d47410f5b00816be46a",
+"T3T1_de_test_passphrase_bde.py::test_cycle_through_last_character": "f02060030cee37da1f4a787e6f8aae907794d1ccb73547570b34f70f40450a4a",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "f1228e046d1464617bc83d1d85a12071317c98242716f6f15c66cc88d1b604cd",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_delete": "7fb3bf2c984e0bc25cdd60db4d8aadc391b4b69ddebbb2a4548530de62c03180",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_delete_all": "61c7fa540468fecc8812d3ced58b5170d9b47c3a16c8e45aa7cc92873f46ae1c",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "28e81cd642ec6adc238c58673ef919541fd28465ddfd2cfbd49fb90a4a7f4d4d",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "87ac88052b2d4ed6048b8226ab9fcdbd942eed8419ad9787554790e80c672708",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "eba5a41d64967d7b61744bbad44414871804107dcca8cd15f98601ea7b7c2011",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "8dc4f7ba5185859c6515857696221d381db0081d3aabd8094614611aee9061a1",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "6be89a174331e3ec529d5c299023712a7f1cbebfdd9faff0cb810597a8b07cbd",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "f0d294a30950069fbae5e5a59f189ee8fd505c4267644cf75068416879c403c7",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "6be89a174331e3ec529d5c299023712a7f1cbebfdd9faff0cb810597a8b07cbd",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "cc3d6f9417a37433f75e3954c41fd531aff8dcb4666ea645fb2a31abfe44f38b",
"T3T1_de_test_passphrase_bde.py::test_passphrase_loop_all_characters": "ffc3cb10736d301638c2fa47666650a6d283b95e253ba289027cc3b12fb93047",
-"T3T1_de_test_passphrase_bde.py::test_passphrase_prompt_disappears": "56f83926e5b816cda4e5f08ea95ff64a42f4194507717c17af8128fe6c51626d",
+"T3T1_de_test_passphrase_bde.py::test_passphrase_prompt_disappears": "6c4df14ee79f169c95d68217d2ad7520aa537a6d693eff4ef3a06b3d0040bf48",
"T3T1_de_test_pin.py::test_last_digit_timeout": "fa83d2b9848a4b7850c42c00e43d9c46a238d90f42e78de718d03c8bb1df6772",
"T3T1_de_test_pin.py::test_long_press_digit": "5e3ac0092f79efb45af40373ae45f3b5d53ee3148d6f3b97afaa48c4104ae91c",
"T3T1_de_test_pin.py::test_pin_cancel": "4b6681b03bd75c25b3109f952f7b97b1ac0018d451e8eb59ce8f773a64d68701",
@@ -22076,9 +22076,9 @@
"T3T1_de_test_tutorial_delizia.py::test_tutorial_menu_repeat": "488bac3fe1287a00a749feed8570857f1beb3763dbcb33610a5e238bcb31ba0c",
"T3T1_en_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "f996f5a1279cf7c1705c78d5b8c45cbdff6f64804bf77057d2a8a64a46b6c821",
"T3T1_en_test_autolock.py::test_autolock_does_not_interrupt_signing": "79250a9d19ce06e6d9864e3b64482fc568206aec2de014299439daa5d3e9b348",
-"T3T1_en_test_autolock.py::test_autolock_interrupts_passphrase": "955e1bdc724c2352a8065797463282d8a5ddfa9e778fea73b542b2683b57ebfc",
+"T3T1_en_test_autolock.py::test_autolock_interrupts_passphrase": "e2fb0bec0d808d4f1a7988139c86896f52c21fcb52f808ad5a6be774aa364a27",
"T3T1_en_test_autolock.py::test_autolock_interrupts_signing": "0f8a26ab2c454252b368d9a87febe6e935fbee6be8ec2b29085d0a684487463d",
-"T3T1_en_test_autolock.py::test_autolock_passphrase_keyboard": "a96d5a534518bdd0eabb3a32e4baeeb076eb4d6a107e1eb7e64cdc5261c634ba",
+"T3T1_en_test_autolock.py::test_autolock_passphrase_keyboard": "48865c482f93286c21f4b9480d72d389aee396335802568ee6b1b9760aedab26",
"T3T1_en_test_autolock.py::test_dryrun_enter_word_slowly": "82cdb7bac5bf7dbbf0b64a4f7d3fa872faeb566f61492dd7f7d12c00418f8363",
"T3T1_en_test_autolock.py::test_dryrun_locks_at_number_of_words": "9b0f01ff10b9102f374daab79ef91b054d24bfc8d77695ec18a036de3ef37fb5",
"T3T1_en_test_autolock.py::test_dryrun_locks_at_word_entry": "dd24cc3c8bea51d1aeb510394b312b2f15ea7a727792b6ce74d293dafc0e2b70",
@@ -22086,20 +22086,20 @@
"T3T1_en_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "b60219473fb54bc6e942d636af2b85813743cc0a843840646810822da582e000",
"T3T1_en_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "1d812d862c39e92ba3c10fd76681541e073b8d7c00eb59e527c27fa271db734b",
"T3T1_en_test_lock.py::test_hold_to_lock": "55399f923ba572dc7b34eca78756b252b3c8c405abfbf6bbca86781040e1fdbc",
-"T3T1_en_test_passphrase_bde.py::test_cycle_through_last_character": "0859cee9ab21d846fe852c1b2815afc3f0557f1e5d779f9334ef44ecd3f0f8e6",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "2b6611f948dd9d759fcc6f3441bd2551830a13bcc00a303ad35e2f779f6b74cb",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_delete": "bbe0401aa90baea8409d17cd334d17b7088661630773ff75981f25a098bb6f3a",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_delete_all": "095a71637b806e4058b8c9ba20a7a95971f3c8a503a87d2d38594573202e611f",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "a5ffaa636ca2875b5f23c6520139d6232df8bbab562f69e6ed862d9fce3d53a9",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "7586ec8f431f0dc2bcf5cfeb07304263339320367fb417455e238d8ec9f89805",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "9c54678547c9e170e72c45db76a66d76f3a49edfd127712633abe4b03920a3cd",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "b2f29e2d0b44a054ce449d743c635582bf015455970b2861f56761dc18187551",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "116a85dcc03547537ee798e158bf83db9e2c17018bcbb82ea8578742b3f0bbaa",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "515c548c4210607c8e9521fc2bb1cfd00906d04742ea617c41796403eb63e1b4",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "116a85dcc03547537ee798e158bf83db9e2c17018bcbb82ea8578742b3f0bbaa",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "bbc60732ce05f05af88d49a1514ad66dbc56829fa532374d120cc042f9fabe3c",
+"T3T1_en_test_passphrase_bde.py::test_cycle_through_last_character": "9be8bff547b7710a91fc533458f745b515a91874168adc1640b039bc6e065258",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "61987642e83f506f506026f67282ea68f095b5db34a2f9b3370ce70413bb966a",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_delete": "aea505a9ca81acff317babbced75fe6f216e3284421c7b61438f6c0ea104083d",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_delete_all": "5e34d8b534effac395438e684eee7bf1850fe097b00535535bcb6abf95d1a36e",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "81107c217cc4663a9689261de211b3568dd3ae28f4d11ff29b93a391987d761b",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "254072f2b9ca55a716c716cfc0778d817f4996decf3a1c2ecb11b8f59759287d",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "311f3f5d4433d9360cad15150be8a8d3dba93b45310fc0c30178e0a7e835a00b",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "389b27ea6569efd5d16b58110580ea0dc663fec1f81e911b722ef6f82a6c9331",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "fd61cc1a376f743c4c3946425c1386c46368ef1057162aff7d28f559733a1f9b",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "df5620f8207f74f0dd569ee4075d72c4c16159c16b2d91e5aea03d2da5c48a3d",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "fd61cc1a376f743c4c3946425c1386c46368ef1057162aff7d28f559733a1f9b",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "64e37ad97702fb03a87daefefaf748973dfc0f404c3fd627389068e2d1f73702",
"T3T1_en_test_passphrase_bde.py::test_passphrase_loop_all_characters": "0a2eca4518d032b3099342633ece4ebc26e0968cb6d5fb7aa41193d26ae3fca5",
-"T3T1_en_test_passphrase_bde.py::test_passphrase_prompt_disappears": "857adc0205804f4e41e986799b50292e6e26ffb8c5300ded1a14e738093a458f",
+"T3T1_en_test_passphrase_bde.py::test_passphrase_prompt_disappears": "a2ca321c01f02340b83a5ef9217ff54550cfcaee368c7808e295d83bb82eeacb",
"T3T1_en_test_pin.py::test_last_digit_timeout": "11884abeebad628acfa7d38f2534de3d684a0e3c787c9707be0fca558aee5e4d",
"T3T1_en_test_pin.py::test_long_press_digit": "5a87b06fab23ef91309fa4b842bcdcf476334eb011742e7f3f4506cbd0da6591",
"T3T1_en_test_pin.py::test_pin_cancel": "4b6a3a417a1e1f7fdebe65df361a62435a8819ee1137645b6192399f990d444b",
@@ -22136,9 +22136,9 @@
"T3T1_en_test_tutorial_delizia.py::test_tutorial_menu_repeat": "a025f104b72e6e1aed389f04912fd0843b4b806b54d3def066c32adb535018b4",
"T3T1_es_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "b487ecc2c7d42f07a2547c871fc92a47c8615d2c51342c1e73e2a42479f74878",
"T3T1_es_test_autolock.py::test_autolock_does_not_interrupt_signing": "e21c69297076b495378f256ffc80a2eabade9378f9f3d239bf2caf0258605fee",
-"T3T1_es_test_autolock.py::test_autolock_interrupts_passphrase": "bd7384dbbae578e9491f83e608a60ce2336e306fd464304b8376451df6f5265c",
+"T3T1_es_test_autolock.py::test_autolock_interrupts_passphrase": "70c67a3537b3e93fe05e47f7131faf17f1aebb46d1b4747821d9dbefd9d31dd3",
"T3T1_es_test_autolock.py::test_autolock_interrupts_signing": "812fcce04f7b785702d18d998ea09160834948218ee05d320759816e9c88c5b4",
-"T3T1_es_test_autolock.py::test_autolock_passphrase_keyboard": "1134d1d9853a9e1c884cb68fccc563daa606bda011faad13d3c108f0190b004f",
+"T3T1_es_test_autolock.py::test_autolock_passphrase_keyboard": "1db7f787f2ee6d8e2cb0a4598c9d67d1440e78c28d21eb7d96cbf8e60c5c415a",
"T3T1_es_test_autolock.py::test_dryrun_enter_word_slowly": "ffa75b8a7c5150cfd6fd5dff8ed7b6af2d1bece48aef435b0c7afe2b84cac087",
"T3T1_es_test_autolock.py::test_dryrun_locks_at_number_of_words": "88eb8747e40047e8ced1d9984d895a851246e7ff179276ec25b66dca7c39ae2b",
"T3T1_es_test_autolock.py::test_dryrun_locks_at_word_entry": "0f1ab1ae86e96c676cf6704be0ee0b05c819ace497e0fad3b937fec0a1293a80",
@@ -22146,20 +22146,20 @@
"T3T1_es_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "6877d5f525090c20efcddcb91a09716d9d9dca6bc5b0784fd811bf64b76c9cf6",
"T3T1_es_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "95abdd337659b5981963000377dd284b9fb5662c2db14cdd0b31b85497679ead",
"T3T1_es_test_lock.py::test_hold_to_lock": "dfd5a143d77e3412b3215f77afef8df9bd3a3aebe054b321f419aa951f7db142",
-"T3T1_es_test_passphrase_bde.py::test_cycle_through_last_character": "f5e7ab6ed50ea5b30bfa14ca1236bac394db9934aeccd23d39ea44d2a294213e",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "ff6a7f307231906b14774845db1541b0109305f47fc44e4564a1e4aea14630a1",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_delete": "cb504b8e86a294979f921e622384b793f4e475d6078234fbfc88e450846880f2",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_delete_all": "16a7f6061a7421564e4eede87ac181a0acc03ef360d8fe33401f734efaea965c",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "282ccac5d836bdbca95b8558ec463a2ee678e6a84492996c3f368458de22dc5f",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "a193e19d7a5576fa2609983e303c35d5ec6aaafd1c49c6706742f344716fce3e",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "2a96ed6e9c33513651e8fe9b21a206adb334d3123470953aeedca14a99478b5f",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "479397b0d3fa5422dbb1d63a5b3ac0f5727731924029b7bc8d63beb285ab296c",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "65b550278990172e6b4c68315f9318905a1f7cf0bf41219c0238bbbb3cd5d862",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "5036205578062bc37e21ca501672c03ccc638aa38b50afefc7d5ca4758e2ac5f",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "65b550278990172e6b4c68315f9318905a1f7cf0bf41219c0238bbbb3cd5d862",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "149a4e580ca29fc9f2e9a38a39d45012ebbe04b626913ad9e956925b3519cd1f",
+"T3T1_es_test_passphrase_bde.py::test_cycle_through_last_character": "6a5122475accc56f066adfafe4b3675d897c6b07aa44a0701ae489e16eb03088",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "7f1124d17e80fbb37ced420e9a9649442fa95a5eface9fdae62e3396f0c8fe09",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_delete": "888ea9c3c6a54ce2d01ca1bf4534147668ede4dfec10f3014c6f02f8bdbcffba",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_delete_all": "6bcd53add0b6b7e0307f17e1e108140fc1c0304c3968fa337696cf0d7632dbf4",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "9e6ffc83d63d8bc315c750e52d6102bf6b5343bca12281d3f8c8544177ed93ff",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "ca589b9abed85d9cb24c818086cb36ff0d3c4213b8e56f477781de2fdc52fc6d",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "c711b6fb3772771d61667cb1488a7079187e69c4e54359288fef37cee6ab25b3",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "aa4534e997d8f9a0a1293a073c56b599dc27b7b434edc68aadb36684e9c65aa2",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "613018c194327ef04e9dcc39831811eb8ae4ccf3c4dc6bd22c28fe710961accc",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "c2bb95b88ee2538acafb696d479f5db69e747388ecff76de5f1435826fe7825c",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "613018c194327ef04e9dcc39831811eb8ae4ccf3c4dc6bd22c28fe710961accc",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "6274e08bc59bc1dfe0bd2e7706dbbc8fb400c6ecbc498bcfc5782fbac95953f1",
"T3T1_es_test_passphrase_bde.py::test_passphrase_loop_all_characters": "9ec8546d5404713aa74589802a1799e4844b27c25aa9881a86a0d7b600828bff",
-"T3T1_es_test_passphrase_bde.py::test_passphrase_prompt_disappears": "ae051fa84b1252bff9ce4e869b67a94aa32c8bcaaff88fe5adbdbf00feffce2e",
+"T3T1_es_test_passphrase_bde.py::test_passphrase_prompt_disappears": "15103813df2b30504ca54cb9a7bbc4ad5e44d17e4e313a7405df0bed30a824fd",
"T3T1_es_test_pin.py::test_last_digit_timeout": "fbe9d4b8570d97a421a2914167605e8cf4748600c38d016127442dea0789939f",
"T3T1_es_test_pin.py::test_long_press_digit": "bf0c4056d49dfef41cd42ea4b96fa07f83a96b3e670b54705503f011bb0c63eb",
"T3T1_es_test_pin.py::test_pin_cancel": "bd30d270187a7b99dbbf5bbb96db6b08f4c3ba72714b9f2bf945c17fee7bd48d",
@@ -22196,9 +22196,9 @@
"T3T1_es_test_tutorial_delizia.py::test_tutorial_menu_repeat": "0e49fe7cfee8ed2fa0fb9361945efca793f930d0da7dc5ccade5f44ea2c41a10",
"T3T1_fr_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "8ec82a067b142ff71464a5cc696e48c896e26bca5178dbe76952f1f4b4563e43",
"T3T1_fr_test_autolock.py::test_autolock_does_not_interrupt_signing": "1af6ba23f947fc79eca72af800d30258ec839e1ebe203512ef272eacb832da2b",
-"T3T1_fr_test_autolock.py::test_autolock_interrupts_passphrase": "d2d41cfb6385a0995fea4b01277b6c5872d39fc86b68255087a7cbea89094ca0",
+"T3T1_fr_test_autolock.py::test_autolock_interrupts_passphrase": "99bc72189b478dbe1403ba24081eedf9e47ed666d69ae31311897706e5b0dbfd",
"T3T1_fr_test_autolock.py::test_autolock_interrupts_signing": "1830d4383f73cfe4e976540c69981bb0df6afb8616d62e029700606f01e23a60",
-"T3T1_fr_test_autolock.py::test_autolock_passphrase_keyboard": "a9d3b68979cf231f9b42f3591440e903bc488346df032f5364d9c33d9bf3081a",
+"T3T1_fr_test_autolock.py::test_autolock_passphrase_keyboard": "730f84ef6d311104342335c9340850e0c96deacf93952a70ae6f8f44e4d5f683",
"T3T1_fr_test_autolock.py::test_dryrun_enter_word_slowly": "2d6bf7179110b8b15e572a4696e7c78a30c899b7f449aee13d6bfbd0c12b9a9f",
"T3T1_fr_test_autolock.py::test_dryrun_locks_at_number_of_words": "b37977f15ef333054b2cd25707b7389e65afa8853e001153f91e78f9150c645f",
"T3T1_fr_test_autolock.py::test_dryrun_locks_at_word_entry": "fc263436e21907ab81e1bc8d2cd282bc64e0752c6b069e30429cd4d04e741941",
@@ -22206,20 +22206,20 @@
"T3T1_fr_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "bd500adf58f103ac8abb1994ecccc717472a4fc0b5f9ef9fcab1538c793eaba1",
"T3T1_fr_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "e7ab6ddd6b71736497297b7a7c4661028cad3e2a2da1e5e7ab9b3cad607c0f9a",
"T3T1_fr_test_lock.py::test_hold_to_lock": "ec66a60a9b83a2cecaeba570aa6c3b30a4539fd415040369139ce4407a628faf",
-"T3T1_fr_test_passphrase_bde.py::test_cycle_through_last_character": "d88647cc508fa5fadd02b4eed6f12fc11a4a47efac774e281e818405faf50d39",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "957c3745b6d7573823e19cf7ca4d7b17bb6e68ab6e94abf8011e2238e4d3ab87",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_delete": "7e2eeb4befc1037dd7c6fad82e9709b1e51f28677a27b5824f10ba821bd2a004",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_delete_all": "99e44854e9e999469af6cba1f446c8b288fb7771b512466361649703249efd7a",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "b730e38e0aea91a98de20827eed2c8deef2f020c93cf3db90ad1b5a74ab40006",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "7d8657e10f72becddceb4da40dccd4ac01daa3cd9482cbadd94d52bccee7dcf1",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "b1bf53bb1574d411eb66f6fede7c891f8e8a5a5c31e68d1117e082d0d1849e98",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "73adfd5294ad7b3723beefc400ae495d9833c7d317a4fa7814fcde0d129d2a50",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "aae6d8cbcc8a3d84d2145184692c253dfdf79ed4490406bba3845c57bb8d6f51",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "c9aaded859c06210fd33ead4e0907cde5058293f07625f6c1bf8053058f0ff38",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "aae6d8cbcc8a3d84d2145184692c253dfdf79ed4490406bba3845c57bb8d6f51",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "13b92dc7ce2e645a81071bfb339126229c807d6c0702f43c9150a55c2ac92f9b",
+"T3T1_fr_test_passphrase_bde.py::test_cycle_through_last_character": "0dce5e75117737d6c859c930cb2012008ee8794427c8038d704e1ded46a431b6",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "23937097a7068055a8733d63b453b38efc01f4203c3a901bcfaa756c63d52e24",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_delete": "56a1e2d546a1eef53501439ccec8effd626829859358c91845b6ad5e59b0b063",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_delete_all": "f2135654683f073b97b80949c43f372828943e3fa92f5e6b700209a6d4eee6a0",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "d9c7e9c0c04c7e7ee39ca815070ffed85854c0eacd4240291146641d18e17e9c",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "3f273d6b59db1f174c3c93b651c1b701eb1dfb48dbb028c26af08e5dcbf07b80",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "d5b4971fd501e0b069cb4b570dddb355f306191fdfedb7175a9c197ce986c50f",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "2c3fa24f3aeaefb098af3379d9ef7aaba6a97eb332bb503a92945ad39701dbe2",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "27f0e9f93f858a474a9666a8753262b40b88553333fb85b504efefc452f4d810",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "a498642e9b22a2949d6c2970b8ee7e54adbf83b527ef92dffbdfbabe49379fa9",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "27f0e9f93f858a474a9666a8753262b40b88553333fb85b504efefc452f4d810",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "fd7afd0e062970844a21cb43a7337f6ecfc03eec0d7d7713f6106b46a6aa7909",
"T3T1_fr_test_passphrase_bde.py::test_passphrase_loop_all_characters": "40d3fa01d97d0ab5c6d8e2d3e2eee3e4cab9e598889d486ea2128fc4ce9c6aab",
-"T3T1_fr_test_passphrase_bde.py::test_passphrase_prompt_disappears": "d558ef2926e5932dce83f36a2fe4d767c774d517986d42b93979bb2af2130177",
+"T3T1_fr_test_passphrase_bde.py::test_passphrase_prompt_disappears": "6dbd6493670bb50377b1c82a84c860caad89b35b5e99bdbcce0f3758ff9c0762",
"T3T1_fr_test_pin.py::test_last_digit_timeout": "c3fdfb11b38042338ed8757ff84a8bc7266f73a065e890755959b3ab4039c526",
"T3T1_fr_test_pin.py::test_long_press_digit": "fac6d1c45105a9e252c99c1a0bc3b3329e03aead9f990b0613bc0116bad85711",
"T3T1_fr_test_pin.py::test_pin_cancel": "d84213ac7ff12ba02a4961150ceb5fc5c15767dbfdfae8c11e4f3bec69f6afc3",
@@ -22256,9 +22256,9 @@
"T3T1_fr_test_tutorial_delizia.py::test_tutorial_menu_repeat": "d8fca1ad633c6dca0d3fe2ec77ee2c7e14fa25095d8149b79c1c482073af4fe8",
"T3T1_pt_test_autolock.py::test_autolock_does_not_interrupt_preauthorized": "ce36be3fbf6690b1ca8a003b450d45ae9714b5050bccd409f9054d01d0d6bfc4",
"T3T1_pt_test_autolock.py::test_autolock_does_not_interrupt_signing": "f62f8ca2fdaf29bb5b1706f2952955666b9b57db90326c2b9afdb643c6bd897c",
-"T3T1_pt_test_autolock.py::test_autolock_interrupts_passphrase": "9d920a07db146fd6f9387696fc748d007829b5ce6a09bd509c04fb8779bdd1e9",
+"T3T1_pt_test_autolock.py::test_autolock_interrupts_passphrase": "12eca7306660508e5914dd31c27f95dfa91eb050bbfe10c2cd9d6fb20acf2ab1",
"T3T1_pt_test_autolock.py::test_autolock_interrupts_signing": "5a01ecc3e4aaea157a5b39ff7345120c31d3f1cd14521996791c686a81b768fd",
-"T3T1_pt_test_autolock.py::test_autolock_passphrase_keyboard": "0901c1ae28a4e108b8cabe196cf4bb5001922d7f0732256ac7bc46bd34555f38",
+"T3T1_pt_test_autolock.py::test_autolock_passphrase_keyboard": "85e02c1ae197e8accd055f383033802e12164e1b4b8983975f13552c6642610c",
"T3T1_pt_test_autolock.py::test_dryrun_enter_word_slowly": "1c533f7fb9d8f60e0664a3675e26193b6d6b3937297827db53f5f0be9959f9ea",
"T3T1_pt_test_autolock.py::test_dryrun_locks_at_number_of_words": "ded0d1509a3117e5c03258a9b11369ecd8a4557ad51a7fb8cb698b58cc8813a3",
"T3T1_pt_test_autolock.py::test_dryrun_locks_at_word_entry": "1191d294c1c7aa148fce97ca052b36647f1289296dfaf7d78045326b57dde8d4",
@@ -22266,20 +22266,20 @@
"T3T1_pt_test_backup_slip39_custom.py::test_backup_slip39_custom[2of3]": "e0db692669492044a211bdd39445b0ad2864d6520e3812e106f082b3b6ebeb25",
"T3T1_pt_test_backup_slip39_custom.py::test_backup_slip39_custom[5of5]": "aecaa6768e8020482c6f94906142a45679d8473a7b85d349523cd7449203d6fc",
"T3T1_pt_test_lock.py::test_hold_to_lock": "930b34a1d834ea631521067f602cea060bb83f72ccf8beb8afeab5fcc0c74860",
-"T3T1_pt_test_passphrase_bde.py::test_cycle_through_last_character": "d917954db50c570a6d438c7dee1e60ab1dd1427af22d1fb2130d60c69092d7bf",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "92b13fd42fa693c52a8fcf9c612d08d1e319aa454fc9dc63eadd3c5bc0970cb7",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_delete": "b16c5935db618e2e261bb8cc516b64e03e0c32b814ad7b7358cdee4134b71164",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_delete_all": "3263cb9841458a99e8efeeaebae5ac3d0074b22a06e4ea6bc3c4e19a904abf3c",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "f86c5dfa65316bf797477349f3413cb3bb821eca58282fe3cd3dfc2a45b2b72e",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "c733be58b4b1951643b9b70b75d58fe4fd3695a4534d65a1a6ec8ad4b1dbf91f",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "ee660cffab79e22d1bcc4de28a792117860539ee17e43b71a1473e11861d6d34",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "3dbb6757ed0ef534fd440d1a019bcc696666188d1288076fc0ccc4855a4060f7",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "c0783fca9652d14f93c0507c9246def3546587b1e1be41460ef314034d24593c",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "d6a263cc5507920f245ab0e5b592d357aa3fd2dc8d1103c5e31eb640d6f667c0",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "c0783fca9652d14f93c0507c9246def3546587b1e1be41460ef314034d24593c",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "a8b5d717a4137646cca1a166b84488b47f196fc68017baedcf8904e50710a63e",
+"T3T1_pt_test_passphrase_bde.py::test_cycle_through_last_character": "493f6003077312c6609336fef8ac1661990a0d68c0999d9188c70c9ecd20fc84",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_click_same_button_many_times": "37a9c895fbaf41fbc2142afe7c1c81c56be07b435607e049560d66e48f05f43c",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_delete": "277dc82cc7929014f584538780d69350bf9ea6bf7b987703899c04ef8869dadf",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_delete_all": "239ef38a5a941574aed5d43a297b5b13bfe98b0d93d7f50f7e5298ff1538bad2",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_dollar_sign_deletion": "cdfe9d6b145af98ca21ea14a53112c971ae1e172d0cc6081e2d2a368e5469063",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[Y@14lw%p)JN@f54MYvys@zj'g-mnkoxeaMzLgfCxUdDSZ-aaae4aa2": "749d364750b89cba191474fb105728cb8068ce7b8b9d365bc3fd4f7fdeff64ce",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[abc 123-mvqzZUb9NaUc62Buk9WCP4L7hunsXFyamT]": "f6461b93414aa31d09a4cdc22a3e3fe78db83fbd2cfc0d9d3fbe736e458700f8",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[abc123ABC_<>-mtHHfh6uHtJiACwp7kzJZ97yueT6sEdQiG]": "af8efaf65fdb77dac265bbd763bae3e7d03dc4fcd1245c3c6cc699e80d2b23e5",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-66a83b65": "a7a1b6b37b06d37d0beb65de7ec78847d81991292b3b620090eac7a542d5f059",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_input[dadadadadadadadadadadadadadadadadadadadadadad-7159c03e": "47cc0e7142bf33d9ecf201b2f27d27aaa7578dded3f9287a36b9d1211e5e6e07",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_input_over_50_chars": "a7a1b6b37b06d37d0beb65de7ec78847d81991292b3b620090eac7a542d5f059",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_long_spaces_deletion": "8489229b91f44223908a80bb2538da9d65fb13e5d96fd913630a10db515c61cf",
"T3T1_pt_test_passphrase_bde.py::test_passphrase_loop_all_characters": "a5b12a9c0a4d5c10b72f072b6d49dae804680dc50cc56667f6cf888b18cfb2e6",
-"T3T1_pt_test_passphrase_bde.py::test_passphrase_prompt_disappears": "52d63a2274c8a5a61f9350cbeaf544862465625f7dee8008a580c9e2bcd3f1b6",
+"T3T1_pt_test_passphrase_bde.py::test_passphrase_prompt_disappears": "8a30085d9816dce73ad00bc53b2f1ed85290ffcbdb26678c172a0eee7f9bda2e",
"T3T1_pt_test_pin.py::test_last_digit_timeout": "1073b896c52e58355b7ad9f1dad50c2f481d58c5f3210d5303055ad558db61bc",
"T3T1_pt_test_pin.py::test_long_press_digit": "d25d107523292b975aae419efedee5bcf718f8e19ee95cbeadec7f7cde95a1b4",
"T3T1_pt_test_pin.py::test_pin_cancel": "48f1e4001adb2977a46db5c9b8e661d0aec86ea31dc474e559dd2a43f6924044",
Why this scored 29/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.