Skip to content

Commit dc6934f

Browse files
committed
vendor: add rust-bip39 dep
We use our fork that has two custom patches: - fix bitcoin_hashes transitive dep version to avoid duplicates - add async version of the function to derive a bip39 seed This will be used to convert our BIP39 unlock to be an async operation, not blocking the mainloop.
1 parent 565159b commit dc6934f

File tree

7 files changed

+86
-9
lines changed

7 files changed

+86
-9
lines changed

.cargo/config.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ git = "https://github.com/BitBoxSwiss/rust-bip32-ed25519"
1111
tag = "v0.2.1"
1212
replace-with = "vendored-sources"
1313

14-
[source."git+https://github.com/benma/rust-bip39.git?branch=bb02"]
15-
git = "https://github.com/benma/rust-bip39.git"
16-
branch = "bb02"
14+
[source."git+https://github.com/BitBoxSwiss/rust-bip39.git?branch=bitbox-20250922"]
15+
git = "https://github.com/BitBoxSwiss/rust-bip39.git"
16+
branch = "bitbox-20250922"
1717
replace-with = "vendored-sources"
1818

1919
[source.vendored-sources]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"files":{".editorconfig":"cfca97a9600b0581127f3075083447e3221a823b937e940bb87d9747175a9adb",".github/workflows/rust.yml":"8f69f78c671bd2ec88803bbcefec49055a6a2b24c276d2d0de8aef5c441c8089",".rustfmt.toml":"090f8fdb44474290d98f32e9b69f7d9d9806cb17874aed6b64e3e3ebb258f781","CHANGELOG.md":"30b9addc19f1f923d252ac262eaaed7ee4dc28e39a9784f74b7d39dea80946a4","Cargo-minimal.lock":"f26f1c7bf57f8120047d15fc8c90f2be101ccb3a4c093da79c2089d431aa95d6","Cargo.toml":"a9048e13d747618996fbc221205304b7a38dde0708961e8fe5758b4e7bf001be","LICENSE":"7179683e8000e6bdc9bbc60d85edf0a4ac8e76f951857f54fcb775d5886f1309","README.md":"d7e0e2aae5ba9e3b285107a16b9a719ce3cc8d52449032656e46fc9f455ac180","benches/bench.rs":"84781745a31f1a63c761d5c6bfcaabf8b2f8f570645a46a7ef0dd030958e866f","contrib/test.sh":"7f659d719cd4d9ffe741615dda795dd314aa08f9cffdd3e94821d8ba2f211291","src/internal_macros.rs":"76710d6d4eb360e40931344e8119b5e21d1d40f25bf1965ab95413f528e5373e","src/language/chinese_simplified.rs":"379581a1a5de22d783bcfeb807c0fca1fe1a3a0be804c1a86448285bff42ed24","src/language/chinese_traditional.rs":"60cd3fe7696d2be88ec9569d9fa16cf1381f23a9f97674d54459e284b9dad103","src/language/czech.rs":"80555a97108ba7d86e536d98585ccbede6ddfe0cd91c01e8a05e5cf4eaff453c","src/language/english.rs":"3f4d2e39891d12d8193741c68663d29f568606cec65c864eff7e3231f0d29693","src/language/french.rs":"b51846bb6f7cd8960499a32c10c1767ef87f2dd052d09bccf082189af3dcc36d","src/language/italian.rs":"17c46fefcc8f67884867cd70240f4c1e2813408ef65912cbce70b925d55d7c59","src/language/japanese.rs":"fc3860147c5cee29eab715499e748de7d29626fc8b279a7761f79a08235aab2e","src/language/korean.rs":"e0e982106c18911389e7d8c7eda92155681f7d60bd19b895196316d2ef195e90","src/language/mod.rs":"870151f8c2b72a7b3b7a26566b73126fe7ba217370c6e52a77586916a240f9e1","src/language/portuguese.rs":"3ff2f0fcf0902907097f53c1f84293109a8368e76a0b725e6a7b8eed106f80e9","src/language/spanish.rs":"d4bb09a9eb9d1a54fed4d6d32b110038a998c59dc77f7bb79df5d6738d69bc0e","src/lib.rs":"6a15087ec5f8dc8a016a05256bc23b4ae1209eaba1109f439d2f65fc9ff6a4c3","src/pbkdf2.rs":"f5c255f7c795f8c74e6defda589fdb8907a349ddaf0249418ccd35635a6616d7"},"package":null}
1+
{"files":{".editorconfig":"cfca97a9600b0581127f3075083447e3221a823b937e940bb87d9747175a9adb",".github/workflows/rust.yml":"8f69f78c671bd2ec88803bbcefec49055a6a2b24c276d2d0de8aef5c441c8089",".rustfmt.toml":"090f8fdb44474290d98f32e9b69f7d9d9806cb17874aed6b64e3e3ebb258f781","CHANGELOG.md":"30b9addc19f1f923d252ac262eaaed7ee4dc28e39a9784f74b7d39dea80946a4","Cargo-minimal.lock":"f26f1c7bf57f8120047d15fc8c90f2be101ccb3a4c093da79c2089d431aa95d6","Cargo.toml":"8f90f307f5464fe32c615b98162bc94e1dcd07e80848f6ffeebf4bf2a56a6bdd","LICENSE":"7179683e8000e6bdc9bbc60d85edf0a4ac8e76f951857f54fcb775d5886f1309","README.md":"d7e0e2aae5ba9e3b285107a16b9a719ce3cc8d52449032656e46fc9f455ac180","benches/bench.rs":"84781745a31f1a63c761d5c6bfcaabf8b2f8f570645a46a7ef0dd030958e866f","contrib/test.sh":"7f659d719cd4d9ffe741615dda795dd314aa08f9cffdd3e94821d8ba2f211291","src/internal_macros.rs":"76710d6d4eb360e40931344e8119b5e21d1d40f25bf1965ab95413f528e5373e","src/language/chinese_simplified.rs":"379581a1a5de22d783bcfeb807c0fca1fe1a3a0be804c1a86448285bff42ed24","src/language/chinese_traditional.rs":"60cd3fe7696d2be88ec9569d9fa16cf1381f23a9f97674d54459e284b9dad103","src/language/czech.rs":"80555a97108ba7d86e536d98585ccbede6ddfe0cd91c01e8a05e5cf4eaff453c","src/language/english.rs":"3f4d2e39891d12d8193741c68663d29f568606cec65c864eff7e3231f0d29693","src/language/french.rs":"b51846bb6f7cd8960499a32c10c1767ef87f2dd052d09bccf082189af3dcc36d","src/language/italian.rs":"17c46fefcc8f67884867cd70240f4c1e2813408ef65912cbce70b925d55d7c59","src/language/japanese.rs":"fc3860147c5cee29eab715499e748de7d29626fc8b279a7761f79a08235aab2e","src/language/korean.rs":"e0e982106c18911389e7d8c7eda92155681f7d60bd19b895196316d2ef195e90","src/language/mod.rs":"870151f8c2b72a7b3b7a26566b73126fe7ba217370c6e52a77586916a240f9e1","src/language/portuguese.rs":"3ff2f0fcf0902907097f53c1f84293109a8368e76a0b725e6a7b8eed106f80e9","src/language/spanish.rs":"d4bb09a9eb9d1a54fed4d6d32b110038a998c59dc77f7bb79df5d6738d69bc0e","src/lib.rs":"e0b61730e7ac073d94cb1d10796c08d93d2c6bccf8e8606b08b2f3993c1d75d4","src/pbkdf2.rs":"30a2553fa0a7b294f63fbe7487c7cce5a9d34bb96c1ee985cdddf693aa79641c"},"package":null}

external/vendor/bip39/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,10 @@ bitcoin_hashes = ">=0.12,<0.15"
116116
[dev-dependencies.bip39]
117117
path = "."
118118
features = ["rand"]
119+
120+
[dev-dependencies.tokio]
121+
version = "1"
122+
features = [
123+
"macros",
124+
"rt",
125+
]

external/vendor/bip39/src/lib.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,27 @@ impl Mnemonic {
557557
seed
558558
}
559559

560+
/// Async version of `to_seed_normalized`.
561+
pub async fn to_seed_normalized_async(
562+
&self,
563+
normalized_passphrase: &str,
564+
yield_now: impl AsyncFn(),
565+
) -> [u8; 64] {
566+
const PBKDF2_ROUNDS: usize = 2048;
567+
const PBKDF2_BYTES: usize = 64;
568+
569+
let mut seed = [0u8; PBKDF2_BYTES];
570+
pbkdf2::pbkdf2_async(
571+
self.words(),
572+
normalized_passphrase.as_bytes(),
573+
PBKDF2_ROUNDS,
574+
&mut seed,
575+
yield_now,
576+
)
577+
.await;
578+
seed
579+
}
580+
560581
/// Convert to seed bytes.
561582
#[cfg(feature = "unicode-normalization")]
562583
pub fn to_seed<'a, P: Into<Cow<'a, str>>>(&self, passphrase: P) -> [u8; 64] {
@@ -729,8 +750,8 @@ mod tests {
729750
}
730751
}
731752

