Browse Source

Documentation updates (Bech32, password generation)
- Getting-Started-with-MMGen.md (bech32)
- MMGen-Quick-Start-with-Regtest-Mode.md (error fix)
- Recovering-Your-Keys-Without-the-MMGen-Software.md (bech32, password generation)

MMGen 7 years ago
parent
commit
5f8c35c42c

+ 27 - 12
doc/wiki/using-mmgen/Getting-Started-with-MMGen.md

@@ -155,7 +155,7 @@ overestimated.
 
 #### <a name='a_ga'>Generate addresses (offline computer)</a>
 
-Now generate ten Segwit addresses with your just-created wallet:
+Now generate ten Segwit-P2SH addresses with your just-created wallet:
 
 	$ mmgen-addrgen --type=segwit 1-10
 	...
@@ -178,17 +178,22 @@ Now generate ten Segwit addresses with your just-created wallet:
 Note that the address range ‘1-10’ specified on the command line is included in
 the resulting filename.
 
-MMGen currently supports three address types: legacy uncompressed, compressed
-P2PKH and Segwit, denoted by the respective code letters ‘L’, ‘C’ and ‘S’.  For
-backwards compatibility, legacy addresses are generated by default.  To generate
-compressed addresses, specify `--type=compressed` on the command line.
+MMGen currently supports four Bitcoin address types: ‘legacy’ (uncompressed
+P2PKH), ‘compressed’ (compressed P2PKH), ‘segwit’ (P2SH-P2WPKH) and ‘bech32’
+(native Segwit), denoted by the code letters ‘L’, ‘C’, ‘S’ and ‘B’ respectively.
+Address types can be referred to either in full or by code letter.  To generate
+Bech32 addresses, for example, you can specify either `--type=bech32` or
+`--type=B` on the command line.
 
-Legacy addresses are of interest only for existing pre-Segwit MMGen
-installations, and it's unlikely you'll wish to generate them.  Compressed
-addresses are the preferred choice for Bitcoin Cash (BCH) wallets, since Bitcoin
-Cash doesn't support Segwit.
+For backwards compatibility, legacy addresses are generated by default, but this
+is probably not what you want unless you have a very old MMGen installation
+created before compressed address support was added.  Most new users will wish
+to generate either Segwit-P2SH (‘S’) or Bech32 (‘B’) addresses instead.  For
+BCH, which lacks Segwit support, compressed (‘C’) addresses are the best choice.
 
-	# legacy uncompressed
+Generation examples for various address types:
+
+	# legacy (uncompressed P2PKH)
 	$ mmgen-addrgen 1-10
 	...
 	$ cat '89ABCDEF[1-10].addrs'
@@ -204,6 +209,14 @@ Cash doesn't support Segwit.
 	  1   13jbRxWjswXtaDzLBJDboMcIe6nLohFb9M
 	...
 
+	# Bech32 (native Segwit)
+	$ mmgen-addrgen --type=bech32 1-10
+	...
+	$ cat '89ABCDEF-B[1-10].addrs'
+	89ABCDEF BECH32 {
+	  1   bc1q9c9273thh3xh86lk6z34raejz6j2s8ytgyb7my
+	...
+
 Note that for non-legacy address types the code letter is included in the
 filename.
 
@@ -279,8 +292,10 @@ addresses where the funds are stored in a separate file to use during signing.*
 
 Note that each address has a unique ID (the ‘MMGen ID’) consisting of a Seed ID,
 address type code letter, and index.  Addresses of different types may be
-imported into the same tracking wallet; since they're generated from different
-sub-seeds you needn't worry about key reuse.
+imported into the same tracking wallet, and since they're generated from different
+sub-seeds you needn't worry about key reuse.  For example, the addresses
+`89ABCDEF:S:1` and `89ABCDEF:B:1` are cryptographically distinct: no one but the
+wallet's owner can see that they were generated from the same seed.
 
 Now that your addresses are being tracked, you may go ahead and send some BTC to
 them over the Bitcoin network.  If you send 0.1, 0.2, 0.3 and 0.4 BTC

+ 2 - 1
doc/wiki/using-mmgen/MMGen-Quick-Start-with-Regtest-Mode.md

@@ -11,9 +11,10 @@ and stop the Bitcoin daemon automatically as needed.
 
 This tutorial provides a quick, hands-on introduction.
 
-1. Create the regtest blockchain and Bob and Alice's tracking wallets:
+1. Initialize MMGen regtest mode and start the regtest daemon:
 
 		$ mmgen-regtest setup
+		$ mmgen-regtest bob
 
 2. Generate Bob's MMGen wallet:
 

+ 86 - 52
doc/wiki/using-mmgen/Recovering-Your-Keys-Without-the-MMGen-Software.md

@@ -2,10 +2,13 @@
 
 * <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'>Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords)</a>
+	* <a href='#a_ss'>Convert the seed to binary (legacy uncompressed addresses)</a>
+	* <a href='#a_cs'>Scramble the seed and save to binary (non-legacy and altcoin addresses and passwords)</a>
 * <a href='#a_gk'>Generating the keys</a>
+	* <a href='#a_cr'>Checking the result (optional, address example)</a>
+	* <a href='#a_hpw'>Converting the hex value to a password (password example)</a>
 * <a href='#a_hw'>Hex to WIF by hand</a>
+	* <a href='#a_bcu'>Base-conversion utility</a>
 * <a href='#a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
 
 #### <a name='a_i'>Introduction</a>
@@ -48,8 +51,9 @@ case too:
 	  3  37wM8hwt69qwH7hZHAMn6RVdc8vMuM1CwJ
 	}
 
-Keys for MMGen's compressed ('C') addresses are generated in a similar way as
-Segwit ones, as you'll see below, so we won't consider that case separately.
+Keys for compressed ('C'), Bech32 (‘B’) and altcoin addresses, as well as
+passwords, are generated in a way analogous to Segwit keys, so for them you’ll
+proceed as with the Segwit case.
 
 Here's the seed itself in mmhex format, which you've stored in some safe place (on
 paper in a safe-deposit box, for example):
@@ -66,7 +70,7 @@ 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.
 
-> ####  <a name='a_ss'>Convert the seed to binary (legacy addresses)</a>
+> #### <a name='a_ss'>Convert the seed to binary (legacy uncompressed addresses)</a>
 
 > For the legacy addresses, we begin by converting the seed to binary form and
 > storing it in a file.  For that we use 'xxd', a handy tool for converting binary
@@ -75,7 +79,7 @@ Linux or other Unix-like system.
 
 	$ echo 456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > myseed.bin
 
-> ####  <a name='a_cs'>Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords)</a>
+> #### <a name='a_cs'>Scramble the seed and save to binary (non-legacy and altcoin addresses and passwords)</a>
 
 > Other address types and passwords are generated by first “scrambling” the
 > seed with a unique identifier, or “scramble string”, using the HMAC-SHA256
@@ -84,39 +88,46 @@ Linux or other Unix-like system.
 
 > 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
+> 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
+> 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:
-
-> | 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`     |
+> format, e.g. `b58`; the password length, e.g. `20`; and the password ID
+> string, e.g. `alice@fubar.io`, all separated by colons:
+
+> | Coin + Address type                      | Scramble String          |
+> |:-----------------------------------------|:-------------------------|
+> | BTC/BCH compressed                       | `compressed`             |
+> | BTC Segwit-P2SH                          | `segwit`                 |
+> | BTC native Segwit (Bech32)               | `bech32`                 |
+> | 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`            |
+
+> | Password type                            | Scramble String          |
+> |:-----------------------------------------|:-------------------------|
+> | 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, default 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:
+> follows using the `openssl` utility available by default on any Unix-based
+> system:
 
 	# 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
 
+	# E.g. for default-format passwords for Alice's email account:
+	$ echo -n 'b58:20:alice@fubar.io' | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > scrambled-round0.bin
+
 > Now add the ten rounds of sha256:
 
 	$ for i in 0 1 2 3 4 5 6 7 8 9; do
@@ -124,7 +135,7 @@ Linux or other Unix-like system.
 	  done
 	$ mv scrambled-round10.bin myseed.bin
 
-####  <a name='a_gk'>Generating the keys</a>
+#### <a name='a_gk'>Generating the keys</a>
 
 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
@@ -136,14 +147,18 @@ save it in binary form:
 A double SHA-256 hash of the first link gives us the key of our first address:
 
 	$ sha256sum link1.bin | xxd -r -p | sha256sum
