Skip to content

Commit

Permalink
Topics: add three new topic pages
Browse files Browse the repository at this point in the history
- CLTV expiry delta
- Proof of reserves
- X-only public keys
  • Loading branch information
harding committed Apr 4, 2024
1 parent 70ad584 commit 73327b5
Show file tree
Hide file tree
Showing 3 changed files with 359 additions and 0 deletions.
150 changes: 150 additions & 0 deletions _topics/en/cltv-expiry-delta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
title: CLTV expiry delta

## Optional. Shorter name to use for reference style links e.g., "foo"
## will allow using the link [topic foo][]. Not case sensitive
# shortname: foo

## Optional. An entry will be added to the topics index for each alias
#aliases:
# - Foo

## Required. At least one category to which this topic belongs. See
## schema for options
categories:
- Lightning Network

## Optional. Produces a Markdown link with either "[title][]" or
## "[title](link)"
primary_sources:
- title: BOLT2
link: bolt2

## Optional. Each entry requires "title" and "url". May also use "feature:
## true" to bold entry and "date"
optech_mentions:
- title: "BOLTs #1086 specifies 2,016 blocks as the default absolute maximum CLTV expiry"
url: /en/newsletters/2023/11/01/#bolts-1086

- title: "LND #2759 lowers the default CLTV delta for all channels from 144 blocks to 40 blocks"
url: /en/newsletters/2019/04/02/#lnd-2759

- title: "LN-Symmetry requires longer CLTV expiry deltas than expected"
url: /en/newsletters/2024/01/10/#expiry-deltas

- title: "New attack against LN payment atomicity: raising CLTV expiry delta recommended"
url: /en/newsletters/2020/04/29/#new-attack-against-ln-payment-atomicity

- title: "LND #4488 updates the minimum CLTV expiry delta users may set to 18 blocks"
url: /en/newsletters/2020/08/05/#lnd-4488

- title: "BOLTS #785 updates the minimum CLTV expiry delta to 18 blocks"
url: /en/newsletters/2020/08/26/#bolts-785

- title: "Rust-Lightning #849 makes `cltv_expiry_delta` configurable and reduces the default from 72 to 36"
url: /en/newsletters/2021/03/31/#rust-lightning-849

- title: "Eclair #2468 implements BOLTs #1032, allowing accepting a longer expiry than requested"
url: /en/newsletters/2022/11/09/#eclair-2468

- title: "Eclair #2677 raises its `max_cltv` to 2,016 blocks due widespread increases in CLTV expiry deltas"
url: /en/newsletters/2023/06/14/#eclair-2677

- title: "LND #7768 implements BOLTs #1032 and #1063, allowing accepting a longer expiry than requested"
url: /en/newsletters/2023/07/19/#lnd-7768

- title: "Longer CLTV expiry deltas as a mitigation against replacement cycling attacks"
url: /en/newsletters/2023/10/25/#longer-cltv-expiry-deltas

## Optional. Same format as "primary_sources" above
see_also:
- title: HTLCs
link: topic htlc

- title: Channel jamming attacks
link: topic channel jamming attacks

## Optional. Force the display (true) or non-display (false) of stub
## topic notice. Default is to display if the page.content is below a
## threshold word count
#stub: false

## Required. Use Markdown formatting. Only one paragraph. No links allowed.
## Should be less than 500 characters
excerpt: >
**CLTV expiry delta** is the number of blocks a node has to settle a
stalled payment before it could potentially lose money. The deltas
apply within a chain of HTLCs and use the `OP_CHECKLOCKTIMEVERIFY`
(CLTV) opcode.
---
Imagine Alice forwards a payment to Bob who forwards the payment to
Carol.

Forwarded payments:

Alice ------> Bob ------> Carol
(1 BTC) (1 BTC)

If Carol doesn't claim the payment by releasing the [HTLC][topic
HTLC] preimage, but she also doesn't reject the payment, Bob's funds are
stuck. Not only that, but he can't resolve the forwarded payment he
received from Alice, so her funds are stuck as well. To avoid funds
becoming permanently stuck, HTLCs have an expiry after which Bob will
be able to claim a refund. After Bob receives his refund from Carol, he
can reject the payment from Alice---giving her a refund. Alternatively,
Alice can wait for her own expiry and reclaim the payment she forwarded
to Bob. Everyone gets back what they started with, which is a safe
outcome.

Forwarded payments:

Alice ------> Bob ------> Carol
(1 BTC) (1 BTC)

Refunds after expiry:

Alice <------ Bob <------ Carol
(1 BTC) (1 BTC)

However, if Alice can claim her refund before Bob receives his refund,
then it's possible for Carol to accept her payment. In this case, Alice
spends nothing and Carol receives payment with Bob losing the
difference.

Forwarded payments:

Alice ------> Bob ------> Carol
(1 BTC) (1 BTC)

Refund after expiry to Alice and payment to Carol:

Alice <------ Bob ------> Carol
(1 BTC) (1 BTC)

The CLTV expiry delta tries to prevent Bob from losing value this way.
When Alice gives Bob an HTLC that allows her to claim a refund after
`x` blocks, Bob gives Carol an HTLC that allows him to claim a refund
after `x - y` blocks. The _y_ parameter is Bob's CLTV expiry delta:
it's how many blocks he has to claim a refund onchain before he could
potentially lose money if Alice claims her refund.

Higher CLTV expiry deltas provide more safety as they give an LN node more time
to get an HTLC refund transaction confirmed onchain before that node is
at risk of losing funds. However, higher CLTV expiry deltas magnify the
problems of channel stalling, both accidental stalling (e.g. a node goes
offline suddenly) and malicious stalling (e.g. [channel jamming
attacks][topic channel jamming attacks]).

For example, imagine a payment that will be sent across 20 hops each
with an CLTV expiry delta of 100 blocks. If that payment stalls, it
could be up to 2,000 blocks (about two weeks) until the spender gets
a refund and can resend the payment again.

There's no universally agreed-upon tradeoff between security and
worst-case payment delivery time, so LN implementations tend to each use
different default CLTV expiry deltas, often change those defaults, and
usually allow users to choose their own setting.

{% include references.md %}
{% include linkers/issues.md issues="" %}
105 changes: 105 additions & 0 deletions _topics/en/proof-of-reserves.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: Proof of reserves

## Optional. Shorter name to use for reference style links e.g., "foo"
## will allow using the link [topic foo][]. Not case sensitive
# shortname: foo

## Optional. An entry will be added to the topics index for each alias
#aliases:
# - Foo

## Required. At least one category to which this topic belongs. See
## schema for options
categories:
- Security Enhancements
- Wallet Collaboration Tools

## Optional. Produces a Markdown link with either "[title][]" or
## "[title](link)"
primary_sources:
- title: "BIP127: simple proof-of-reserves transactions"
link: https://github.com/bitcoin/bips/blob/master/bip-0127.mediawiki

## Optional. Each entry requires "title" and "url". May also use "feature:
## true" to bold entry and "date"
optech_mentions:
- title: Tool released for generating and verifying bitcoin ownership proofs
url: /en/newsletters/2019/02/12/#tool-released-for-generating-and-verifying-bitcoin-ownership-proofs

- title: Standardized format proposed for proof of reserves
url: /en/newsletters/2019/12/28/#bip127

- title: "BIP322 generic signmessage updated to remove abstraction for proof of reserves"
url: /en/newsletters/2020/04/01/#proposed-update-to-bip322-generic-signmessage

- title: "BIP322 generic signmessage updated to use virtual transactions that support basic proof of reserves"
url: /en/newsletters/2020/10/07/#alternative-to-bip322-generic-signmessage

- title: "Kraken announces proof of reserves scheme"
url: /en/newsletters/2022/02/16/#kraken-announces-proof-of-reserves-scheme

## Optional. Same format as "primary_sources" above
see_also:
- title: BIP322 signature proofs
link: BIP322

## Optional. Force the display (true) or non-display (false) of stub
## topic notice. Default is to display if the page.content is below a
## threshold word count
#stub: false

## Required. Use Markdown formatting. Only one paragraph. No links allowed.
## Should be less than 500 characters
excerpt: >
**Proof of reserves** are a timestamped commitment to a distribution
of funds signed by the entity who controls those funds.
---
For example, Alice, Bob, and Carol all have bitcoin-denominated deposits
with Bank Corp. Each week, Bank Corp uses the private key controlling
their onchain funds to sign a message saying "Alice has 1 BTC on
deposit; Bob has 2 BTC on deposit; and Carol has 3 BTC on deposit." If
the key Bank Corp uses to sign that message contains 6 BTC or more, the
depositors have some assurance that Bank Corp could return their
deposited amounts if it was willing.

Proof of reserves cannot guarantee that the funds are available. For
example, Bank Corp could contract with a third party who controls 6 BTC
to have them generate the proof. In that case, Bank Corp may not
control any bitcoins even though its "proof" seems to indicate that it
does.

The simplest form of proof of reserves lists each depositor's name in a
form that can't be confused with any other depositor's name. The use of explicit
names prevents the custodian from using the same bitcoins as proof for
two or more different depositors. For example, imagine two different
people both named Alice who both have 1 BTC on deposit. The example
proof described for 6 BTC earlier would satisfy both of them, plus Bob
and Carol, even though the actual total on deposit needs to be 7 BTC.

For privacy, each depositor's name may be replaced with a pseudonym.
However, depositors still need to ensure they are each given a unique
name. For more privacy, the association between the name and the exact deposit
amount may be obscured, for example using a merkle-sum tree to show each
depositor their specific amount and how it contributes towards the total
amount of proven reserves. For example, Alice is shown that her
contribution is 1 BTC and that the contribution of the amount paired
with hers is 2 BTC. That aggregated amount is paired with some number of
accounts also totaling 3 BTC for a grand total of 6 BTC:

6 BTC
/ \
3 BTC 3 BTC
/ \
1 BTC 2 BTC
|
Alice

The above describes only a simple privacy-respecting scheme, a scheme
that can fool depositors if they aren't careful about verifying it and
understanding exactly what it proves. Many more advanced schemes have
been proposed, and several have been used in production.

{% include references.md %}
{% include linkers/issues.md issues="" %}
104 changes: 104 additions & 0 deletions _topics/en/x-only-public-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: X-only public keys

## Optional. Shorter name to use for reference style links e.g., "foo"
## will allow using the link [topic foo][]. Not case sensitive
# shortname: foo

## Optional. An entry will be added to the topics index for each alias
#aliases:
# - Foo

## Required. At least one category to which this topic belongs. See
## schema for options
categories:
- Scripts and Addresses

## Optional. Produces a Markdown link with either "[title][]" or
## "[title](link)"
primary_sources:
- title: "BIP340 schnorr signatures for secp256k1"
link: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design

## Optional. Each entry requires "title" and "url". May also use "feature:
## true" to bold entry and "date"
optech_mentions:
- title: "Suggestion to use x-only public keys in taproot"
url: /en/newsletters/2019/05/29/#move-the-oddness-byte

- title: "Request for discussion about using x-only public keys in taproot"
url: /en/newsletters/2019/08/14/#proposed-change-to-schnorr-pubkeys

- title: "Summary of updates to taproot proposal, including x-only public keys"
url: /en/newsletters/2019/10/16/#taproot-update

- title: "Taproot review: blog post published about x-only pubkeys"
url: /en/newsletters/2019/11/13/#taproot-review-discussion-and-related-information

- title: "Alternative x-only tiebreaker proposed and discussion of safety of precomputed pubkeys"
url: /en/newsletters/2020/02/05/#alternative-x-only-pubkey-tiebreaker

- title: "X-only workaround for covenant-based protocols"
url: /en/newsletters/2022/07/13/#x-only-workaround

- title: "Core Lightning #5646 updates the experimental implementation of offers to remove x-only public keys"
url: /en/newsletters/2022/11/02/#core-lightning-5646

- title: "Libsecp256k1 #993 includes in the default build options a modules for working with x-only pubkeys"
url: /en/newsletters/2022/11/30/#libsecp256k1-993

## Optional. Same format as "primary_sources" above
see_also:
- title: Schnorr signatures
link: topic schnorr signatures

title: Taproot
link: topic taproot

## Optional. Force the display (true) or non-display (false) of stub
## topic notice. Default is to display if the page.content is below a
## threshold word count
#stub: false

## Required. Use Markdown formatting. Only one paragraph. No links allowed.
## Should be less than 500 characters
excerpt: >
**X-only public keys** are public keys for the secp256k1 elliptic
curve that only provide the _x_ coordinate for their position in the
finite field. This is in comparison to _uncompressed public keys_ that
provide both their _x_ and _y_ coordinates and _compressed public
keys_ that provide their _x_ coordinate plus an additional bit to
differentiate the two _y_ alternatives.
---
Bitcoin public keys are points on the secp256k1 elliptic curve over
a 256-bit finite field. It's easy to describe such a point by giving
its _x_ and _y_ coordinates, using a 256-bit number for each (32 bytes
each, for a total of 64 bytes). Uncompressed public keys do this,
adding a prefix byte for a total of 65 bytes.

If we describe just the _x_ coordinate and use the curve equation to
derive the _y_ coordinate, we find that each _x_ coordinate corresponds
to two different _y_ coordinates. This allows us to compact our
description to 256 bits for the _x_ coordinate plus a single extra bit
to indicate which of the _y_ coordinates to use. Compressed public keys
do this, containing the bit within their prefix byte for a total of 33
bytes.

The extra bit can be eliminated if only one of the two alternative _y_
coordinates is allowed. X-only public keys do this, using a total of
32 bytes. Segwit v1 ([taproot][topic taproot]) and the initial version
of [tapscript][topic tapscript] use x-only public keys for all signature
checking operations to reduce the size of public keys.

The advantage of x-only public keys is that they save space. The
downside is that public keys need to be generated in a way that ensures
they only use the allowed _y_ coordinate. This is easy for a wallet
generating a public key but it
was later realized that it could be quite challenging for any
[covenant][topic covenants] that needed to modify taproot witness
programs that commit to both a [MAST][topic mast]-like tree of scripts
and an x-only internal public key.

{% include references.md %}
{% include linkers/issues.md issues="" %}

0 comments on commit 73327b5

Please sign in to comment.