diff --git a/Getting-Started-with-MMGen.md b/Getting-Started-with-MMGen.md
index 8af8b7f..6fe5060 100644
--- a/Getting-Started-with-MMGen.md
+++ b/Getting-Started-with-MMGen.md
@@ -9,8 +9,8 @@
* Send a transaction
#### Additional Features
-* Using the mnemonic and seed features
-* Mnemonics and seeds: additional information
+* Using the mnemonic, seed and hexseed formats
+* Mnemonics, seeds and hexseeds: additional information
* Incognito wallets
* Hidden incognito wallets
@@ -26,7 +26,7 @@ and no Bitcoin balance.
*NOTE: Beginning with v0.8.7a, MMGen supports testnet, allowing you to perform
the entire set of MMGen operations without risking real funds (free testnet
-coins may be obtained at [https://tpfaucet.appspot.com/][2]). To use this
+coins may be obtained at [https://tpfaucet.appspot.com/][02]). To use this
feature, start bitcoind with the -testnet option and sync the testnet blockchain
(about 9GB at this time of writing). To make MMGen use testnet instead of
mainnet, supply the `--testnet=1` option as the first argument to all MMGen
@@ -176,7 +176,7 @@ also).
TOTAL: 0 BTC
*While not covered in this introduction, note that it’s also possible to [import
-ordinary Bitcoin addresses into your tracking wallet][1]. This allows you to
+ordinary Bitcoin addresses into your tracking wallet][01]. This allows you to
move funds from another wallet directly to MMGen without having to go through
the network. To use it, you must save the keys corresponding to the addresses
where the funds are stored in a separate file for use during signing.*
@@ -308,7 +308,7 @@ by invoking the desired command with the `-h` or `--help` switch.
### Additional Features
-#### Using the mnemonic and seed features:
+#### Using the mnemonic, seed and hexseed formats:
Continuing our example above, generate a mnemonic from the default wallet:
@@ -387,10 +387,28 @@ Or you can do the same thing with 'mmgen-tool':
$ mmgen-tool str2id6 'XnyC NfPH piuW dQ2d nM47 VU'
0fe02f
-#### Mnemonics and seeds: additional information
+Beginning with version 0.9.0, export to and generation from hexadecimal
+(hexseed) format is also supported. Hexseed files are identical to seed files
+but encoded in hexadecimal rather than base 58. They bear the extension
+'.mmhex':
-MMGen commands that take mnemonic and seed data may receive the data from a
-prompt instead of a file. Just omit the file name and specify the input format:
+ $ cat FE3C6545.mmhex
+ afc3fe 456d 7f5f 1c4b fe3b c916 b875 60ae 6a3e
+
+You can easily check that a hexseed is correct by generating its Seed ID with
+standard command-line tools:
+
+ $ echo 456d 7f5f 1c4b fe3b c916 b875 60ae 6a3e | tr -d ' ' | xxd -r -p | sha256sum -b | xxd -r -p | sha256sum -b | cut -c 1-8
+ fe3c6545
+
+A hexseed can be used to easily generate keys even without the MMGen software,
+as explained in [this tutorial][03].
+
+#### Mnemonics, seeds and hexseeds: additional information
+
+MMGen commands that take mnemonic, seed or hexseed data may receive the data
+from a prompt instead of a file. Just omit the file name and specify the input
+format:
$ mmgen-walletconv -i words
...
@@ -531,5 +549,6 @@ Transaction signing uses the same syntax:
...
Signed transaction written to file 'ABCDEF[0.1].sigtx'
-[1]: https://github.com/mmgen/mmgen/wiki/Tracking-and-spending-ordinary-Bitcoin-addresses
-[2]: https://tpfaucet.appspot.com
+[01]: https://github.com/mmgen/mmgen/wiki/Tracking-and-spending-ordinary-Bitcoin-addresses
+[02]: https://tpfaucet.appspot.com
+[03]: Recovering-Keys-Without-MMGen
diff --git a/Home.md b/Home.md
index ca16987..56b8ff8 100644
--- a/Home.md
+++ b/Home.md
@@ -11,6 +11,8 @@
> #### [MMGen command help](MMGen-command-help)
+> #### [Recovering your keys without the MMGen software](Recovering-Keys-Without-MMGen)
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[**Forum**](https://bitcointalk.org/index.php?topic=567069.0) |
diff --git a/Recovering-Keys-Without-MMGen.md b/Recovering-Keys-Without-MMGen.md
new file mode 100644
index 0000000..70b464b
--- /dev/null
+++ b/Recovering-Keys-Without-MMGen.md
@@ -0,0 +1,173 @@
+If you're considering using MMGen and are a Bitcoiner with a normal, healthy
+degree of paranoia, then the following question will probably come to mind:
+“What if I have funds in an MMGen wallet and I lose the software? How do I
+recover my coins?”
+
+Let's take this scenario to its logical extreme and assume you've lost all
+backup copies of the software, MMGen's project page has disappeared from Github
+(or been hacked) and no other repositories or copies are available on the
+Internet. The following primer will show you how to recover your keys in the
+event this unlikely combination of circumstances ever occurs.
+
+#### Obtaining the raw seed
+
+To keep things simple, we'll assume you have a copy of your seed in hexadecimal
+(mmhex) format. If your only backup's in Base-58 (mmseed) or mnemonic format,
+an additional base-conversion step will be required. If your only backup is an
+MMGen wallet, it will need to be decrypted. Both of these cases will be covered
+in a future tutorial.
+
+Okay, so let's say we have a 128-bit seed with Seed ID FE3C6545, and funds in
+the first five addresses of this seed. Here are the addresses:
+
+ FE3C6545 {
+ 1 1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL
+ 2 15EfKymfe3v7mqCaL174hTWSgBLFAHvtaR
+ 3 1CUDd6nPHdP5pT7nN8k2AA5WdKRaKPjmea
+ 4 1Kw2cPuBwY44iWJrzUk7bb2qfpaH6yZuyR
+ 5 1BNApVR8REhT1BzWP2CvAHKt6ZRxjpubew
+ }
+
+And here's the seed in hex format, which we've stored in some safe place (on
+paper in a safe-deposit box, for example):
+
+ afc3fe 456d 7f5f 1c4b fe3b c916 b875 60ae 6a3e
+
+Now our task is to generate keys for the five addresses so we can spend our
+coins. This task is divided into two parts: 1) generating the keys in
+hexadecimal format, and 2) converting the hex keys to wallet interchange
+(WIF) format so they can be imported into Bitcoin Core or some other wallet.
+
+We'll solve this task using standard command-line utilities available on any
+Linux or other Unix-like system.
+
+The first thing we must do is convert the key to binary form and store it in a
+file. For that we use 'xxd', a handy tool for converting binary to hex and vice
+versa:
+
+ $ echo 456d 7f5f 1c4b fe3b c916 b875 60ae 6a3e | xxd -r -p > myseed.bin
+
+Note that we've omitted the key's checksum.
+
+#### Generating the keys
+
+The MMGen key-generating algorithm uses a chain of SHA-512 hashes with double
+SHA-256 branches to generate the keys from which each address is derived. To
+obtain the chain's first link, we take a single SHA-512 hash of the seed, which
+we save in binary form:
+
+ $ sha512sum myseed.bin | xxd -r -p > link1.bin
+
+A double SHA-256 hash of the link gives us the key of our first address:
+
+ $ sha256sum link1.bin | xxd -r -p | sha256sum
+ 05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 -
+
+With 'mmgen-tool', we can easily generate the WIF key and address from this
+hexadecimal key and see that it's correct:
+
+ $ ./mmgen-tool hex2wif 05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
+ 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
+
+ ./mmgen-tool wif2addr 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
+ 1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL # matches FE3C6545:1 above
+
+But since we've lost the MMGen software, we must do the hex-to-WIF conversion
+some other way. We could use one of many key-manipulation tools available on
+the Internet, such as [this one][01], or [this one][02] (bear in mind that MMGen
+currently uses uncompressed public keys, and this must be specified when
+converting the hex key to WIF format). Or we could do it ourselves: that will
+be covered in the next section.
+
+Meanwhile, let's finish generating hex keys for the rest of our addresses. To
+get the next key, we generate the next link in the chain from the first link and
+take its double SHA-256 hash, just as we did for the first one:
+
+ $ sha512sum link1.bin | xxd -r -p > link2.bin
+ $ sha256sum link2.bin | xxd -r -p | sha256sum
+ 5db8fe3c8b52ccc98deab5afae780b6fbe56629e7ee1c6ed826fc2d6a81fb144 -
+
+And so on and so forth, until we've generated all five keys.
+
+#### Hex to WIF the hard way
+
+If we've chosen to convert our hex keys to WIF format manually, then we have a
+bit of work ahead of us. Let's use our just-generated key #1 as an example:
+
+ 05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
+
+WIF format prepends hex '80' to the beginning of the key. If the key is
+associated with a compressed public key, it also appends '01'. Since MMGen uses
+uncompressed public keys, we just append the '80':
+
+ 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
+
+The Base58Check format invented by Satoshi for Bitcoin addresses and keys
+contains a checksum, which we now generate by taking the first four bytes (eight
+characters) of the double SHA-256 of the above result:
+
+ $ echo 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 | xxd -r -p | sha256sum | xxd -r -p | sha256sum | cut -c 1-8
+ 7b818629
+
+The checksum gets appended to the end, giving us the following final result:
+
+ 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629
+
+The last step is to convert all this into Base 58. Satoshi created Base-58
+encoding for convenient and error-free writing down and dictating of Bitcoin
+keys and addresses. He began with a Base-62 alphabet consisting of the ten
+digits plus the upper and lower case Latin letters (10 + 26 + 26 = 62):
+
+ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijlkmnopqrstuvwxyz
+
+Since '0' (zero) is easily confused with capital 'O' visually, and capital 'I'
+with lowercase 'l', he dropped those characters, leaving the following 58:
+
+ 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
+
+With '0' gone, '1' now represents decimal zero, '2' represents decimal one, and
+so forth all the way up to 'z', representing decimal fifty-seven. So the
+familiar '1' at the beginning of most Bitcoin addresses is actually just a
+prepended zero!
+
+Now all that remains is to convert our hexadecimal key to decimal and then to
+Base 58 using this alphabet. This can be done in just four lines of code you can
+try out at the Python prompt:
+
+ $ python
+ >>> b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
+ >>> num = int('8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629',16)
+ >>> result = [b58a[num / 58**e % 58] for e in range(60)]
+ >>> print ''.join(reversed(result)).lstrip('1')
+ 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
+
+The variable 'b58a' holds the Base 58 alphabet, 'num' is the key converted to
+decimal, the third line is the base conversion routine proper, and the last line
+reverses the result, converts it to a string and strips off the leading zeroes
+('1's). As you can see, the output matches the key we generated above.
+
+Those who know a bit of programming but are unfamiliar with Python might find
+the following base conversion code clearer:
+
+ def numtob58(n):
+ result = []
+ while n:
+ result = result + [b58a[n % 58]] # divide 'n' by 58 and take the remainder
+ n = n / 58
+ return result
+
+ result = numtob58(num)
+
+Putting our code into a file gives us have a handy conversion utility we can use
+by calling `hex2b58.py `.
+
+ $ cat hex2b58.py
+ #!/usr/bin/env python
+ import sys
+ b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
+ num = int(sys.argv[1],16)
+ result = [b58a[num / 58**e % 58] for e in range(60)]
+ print ''.join(reversed(result)).lstrip('1')
+
+[01]: https://github.com/casascius/Bitcoin-Address-Utility
+[02]: https://github.com/matja/bitcoin-tool
diff --git a/man-addrgen.md b/man-addrgen.md
index 90c1e7e..c07591b 100644
--- a/man-addrgen.md
+++ b/man-addrgen.md
@@ -45,6 +45,7 @@
Format FileExt Valid codes
------ ------- -----------
Brainwallet .mmbrain mmbrain,brainwallet,brain,bw,b
+ HexSeedFile .mmhex seedhex,hexseed,hex,mmhex
IncogWallet .mmincog mmincog,incog,icg,i
IncogWalletHex .mmincox mmincox,incox,incog_hex,xincog,ix,xi
IncogWalletHidden None incog_hidden,hincog,ih,hi
diff --git a/man-keygen.md b/man-keygen.md
index a49963e..8f224bf 100644
--- a/man-keygen.md
+++ b/man-keygen.md
@@ -46,6 +46,7 @@
Format FileExt Valid codes
------ ------- -----------
Brainwallet .mmbrain mmbrain,brainwallet,brain,bw,b
+ HexSeedFile .mmhex seedhex,hexseed,hex,mmhex
IncogWallet .mmincog mmincog,incog,icg,i
IncogWalletHex .mmincox mmincox,incox,incog_hex,xincog,ix,xi
IncogWalletHidden None incog_hidden,hincog,ih,hi
diff --git a/man-passchg.md b/man-passchg.md
index 16e5c86..8cad6be 100644
--- a/man-passchg.md
+++ b/man-passchg.md
@@ -35,6 +35,7 @@
Format FileExt Valid codes
------ ------- -----------
Brainwallet .mmbrain mmbrain,brainwallet,brain,bw,b
+ HexSeedFile .mmhex seedhex,hexseed,hex,mmhex
IncogWallet .mmincog mmincog,incog,icg,i
IncogWalletHex .mmincox mmincox,incox,incog_hex,xincog,ix,xi
IncogWalletHidden None incog_hidden,hincog,ih,hi
diff --git a/man-txcreate.md b/man-txcreate.md
index 303e8a9..3694515 100644
--- a/man-txcreate.md
+++ b/man-txcreate.md
@@ -1,4 +1,4 @@
- MMGEN-TXCREATE: Create a BTC transaction with outputs to specified addresses
+ MMGEN-TXCREATE: Create a transaction with outputs to specified Bitcoin or MMGen addresses
USAGE: mmgen-txcreate [opts] ... [change addr] [addr file] ...
OPTIONS:
-h, --help Print this help message
diff --git a/man-txsign.md b/man-txsign.md
index ed54a11..aa91e34 100644
--- a/man-txsign.md
+++ b/man-txsign.md
@@ -58,6 +58,7 @@
Format FileExt Valid codes
------ ------- -----------
Brainwallet .mmbrain mmbrain,brainwallet,brain,bw,b
+ HexSeedFile .mmhex seedhex,hexseed,hex,mmhex
IncogWallet .mmincog mmincog,incog,icg,i
IncogWalletHex .mmincox mmincox,incox,incog_hex,xincog,ix,xi
IncogWalletHidden None incog_hidden,hincog,ih,hi
diff --git a/man-walletchk.md b/man-walletchk.md
index 4a85766..5251bf5 100644
--- a/man-walletchk.md
+++ b/man-walletchk.md
@@ -34,6 +34,7 @@
Format FileExt Valid codes
------ ------- -----------
Brainwallet .mmbrain mmbrain,brainwallet,brain,bw,b
+ HexSeedFile .mmhex seedhex,hexseed,hex,mmhex
IncogWallet .mmincog mmincog,incog,icg,i
IncogWalletHex .mmincox mmincox,incox,incog_hex,xincog,ix,xi
IncogWalletHidden None incog_hidden,hincog,ih,hi
diff --git a/man-walletconv.md b/man-walletconv.md
index acdde98..365352e 100644
--- a/man-walletconv.md
+++ b/man-walletconv.md
@@ -44,6 +44,7 @@
Format FileExt Valid codes
------ ------- -----------
Brainwallet .mmbrain mmbrain,brainwallet,brain,bw,b
+ HexSeedFile .mmhex seedhex,hexseed,hex,mmhex
IncogWallet .mmincog mmincog,incog,icg,i
IncogWalletHex .mmincox mmincox,incox,incog_hex,xincog,ix,xi
IncogWalletHidden None incog_hidden,hincog,ih,hi
diff --git a/man-walletgen.md b/man-walletgen.md
index f6105c4..f1d93dc 100644
--- a/man-walletgen.md
+++ b/man-walletgen.md
@@ -37,6 +37,7 @@
Format FileExt Valid codes
------ ------- -----------
Brainwallet .mmbrain mmbrain,brainwallet,brain,bw,b
+ HexSeedFile .mmhex seedhex,hexseed,hex,mmhex
IncogWallet .mmincog mmincog,incog,icg,i
IncogWalletHex .mmincox mmincox,incox,incog_hex,xincog,ix,xi
IncogWalletHidden None incog_hidden,hincog,ih,hi