-	05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 -
+	05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
+
+	# or, for the Segwit example:
+	b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0
 
-Or, in the Segwit case:
+	# or, for the password example:
+	bd60b8ba034bbb40498667ee600bc0cc0b99eb19164e8d412a48f16da4e00d6b
 
-	b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 -
+> #### <a name='a_cr'>Checking the result (optional, address example)</a>
 
-With 'mmgen-tool', we can easily generate the WIF key and address from this
-hexadecimal key and see that it's correct:
+> 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
@@ -151,7 +166,7 @@ hexadecimal key and see that it's correct:
 	$ mmgen-tool wif2addr 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
 	1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL # matches FE3C6545:L:1 above
 
-Or, in the Segwit case:
+> Or, for the Segwit example:
 
 	$ mmgen-tool hex2wif b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 compressed=1
 	L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
@@ -160,24 +175,41 @@ Or, in the Segwit case:
 	$ mmgen-tool wif2addr L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F segwit=1
 	3LpkKqtGkcCukRrgEFWyCajSApioiEWeTw # matches FE3C6545:S:1 above
 
-But since we're trying to do this without the MMGen software, we need to find
-some other way to do the hex-to-WIF conversion.  We could use one of many
-key-manipulation tools available on the Internet, such as [this one][01], or
-[this one][02]. Or we can do it ourselves: that will be covered in the next
-section.
+> But since we're trying to do this without the MMGen software, we need to find
+> some other way to do the hex-to-WIF conversion.  We could use one of many
+> key-manipulation tools available on the Internet, such as [this one][01], or
+> [this one][02]. Or we can 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:
+Meanwhile, let's finish generating hex keys for the rest of our addresses (or
+passwords).  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 - (uncompressed example)
-	42f1b998f0f9b7b27b5d0b92ffa8c1c6b96d7202789c41b6e6a6a402e318a04d - (Segwit example)
+	5db8fe3c8b52ccc98deab5afae780b6fbe56629e7ee1c6ed826fc2d6a81fb144 (uncompressed example)
+	42f1b998f0f9b7b27b5d0b92ffa8c1c6b96d7202789c41b6e6a6a402e318a04d (Segwit example)
+	9b59cec2e5d4f2a74f0d4eb2400efcf854f5a893bef0e9bf1ee83f72ca1118c3 (password example)
 
 And so on and so forth, until we've generated all the keys we need: three, in our case.
 
-####  <a name='a_hw'>Hex to WIF by hand</a>
+> #### <a name='a_hpw'>Converting the hex value to a password (password example)</a>
+
+> If it's passwords we're generating, we must now convert our hex key to the
+> desired password format.  This example uses the default base-58, 20-character
+> format and the key we generated above using the ID string `alice@fubar.io`.
+> We can convert the key to base 58 using our homemade `hex2b58.py` utility (see
+> <a href='#a_bcu'>Base-conversion utility</a> below):
+
+	$ ./hex2b58.py bd60b8ba034bbb40498667ee600bc0cc0b99eb19164e8d412a48f16da4e00d6b
+	DkFbZk2fDKQ7C55ASHQjhwcCdTsCiRq4ZLMMD5WQVAvv
+
+> The password is just the last 20 characters of the output:
+
+	dTsCiRq4ZLMMD5WQVAvv
+
+#### <a name='a_hw'>Hex to WIF by hand</a>
 
 Since we've chosen to convert our hex keys to WIF format manually, we have a bit
 of work ahead of us.  Let's begin with our just-generated key #1 from seed
@@ -264,8 +296,10 @@ clearer:
 
 	result = numtob58(num)
 
-Adapting our code a bit and putting it in a file gives us have a handy
-conversion utility we can use for any key:
+> #### <a name='a_bcu'>Base-conversion utility</a>
+
+> Adapting our code a bit and putting it in a file gives us have a handy
+> conversion utility we can use for any key:
 
 	$ cat hex2b58.py
 	#!/usr/bin/env python
@@ -281,7 +315,7 @@ conversion utility we can use for any key:
 	$ hex2b58.py 80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812
 	L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
 
-####  <a name='a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
+#### <a name='a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
 
 Our familiar base-10 system uses a series of ten symbols known as digits to
 represent numbers from zero to nine: