Skip to content

Commit

Permalink
Fix the version of bip32 private_key generation
Browse files Browse the repository at this point in the history
We set the version BIP32_VER_TEST_PRIVATE for testnet/regtest
BIP32 privkey generation with libwally-core, and set
BIP32_VER_MAIN_PRIVATE for mainnet.
For litecoin, we also set it like bitcoin else.
  • Loading branch information
trueptolemy authored and rustyrussell committed Mar 18, 2019
1 parent 04c6017 commit 92c08cd
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ provide appropriate suffixes for JSON input fields.
- You can no longer make giant unpayable "wumbo" invoices.
- CLTV of total route now correctly evaluated when finding best route.
- `riskfactor` arguments to `pay` and `getroute` now have an effect.
- Fixed the version of bip32 private_key to BIP32_VER_MAIN_PRIVATE: we used
BIP32_VER_MAIN_PRIVATE for bitcoin/litecoin mainnet, and BIP32_VER_TEST_PRIVATE
for others. (PR #2436)

### Security

Expand Down
22 changes: 17 additions & 5 deletions bitcoin/chainparams.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
#include <ccan/str/str.h>
#include <string.h>

/* Version codes for BIP32 extended keys in libwally-core.
* Stolen from wally_bip32.h in libwally-core*/
#define BIP32_VER_MAIN_PUBLIC 0x0488B21E
#define BIP32_VER_MAIN_PRIVATE 0x0488ADE4
#define BIP32_VER_TEST_PUBLIC 0x043587CF
#define BIP32_VER_TEST_PRIVATE 0x04358394

const struct chainparams networks[] = {
{.network_name = "bitcoin",
.bip173_name = "bc",
Expand All @@ -21,7 +28,8 @@ const struct chainparams networks[] = {
.max_payment = AMOUNT_MSAT_INIT(0xFFFFFFFFULL),
/* "Lightning Charge Powers Developers & Blockstream Store" */
.when_lightning_became_cool = 504500,
.testnet = false},
.testnet = false,
.bip32_key_version = {.bip32_pubkey_version = BIP32_VER_MAIN_PUBLIC, .bip32_privkey_version = BIP32_VER_MAIN_PRIVATE}},
{.network_name = "regtest",
.bip173_name = "bcrt",
.genesis_blockhash = {{{.u.u8 = {0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f}}}},
Expand All @@ -32,7 +40,8 @@ const struct chainparams networks[] = {
.max_funding = AMOUNT_SAT_INIT((1 << 24) - 1),
.max_payment = AMOUNT_MSAT_INIT(0xFFFFFFFFULL),
.when_lightning_became_cool = 1,
.testnet = true},
.testnet = true,
.bip32_key_version = {.bip32_pubkey_version = BIP32_VER_TEST_PUBLIC, .bip32_privkey_version = BIP32_VER_TEST_PRIVATE}},
{.network_name = "testnet",
.bip173_name = "tb",
.genesis_blockhash = {{{.u.u8 = {0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00}}}},
Expand All @@ -42,7 +51,8 @@ const struct chainparams networks[] = {
.dust_limit = { 546 },
.max_funding = AMOUNT_SAT_INIT((1 << 24) - 1),
.max_payment = AMOUNT_MSAT_INIT(0xFFFFFFFFULL),
.testnet = true},
.testnet = true,
.bip32_key_version = {.bip32_pubkey_version = BIP32_VER_TEST_PUBLIC, .bip32_privkey_version = BIP32_VER_TEST_PRIVATE}},
{.network_name = "litecoin",
.bip173_name = "ltc",
.genesis_blockhash = {{{.u.u8 = {0xe2, 0xbf, 0x04, 0x7e, 0x7e, 0x5a, 0x19, 0x1a, 0xa4, 0xef, 0x34, 0xd3, 0x14, 0x97, 0x9d, 0xc9, 0x98, 0x6e, 0x0f, 0x19, 0x25, 0x1e, 0xda, 0xba, 0x59, 0x40, 0xfd, 0x1f, 0xe3, 0x65, 0xa7, 0x12 }}}},
Expand All @@ -53,7 +63,8 @@ const struct chainparams networks[] = {
.max_funding = AMOUNT_SAT_INIT(60 * ((1 << 24) - 1)),
.max_payment = AMOUNT_MSAT_INIT(60 * 0xFFFFFFFFULL),
.when_lightning_became_cool = 1320000,
.testnet = false},
.testnet = false,
.bip32_key_version = {.bip32_pubkey_version = BIP32_VER_MAIN_PUBLIC, .bip32_privkey_version = BIP32_VER_MAIN_PRIVATE}},
{.network_name = "litecoin-testnet",
.bip173_name = "tltc",
.genesis_blockhash = {{{.u.u8 = { 0xa0, 0x29, 0x3e, 0x4e, 0xeb, 0x3d, 0xa6, 0xe6, 0xf5, 0x6f, 0x81, 0xed, 0x59, 0x5f, 0x57, 0x88, 0x0d, 0x1a, 0x21, 0x56, 0x9e, 0x13, 0xee, 0xfd, 0xd9, 0x51, 0x28, 0x4b, 0x5a, 0x62, 0x66, 0x49 }}}},
Expand All @@ -64,7 +75,8 @@ const struct chainparams networks[] = {
.max_funding = AMOUNT_SAT_INIT(60 * ((1 << 24) - 1)),
.max_payment = AMOUNT_MSAT_INIT(60 * 0xFFFFFFFFULL),
.when_lightning_became_cool = 1,
.testnet = true}
.testnet = true,
.bip32_key_version = {.bip32_pubkey_version = BIP32_VER_TEST_PUBLIC, .bip32_privkey_version = BIP32_VER_TEST_PRIVATE}}
};

const struct chainparams *chainparams_for_network(const char *network_name)
Expand Down
8 changes: 8 additions & 0 deletions bitcoin/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
#include <common/amount.h>
#include <stdbool.h>

struct bip32_key_version {
u32 bip32_pubkey_version;
u32 bip32_privkey_version;
};

struct chainparams {
const char *network_name;
const char *bip173_name;
Expand All @@ -21,6 +26,9 @@ struct chainparams {

/* Whether this is a test network or not */
const bool testnet;

/* Version codes for BIP32 extended keys in libwally-core*/
const struct bip32_key_version bip32_key_version;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions hsmd/hsm_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ hsmstatus_client_bad_request,,description,wirestring
hsmstatus_client_bad_request,,len,u16
hsmstatus_client_bad_request,,msg,len*u8

#include <bitcoin/chainparams.h>
# Start the HSM.
hsm_init,11
hsm_init,,bip32_key_version,struct bip32_key_version

#include <common/bip32.h>
hsm_init_reply,111
Expand Down
21 changes: 18 additions & 3 deletions hsmd/hsmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ static struct {
struct ext_key bip32;
} secretstuff;

/* Version codes for BIP32 extended keys in libwally-core.
* It's not suitable to add this struct into client struct,
* so set it static.*/
static struct bip32_key_version bip32_key_version;

/*~ We keep track of clients, but there's not much to keep. */
struct client {
/* The ccan/io async io connection for this client: it closes, we die. */
Expand Down Expand Up @@ -351,7 +356,16 @@ static void populate_secretstuff(void)
u32 salt = 0;
struct ext_key master_extkey, child_extkey;

assert(bip32_key_version.bip32_pubkey_version == BIP32_VER_MAIN_PUBLIC
|| bip32_key_version.bip32_pubkey_version == BIP32_VER_TEST_PUBLIC);

assert(bip32_key_version.bip32_privkey_version == BIP32_VER_MAIN_PRIVATE
|| bip32_key_version.bip32_privkey_version == BIP32_VER_TEST_PRIVATE);

/* Fill in the BIP32 tree for bitcoin addresses. */
/* In libwally-core, the version BIP32_VER_TEST_PRIVATE is for testnet/regtest,
* and BIP32_VER_MAIN_PRIVATE is for mainnet. For litecoin, we also set it like
* bitcoin else.*/
do {
hkdf_sha256(bip32_seed, sizeof(bip32_seed),
&salt, sizeof(salt),
Expand All @@ -360,7 +374,7 @@ static void populate_secretstuff(void)
"bip32 seed", strlen("bip32 seed"));
salt++;
} while (bip32_key_from_seed(bip32_seed, sizeof(bip32_seed),
BIP32_VER_TEST_PRIVATE,
bip32_key_version.bip32_privkey_version,
0, &master_extkey) != WALLY_OK);

/* BIP 32:
Expand All @@ -380,7 +394,8 @@ static void populate_secretstuff(void)
* separate keychains for these should use the external one for
* everything.
*
* - m/iH/0/k corresponds to the k'th keypair of the external chain of account number i of the HDW derived from master m.
* - m/iH/0/k corresponds to the k'th keypair of the external chain of
* account number i of the HDW derived from master m.
*/
/* Hence child 0, then child 0 again to get extkey to derive from. */
if (bip32_key_from_parent(&master_extkey, 0, BIP32_FLAG_KEY_PRIVATE,
Expand Down Expand Up @@ -522,7 +537,7 @@ static struct io_plan *init_hsm(struct io_conn *conn,
* definitions in hsm_client_wire.csv. The format of those files is
* an extension of the simple comma-separated format output by the
* BOLT tools/extract-formats.py tool. */
if (!fromwire_hsm_init(msg_in))
if (!fromwire_hsm_init(msg_in, &bip32_key_version))
return bad_req(conn, c, msg_in);

maybe_create_new_hsm();
Expand Down
4 changes: 3 additions & 1 deletion lightningd/hsm_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <errno.h>
#include <hsmd/gen_hsm_wire.h>
#include <inttypes.h>
#include <lightningd/bitcoind.h>
#include <lightningd/hsm_control.h>
#include <lightningd/log.h>
#include <lightningd/log_status.h>
Expand Down Expand Up @@ -92,7 +93,8 @@ void hsm_init(struct lightningd *ld)
err(1, "Could not subd hsm");

ld->hsm_fd = fds[0];
if (!wire_sync_write(ld->hsm_fd, towire_hsm_init(tmpctx)))
if (!wire_sync_write(ld->hsm_fd, towire_hsm_init(tmpctx,
&ld->topology->bitcoind->chainparams->bip32_key_version)))
err(1, "Writing init msg to hsm");

ld->wallet->bip32_base = tal(ld->wallet, struct ext_key);
Expand Down
7 changes: 7 additions & 0 deletions wire/fromwire.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "wire.h"
#include <bitcoin/chainparams.h>
#include <bitcoin/preimage.h>
#include <bitcoin/pubkey.h>
#include <bitcoin/shadouble.h>
Expand Down Expand Up @@ -288,3 +289,9 @@ struct amount_sat fromwire_amount_sat(const u8 **cursor, size_t *max)
return sat;
}

void fromwire_bip32_key_version(const u8** cursor, size_t *max,
struct bip32_key_version *version)
{
version->bip32_pubkey_version = fromwire_u32(cursor, max);
version->bip32_privkey_version = fromwire_u32(cursor, max);
}
7 changes: 7 additions & 0 deletions wire/towire.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "wire.h"
#include <assert.h>
#include <bitcoin/chainparams.h>
#include <bitcoin/preimage.h>
#include <bitcoin/shadouble.h>
#include <bitcoin/tx.h>
Expand Down Expand Up @@ -193,3 +194,9 @@ void towire_amount_sat(u8 **pptr, const struct amount_sat sat)
{
towire_u64(pptr, sat.satoshis); /* Raw: primitive */
}

void towire_bip32_key_version(u8 **pptr, const struct bip32_key_version *version)
{
towire_u32(pptr, version->bip32_pubkey_version);
towire_u32(pptr, version->bip32_privkey_version);
}
5 changes: 5 additions & 0 deletions wire/wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define LIGHTNING_WIRE_WIRE_H
#include "config.h"
#include <bitcoin/block.h>
#include <bitcoin/chainparams.h>
#include <bitcoin/privkey.h>
#include <bitcoin/pubkey.h>
#include <bitcoin/shadouble.h>
Expand Down Expand Up @@ -73,6 +74,8 @@ void towire_bitcoin_tx(u8 **pptr, const struct bitcoin_tx *tx);
void towire_wirestring(u8 **pptr, const char *str);
void towire_siphash_seed(u8 **cursor, const struct siphash_seed *seed);

void towire_bip32_key_version(u8 **cursor, const struct bip32_key_version *version);

const u8 *fromwire(const u8 **cursor, size_t *max, void *copy, size_t n);
u8 fromwire_u8(const u8 **cursor, size_t *max);
u16 fromwire_u16(const u8 **cursor, size_t *max);
Expand Down Expand Up @@ -115,4 +118,6 @@ struct bitcoin_tx *fromwire_bitcoin_tx(const tal_t *ctx,
const u8 **cursor, size_t *max);
void fromwire_siphash_seed(const u8 **cursor, size_t *max,
struct siphash_seed *seed);
void fromwire_bip32_key_version(const u8 **cursor, size_t *max,
struct bip32_key_version *version);
#endif /* LIGHTNING_WIRE_WIRE_H */

0 comments on commit 92c08cd

Please sign in to comment.