1313// limitations under the License.
1414
1515use alloc:: string:: { String , ToString } ;
16+ use alloc:: vec:: Vec ;
1617
1718/// `idx` must be smaller than BIP39_WORDLIST_LEN.
1819pub fn get_word ( idx : u16 ) -> Result < zeroize:: Zeroizing < String > , ( ) > {
@@ -25,6 +26,14 @@ pub fn get_word(idx: u16) -> Result<zeroize::Zeroizing<String>, ()> {
2526 ) )
2627}
2728
29+ /// Decode a BIP39 mnemonic.
30+ pub fn mnemonic_to_seed ( mnemonic : & str ) -> Result < zeroize:: Zeroizing < Vec < u8 > > , ( ) > {
31+ let mnemonic =
32+ bip39:: Mnemonic :: parse_in_normalized ( bip39:: Language :: English , mnemonic) . map_err ( |_| ( ) ) ?;
33+ let ( seed, seed_len) = mnemonic. to_entropy_array ( ) ;
34+ Ok ( zeroize:: Zeroizing :: new ( seed[ ..seed_len] . to_vec ( ) ) )
35+ }
36+
2837// C API
2938
3039#[ unsafe( no_mangle) ]
@@ -93,4 +102,37 @@ mod tests {
93102 assert_eq ! ( get_word( 2047 ) . unwrap( ) . as_ref( ) as & str , "zoo" ) ;
94103 assert_eq ! ( get_word( 563 ) . unwrap( ) . as_ref( ) as & str , "edit" ) ;
95104 }
105+
106+ #[ test]
107+ fn test_mnemonic_to_seed ( ) {
108+ assert ! ( mnemonic_to_seed( "invalid" ) . is_err( ) ) ;
109+
110+ // Zero seed
111+ assert_eq ! (
112+ mnemonic_to_seed( "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" ) . unwrap( ) . as_ref( ) as & [ u8 ] ,
113+ & [ 0u8 ; 16 ] ,
114+ ) ;
115+
116+ // 12 words
117+ assert_eq ! (
118+ mnemonic_to_seed(
119+ "trust cradle viable innocent stand equal little small junior frost laundry room"
120+ )
121+ . unwrap( )
122+ . as_ref( ) as & [ u8 ] ,
123+ b"\xe9 \xa6 \x3f \xcd \x3a \x4d \x48 \x98 \x20 \xa6 \x63 \x79 \x2b \xad \xf6 \xdd " ,
124+ ) ;
125+
126+ // 18 words
127+ assert_eq ! (
128+ mnemonic_to_seed( "pupil parent toe bright slam plastic spy suspect verb battle nominee loan call crystal upset razor luggage join" ) . unwrap( ) . as_ref( ) as & [ u8 ] ,
129+ b"\xad \xf4 \x07 \x8e \x0e \x0c \xb1 \x4c \x34 \xd6 \xd6 \xf2 \x82 \x6a \x57 \xc1 \x82 \x06 \x6a \xbb \xcd \x95 \x84 \xcf " ,
130+ ) ;
131+
132+ // 24 words
133+ assert_eq ! (
134+ mnemonic_to_seed( "purity concert above invest pigeon category peace tuition hazard vivid latin since legal speak nation session onion library travel spell region blast estate stay" ) . unwrap( ) . as_ref( ) as & [ u8 ] ,
135+ b"\xae \x45 \xd4 \x02 \x3a \xfa \x4a \x48 \x68 \x77 \x51 \x69 \xfe \xa5 \xf5 \xe4 \x97 \xf7 \xa1 \xa4 \xd6 \x22 \x9a \xd0 \x23 \x9e \x68 \x9b \x48 \x2e \xd3 \x5e " ,
136+ ) ;
137+ }
96138}
0 commit comments