modified: Getting-Started-with-MMGen.md
modified: Home.md new file: Recovering-Keys-Without-MMGen.md modified: man-addrgen.md modified: man-keygen.md modified: man-passchg.md modified: man-txcreate.md modified: man-txsign.md modified: man-walletchk.md modified: man-walletconv.md modified: man-walletgen.md
parent
7039b8d9aa
commit
7713b88ecc
11 changed files with 212 additions and 11 deletions
|
|
@ -9,8 +9,8 @@
|
|||
* <a href='#a_st'>Send a transaction</a>
|
||||
|
||||
#### <a href='#a_af'>Additional Features</a>
|
||||
* <a href='#a_ms'>Using the mnemonic and seed features</a>
|
||||
* <a href='#a_ai'>Mnemonics and seeds: additional information</a>
|
||||
* <a href='#a_ms'>Using the mnemonic, seed and hexseed formats</a>
|
||||
* <a href='#a_ai'>Mnemonics, seeds and hexseeds: additional information</a>
|
||||
* <a href='#a_ic'>Incognito wallets</a>
|
||||
* <a href='#a_hi'>Hidden incognito wallets</a>
|
||||
|
||||
|
|
@ -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.
|
|||
|
||||
### <a name='a_af'>Additional Features</a>
|
||||
|
||||
#### <a name='a_ms'>Using the mnemonic and seed features:</a>
|
||||
#### <a name='a_ms'>Using the mnemonic, seed and hexseed formats:</a>
|
||||
|
||||
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
|
||||
|
||||
#### <a name='a_ai'>Mnemonics and seeds: additional information</a>
|
||||
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].
|
||||
|
||||
#### <a name='a_ai'>Mnemonics, seeds and hexseeds: additional information</a>
|
||||
|
||||
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
|
||||
|
|
|
|||
2
Home.md
2
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) |
|
||||
|
|
|
|||
173
Recovering-Keys-Without-MMGen.md
Normal file
173
Recovering-Keys-Without-MMGen.md
Normal file
|
|
@ -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 <hex key with chksum>`.
|
||||
|
||||
$ 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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] <addr,amt> ... [change addr] [addr file] ...
|
||||
OPTIONS:
|
||||
-h, --help Print this help message
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue