Skip to content

fix(key-wallet): normalize a mnemonic phrase once, into a wiped buffer - #1274

Merged
xdustinface merged 1 commit into
devfrom
pasta/mnemonic-from-phrase-wipe
Nov 1, 2026
Merged

xdustinface merged 1 commit into
devfrom
pasta/mnemonic-from-phrase-wipe

Conversation

@PastaPastaPasta

@PastaPastaPasta PastaPastaPasta commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #1271.

Mnemonic::from_phrase tries each wordlist with bip39::Mnemonic::parse_in, which normalizes the phrase to NFKD each time it is called. When the phrase isn't already NFKD, for example an NFC phrase with accented words, each try builds a new normalized String. That string grows as it is built, and none of these copies is wiped. With English first and nine more wordlists, that is up to ten copies.

from_phrase now normalizes the phrase once into a Zeroizing<String>, allocated at its final size so it never reallocates, and tries each wordlist with parse_in_normalized. A phrase that is already NFKD, such as one from Mnemonic::phrase, is used as it is, with no copy. The same phrases parse as before, in the same language order, with the same error text.

Copies made inside bip39 and unicode-normalization themselves aren't covered.

Changelog

  • Mnemonic::from_phrase in key-wallet normalizes a non-NFKD phrase once, into a buffer that is wiped when dropped

Tests

  • test_nfkd_zeroizing_normalizes_into_an_exact_size_buffer: NFKD input isn't copied, and NFC input is normalized into a buffer whose capacity equals its length.
  • The existing test_from_phrase_nfc_input_matches_nfkd and test_from_phrase_round_trip_all_languages cover parsing.
  • The wiping itself can't be observed from a test, and parsing results don't change, so no test fails on dev.
  • Locally: fmt, workspace clippy -D warnings (all features and targets), and the key-wallet and key-wallet-ffi tests.

🤖 Generated with Claude Code

PR Hygiene · 7a665ff

  • Bots — coderabbitai not yet — /skip-bots proceeds without the ones not yet reported
  • Self-review — post /self-reviewed
  • Build running
  • Approvals
    • key-wallet (key-wallet/src/mnemonic.rs) — QuantumExplorer or ZocoLini or xdustinface

When every merge requirement is met, the PR Hygiene check passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.

Mnemonic::from_phrase tried each wordlist with bip39's parse_in, which
normalizes the phrase to NFKD again for every language it is given. When
the phrase is not already NFKD, each try builds a new normalized String,
grown as it is built, and none of them is wiped.

from_phrase now normalizes the phrase once, into a Zeroizing buffer
allocated at its final size, and tries each wordlist with
parse_in_normalized. A phrase that is already NFKD, such as one from
Mnemonic::phrase, is used as it is, without a copy. Which phrases parse,
and in which language, is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 5 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 962db06 and 7a665ff.

Files selected for processing: 1
  • key-wallet/src/mnemonic.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai not yet. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added the waiting-bots Waiting for the review bots to report on this head label Nov 1, 2026
@codecov

codecov Bot commented Nov 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.71%. Comparing base (962db06) to head (7a665ff).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1274      +/-   ##
==========================================
- Coverage   80.71%   80.71%   -0.01%     
==========================================
  Files         291      291              
  Lines       77818    77841      +23     
==========================================
+ Hits        62813    62830      +17     
- Misses      15005    15011       +6     
Flag Coverage Δ
core 78.34% <ø> (ø)
ffi 58.20% <ø> (ø)
rpc 52.05% <ø> (ø)
spv 93.69% <ø> (-0.03%) ⬇️
wallet 82.91% <100.00%> (+0.01%) ⬆️
Files with missing lines Coverage Δ
key-wallet/src/mnemonic.rs 98.58% <100.00%> (+0.04%) ⬆️

... and 3 files with indirect coverage changes

@xdustinface
xdustinface merged commit 4f1bfcb into dev Nov 1, 2026
38 of 39 checks passed
@xdustinface
xdustinface deleted the pasta/mnemonic-from-phrase-wipe branch November 1, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-bots Waiting for the review bots to report on this head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants