Getting-Started-with-MMGen.md 20 KB

Table of Contents

Basic Operations

Additional Features

Basic Operations

Generate a wallet (offline computer):

On your offline computer, generate a wallet with a random seed:

    $ mmgen-walletgen
    ...
    Wallet saved to file '89ABCDEF-76543210[256,3].mmdat'

"89ABCDEF" is the Seed ID; "76543210" is the Key ID. These are randomly generated, so your IDs will of course be different than the fictitious ones used here.

The Seed ID never changes and will be used to identify all keys/addresses generated by this seed. The Key ID changes when the wallet's password or hash preset are changed.

"256" is the seed length; "3" is the scrypt hash preset. These values are configurable: type 'mmgen-walletgen --help' for details.

Generate addresses (offline computer):

Now generate ten addresses with your just-created wallet:

    $ mmgen-addrgen 89ABCDEF-76543210[256,3].mmdat 1-10
    ...
    Address data saved to file '89ABCDEF[1-10].addrs'

    $ cat '89ABCDEF[1-10].addrs'
    89ABCDEF {
      1    16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE
      2    1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc
      3    1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N
      4    14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s
      5    1PeI55vtp2bX2uKDkAAR2c6ekHNYe4Hcq7
      6    1FEqfEsSILwXPfMvVvVuUovzTaaST62Mnf
      7    1LTTzuhMqPLwQ4IGCwwugny6ZMtUQJSJ1
      8    1F9495H8EJLb54wirgZkVgI47SP7M2RQWv
      9    1JbrCyt7BdxRE9GX1N7GiEct8UnIjPmpYd
      10   1H7vVTk4ejUbQXw45I6g5qvPBSe9bsjDqh
    }

Note that the address range, "1-10", is reflected in the resulting filename. MMGen addresses are identified by their seed ID and index number, separated by a colon. In this example, "89ABCDEF:1" is the MMGen equivalent of Bitcoin address 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE, "89ABCDEF:2" the equivalent of 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc, and so forth.

Let's say you've decided to transfer some BTC into the first four addresses above. Your first step, then, will be to import these addresses into the tracking wallet on your online machine so their balances will be visible. For convenient identification, you've chosen to provide the addresses with the labels "Donations", "Storage 1", "Storage 2" and "Storage 3".

Make a copy of the file:

    $ cp '89ABCDEF[1-10].addrs' my.addrs

and edit the copy using your favorite text editor to look like this:

    $ cat my.addrs
    # My first MMGen addresses
    89ABCDEF {
      1    16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE  Donations
      2    1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc  Storage 1
      3    1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N  Storage 2
      4    14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s  Storage 3
    }

Note the comment beginning with a '#' symbol. Comments may be placed at the ends of lines as well. Note also that rows in the list may be arranged in any order: addresses need not be consecutive.

Copy this file onto a USB stick and transfer it to your online computer.

Import addresses (online computer):

On your online computer, go to your bitcoind data directory and move any existing 'wallet.dat' file out of the way. Start bitcoind and let it generate a new 'wallet.dat', which you'll use as your tracking wallet. Import your four addresses into the new tracking wallet with the command:

    $ mmgen-addrimport my.addrs

These addresses will now be tracked by bitcoind. Any BTC transferred to them will show up in your listing of address balances. Balances can be viewed with the 'mmgen-tool' utility:

    $ mmgen-tool listaddresses
    No addresses with balances!

The 'showempty' option shows all tracked addresses, even ones with no balances, so the four imported addresses should now show up on the listing:

    $ mmgen-tool listaddresses showempty=1
    ADDRESS        COMMENT                            BALANCE
    89ABCDEF:1     Donations                          0
    89ABCDEF:2     Storage 1                          0
    89ABCDEF:3     Storage 2                          0
    89ABCDEF:4     Storage 3                          0

If you have any existing addresses with balances, you'll want to track them too. Make a plain list of these addresses, one address per line, and import the list into the tracking wallet using 'mmgen-addrimport -l'.

    $ mmgen-addrimport --rescan -l my_existing_addrs_with_balances

NOTE: The '--rescan' option forces a rescan of the entire block chain, which is required for all addresses with existing balances. Since the rescanning process is very slow, you'll save yourself a great deal of time by always importing new addresses BEFORE spending into them.

Continue in this fashion until you've imported all addresses with balances into your tracking wallet.

Create a transaction (online computer):

Now that your existing addresses are imported, you're ready to create a test transaction using the 'mmgen-txcreate' command. Note that transactions are harmless until they're signed and broadcast to the network, so feel free to experiment with different transactions using different combinations of inputs and outputs.

First of all you'll want to examine your balances. Note that 'mmgen-tool listaddresses' shows only MMGen address balances; to view all balances, including your non-MMGen ones, use the 'mmgen-txcreate' command:

    $ mmgen-txcreate -i

A list of all unspent outputs will appear, along with a menu allowing you to sort the outputs by four criteria: transaction ID, address, amount and transaction age. Your overall balance in BTC appears at the top of the screen. The list may be viewed in a pager or printed to file. For a wallet with ten unspent outputs, the display might look something like this:

    UNSPENT OUTPUTS (sort order: reverse amount)  Total BTC: 39.72
     Num  TX id  Vout    Address                            Amount (BTC)  Age(days)
     1)   04f97185... 2  1F93Znz8PI5Pnvv8ZAJsb74EzKpmRMLFbk  10           320
     2)   dd900544... 1  194Fceqx86jqIWumphUmfVyFMjAAbMLcSE   9.9287435   7
     3)   7ec81a8f... 0  1FhIkRabPSZhhUsA6qvukmfK4T4PZLbC4M   7.26        17
     4)   64094b55... 0  16JSUJdGMbxUBEQatAR5sGE89tbSIsLHqg   3.15        140
     5)   fd687c65... 1  1QKAtU66aUntCBx9m6TfEIf3gQuCNWCVDY   3.15        140
     6)   9a8f20e2... 1  1FMNDFz1yUywjJSprjvYY9t1yxkE8GGIwT   3.15        140
     7)   03a7c51a... 3  1svxnSdKVIcMs6qWYA7qLzA29orXbzXUm    1.6382466   54
     8)   9955f06c... 2  18nWPLQGUzI7X1Rcm4zmVV6Z3xhokdYx9G   1.2         27
     9)   8a4ab4f5... 0  13S9HNu7PQn1aJ4qILfhqRSakXwvSTnbwJ   0.23033     3
     10)  5bfe5621... 1  1FV1Lhs6Dnc9gMxjJTo6h4nTeIjJbQ1PgV   0.01        42

    Sort options: [t]xid, [a]mount, a[d]dress, [A]ge, [r]everse, [M]mgen addr
    View options: [g]roup, show [m]mgen addr
    (Type 'q' to quit sorting, 'p' to print to file, 'v' to view in pager):

Now let's actually create a transaction. Let's say you've decided to gradually begin moving your 39.72 BTC balance into your shiny new MMGen wallet with seed ID 89ABCDEF.

Before moving any funds into your MMGen wallet, you should back it up in several places and possibly on several media too: paper, flash memory or CD-ROM, for example. Of course the wallet should have a passphrase. Otherwise, anyone who gains physical access to one of your backups can easily steal your coins.

Recall that there's no limit to the number of addresses you can generate with your seed. You've wisely determined that having many addresses with relatively small balances is a Good Idea. So you've decided to begin by breaking up the address with the largest balance, 10 BTC, into three roughly equal parts, sending it to the addresses labeled "Storage 1", "Storage 2" and "Storage 3" (89ABCDEF:2, 89ABCDEF:3 and 89ABCDEF:4).

To refresh your memory, here are the three addresses in question:

    $ cat my.addrs
    # My first MMGen addresses
    89ABCDEF {
      1    16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE  Donations
      2    1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc  Storage 1
      3    1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N  Storage 2
      4    14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s  Storage 3
    }

The following command will send 3.3 BTC to the first two addresses and the remainder of the transaction's 10 BTC input to the third, subtracting a default transaction fee of 0.001 BTC:

    $ mmgen-txcreate 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc,3.3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N,3.3 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s

The bare address with no amount is the change address. MMGen will compute the change amount (3.399 BTC in this case) automatically.

Note that the above transaction can be written much more elegantly and concisely using MMGen addresses in place of their Bitcoin equivalents:

    $ mmgen-txcreate 89ABCDEF:2,3.3 89ABCDEF:3,3.3 89ABCDEF:4

After hitting ENTER you'll be presented with the same display produced by the '-i' option above, plus an interactive menu. After quitting with 'q', you'll be prompted to choose the transaction's inputs.

    Enter a range or space-separated list of outputs to spend:

Find the input with the 10 BTC balance in the list. This is input 1), so type '1' and ENTER. After several more prompts and confirmations 'mmgen-txcreate' will exit with the message:

    Transaction data saved to file 'tx_1EDCBA[6.6].raw'

Note that the transaction has a unique ID, and the non-change spend amount, 6.6 BTC, is conveniently included in the filename.

Sign a transaction (offline computer):

Now copy the raw transaction you've just created to a USB stick and transfer it to your offline computer for signing. You need to find the key for your transaction's one input address, 1F9495H8EJL.... If the key in question is in a bitcoin 'wallet.dat', there's an included command (a modified version of the well-known pywallet utility) that will conveniently extract it for you:

    $ mmgen-pywallet -k wallet.dat
    ...
    wallet.dat secret keys saved to file wd_EDBC983A[102].keys

You've in fact extracted a list of all of the wallet's 102 keys here, but that's not a problem, since the unused keys will be ignored (you can extract only the keys you need using the '--keys-for-addrs' option). Now go ahead and sign the transaction using this list of keys.

    $ mmgen-txsign -k wd_EDBC983A[102].keys tx_1EDCBA[6.6].raw
    ...
    Signed transaction saved to file tx_ABCDEF[0.1].sig

Note that 'mmgen-pywallet's output is just a flat list of keys. So if you have several Bitcoin wallets with balances, you can just dump all their keys and merge them into a single file which you can use to sign all future transactions with wallet.dat inputs:

    $ mmgen-pywallet -k wallet1.dat
    $ mmgen-pywallet -k wallet2.dat
    $ mmgen-pywallet -k wallet3.dat
    $ cat wd_*.keys > all_keys

For your future transactions with MMGen address inputs, you'll list the MMGen seed source (wallet, mnemonic or seed file) on the command line after the transaction file, and the required keys will be generated automatically, as in this example:

    $ mmgen-txsign tx_9D2C3A[1.23].raw B73B58EA-125FB230[256,3].mmdat
    ...
    Signed transaction saved to file tx_9D2C3A[1.23].sig

Transactions may contain a mixture of MMGen and non-MMGen inputs as well as inputs with more than one MMGen seed ID. Just provide a seed source for each seed ID on the command line.

Eventually, when you've placed all your BTC under MMGen control, you'll never have deal with keys directly again, because MMGen generates all keys on the fly using the seed.

Send a transaction (online computer):

Now you're ready for the final step: broadcasting the transaction to the network. Copy the 'tx_*.sig' file to your online computer, start bitcoind, if it's not running, and execute the command:

    $ mmgen-txsend tx_1EDCBA[6.6].sig

Like all MMGen commands, 'mmgen-txsend' is interactive, so you'll be asked for confirmation before the transaction is actually sent.

Once the transaction's confirmed by the network, your three new MMGen addresses will appear on the listing of 'mmgen-txcreate -i'. Type 'm' at the menu to see them displayed in MMGen format.

Congratulations! You've performed your first MMGen transaction and placed your first funds under MMGen's control.

Additional Features

Using the mnemonic and seed features:

Continuing our example above, generate a mnemonic from the wallet:

    $ mmgen-walletchk -m '89ABCDEF-76543210[256,3].mmdat'
    ...
    Mnemonic data saved to file '89ABCDEF.mmwords'

    $ cat 89ABCDEF.mmwords
    pleasure tumble spider laughter many stumble secret bother after search
    float absent path strong curtain savior worst suspend bright touch away
    dirty measure thorn

Note: a 128- or 192-bit seed will generate a shorter mnemonic of 12 or 18 words. You may generate a wallet with these seed lengths using the '-l' option to 'mmgen-walletgen'.

Though some consider 128 bits of entropy to provide adequate security for the foreseeable future, you should stick to the default 256-bit seed length if you're not planning to use the mnemonic feature.

NOTE: MMGen mnemonics are generated from the Electrum wordlist, but using ordinary base conversion instead of Electrum's more complicated algorithm.

Generate addresses 1-11 of seed 89ABCDEF using the mnemonic instead of the wallet:

    $ mmgen-addrgen 89ABCDEF.mmwords 1-11
    ...
    Address data saved to file '89ABCDEF[1-11].addrs'

Compare the first ten addresses with those earlier generated by the wallet. You'll see they're the same.

Regenerate a lost wallet using the mnemonic:

    $ mmgen-walletgen 89ABCDEF.mmwords
    ...
    Wallet saved to file '89ABCDEF-01234567[256,3].mmdat'

Note that the regenerated wallet has a different Key ID but of course the same Seed ID.

Seed files bear the extension '.mmseed' and are listed on the command line the same way mnemonic files are.

A seed file for a 256-bit seed looks like this:

    $ cat 8B7392ED.mmseed
    f4c84b C5ZT wWpT Jsoi wRVw 2dm9 Aftd WLb8 FggQ eC8h Szjd da9L

And for a 128-bit seed:

    $ cat 8E0DFB78.mmseed
    0fe02f XnyC NfPH piuW dQ2d nM47 VU

As you can see, the latter file is short enough to be memorized or written down on a scrap of paper. From the unix command line, you can test your memory using the seed's checksum ("0fe02f" in this example) as follows:

    $ echo -n XnyC NfPH piuW dQ2d nM47 VU | tr -d ' ' |sha256sum |cut -c 1-6
    0fe02f

Or better yet, use 'mmgen-tool' to do the same thing:

    $ mmgen-tool str2id6 'XnyC NfPH piuW dQ2d nM47 VU'
    0fe02f

Mnemonics and seeds — additional information:

With the '-m' or '-s' option, MMGen commands that take mnemonic and seed data may receive the data from a prompt instead of a file.

MMGen commands that produce mnemonic and seed data may be forced to print it to standard output instead of file with the '-S' option. This feature has intentionally been made optional to safeguard against looking-over-the-shoulder, Van Eyck phreaking and other side-channel attacks. MMGen commands never print private data to the screen unless explicitly asked to.

The output of any MMGen command may be written to a directory of your choice using the '-d' option. For example, on a Linux system you can use '-d /dev/shm' to write key and seed data to volatile memory instead of disk. This also has obvious security benefits, ensuring that no sensitive data remains on disk after your computer's been powered down.

Incognito wallets

A wallet exported to incognito format is indistinguishable from random data, allowing you to hide your wallet at an offset within a random-filled file or partition. Thus both the location and nature of the data are unknown to a potential attacker, who in addition cannot be sure that the file or partition contains anything useful at all, barring any inside knowledge.

An incognito wallet with a reasonably secure password could even be hidden on unencrypted cloud storage. Hiding your wallet at some offset in a 1 GB file increases the difficulty of any attack by a factor of one billion, assuming a potential attacker even knows or suspects you have an MMGen wallet hidden there.

If you plan to store your incognito wallet in an insecure location such as cloud storage, you're advised to use a strong scrypt preset and a strong password. These can be changed using the 'mmgen-passchg' utility:

    $ mmgen-passchg -p 5 89ABCDEF-01234567[256,3].mmdat
    ...
    Hash preset has changed (3 -> 5)
    Enter new passphrase: <my new strong passphrase>
    ...
    Wallet saved to file '89ABCDEF-87654321[256,5].mmdat'

The new scrypt preset is indicated by the numeral '5' after the comma in the new wallet filename. Now export your new strengthened wallet to incognito format:

    $ mmgen-walletchk -g 89ABCDEF-87654321[256,5].mmdat
    ...
    Incognito wallet data saved to file '89ABCDEF-87654321-ECA86420[256,5].mmincog'

'ECA86420' is the Incog ID. This can be used by the 'mmgen-tool' utility to search through a file or partition and locate your wallet if you've forgotten where you hid it (see below).

Repeat the same export operation, but output to hexadecimal:

    $ mmgen-walletchk -X 89ABCDEF-87654321[256,5].mmdat
    ...
    Incognito wallet data saved to file '89ABCDEF-87654321-CA86420E[256,5].mmincox'

    $ cat 89ABCDEF-87654321-1EE402F4[256,5].mmincox
    6772 edb2 10cf ad0d c7dd 484b cc7e 42e9
    4fe6 e07a 1ce2 da02 6da7 94e4 c068 57a8
    3706 c5ce 56e0 7590 e677 6c6e 750a d057
    b43a 21f9 82c7 6bd1 fe96 bad9 2d54 c4c0

Note that the Incog ID is different here: it's generated from the init vector, which is a different random number each time, making the incog data as a whole different as well. This allows you to store your incog data in multiple insecure locations without having repeated "random" wallet data give you away.

As you can see, this data is ideally suited for a paper wallet. Just print it out on a printer and you're ready to go.

Your incognito wallet (whether hex or binary) can be used just like any other MMGen wallet, mnemonic or seed file. Generate addresses with it like this:

    $ mmgen-addrgen 89ABCDEF-87654321-CA86420E[256,5].mmincox 100-110
    ...
    Generated 10 addresses
    Addresses written to file '89ABCDEF[100-110].addrs'

Or sign a transaction like this:

    $ mmgen-txsign tx_FABCDE[0.3].raw 89ABCDEF-87654321-CA86420E[256,5].mmincox
    ...
    Signed transaction saved to file tx_FABCDE[0.3].sig

You can create an incognito wallet and hide it at a specified offset in a file or partition in one convenient operation using the '-G' ('--export-incog-hidden') option. Here's how you'd hide a wallet in a 1GB file filled with random data. First create the random file:

    $ dd if=/dev/urandom of=random.dat bs=1K count=1M

Or better yet, use 'mmgen-tool' to do the same job but with some additional user entropy and a progress meter:

    $ mmgen-tool -r40 rand2file random.dat 1G

Now export your wallet to hidden incognito format, hiding it in this 1GB random file at offset 123456789:

    $ mmgen-walletchk -G random.dat,123456789 89ABCDEF-87654321[256,5].mmdat
    ...
    Incog ID: ED1F2ACB
    Data written to file 'random.dat' at offset 123456789

The altered random file can now be uploaded to a cloud storage service, for example, or some other, preferably non-public, location on the Net (in a real-life situation you'll choose a less obvious offset than '123456789' though, won't you?).

If at some point in the future you download this file to recover your wallet data but find you've forgotten the offset, you can recover it using the saved Incog ID as follows:

    $ mmgen-tool find_incog_data random.dat ED1F2ACB
    ...
    Incog data for ID ED1F2ACB found at offset 123456789

Hidden incog wallets are almost as convenient to use as ordinary ones. Generating ten addresses with your hidden incog data is as easy as this:

    $ mmgen-addrgen -G random.dat,123456789,256 32-42

Use the same syntax to sign a transaction:

    $ mmgen-txsign -G random.dat,123456789,256 tx_ABCDEE[0.1].raw
    ...
    Signed transaction saved to file tx_ABCDEE[0.1].sig

Note that the seed length parameter here will always be '256' unless you're using a non-default seed length.