bip39/seed.rs
1use crypto::pbkdf2;
2use mnemonic::Mnemonic;
3use std::fmt;
4
5/// The secret value used to derive HD wallet addresses from a [`Mnemonic`][Mnemonic] phrase.
6///
7/// Because it is not possible to create a [`Mnemonic`][Mnemonic] instance that is invalid, it is
8/// therefore impossible to have a [`Seed`][Seed] instance that is invalid. This guarantees that only
9/// a valid, intact mnemonic phrase can be used to derive HD wallet addresses.
10///
11/// To get the raw byte value use [`Seed::as_bytes()`][Seed::as_bytes()]. These can be used to derive
12/// HD wallet addresses using another crate (deriving HD wallet addresses is outside the scope of this
13/// crate and the BIP39 standard).
14///
15/// [Mnemonic]: ./mnemonic/struct.Mnemonic.html
16/// [Seed]: ./seed/struct.Seed.html
17/// [Seed::as_bytes()]: ./seed/struct.Seed.html#method.as_bytes
18
19#[derive(Clone)]
20pub struct Seed {
21 bytes: Vec<u8>,
22}
23
24impl Seed {
25 /// Generates the seed from the [`Mnemonic`][Mnemonic] and the password.
26 ///
27 /// [Mnemonic]: ./mnemonic/struct.Mnemonic.html
28 pub fn new(mnemonic: &Mnemonic, password: &str) -> Self {
29 let salt = format!("mnemonic{}", password);
30 let bytes = pbkdf2(mnemonic.entropy(), &salt);
31
32 Self {
33 bytes,
34 }
35 }
36
37 /// 通过对比 EtherJs 中的代码,生成种子是直接使用的 mnemonic 而不是 entropy
38 pub fn new_cpc(mnemonic: &Mnemonic, password: &str) -> Self {
39 let salt = format!("mnemonic{}", password);
40 let bytes = pbkdf2(mnemonic.phrase().as_bytes(), &salt);
41
42 Self {
43 bytes,
44 }
45 }
46
47 /// Get the seed value as a byte slice
48 pub fn as_bytes(&self) -> &[u8] {
49 &self.bytes
50 }
51}
52
53impl AsRef<[u8]> for Seed {
54 fn as_ref(&self) -> &[u8] {
55 self.as_bytes()
56 }
57}
58
59impl fmt::Debug for Seed {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 write!(f, "{:#X}", self)
62 }
63}
64
65impl fmt::LowerHex for Seed {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 if f.alternate() {
68 f.write_str("0x")?;
69 }
70
71 for byte in &self.bytes {
72 write!(f, "{:x}", byte)?;
73 }
74
75 Ok(())
76 }
77}
78
79impl fmt::UpperHex for Seed {
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 if f.alternate() {
82 f.write_str("0x")?;
83 }
84
85 for byte in &self.bytes {
86 write!(f, "{:X}", byte)?;
87 }
88
89 Ok(())
90 }
91}