Well, you guys were too slow and I just did it anyway. I also left out one critical reason: I really wanted this feature for myself! And I don't want to wait 2 months for it! I knew it would take me a day, and I'm sure someone would benefit from it, now. Also, it's not wasted effort -- it's more sample code for other users, and I got the fragment data structures ironed out which will be recycled when I implement it in the GUI.
I have tested the heck out of it, and successfully restored quite a few test wallets with it. Let me know what you think!
- Create M-of-N fragmented backup, for any value of N, and 2<=M<=8
- Works with any Armory *.wallet files, encrypted or not (will prompt for passphrase if encrypted)
- Creates N text files that can easily be opened and printed (sorry, no QR codes from terminal)
- Deterministic fragments means you can re-print lost fragments, or create more later (increase N)
- The git-commit version is put in the text file, in case you want to know exactly what version created it
- Error correction up to one character per line. Identifies which file&line has 2+ errors that can't be corrected automatically.
- Use the "unfrag" script right after "fragging" to test recombining various subsets of fragment files (for your own peace of mind)
- Endless error checking to make sure you get it right, or know what you did wrong.
Checkout the armoryd branch, and the scripts are in the extras directory.Sorry, this only works if you can run python scripts (possible in Windows, but you have to install some stuff).
$ python frag_wallet.py ~/.armory/armory_2QQkCkdt_.wallet 3 5
$ python unfrag_wallet.py wallet_2QQkCkdt_frag*.txt --test
$ python unfrag_wallet.py wallet_2QQkCkdt_frag*.txt
Use the
extras/frag_wallet.py script to break your paper backup in N files, and then you can immediately use the
extras/unfrag_wallet.py script to execute the recovery process on 20 different subsets of M fragment files. Without the --test option, it will ask you for the appropriate encryption options, and then create an armory*.wallet file that can imported natively into Armory.
Output of the fragging script$ python frag_wallet.py ~/.armory/armory_2QQkCkdt_.wallet 3 5
********************************************************************************
* Executing wallet-fragmenting script. Split your Armory wallet
* into N pieces, requiring any M to recover the wallet.
********************************************************************************
Found hash of current git commit: cf8ebe7cecf4bbd0457e8f984354aabb6e869e66
Here is the paper backup information for this wallet.
Root Key: hrfr dejf snwf rtun rtin dhri snor aihd wiut
otjf osws teaa gjei ihoa ffaa fojn swng tusg
Chaincode: kwig jorj agtj ragt kwrn dnhf ojgw tkwg snti
hdst aurh osfj ajhd nwra ogdd dsiw saff fwra
Will create 3-of-5 fragmentation of your paper backup.
Continue? [Y/n]: y
About to create the fragments. Any other info/identifiers you would
like to add to each of the fragment files? Enter it on the next line:
(Enter info or leave blank): This fragment belongs to forum user etotheipi
Fragment 1: wallet_2QQkCkdt_frag1_need_3.txt
ID: 0301 02d1 93af fa6f
x1: aiow gnrr haaj hthf hsnf rskj tooi kjta ajuf
x2: jgto kgir ekgs whod kdkr rwsr hase jdui irdh
x3: rugh hoas sghk sowr esdj kgnw hihe jnri jehu
x4: eagt fair gjan ifwd retd ewnd aofu gnur jdut
y1: owrn sowu nfrw oeeo gggs ikkw feii ueja hwns
y2: aogt osig wonk jkis fkur gfhk kowt gwdu tter
y3: eats akge jeot rdug oeki frgd onia einn rddj
y4: dkfj nsed tijj nfkn dkne nieu ittf gnrg gkhj
Fragment 2: wallet_2QQkCkdt_frag2_need_3.txt
ID: 0302 02d1 93af fa6f
x1: fadf gtko nwii gfwd nogk osak jodn tess dgdt
x2: wris jthf kgdu jiwj jeho suii ugnw rewd rtoi
...
Fragment 5: wallet_2QQkCkdt_frag5_need_3.txt
ID: 0305 02d1 93af fa6f
x1: hfte nufh utis sseh aweu jkgw ugno iaow kdue
x2: nkwo ndsw jief taar tfrg kejn knwg tfkt akuw
x3: ofat fgui iwsk eofg toeo widn gwnh hauk knhg
x4: ugut wfww rfon kdkg uddi rutn nefh ftid iorn
y1: oerh rdie rnth dnda iaws ateg utaf drhh grnu
y2: hrte iaoh khwa jrfa dfeh doej usit infh fjhj
y3: uije nsga suod jiid sjau rhwh swsg rfgn gwud
y4: nwnd eheo issg tdrw kdei fhoj joun iuit jirf
NOTE: If you rerun this fragment script on the same wallet
with the same fragments-required value, M, then you will
get the same fragments. Use this to replace fragments,
or using a higher N-value to produce more pieces (but you
MUST use the same M value!)
Each file looks like the following:Wallet ID: 2QQkCkdt
Create Date: 2013-Mar-06 12:29am
Git Commit: cf8ebe7cecf4bbd0457e8f984354aabb6e869e66
This fragment belongs to forum user etotheipi
This Fragment: #1
Fragments Needed: 3
Fragments Created: 5 (more fragments may have been created later)
The following is a single fragment of your wallet. Execute
the reconstruction script with any 3 of these fragment files
in the execution directory to recover your original wallet.
Each file can be reconstructed by manually typing the data
into a text editor. Only the following 9 lines (with prefixes)
are necessary in each file. All other data can be omitted.
ID: 0301 02d1 93af fa6f
x1: aiow gnrr haaj hthf hsnf rskj tooi kjta ajuf
x2: jgto kgir ekgs whod kdkr rwsr hase jdui irdh
x3: rugh hoas sghk sowr esdj kgnw hihe jnri jehu
x4: eagt fair gjan ifwd retd ewnd aofu gnur jdut
y1: owrn sowu nfrw oeeo gggs ikkw feii ueja hwns
y2: aogt osig wonk jkis fkur gfhk kowt gwdu tter
y3: eats akge jeot rdug oeki frgd onia einn rddj
y4: dkfj nsed tijj nfkn dkne nieu ittf gnrg gkhj
Run the unfrag test: (it works without the --test flag, if you have more than M files)
$ python unfrag_wallet.py wallet_2QQkCkdt_frag*.txt --test
********************************************************************************
* Restoring wallet from 3-of-N fragmented backup!
********************************************************************************
Recovered paper backup: 2QQkCkdt
hrfr dejf snwf rtun rtin dhri snor aihd wiut
otjf osws teaa gjei ihoa ffaa fojn swng tusg
kwig jorj agtj ragt kwrn dnhf ojgw tkwg snti
hdst aurh osfj ajhd nwra ogdd dsiw saff fwra
Testing reconstruction on 20 subsets:
Using fragments (0,1,3) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (2,3,4) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (1,3,4) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (1,2,3) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (0,1,2) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (0,3,4) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (0,3,4) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (2,3,4) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
Using fragments (0,2,4) Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
...
Recover the wallet:$ python unfrag_wallet.py wallet_2QQkCkdt_frag*.txt
********************************************************************************
* Restoring wallet from 3-of-N fragmented backup!
********************************************************************************
Recovered paper backup: 2QQkCkdt
hrfr dejf snwf rtun rtin dhri snor aihd wiut
otjf osws teaa gjei ihoa ffaa fojn swng tusg
kwig jorj agtj ragt kwrn dnhf ojgw tkwg snti
hdst aurh osfj ajhd nwra ogdd dsiw saff fwra
You have supplied more pieces (5) than needed for reconstruction (3).
Are you trying to run the reconstruction test instead of actually
recovering the wallet? If so, wallet recovery will be skipped. [Y/n] n
Proceeding with wallet recovery...
Would you like to encrypt the recovered wallet? [Y/n]: y
Choose an encryption passphrase:
Passphrase:
Again:
Set the key-stretching parameters:
Seconds to compute (default 0.25): 2
Max RAM used, in MB (default 32): 16
Creating new wallet...
Please wait while the address pool is being populated....
Created armory_2QQkCkdt_recovered.wallet
Exhaustive error catching and useful information$ python unfrag_wallet.py wallet_2QQkCkdt_frag*.txt --testnet
ERROR: Some files are duplicates!
wallet_2QQkCkdt_frag1_need_3.txt is Fragment 1
wallet_2QQkCkdt_frag2_need_3.txt is Fragment 1
wallet_2QQkCkdt_frag4_need_3.txt is Fragment 4
Aborting
$ python unfrag_wallet.py wallet_2QQkCkdt_frag*.txt --testnet
********************************************************************************
* Restoring wallet from 3-of-N fragmented backup!
********************************************************************************
(WARNING) armoryengine.py:1235 - ***Checksum error! Attempting to fix...
(WARNING) armoryengine.py:1259 - Checksum fix failed
ERROR: Uncorrectable error
File: wallet_2QQkCkdt_frag1_need_3.txt
Line: y2