I've been working on an alternative to BIP39. These are my main motivations:
- I wanted to get rid of the wordlist, and replace it with a more language agnostic representation that's still relatively easy to read.
- Much more compact representation.
- Use a configurable n-of-m representation of the root key instead of passwords
Additionally, the prototype that I have has these features:
- Very compact representation: 16bit overhead for each share
- 4 version bits. This prototype is currently version 0.
- Supports n-of-m shares, up to 4-of-4.
- Very good safety against typos: The probability that a typo of a 2-of-m share is undetected is 1 in 262144.
- Very compact QR code: 128 bit encode into 45 Alphanumeric characters, so version 2 is enough. E.g. see https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=BASABMIVAPPOTUFJULOHHIFOBRIGIJPAJIHLUTOLHAJAJ
- Accidentally mixing two shares that were constructed from different secret is undetected with a probability of 1 in 65536.
- the proquints representation is optional, e.g. base 58 is also possible.
Here is a sample random 128 bit secret encoded in 2-of-3 shares:
batod kibab namus jupag pahot zumas filur fuhuk hojid
bipap bupar bugul nadun lokil kuhoj jilub buzih pijuv
bonik foguf mutal fasoz gaham dugar mubab dakap bofifEach share consists of 9 proquints (see
https://arxiv.org/html/0901.4016) encoding 16 bits each. The first proquint is special: it encodes the version, share ID, number of required shares to reconstruct the secret, and checksum.
- Version: the first 4 bit. Since the first 4 bit are encoded by the first letter, the letter for version 0 is always 'b'.
- Share ID: 2 bits to identify the ID of the share (1, 2, 3, 4).
- The next 10 bits encode the number of required shares (2 bit), and 1-byte checksum of the reconstructed secret. These 10 bit are XORed with 10 bits of the checksum of the share when the 10 bits were set to zero. When decoding the message from two shares, the number of required shares and 1-byte checksum of the secret is reconstructed for each share by XORing back with the share's checksum. Both shares must decode the same 10 bits to be valid. Additionally, the first byte of the reconstructed secret's checksum must match for a reconstruction to be successfull. Thus, the actual safety of this checksumming system is 2^10 * 2^8 = 2^18 = 262144 (there is a 1 in 262144 chance that a typo remains undetected).
I have a prototypical implementation in Ruby here:
https://github.com/martinus/bitcoin-mnemonic/blob/master/bitcoin-mnemonic.rb.
What do you think? I appreciate any comments!