From 28792479b3791f75f135535240070686a66e27db Mon Sep 17 00:00:00 2001 From: MMGen Date: Mon, 15 Jan 2018 17:42:57 +0300 Subject: [PATCH] modified: Install-MMGen-on-Debian-or-Ubuntu-Linux.md modified: Recovering-Your-Keys-Without-the-MMGen-Software.md --- Install-MMGen-on-Debian-or-Ubuntu-Linux.md | 2 +- ...ng-Your-Keys-Without-the-MMGen-Software.md | 106 +++++++++++------- 2 files changed, 66 insertions(+), 42 deletions(-) diff --git a/Install-MMGen-on-Debian-or-Ubuntu-Linux.md b/Install-MMGen-on-Debian-or-Ubuntu-Linux.md index 35e44a5..09dd563 100644 --- a/Install-MMGen-on-Debian-or-Ubuntu-Linux.md +++ b/Install-MMGen-on-Debian-or-Ubuntu-Linux.md @@ -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: diff --git a/Recovering-Your-Keys-Without-the-MMGen-Software.md b/Recovering-Your-Keys-Without-the-MMGen-Software.md index 51692b3..45aa2d9 100644 --- a/Recovering-Your-Keys-Without-the-MMGen-Software.md +++ b/Recovering-Your-Keys-Without-the-MMGen-Software.md @@ -3,7 +3,7 @@ * Introduction * Obtaining the binary seed * Convert the seed to binary (legacy addresses) - * Cook the seed and save to binary (Segwit and compressed addresses) + * Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords) * Generating the keys * Hex to WIF by hand * Converting an MMGen mnemonic to hexadecimal format @@ -75,30 +75,54 @@ Linux or other Unix-like system. $ echo 456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > myseed.bin -> #### Cook the seed and save to binary (Segwit and compressed addresses) +> #### Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords) -> 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 #### Generating the keys @@ -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)