From 33f2c75e4a44e95d0c55cce49cb708d910adf089 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Tue, 21 Jan 2020 16:21:00 +0100 Subject: [PATCH 1/3] sphinx: Actually use the pad stream to generate the packet We flipped two buffers and were not actually using the chacha20 stream. --- common/sphinx.c | 2 +- tests/test_pay.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/sphinx.c b/common/sphinx.c index aea8b6ae8599..4ffa61b74a80 100644 --- a/common/sphinx.c +++ b/common/sphinx.c @@ -425,7 +425,7 @@ struct onionpacket *create_onionpacket( /* Note that this is just hop_payloads: the rest of the packet is * overwritten below or above anyway. */ generate_key(padkey, "pad", 3, sp->session_key); - generate_cipher_stream(stream, padkey, ROUTING_INFO_SIZE); + generate_cipher_stream(packet->routinginfo, padkey, ROUTING_INFO_SIZE); generate_header_padding(filler, sizeof(filler), sp, params); diff --git a/tests/test_pay.py b/tests/test_pay.py index da974239bb3a..420e66560f08 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -2479,7 +2479,7 @@ def test_createonion_rpc(node_factory): # The trailer is generated using the filler and can be ued as a # checksum. This trailer is from the test-vector in the specs. print(res) - assert(res['onion'].endswith('be89e4701eb870f8ed64fafa446c78df3ea')) + assert(res['onion'].endswith('9400f45a48e6dc8ddbaeb3')) @unittest.skipIf(not DEVELOPER, "gossip propagation is slow without DEVELOPER=1") From c954525f6fa09d87c4d2bf74c550855a5c3c7358 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Tue, 21 Jan 2020 17:36:14 +0100 Subject: [PATCH 2/3] sphinx: Fix the broken legacy payload loading from test-vectors We were for some reason encoding all payloads as raw payloads instead of loading legacy payloads into a padded array. --- devtools/onion.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/devtools/onion.c b/devtools/onion.c index 5ebca057817b..5a8d53eaf20f 100644 --- a/devtools/onion.c +++ b/devtools/onion.c @@ -220,15 +220,16 @@ static void runtest(const char *filename) json_to_pubkey(buffer, pubkeytok, &pubkey); if (!typetok || json_tok_streq(buffer, typetok, "legacy")) { /* Legacy has a single 0 prepended as "realm" byte */ - full = tal_arrz(ctx, u8, 1); + full = tal_arrz(ctx, u8, 33); + memcpy(full + 1, payload, tal_bytelen(payload)); } else { /* TLV has length prepended */ full = tal_arr(ctx, u8, 0); towire_bigsize(&full, tal_bytelen(payload)); + prepended = tal_bytelen(full); + tal_resize(&full, prepended + tal_bytelen(payload)); + memcpy(full + prepended, payload, tal_bytelen(payload)); } - prepended = tal_bytelen(full); - tal_resize(&full, prepended + tal_bytelen(payload)); - memcpy(full + prepended, payload, tal_bytelen(payload)); sphinx_add_hop(path, &pubkey, full); } res = create_onionpacket(ctx, path, &shared_secrets); From 2368e8a6055d473183b4ef0d9bd74e8ad64b7958 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 23 Jan 2020 13:38:13 +0100 Subject: [PATCH 3/3] bitcoin: Compute block hash while parsing This avoids having to re-serialize the block header just to compute the hash. It also frees us from having to carry around all the details in the header and we can hand around a minimal version. --- bitcoin/block.c | 14 ++++++++++++++ bitcoin/block.h | 1 + 2 files changed, 15 insertions(+) diff --git a/bitcoin/block.c b/bitcoin/block.c index 2d48fd56b4db..dc478291d8df 100644 --- a/bitcoin/block.c +++ b/bitcoin/block.c @@ -13,6 +13,7 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, u8 *linear_tx; const u8 *p; size_t len, i, num; + struct sha256_ctx shactx; if (hexlen && hex[hexlen-1] == '\n') hexlen--; @@ -26,10 +27,19 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, if (!hex_decode(hex, hexlen, linear_tx, len)) return tal_free(b); + sha256_init(&shactx); + b->hdr.version = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.version); + pull(&p, &len, &b->hdr.prev_hash, sizeof(b->hdr.prev_hash)); + sha256_update(&shactx, &b->hdr.prev_hash, sizeof(b->hdr.prev_hash)); + pull(&p, &len, &b->hdr.merkle_hash, sizeof(b->hdr.merkle_hash)); + sha256_update(&shactx, &b->hdr.merkle_hash, sizeof(b->hdr.merkle_hash)); + b->hdr.timestamp = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.timestamp); if (is_elements(chainparams)) { b->elements_hdr = tal(b, struct elements_block_hdr); @@ -45,8 +55,12 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, } else { b->hdr.target = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.target); + b->hdr.nonce = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.nonce); } + sha256_double_done(&shactx, &b->hdr.hash); num = pull_varint(&p, &len); b->tx = tal_arr(b, struct bitcoin_tx *, num); diff --git a/bitcoin/block.h b/bitcoin/block.h index 9fa2b385a585..cf0c913b506b 100644 --- a/bitcoin/block.h +++ b/bitcoin/block.h @@ -23,6 +23,7 @@ struct bitcoin_block_hdr { le32 timestamp; le32 target; le32 nonce; + struct sha256_double hash; }; struct elements_block_proof {