Bitcoin Forum
May 09, 2024, 09:43:01 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Seedshift - Encrypt/decrypt your BIP-39 seed words with a date shift cipher  (Read 362 times)
f3tus (OP)
Sr. Member
****
Offline Offline

Activity: 317
Merit: 275


View Profile
April 27, 2018, 02:17:02 PM
Last edit: April 02, 2022, 05:40:03 PM by f3tus
Merited by dbshck (5), ABCbits (3), TryNinja (2), vapourminer (1)
 #1

I wrote this Python script to encrypt BIP-39 mnemonic seed words in a plausibly deniable steganographic way using a date shift cipher, so I can safely store the seed words and not have to worry about a thief finding them. Optionally you can split the encrypted words into "2-out-of-3" sheets where you need to combine two sheets to recover your full mnemonic phrase. I'd rather not write everything I already wrote on GitHub again, so I'll just copy the readme from there. Note that you do not need this script to encrypt/decrypt your seed words with a date shift cipher, you can do all of it by hand on a piece of paper.

https://github.com/mifunetoshiro/Seedshift

Seedshift
Seedshift encrypts/decrypts your mnemonic seed words using a date shift cipher. It supports 12, 15, 18 and 24 word seeds (or their numbers) from the English BIP-39 wordlist of 2048 words, which you also need to download and put in the same folder as this script. To run the script, you need Python 3.x installed on your system.

Purpose
The purpose of this is to be able to safely write down your mnemonic seed words, not having to worry about a thief stealing your private keys, and in case something happens to you, allow your family to regain access to your wallet without needing to know a complex passphrase (TREZOR/Ledger), as all they need to know is the dates you used and the method to decrypt the words (pretty easy if it's in-family birthdays). Gather them around the table and do a couple of examples by hand. If you have a TREZOR or Ledger hardware wallet, having a complex passphrase as the "25th" word is more secure, but the more complex the passphrase is, the easier it is for your family or even you to not remember it at all (unless you wrote it down, which is a security risk in itself). If something were to happen to you, having a simpler passphrase (such as names or birthdates) would make it easier for your family to remember and access your wallet, and you could use both a passphrase and encrypt the seed words with a date shift cipher for extra security.

The script optionally splits the encrypted seed words into "2-out-of-3" recovery sheets, where each sheet stores two thirds of your encrypted seed words. You need to combine any two sheets to recover your full encrypted mnemonic phrase, a single sheet is not enough. Store each at a different safe place or hand out to your family members or attorney. Remember, you need at least two sheets, if you lose them, you will not be able to recover your wallet.

Example usage
Let's say
Code:
oppose duck hello neglect reveal key humor mosquito road evoke flock hedgehog
are your MetaMask seed words. You need to write them down somewhere and keep them safe, but writing the original words down is a security risk. If anyone finds your list of words, they can drain your wallet. Instead, use the English BIP-39 wordlist and encrypt them using a date shift cipher (you don't even need this script to do it, just do it by hand instead if you want).

The script takes dates in YYYY-MM-DD format and sorts them from oldest to newest (to use years before 1000, zero-fill them to 4-digit width, e.g. 0966 for year 966). In case of 24 seed words you can use up to 8 dates, in case of 18 seed words you can use up to 6, and in case of 12 seed words you can use up to 4. So let's say you use 3: your mother's birthday is 1963-07-10, your father's birthday is 1956-04-27, and your birthday is 1994-01-31.

The script will automatically sort the dates from oldest to newest (you don't have to input them in that order) and split each in 3 parts (year, month, day) which will be used to right-shift the words' positions in the English BIP-39 wordlist. In the above example:
Code:
1956, 4, 27, 1963, 7, 10, 1994, 1, 31
Given the above seed words and dates, the script will shift the words and output a table with the shifted words and their number:

Code:
| #  | Original | Number | Shifted | Encrypted | Number |
|----|----------|--------|---------|-----------|--------|
| 1  | oppose   | 1245   | 1956    | mosquito  | 1153   |
| 2  | duck     | 543    | 4       | dust      | 547    |
| 3  | hello    | 855    | 27      | hotel     | 882    |
| 4  | neglect  | 1185   | 1963    | maximum   | 1100   |
| 5  | reveal   | 1476   | 7       | rich      | 1483   |
| 6  | key      | 977    | 10      | kitten    | 987    |
| 7  | humor    | 889    | 1994    | hair      | 835    |
| 8  | mosquito | 1153   | 1       | mother    | 1154   |
| 9  | road     | 1496   | 31      | salute    | 1527   |
| 10 | evoke    | 625    | 1956    | dream     | 533    |
| 11 | flock    | 715    | 4       | flush     | 719    |
| 12 | hedgehog | 853    | 27      | hospital  | 880    |

Write down the encrypted words or their numbers instead of the original seed words and put them in a safe place. To decrypt them and get back your original seed words, the script will accept either the encrypted words or their numbers and the same dates you used to encrypt them (again, you can also do all of this by hand).

Note that the last encrypted word will most likely not be a valid checksum word (in the above example, `hospital` is valid, though). Having a valid checksum last word can provide plausible deniability in that the encrypted words are in fact encrypted, as they are valid BIP-39 seed words. You could even store a small amount of coins there, so if someone ever steals/uses your seed words, that's all they're going to think you have. The script can generate a valid last checksum word for your encrypted words if you want to replace it (if it's already valid, the script will tell you so, and you don't have to replace it), however, it's not possible to decrypt it back to the original checksum word. If you choose to replace it, you will have to remember or write down your original or encrypted last word!

Optionally, you can split the encrypted seed words into 2-out-of-3 recovery sheets. The script will output a table:

Code:
| Sheet 1             | Sheet 2             | Sheet 3             |
|---------------------|---------------------|---------------------|
| #1: mosquito : 1153 | #1: mosquito : 1153 | #2: dust : 547      |
| #2: dust : 547      | #3: hotel : 882     | #3: hotel : 882     |
| #4: maximum : 1100  | #4: maximum : 1100  | #5: rich : 1483     |
| #5: rich : 1483     | #6: kitten : 987    | #6: kitten : 987    |
| #7: hair : 835      | #7: hair : 835      | #8: mother : 1154   |
| #8: mother : 1154   | #9: salute : 1527   | #9: salute : 1527   |
| #10: dream : 533    | #10: dream : 533    | #11: flush : 719    |
| #11: flush : 719    | #12: hospital : 880 | #12: hospital : 880 |

Write down and store each sheet separately at a different location. Please remember that if you replaced the last encrypted seed word with a valid checksum word, you will have to remember or write down your original or encrypted last word somewhere as well!

Safe usage
Only run this script if you understand the code and what it does. Anyone can fork it, turn it malicious and trick you into using it if you don't understand the underlying code. This script does not require any networking modules to function. For safety reasons you should only run this script on an air-gapped computer that is not connected to the internet. Make sure to write down the encrypted seed words or numbers by hand, do not print them. Even better, stamp or engrave them on titanium plates to protect from fire or water damage.

Note that the encrypted words/numbers are not cryptographically secure, as they can be bruteforced to get the original words, but they do give you some protection from the common thief and some extra time to react in case of theft, etc. For reference, with 2 dates in 1900-2021 range there are about 1 billion possibilities (crackable in days), with 3 dates it's 14 trillion (crackable in years), and with 4 dates it's 158 quadrillion (crackable in the distant future with a supercomputer...).
1715247781
Hero Member
*
Offline Offline

Posts: 1715247781

View Profile Personal Message (Offline)

Ignore
1715247781
Reply with quote  #2

1715247781
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715247781
Hero Member
*
Offline Offline

Posts: 1715247781

View Profile Personal Message (Offline)

Ignore
1715247781
Reply with quote  #2

1715247781
Report to moderator
1715247781
Hero Member
*
Offline Offline

Posts: 1715247781

View Profile Personal Message (Offline)

Ignore
1715247781
Reply with quote  #2

1715247781
Report to moderator
1715247781
Hero Member
*
Offline Offline

Posts: 1715247781

View Profile Personal Message (Offline)

Ignore
1715247781
Reply with quote  #2

1715247781
Report to moderator
f3tus (OP)
Sr. Member
****
Offline Offline

Activity: 317
Merit: 275


View Profile
May 07, 2018, 04:18:29 PM
 #2

I added output (and decryption) of Unicode codepoints of Traditional Chinese BIP-39 characters at the same position as the English words in the English wordlist. For example, "canal" is number 265 in the English wordlist, and in the Traditional Chinese wordlist number 265 is "門", whose Unicode codepoint is "9580"; "decide" is number 455 in English, and 455 is "斯" in Traditional Chinese, whose Unicode codepoint is "65AF".

This means you can e.g. write "canal decide" as "9580 65AF" or "958065AF" or "95 80 65 AF", etc., basically obfuscating your seed words and make them look like random hex data, which if you convert into text just returns random nonsense text. All you need is just the standardized BIP-39 English and Traditional Chinese wordlists, you don't need to know or learn Chinese. Unicode is a text encoding standard that is used by pretty much everyone and everything, "斯" will always map to "65AF", there is no possibility to produce a different codepoint or for two characters to have identical codepoints. It's easy to convert the codepoints back to the Chinese characters as well. This is a safe way to encode your seed words with.

See the updated GitHub readme for more info: https://github.com/mifunetoshiro/Seedshift
btc_enigma
Hero Member
*****
Offline Offline

Activity: 688
Merit: 567


View Profile
May 10, 2018, 11:50:26 AM
 #3

Very interesting ! Like the concept of dates encoding the seed. Please note that in most wallets an additional passhphrase is asked to derive the seed from mnemonic from seed. I guess a PIN is used in most hardware wallets. So the procedure you outlined may be uncessary

f3tus (OP)
Sr. Member
****
Offline Offline

Activity: 317
Merit: 275


View Profile
May 10, 2018, 12:35:54 PM
Last edit: May 10, 2018, 02:29:25 PM by f3tus
 #4

Yes, of course, this is just an additional security measure to protect your seed words, to use in cases where the wallet does not offer an additional passphrase (e.g. MetaMask), or simply to obfuscate your seed words so if someone comes across your list, instead of seeing:
Quote
mosquito dust hotel maximum rich kitten hair mother salute dream flush hospital
and knowing those are seed words for a cryptocurrency private key (still with a missing passphrase - they could just return with a gun and force you to tell the passphrase), they'd find:
Quote
5B F6 5B 57 61 62 72 38 6C 2E 6F C3 4E 4E 53 48 95 CA 52 E2 93 2F 4E 95
and have zero clue what that is.

Edit: Actually, I think I'll write a new script that only obfuscates the seed words and maps them into BIP-39 Traditional Chinese Unicode codepoints, without encrypting them with a date shift cipher.
f3tus (OP)
Sr. Member
****
Offline Offline

Activity: 317
Merit: 275


View Profile
May 11, 2018, 09:59:31 AM
 #5

Edit: Actually, I think I'll write a new script that only obfuscates the seed words and maps them into BIP-39 Traditional Chinese Unicode codepoints, without encrypting them with a date shift cipher.
https://github.com/mifunetoshiro/bip39_obfuscator
btc_enigma
Hero Member
*****
Offline Offline

Activity: 688
Merit: 567


View Profile
May 11, 2018, 10:17:52 AM
 #6

Yes, of course, this is just an additional security measure to protect your seed words, to use in cases where the wallet does not offer an additional passphrase (e.g. MetaMask), or simply to obfuscate your seed words so if someone comes across your list, instead of seeing:
Quote
mosquito dust hotel maximum rich kitten hair mother salute dream flush hospital
and knowing those are seed words for a cryptocurrency private key (still with a missing passphrase - they could just return with a gun and force you to tell the passphrase), they'd find:
Quote
5B F6 5B 57 61 62 72 38 6C 2E 6F C3 4E 4E 53 48 95 CA 52 E2 93 2F 4E 95
and have zero clue what that is.

Edit: Actually, I think I'll write a new script that only obfuscates the seed words and maps them into BIP-39 Traditional Chinese Unicode codepoints, without encrypting them with a date shift cipher.

Actually if the robber sees 
Quote
5B F6 5B 57 61 62 72 38 6C 2E 6F C3 4E 4E 53 48 95 CA 52 E2 93 2F 4E 95
, he will know this is not a correct seed words and will force you to tell the correct seed words.

The easiest escape in this case is to have a sleath wallet that has some funds like 0.01 BTC and would have seed word list same as the actual wallet (except for one word). In case someone threatens you at gunpoint, you reveal the paper with the seed words of the sleath wallet and let him take the funds. The actual wallet funds are still safe, since only you know which word to substitute.


This was  also talked about Andreas, that a in person attack, is much more powerful rather than online hacking. As it is difficult to later reverse funds also (as in case of banks)


f3tus (OP)
Sr. Member
****
Offline Offline

Activity: 317
Merit: 275


View Profile
May 11, 2018, 10:29:04 AM
 #7

Actually if the robber sees 
Quote
5B F6 5B 57 61 62 72 38 6C 2E 6F C3 4E 4E 53 48 95 CA 52 E2 93 2F 4E 95
, he will know this is not a correct seed words and will force you to tell the correct seed words.
If a robber sees "5B F6 5B 57 61 62 72 38 6C 2E 6F C3 4E 4E 53 48 95 CA 52 E2 93 2F 4E 95," he won't have any idea what those numbers and letters represent. He won't have the slightest clue that they are seed words for your crypto wallet Wink
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!