|
1 | 1 | mod bit_accumulator; |
2 | 2 | mod entropy; |
3 | 3 | mod phrase; |
| 4 | +mod seed; |
4 | 5 |
|
5 | 6 | #[cfg(not(feature = "std"))] |
6 | 7 | use alloc::{ |
7 | 8 | borrow::Cow, |
8 | | - format, |
9 | 9 | string::{String, ToString}, |
10 | 10 | vec::Vec, |
11 | 11 | }; |
12 | 12 | use core::{fmt, marker::PhantomData, mem, str}; |
13 | 13 | #[cfg(feature = "std")] |
14 | 14 | use std::borrow::Cow; |
15 | 15 |
|
16 | | -use hmac::Hmac; |
17 | | -use sha2::Sha512; |
18 | 16 | use unicode_normalization::{IsNormalized, UnicodeNormalization, is_nfkd_quick}; |
19 | 17 | use zeroize::Zeroizing; |
20 | 18 |
|
21 | 19 | use self::{ |
22 | 20 | bit_accumulator::BitAccumulator, |
23 | 21 | entropy::{encode_entropy, encode_entropy_with}, |
24 | 22 | phrase::{DecodeMode, decode_phrase}, |
| 23 | + seed::to_seed, |
25 | 24 | }; |
26 | 25 | use crate::{ |
27 | 26 | error::Error, |
@@ -406,30 +405,8 @@ assert_eq!(result.unwrap_err(), Error::UnknownWord("ばか".nfkd().to_string())) |
406 | 405 | /// assert_eq!(mnemonic.to_seed("").len(), 64); |
407 | 406 | /// ``` |
408 | 407 | pub fn to_seed<P: AsRef<str>>(&self, passphrase: P) -> [u8; 64] { |
409 | | - // use the PBKDF2 function with a mnemonic sentence (in UTF-8 NFKD) used as the password |
410 | | - // and the string "mnemonic" + passphrase (again in UTF-8 NFKD) used as the salt. |
411 | | - // The iteration count is set to 2048 and HMAC-SHA512 is used as the pseudo-random function. |
412 | | - // The length of the derived key is 512 bits (= 64 bytes). |
413 | | - const PBKDF2_ROUNDS: u32 = 2048; |
414 | | - const PBKDF2_BYTES: usize = 64; |
415 | | - |
416 | 408 | // the phrase has been normalized |
417 | | - let normalized_password = self.phrase(); |
418 | | - let normalized_salt = { |
419 | | - let mut salt = Cow::Owned(format!("mnemonic{}", passphrase.as_ref())); |
420 | | - normalize_utf8(&mut salt); |
421 | | - salt |
422 | | - }; |
423 | | - |
424 | | - let mut seed = [0u8; PBKDF2_BYTES]; |
425 | | - pbkdf2::pbkdf2::<Hmac<Sha512>>( |
426 | | - normalized_password.as_bytes(), |
427 | | - normalized_salt.as_bytes(), |
428 | | - PBKDF2_ROUNDS, |
429 | | - &mut seed, |
430 | | - ) |
431 | | - .expect("HMAC can be initialized with any key length"); |
432 | | - seed |
| 409 | + to_seed(self.phrase(), passphrase.as_ref()) |
433 | 410 | } |
434 | 411 |
|
435 | 412 | /// Returns the mnemonic phrase as a string slice. |
@@ -688,26 +665,8 @@ assert_eq!(result.unwrap_err(), Error::UnknownWord("ばか".nfkd().to_string())) |
688 | 665 | /// assert_eq!(seed.len(), 64); |
689 | 666 | /// ``` |
690 | 667 | pub fn to_seed<P: AsRef<str>>(&self, passphrase: P) -> [u8; 64] { |
691 | | - // same as Mnemonic::to_seed; phrase is already normalized |
692 | | - const PBKDF2_ROUNDS: u32 = 2048; |
693 | | - const PBKDF2_BYTES: usize = 64; |
694 | | - |
695 | | - let normalized_password = self.phrase(); |
696 | | - let normalized_salt = { |
697 | | - let mut salt = Cow::Owned(format!("mnemonic{}", passphrase.as_ref())); |
698 | | - normalize_utf8(&mut salt); |
699 | | - salt |
700 | | - }; |
701 | | - |
702 | | - let mut seed = [0u8; PBKDF2_BYTES]; |
703 | | - pbkdf2::pbkdf2::<Hmac<Sha512>>( |
704 | | - normalized_password.as_bytes(), |
705 | | - normalized_salt.as_bytes(), |
706 | | - PBKDF2_ROUNDS, |
707 | | - &mut seed, |
708 | | - ) |
709 | | - .expect("HMAC can be initialized with any key length"); |
710 | | - seed |
| 668 | + // phrase is already normalized |
| 669 | + to_seed(self.phrase(), passphrase.as_ref()) |
711 | 670 | } |
712 | 671 |
|
713 | 672 | /// Returns the language used to encode/decode this mnemonic. |
|
0 commit comments