iancoleman / slip39

A web tool for SLIP39 mnemonic shares
https://iancoleman.io/slip39/
MIT License
54 stars 23 forks source link

The master secret field should accept any text, not just a Hex string #8

Open grempe opened 4 years ago

grempe commented 4 years ago

The slip39-js library provides an encodeHex() function for strings. It should be possible to enter any string and have it be split to shares, and be able to be recovered from shares.

https://github.com/ilap/slip39-js/blob/master/test/test.js#L5

The example shows a string that is 16 Bytes (128 bits) in length, which is the minimum size according to the spec. If the string entered is less than 128 bits it should be padded to 128 bits, and the padding removed when the shares are decoded.

Currently, pasting in the test secret ABCDEFGHIJKLMNOP fails with a Master Secret must be at least 128 bits (32 hex chars) error.

Using an ASCII secret of sufficient length (but not Hex) ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP results in a decoded master secret of abcdef0000000000abcdef0000000000 which is incorrect.

According to the spec the original string master secret would need to be padded to The length of S in bits is at least 128 and a multiple of 16. and the padding would also need to be a multiple of 16.

iancoleman commented 4 years ago

Thanks for the question. It's a good one.

I had initialy included this option, but removed it for first release because there were some edge cases to discuss and clarify.

I think the best non-hex encoding is the base58 bip32 root key (using master secret bytes as the bip32 seed / entropy), since the the master secret is intended by the SLIP39 spec to be used in that way.

I feel that encodeHex is not a suitable function to be using in this tool. You'll notice that method uses charCodeAt (slip39_helper:L67). The documentation says this method "returns an integer between 0 and 65535 representing the UTF-16 code unit at the given index" which is not secure when converting the master secret chars to bytes because users aren't able to type the full 0-256 bits range for each byte into the master secret field.

I'm definitely open to further thoughts on this since hex encoding is not very user friendly.