modified: Install-MMGen-on-Debian-or-Ubuntu-Linux.md

modified:   Recovering-Your-Keys-Without-the-MMGen-Software.md
MMGen 2018-01-15 17:42:57 +03:00
commit 28792479b3
Signed by untrusted user who does not match committer: mmgen
GPG key ID: 62DBE9E5212F05BE
2 changed files with 70 additions and 46 deletions

@ -6,7 +6,7 @@
> Install fast ed25519 Python package (optional, but recommended for Monero addresses):
$ sudo pip install ed25519ll
$ sudo -H pip install ed25519ll
> Install the secp256k1 library:

@ -3,7 +3,7 @@
* <a href='#a_i'>Introduction</a>
* <a href='#a_rs'>Obtaining the binary seed</a>
* <a href='#a_ss'>Convert the seed to binary (legacy addresses)</a>
* <a href='#a_cs'>Cook the seed and save to binary (Segwit and compressed addresses)</a>
* <a href='#a_cs'>Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords)</a>
* <a href='#a_gk'>Generating the keys</a>
* <a href='#a_hw'>Hex to WIF by hand</a>
* <a href='#a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
@ -75,30 +75,54 @@ Linux or other Unix-like system.
$ echo 456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > myseed.bin
> #### <a name='a_cs'>Cook the seed and save to binary (Segwit and compressed addresses)</a>
> #### <a name='a_cs'>Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords)</a>
> For the other address types, we first “cook” the seed with an identifier
> string using the HMAC-SHA256 algorithm, add ten rounds of SHA256, and save the
> result in binary form. This can be done with the 'openssl' utility, also
> included by default on Unix-based systems:
> Other address types and passwords are generated by first “scrambling” the
> seed with a unique identifier, or “scramble string”, using the HMAC-SHA256
> algorithm. The scrambled seed is then given ten rounds of SHA256 to create the
> base seed used to generate our keys.
$ echo -n segwit | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > cooked-seed.bin
> Our first task then is to find out the correct scramble string for our coin
> and address type (or password). For BTC and BTC fork coins, the string will
> be simply the address type: 'compressed' or 'segwit'. For Bitcoin-derived
> altcoins, the string is the coin symbol and address type separated by a colon,
> e.g. 'ltc:legacy'. The strings for non-Bitcoin-derived altcoins are irregular
> and are listed in the table below. For passwords, the string is the password
> format, e.g. 'b58'; the password length, e.g. '20'; and the password ID
> string, e.g. 'alice@fubar.io', all separated by colons:
> If your addresses are of the compressed ('C') type, just use the string
> 'compressed' instead of 'segwit' as the 'echo' command's argument.
> | Coin+Addrtype / Passwd type+length+ID | | | Scramble String |
> |:----------------------------------------|-|-|:-------------------------|
> | BTC compressed | | | `compressed` |
> | BTC Segwit | | | `segwit` |
> | LTC legacy | | | `ltc:legacy` |
> | LTC compressed | | | `ltc:compressed` |
> | LTC Segwit | | | `ltc:segwit` |
> | DASH legacy | | | `dash:legacy` |
> | DASH compressed | | | `dash:compressed` |
> | ETH | | | `eth` |
> | ETC | | | `etc` |
> | XMR | | | `xmr:monero` |
> | ZEC-T | | | `zec:legacy` |
> | ZEC-Z | | | `zec:zcash_z` |
> | Base58 passwords for Alice's email acct.| | | `b58:20:alice@fubar.io` |
> | Same as above, half-length passwords | | | `b58:10:alice@fubar.io` |
> | Same as above, Base32 passwords | | | `b32:24:alice@fubar.io` |
> | Hex seed for Alice's PGP key | | | `hex:64:alice@gnupg` |
> Once we've determined the correct string, we scramble our seed with it as
> follows using the `openssl` utility, which is included by default on all
> Unix-based systems:
# E.g. for LTC Segwit addresses:
$ echo -n 'ltc:segwit' | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > scrambled-round0.bin
> Now add the ten rounds of sha256:
$ openssl dgst -sha256 -binary cooked-seed.bin > cooked-round1.bin
$ openssl dgst -sha256 -binary cooked-round1.bin > cooked-round2.bin
$ openssl dgst -sha256 -binary cooked-round2.bin > cooked-round3.bin
$ openssl dgst -sha256 -binary cooked-round3.bin > cooked-round4.bin
$ openssl dgst -sha256 -binary cooked-round4.bin > cooked-round5.bin
$ openssl dgst -sha256 -binary cooked-round5.bin > cooked-round6.bin
$ openssl dgst -sha256 -binary cooked-round6.bin > cooked-round7.bin
$ openssl dgst -sha256 -binary cooked-round7.bin > cooked-round8.bin
$ openssl dgst -sha256 -binary cooked-round8.bin > cooked-round9.bin
$ openssl dgst -sha256 -binary cooked-round9.bin > myseed.bin
$ for i in 0 1 2 3 4 5 6 7 8 9; do
openssl dgst -sha256 -binary scrambled-round${i}.bin > scrambled-round$((i+1)).bin
done
$ mv scrambled-round10.bin myseed.bin
#### <a name='a_gk'>Generating the keys</a>
@ -277,10 +301,10 @@ Thus the number 1234, for example, can be represented as follows:
Or in exponential notation:
4 x 10^0 +
3 x 10^1 +
2 x 10^2 +
1 x 10^3
4 x 10 +
3 x 10¹ +
2 x 10² +
1 x 10³
An MMGen seed mnemonic is a number too, only the “digits” it's comprised of come
from an alphabetically sorted series of 1626 words, the [Electrum wordlist][03],
@ -295,7 +319,7 @@ and ends like this:
(Type `mmgen-tool mn_printlist` to see the full list)
The words of the Electrum wordlist thus make up a base-1626 numbering system,
just like the ten digits that make up our familiar base-10 system.
just like the ten digits of our familiar base-10 system.
Here's the mnemonic of our seed (FE3C6545):
@ -320,27 +344,27 @@ along with the value of each word corresponding to its position in the wordlist:
All that remains is to multiply the values by increasing powers of 1626 and sum
the results:
200 x 1626^0 +
59 x 1626^1 +
1384 x 1626^2 +
221 x 1626^3 +
379 x 1626^4 +
1493 x 1626^5 +
1433 x 1626^6 +
1348 x 1626^7 +
1459 x 1626^8 +
386 x 1626^9 +
562 x 1626^10 +
439 x 1626^11
200 x 1626 +
59 x 1626¹ +
1384 x 1626² +
221 x 1626³ +
379 x 1626 +
1493 x 1626 +
1433 x 1626 +
1348 x 1626 +
1459 x 1626 +
386 x 1626 +
562 x 1626¹⁰ +
439 x 1626¹¹
While we could do this with pencil and paper, a few lines of Python code will
make life much easier:
While we could theoretically do the math with pencil and paper, a few lines of
Python will make our work much easier:
$ python
>>> sum = power = 0
>>> sum = exp = 0
>>> for word in 200,59,1384,221,379,1493,1433,1348,1459,386,562,439:
>>> sum += word * 1626 ** power
>>> power += 1
>>> sum += word * 1626 ** exp
>>> exp += 1
>>> print sum
92285275468192044354531703963345906238 # the result in decimal
>>> print '{:x}'.format(sum)