Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

key generation: use standard blinding instead. #3

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ desire to set up a new channel.
* [4:feerate-per-kb]
* [2:to-self-delay]
* [33:Funding pubkey]
* [33:HAKD base point]
* [33:Refund base point]
* [33:revocation-basepoint]
* [33:to-me-basepoint]


The `temporary-channel-id` is used to identify this channel until the funding transaction is established. `funding-satoshis` is the amount the sender is putting into the channel. `dust-limit-satoshis` is the threshold below which no HTLC output should be generated for this node’s commitment transaction; ie. HTLCs below this amount are not enforceable onchain. This reflects the reality that tiny outputs are not considered standard transactions and will not propagate through the bitcoin network.
`max-htlc-value-in-inflight-msat` is a cap on total value of outstanding HTLCs, which allows a node to limit its exposure to HTLCs; similarly `max-num-htlcs` limits the number of outstanding HTLCs the other node can offer. `channel-reserve-satoshis` is the minimum amount that the other node is to keep as a direct payment. `htlc-minimum-msat` indicates the smallest value HTLC this node wil accept. `feerate-per-kb` indicates the initial fee rate which this side will pay for commitment and HTLC transactions (this can be adjusted later with a `update_fee` message). `to-self-delay` is the number of block that the other nodes to-self outputs must be delayed, using `OP_CHECKSEQUENCEVERIFY` delays; this is how long it will have to wait in case of breakdown before redeeming its own funds.


The `funding-pubkey` is the public key in the 2-of-2 multisig script of the funding transaction output. The `hakd-base-point` is combined with the revocation hash for this commitment transaction to generate a unique revocation key for this commitment transaction (HAKD = homomorphic adversarial key derivation). The `refund-base-point` is similarly used to generate a series of keys for non-HTLC outputs, ensuring that the transaction ID of each commitment transaction is unpredictable by an external observer, even if one commitment transaction is seen: this property is very useful for preserving privacy when outsourcing penalty transactions to third parties.
The `funding-pubkey` is the public key in the 2-of-2 multisig script of the funding transaction output. The `revocation-basepoint` is combined with the revocation hash for this commitment transaction to generate a unique revocation key for this commitment transaction. The `to-me-basepoint` is similarly used to generate a unique key for each commitment transaction which to make payments to this node. We use a unique key for this to ensure that the transaction ID of each commitment transaction is unpredictable by an external observer, even if one commitment transaction is seen: this property is very useful for preserving privacy when outsourcing penalty transactions to third parties.



Expand Down Expand Up @@ -161,11 +161,11 @@ acceptance of the new channel.
* [4:minimum-depth]
* [4:htlc-minimum-msat]
* [4:max-num-htlcs]
* [32:first-commitment-key-offset]
* [2:to-self-delay]
* [33:funding-pubkey]
* [33:HAKD base point]
* [33:Refund base point]
* [33:revocation-basepoint]
* [33:to-me-basepoint]
* [33:first-revocation-key]


### Requirements
Expand All @@ -189,6 +189,7 @@ signature, it will broadcast the funding transaction.
* [32:txid]
* [2:output_index]
* [64:signature]
* [33:first-revocation-key]

FIXME: describe

Expand Down Expand Up @@ -219,8 +220,7 @@ This message indicates that the funding transaction has reached the `minimum-dep
2. data:
* [8:temporary-channel-id]
* [8:channel-id]
* [32:next-key-offset]
* [33:next-revocation-halfkey]
* [33:next-revocation-key]

The `channel-id` is the unique description of the funding transaction.
It is constructed with the most significant 3 bytes as the block
Expand Down Expand Up @@ -689,20 +689,17 @@ The description of key derivation is in [BOLT #3: Key Derivation FIXME].
2. data:
* [8:channel-id]
* [32:per-commitment-secret]
* [32:next-key-offset]
* [33:next-revocation-halfkey]
* [33:next-revocation-key]
* [4:num-htlc-timeouts]
* [num-htlc-timeouts*64:htlc-timeout-signature]

### Requirements


A sending node MUST set `per-commitment-secret` to the secret used to generate keys for the
previous commitment transaction, and must set `next-key-offset` and `next-revocation-halfkey` to the values for its next commitment transaction.


A receiving node MUST check that `per-commitment-secret` generates the previous `key-offset` and `revocation-halfkey`, and MUST fail if it does not. A receiving node MAY fail if the `per-commitment-secret` was not generated by the protocol in [FIXME].
previous commitment transaction, and must set `next-revocation-key` to the revocation pubkey derived from the next revocation secret as defined in [BOLT #3](03-transactions.md).

A receiving node MUST check that `per-commitment-secret` generates the previous `next-revocation-key` (or `first-revocation-key` for the first `MSG_REVOCATION`) and MUST fail if it does not.

A receiving node MUST fail the channel if any htlc-timeout-signature is not valid, or if num-htlc-timeout is not equal to the number of outputs in the sending node's commitment transaction corresponding to HTLCs offered be the sending node. A receiving node MAY fail the channel if the `revocation-key` was not
generated as specified in "Commitment Key Generation"[FIXME] below.
Expand Down
32 changes: 25 additions & 7 deletions 03-transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,23 +118,41 @@ To spend this via penalty, the remote node uses a witness stack `<revocationsig>

Each commitment transaction uses a unique set of keys; <localkey>, <remotekey> and <revocationkey>. Changing the <localkey> and <remotekey> every time ensures that commitment txids cannot be determined by a third party even it knows another commitment transaction, which helps preserve privacy in the case of outsourced penalties. The <revocationkey> is generated such that the remote node is the only one in possession of the secret key once the commitment transaction has been revoked.

For efficiency, keys are generated from a series of per-commitment secrets which are generated from a single seed, allowing the receiver to compactly store them (see [FIXME]).
Public keys (Q') generated from the base point (Q) using a blinding
factor `k`, like so:

Q' = Q + SHA256(Q || k) * G

The corresponding private key (P') is generated by simply adding
`SHA256(Q || k)` to P.

### localkey and remotekey Derivation

The localkey for a commitment transaction is generated by EC addition of the local `refund base point` and the current local `key-offset` multiplied by G (eg. secp256k1_ec_pubkey_tweak_add() from libsecp256k1). The local node knows the secret key corresponding to `refund base point` so can similarly derive the secret key for `localkey`.
The `<localkey>` for a commitment transaction is generated using the
local `to-me-basepoint` and a blinding factor `k` which is
the commitment number represented as a big-endian 64 bit number:

The `key-offset` is generated using HMAC(`per-commit-secret`, “R”) [FIXME: more detail!].
<localkey> = to-me-basepoint + SHA256(to-me-basepoint || commitment-number) * G

The remotekey is generated the same way, using the remote `refund base point` and the current `key-offset` from the remote node: this is given by `first-key-offset` (for the initial commitment transaction) and `next-key-offset` for successive transactions.
The `<remotekey>` is calculated exactly the same, but using the remote
`to-me-basepoint` instead of the local one.

### revocationkey Derivation

The local revocation key is derived from both the remote `HAKD basepoint` and a key derived from the local per-commit secret, called the “revocation-halfkey”.
The revocation public key is calculated by the local node using the
remote node's `revocation-basepoint` and the local
`per-commitment-secret`:

<revocationkey> = revocation-basepoint + SHA256(revocation-basepoint || per-commitment-secret) * G

This key is sent to the remote node (either as `next-revocation-key`
in `MSG_REVOCATION` or `first-revocation-key` in `MSG_ACCEPT_CHANNEL`
or `MSG_FUNDING_CREATED`).

The secret key for the `revocation-halfkey` is HMAC(`per-commit-secret`, “T”) [FIXME: more detail!]. The public key corresponding to this secret key is `revocation-halfkey`. Elliptic curve point addition of `revocation-halfkey` and `HAKD basepoint` gives the `revocationkey`.
Once the `per-commitment-secret` is sent to the remote node (upon
revocation), it can extract the corresponding secret key using:

Upon revocation, the per-commit secret is revealed to the remote node: this allows it to derive the secret key for `revocation-halfkey`, and it already knows the secret key corresponding to the `HAKD basepoint` so it can derive the secret key corresponding to `revocationkey`.
<revocationsecret> = revocation-basepoint-secret + SHA256(revocation-basepoint || per-commitment-secret)


### Per-commitment Secret Requirements
Expand Down