Skip to content
This repository has been archived by the owner on Feb 14, 2024. It is now read-only.

Proposal for Reversible (Palindromic) Mnemonics #52

Open
hatgit opened this issue Dec 3, 2018 · 1 comment
Open

Proposal for Reversible (Palindromic) Mnemonics #52

hatgit opened this issue Dec 3, 2018 · 1 comment

Comments

@hatgit
Copy link

hatgit commented Dec 3, 2018

I've developed a method to check if a mnemonic is also valid when the words are put into reverse order (not the entropy), where a given 12 or 24-word mnemonic could be valid both in little endian and big endian format. I've coined these Palindromic Mnemonics, but perhaps more user-friendly is "reversible mnemonics."

Purpose:
A checksum-valid reversible mnemonic allows two separate vaults to be connected to the same string of words, where all a users must do is enter the words in reverse order (the last word becomes first, second to last becomes second, and so on) to access the secondary (reversed words) vault. This utility could provide multiple use cases, including related to combinations with passphrases and plausible deniability, as well as conveniences for those wishing to use a separate vault tied to the same string of words.

Security
For any randomly generated 12-word mnemonic (128-bits of security) the chances of it also being reversible are 1/16, as a total of 4 bit positions must be identical (4 bits from the normal mnemonic, and another 4 bits from the reversed string). For 24-word mnemonics those values increase to 8 bits that need to match 8 bits from the reversed, leading to about 1 in every 256 mnemonics also being reversible. While the message space of valid reversible mnemonics should be 2^124 for 12 words, that search must still be conducted over a field of 2^128, as the hash-derived checksum values otherwise prevent a way to deterministically find valid reversible mnemonics without first going through invalid reversible ones to check. I think others should chime in on whether they believe there is any security loss, in terms of bits. I estimate at most it would be 4-bits for a 12-word mnemonic, but only if an attacker had a way to search only the space of valid reversible mnemonics (2^124). There could also be errors in my above assumptions, this is a work in progress and sharing it here to solicit feedback.

The following code can be used for testing, and run from terminal/command prompt it is pretty fast to find a valid reversible mnemonics, whereas on IDLE in Python on a 32-bit and 64-bit machine it could take a few seconds for 12 words and sometimes 10 minutes to find a valid 24-word reversible mnemonic: https://github.com/hatgit/BIP39_mnemonic_creation_light_python/blob/master/Palindromic_Mnemonic_experiment.py

Example randomly generated 12-word palindromic (reversible mnemonic):

Entropy length as hex without 0x pad: 32
Initial entropy as hex without pad: 39b2904bf37a267daf618fa03e5395a5
bytearray(b'9\xb2\x90K\xf3z&}\xafa\x8f\xa0>S\x95\xa5') <--- Entropy as bytes
Length of initial entropy as bytearray: 16
8dde9837e6f66605b28edb38573b76fff3504d74d94cb605f20a8061c88ddb9a <--- SHA-256 hash digest of entropy bytes
8 <--- Partial fragment of initial "byte" of hash
8 <--- First n bits of hash to convert to hex
1000 <--- Checksum (hex to bits)
Initial entropy + checksum = total bits: 001110011011001010010000010010111111001101111010001001100111110110101111011000011000111110100000001111100101001110010101101001011000
Length of total bits: 132
['00111001101', '10010100100', '00010010111', '11100110111', '10100010011', '00111110110', '10111101100', '00110001111', '10100000001', '11110010100', '11100101011', '01001011000']
Optional backup hex: 0x39b2904bf37a267daf618fa03e5395a5
Optional backup hex with checksum: 0x39b2904bf37a267daf618fa03e5395a58
Hash digest of initial entropy bytes: 8dde9837e6f66605b28edb38573b76fff3504d74d94cb605f20a8061c88ddb9a
[461, 1188, 151, 1847, 1299, 502, 1516, 399, 1281, 1940, 1835, 600]
defy nest base tragic pen disagree rural cradle parent verb tornado enrich
1101 <--- Last 4 bits of the first word to compare with checksum of mnemonic reverse order (hex to bits)
Palindromic mnemonic phase
['01001011000', '11100101011', '11110010100', '10100000001', '00110001111', '10111101100', '00111110110', '10100010011', '11100110111', '00010010111', '10010100100', '00111001101']
enrich tornado verb parent cradle rural disagree pen tragic base nest defy
Words reverse order = total bits: 010010110001110010101111110010100101000000010011000111110111101100001111101101010001001111100110111000100101111001010010000111001101
Words reverse order without last 4 bits = total bits: 01001011000111001010111111001010010100000001001100011111011110110000111110110101000100111110011011100010010111100101001000011100
gcc: 32
Entropy length as hex without 0x pad: 32
Initial entropy as hex without pad: 4b1cafca50131f7b0fb513e6e25e521c
bytearray(b'K\x1c\xaf\xcaP\x13\x1f{\x0f\xb5\x13\xe6\xe2^R\x1c') <--- Entropy as bytes
Length of initial entropy as bytearray: 16
dbbaacbd2043322a3247e7569af740193eb0db03d79923b83fecbf0de0b00465 <--- SHA-256 hash digest of entropy bytes
d <--- Partial fragment of initial "byte" of hash
d <--- First n bits of hash to convert to hex
1101 <--- Checksum reverse order (hex to bits)
1101 is equal to 1101. It is a palindromic mnemonic

@hatgit
Copy link
Author

hatgit commented Jan 19, 2019

Here is a working version of the above idea in javascript https://bcaventures.com/reversible-mnemonic.html also have a python version in on my repo. I wonder how fast this would run on the Nano? On Python IDLE it is slow, command line runs much faster. Any interest to add this as an advanced feature and one that a user could manually install on the hardware wallet?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant