Skip to content

fix: use ideographic spaces for Japanese mnemonics#90

Open
ethicnology wants to merge 2 commits into
rust-bitcoin:masterfrom
ethicnology:japanese-ideographic-spaces
Open

fix: use ideographic spaces for Japanese mnemonics#90
ethicnology wants to merge 2 commits into
rust-bitcoin:masterfrom
ethicnology:japanese-ideographic-spaces

Conversation

@ethicnology

Copy link
Copy Markdown

Hi, I noticed that when generating a Japanese mnemonic, the output sentence does not use ideographic spaces, and the library is unable to parse it correctly while they are recommended in bip39 Japanese section

Developers implementing phrase generation or checksum verification must separate words using ideographic spaces / accommodate users inputting ideographic spaces. (UTF-8 bytes: 0xE38080; C/C+/Java: "\u3000"; Python: u"\u3000")

I've also added some test vectors used for Japanese mnemonics

@tnull
tnull self-requested a review November 6, 2025 12:49
@ethicnology

Copy link
Copy Markdown
Author

@elsirion

@elsirion elsirion left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the two problems worth discussing here:

  • How does it fit into our no_std support story
  • Is the additional complexity warranted

I think if we just generally deal with japanese whitespaces this might be a good trade-off. But I'll leave that to you. Pinging @uncomputable as a knower of rust and the japanese language 😆

Comment thread src/language/mod.rs
pub fn separator(self) -> &'static str {
match self {
#[cfg(feature = "japanese")]
Language::Japanese => " ", // U+3000 ideographic space

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please make this an escape string so it's easier to review if it is the correct space please?

Comment thread src/language/mod.rs
Comment on lines +179 to +192
/// Split mnemonic into words using language-appropriate separators.
/// Japanese uses ideographic spaces (U+3000), others use standard whitespace.
pub fn split_mnemonic<'a>(self, mnemonic: &'a str) -> Box<dyn Iterator<Item = &'a str> + 'a> {
match self {
#[cfg(feature = "japanese")]
Language::Japanese => {
// For Japanese, only split on ideographic spaces (U+3000)
Box::new(mnemonic.split(' ').filter(|s| !s.is_empty()))
}
_ => {
Box::new(mnemonic.split_whitespace())
}
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only works with the alloc feature, should be gated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, instead of doing it this way, always return a struct like:

struct SplitMnemonic<'a> {
    parts: [&'a str; 24],
    len: usize,
}

And implement Iterator for that. So you could collect into the struct, it has constant size without allocation and you can apply different splitting algorithms. Alternatively, idk if it would be the end of the world to just always also split on japaneses whitespaces.

Comment thread src/lib.rs
Mnemonic::language_of_iter(mnemonic.as_ref().split_whitespace())
// Split on both standard whitespace and ideographic space to handle Japanese
let words: Vec<&str> = mnemonic.as_ref()
.split(|c: char| c.is_whitespace() || c == ' ')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth making the special space a cosntant

@uncomputable

Copy link
Copy Markdown

I can confirm that ideographic spaces significantly increase readability of Japanese BIP 39 mnemonics. (I also think that Japanese mnemonics are reckless to use, but that is not the topic of this PR.)

Developers implementing phrase generation or checksum verification must separate words using ideographic spaces / accommodate users inputting ideographic spaces.

The spec seems to enforce ideographic spaces except for rare cases, so implementing this here seems worthwhile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants