>> (p.1)
    Author Topic: [ANN] M-of-N "Fragmented Backups" now in Armory (command-line only)  (Read 8195 times)
    etotheipi (OP)
    Legendary
    *
    expert
    Offline Offline

    Activity: 1428
    Merit: 1108


    Core Armory Developer


    View Profile WWW
    March 06, 2013, 05:36:29 PM
    Last edit: April 08, 2013, 04:02:06 PM by etotheipi
     #1

    Background: "Fragmenting" your wallet backup was going to be a feature in Armory's new wallets, but other priorities have come up and I can't finish the new wallets yet.  But I still wanted to make this feature available since the math was fully implemented.  Rather than complicate the GUI with more backup options that will have to change once again when I finally do finish the new wallets, I decided to make a command-line utility.  

    Re-post of this message.  Reposting because I figured this was in demand by a wider audience, and there's plenty of folks in the D&TD forum that don't mind using command-line tools (though, this is the only command-line-required function of Armory).

    The "correctness" of the utility should be self-evident.  The output of the "fragging" script is N files in the execution directory.  The input to the "unfragging" script is to have M+ files in the execution directory.  And the unfragging script has a built in "test" so you can see it work correctly on multiple subsets of fragments.    And it puts the git-commit version in the output so you know exactly what version created it (though, it will forever be in the master branch now, and I don't expect it to change).




    Features:
    • Create M-of-N fragmented backup, for any value of N, and 2<=M<=8 (uses Shamir's Secret Sharing)
    • 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)
    • Having M-1 files gives attacker no advantage to brute forcing your wallet any more than having zero pieces.  For a 7-of-20 backup, having 6 pieces is no more useful than having 0.
    • 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.

    Also, there is a completely dependency-less script "sss.py", which contains everything needed to restore these fragments.  If you have python installed, you can run that script in isolation (default python installation, without installing Armory).  The reason for making it, is it's easy to print off for the ultra-paranoid that think that the git-repo won't be available in the future for some reason.  The script doesn't do the unfragging for you, but it has everything you need in a couple hundred lines of code and could be printed out on one or two sheets of paper.



    Use Cases:
    To be used with regular Armory wallets.
    • 2-of-3:  Instead of backing up your wallet to one place where anyone who finds it can recover your funds, create three pieces, of which any two is sufficient for recovering the wallet.  Keep one in your house, one in a safe-deposit box at a bank, and give one to a family member.
    • 5-of-7:  If a company has 7 members, require a large majority of them to recover the funds.  There will still be one or two people managing the offline computer, but it allows that offline computer to be backed up without risk of any one (or 4) members to steal the money.
    • 3-of-5 or 3-of-6:  A nice description here.

    This still assumes a single-sig wallet, and that there is probably an offline computer with an encrypted version of it, accessible by you.  The problem is that it needs to be backed up, and you don't want your backups to become the weakest point in the vulnerability chain.   "Linked wallets" with multi-sig/multi-device is still in the works, and this is not a replacement for that.  This is simply an alternative to backing up your wallet if you're concerned about physical security.




    The scripts are in the extras directory.  They have been pushed to the master branch.
    Sorry, this only works if you can run python scripts (possible in Windows, but you have to install all the python packages listed here for windows, and copy the .pyd file from the installation directory).

    Usage:
    Code:
    $ 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
    Code:
    $  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!)

    $ ls -l
    ...
    -rw-rw-r-- 1 alan alan     1008 Mar  6 11:32 wallet_2QQkCkdt_frag1_need_3.txt
    -rw-rw-r-- 1 alan alan     1008 Mar  6 11:32 wallet_2QQkCkdt_frag2_need_3.txt
    -rw-rw-r-- 1 alan alan     1008 Mar  6 11:32 wallet_2QQkCkdt_frag3_need_3.txt
    -rw-rw-r-- 1 alan alan     1008 Mar  6 11:32 wallet_2QQkCkdt_frag4_need_3.txt
    -rw-rw-r-- 1 alan alan     1008 Mar  6 11:32 wallet_2QQkCkdt_frag5_need_3.txt
    ...

    Each file looks like the following:
    Code:
    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)
    Code:
    $  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 (0,2,4)  Reconstructed (first line): hrfr dejf snwf rtun rtin dhri snor aihd wiut
       ...

    Recover the wallet:
    Code:
    $ 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
    Code:
    $ 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

    Code:
    $ 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

    Founder and CEO of Armory Technologies, Inc.
    Armory Bitcoin Wallet: Bringing cold storage to the average user!
    Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

    Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
Page 1
Viewing Page: 1