732-
#[test]
733-
fn test_vectors_english() {
753+
#[tokio::test]
754+
async fn test_vectors_english() {
734755
// These vectors are tuples of
735756
// (entropy, mnemonic, seed)
736757
let test_vectors = [
@@ -882,6 +903,15 @@ mod tests {
882903
mnemonic_str
883904
);
884905

906+
assert_eq!(
907+
&seed[..],
908+
&mnemonic
909+
.to_seed_normalized_async("TREZOR", tokio::task::yield_now)
910+
.await[..],
911+
"failed vector: {}",
912+
mnemonic_str
913+
);
914+
885915
#[cfg(feature = "unicode-normalization")]
886916
{
887917
assert_eq!(&mnemonic.to_string(), mnemonic_str, "failed vector: {}", mnemonic_str);

external/vendor/bip39/src/pbkdf2.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,41 @@ pub(crate) fn pbkdf2<M>(mnemonic: M, unprefixed_salt: &[u8], c: usize, res: &mut
126126
}
127127
}
128128
}
129+
130+
pub(crate) async fn pbkdf2_async<M>(
131+
mnemonic: M,
132+
unprefixed_salt: &[u8],
133+
c: usize,
134+
res: &mut [u8],
135+
yield_now: impl AsyncFn(),
136+
) where
137+
M: Iterator<Item = &'static str> + Clone,
138+
{
139+
let prf = create_hmac_engine(mnemonic);
140+
141+
for (i, chunk) in res.chunks_mut(sha512::Hash::LEN).enumerate() {
142+
for v in chunk.iter_mut() {
143+
*v = 0;
144+
}
145+
146+
let mut salt = {
147+
let mut prfc = prf.clone();
148+
prfc.input(SALT_PREFIX.as_bytes());
149+
prfc.input(unprefixed_salt);
150+
prfc.input(&u32_to_array_be((i + 1) as u32));
151+
152+
let salt = hmac::Hmac::from_engine(prfc).to_byte_array();
153+
xor(chunk, &salt);
154+
salt
155+
};
156+
157+
for _ in 1..c {
158+
let mut prfc = prf.clone();
159+
prfc.input(&salt);
160+
salt = hmac::Hmac::from_engine(prfc).to_byte_array();
161+
162+
xor(chunk, &salt);
163+
yield_now().await;
164+
}
165+
}
166+
}

src/rust/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ resolver = "2"
3232
# The secp-recovery feature is currently only needed in tests to make use of `RecoverableSignature`.
3333
# Attempting to enable it conditionally only for tests somehow leads to linking errors (duplicate secp256k1 symbols).
3434
bitcoin = { version = "0.32.7", default-features = false, features = ["secp-recovery"] }
35-
# Replace with upstream once https://github.com/rust-bitcoin/rust-bip39/pull/76 is merged and released.
36-
bip39 = { git = "https://github.com/benma/rust-bip39.git", branch = "bb02", default-features = false, features = ["zeroize"] }
35+
# Forked for:
36+
# - https://github.com/rust-bitcoin/rust-bip39/pull/76 -> custom commit can be removed once this is merged
37+
# - async functionality
38+
bip39 = { git = "https://github.com/BitBoxSwiss/rust-bip39.git", branch = "bitbox-20250922", default-features = false, features = ["zeroize"] }
3739
hex = { version = "0.4", default-features = false, features = ["alloc"] }
3840
num-bigint = { version = "0.4.6", default-features = false }
3941
# force-soft-compact reduces the binary size by ~3kB. In future versions of sha2 this will change to

0 commit comments

Comments
 (0)