mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 23:08:36 +01:00
Significantly clarify key derivation and expose methods referenced
This commit is contained in:
parent
42b731d92b
commit
d0c5e9c81d
2 changed files with 67 additions and 47 deletions
|
@ -54,26 +54,30 @@ pub enum SpendableOutputDescriptor {
|
||||||
/// <BIP 143 signature> <empty vector> (MINIMALIF standard rule) <provided witnessScript>
|
/// <BIP 143 signature> <empty vector> (MINIMALIF standard rule) <provided witnessScript>
|
||||||
///
|
///
|
||||||
/// Note that the nSequence field in the spending input must be set to to_self_delay
|
/// Note that the nSequence field in the spending input must be set to to_self_delay
|
||||||
/// (which means the transaction not being broadcastable until at least to_self_delay
|
/// (which means the transaction is not broadcastable until at least to_self_delay
|
||||||
/// blocks after the outpoint confirms).
|
/// blocks after the outpoint confirms).
|
||||||
///
|
///
|
||||||
/// These are generally the result of a "revocable" output to us, spendable only by us unless
|
/// These are generally the result of a "revocable" output to us, spendable only by us unless
|
||||||
/// it is an output from us having broadcast an old state (which should never happen).
|
/// it is an output from an old state which we broadcast (which should never happen).
|
||||||
///
|
///
|
||||||
/// WitnessScript may be regenerated by passing the revocation_pubkey, to_self_delay and
|
/// To derive the delayed_payment key which is used to sign for this input, you must pass the
|
||||||
/// delayed_payment_pubkey to chan_utils::get_revokeable_redeemscript.
|
/// local delayed_payment_base_key (ie the private key which corresponds to the pubkey in
|
||||||
|
/// ChannelKeys::pubkeys().delayed_payment_basepoint) and the provided per_commitment_point to
|
||||||
|
/// chan_utils::derive_private_key. The public key can be generated without the secret key
|
||||||
|
/// using chan_utils::derive_public_key and only the delayed_payment_basepoint which appears in
|
||||||
|
/// ChannelKeys::pubkeys().
|
||||||
///
|
///
|
||||||
/// To derive the delayed_payment key corresponding to the channel state, you must pass the
|
/// To derive the remote_revocation_pubkey provided here (which is used in the witness
|
||||||
/// local delayed_payment_base_key and the provided per_commitment_point to
|
/// script generation), you must pass the remote revocation_basepoint (which appears in the
|
||||||
/// chan_utils::derive_private_key. The resulting key should be used to sign the spending
|
/// call to ChannelKeys::set_remote_channel_pubkeys) and the provided per_commitment point
|
||||||
/// transaction.
|
/// to chan_utils::derive_public_revocation_key.
|
||||||
///
|
///
|
||||||
/// To derive the revocation_pubkey corresponding to the channel state, you must pass the
|
/// The witness script which is hashed and included in the output script_pubkey may be
|
||||||
/// remote revocation_basepoint and the provided per_commitment point to
|
/// regenerated by passing the revocation_pubkey (derived as above), our delayed_payment pubkey
|
||||||
/// chan_utils::derive_public_revocation_key.
|
/// (derived as above), and the to_self_delay contained here to
|
||||||
///
|
/// chan_utils::get_revokeable_redeemscript.
|
||||||
/// Both remote revocation_basepoint and local delayed_payment_base_key should be given
|
//
|
||||||
/// by ChannelKeys, either default implementation (InMemoryChannelKeys) or custom one.
|
// TODO: we need to expose utility methods in KeyManager to do all the relevant derivation.
|
||||||
DynamicOutputP2WSH {
|
DynamicOutputP2WSH {
|
||||||
/// The outpoint which is spendable
|
/// The outpoint which is spendable
|
||||||
outpoint: OutPoint,
|
outpoint: OutPoint,
|
||||||
|
@ -90,7 +94,8 @@ pub enum SpendableOutputDescriptor {
|
||||||
/// The remote_revocation_pubkey used to derive witnessScript
|
/// The remote_revocation_pubkey used to derive witnessScript
|
||||||
remote_revocation_pubkey: PublicKey
|
remote_revocation_pubkey: PublicKey
|
||||||
},
|
},
|
||||||
/// An output to a P2WPKH, spendable exclusively by our payment key.
|
/// An output to a P2WPKH, spendable exclusively by our payment key (ie the private key which
|
||||||
|
/// corresponds to the public key in ChannelKeys::pubkeys().payment_point).
|
||||||
/// The witness in the spending input, is, thus, simply:
|
/// The witness in the spending input, is, thus, simply:
|
||||||
/// <BIP 143 signature> <payment key>
|
/// <BIP 143 signature> <payment key>
|
||||||
///
|
///
|
||||||
|
@ -272,47 +277,47 @@ pub trait ChannelKeys : Send+Clone {
|
||||||
/// return value must contain a signature.
|
/// return value must contain a signature.
|
||||||
fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()>;
|
fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()>;
|
||||||
|
|
||||||
/// Create a signature for a transaction spending an HTLC or commitment transaction output
|
/// Create a signature for the given input in a transaction spending an HTLC or commitment
|
||||||
/// when our counterparty broadcast an old state.
|
/// transaction output when our counterparty broadcasts an old state.
|
||||||
///
|
///
|
||||||
/// Justice transaction may claim multiples outputs at same time if timelock are similar.
|
/// A justice transaction may claim multiples outputs at the same time if timelocks are
|
||||||
|
/// similar, but only a signature for the input at index `input` should be signed for here.
|
||||||
/// It may be called multiples time for same output(s) if a fee-bump is needed with regards
|
/// It may be called multiples time for same output(s) if a fee-bump is needed with regards
|
||||||
/// to an upcoming timelock expiration.
|
/// to an upcoming timelock expiration.
|
||||||
///
|
///
|
||||||
/// Input index is a pointer towards outpoint spent, commited by sigs (BIP 143).
|
/// Amount is value of the output spent by this input, committed to in the BIP 143 signature.
|
||||||
///
|
///
|
||||||
/// Amount is value of the output spent by this input, committed by sigs (BIP 143).
|
/// per_commitment_key is revocation secret which was provided by our counterparty when they
|
||||||
|
/// revoked the state which they eventually broadcast. It's not a _local_ secret key and does
|
||||||
|
/// not allow the spending of any funds by itself (you need our local revocation_secret to do
|
||||||
|
/// so).
|
||||||
///
|
///
|
||||||
/// Per_commitment key is revocation secret such as provided by remote party while
|
/// htlc holds HTLC elements (hash, timelock) if the output being spent is a HTLC output, thus
|
||||||
/// revocating detected onchain transaction. It's not a _local_ secret key, therefore
|
/// changing the format of the witness script (which is committed to in the BIP 143
|
||||||
/// it may cross interfaces, a node compromise won't allow to spend revoked output without
|
/// signatures).
|
||||||
/// also compromissing revocation key.
|
|
||||||
///
|
///
|
||||||
/// htlc holds HTLC elements (hash, timelock) if output spent is a HTLC one, committed as
|
/// on_remote_tx_csv is the relative lock-time that that our counterparty would have to set on
|
||||||
/// part of witnessScript by sigs (BIP 143).
|
/// their transaction were they to spend the same output. It is included in the witness script
|
||||||
///
|
/// and thus committed to in the BIP 143 signature.
|
||||||
/// on_remote_tx_csv is the relative lock-time challenge if output spent is on remote
|
|
||||||
/// balance or 2nd-stage HTLC transactions, committed as part of witnessScript by sigs
|
|
||||||
/// (BIP 143).
|
|
||||||
fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, on_remote_tx_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
|
fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, on_remote_tx_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
|
||||||
|
|
||||||
/// Create a signature for a claiming transaction for a HTLC output on a remote commitment
|
/// Create a signature for a claiming transaction for a HTLC output on a remote commitment
|
||||||
/// transaction, either offered or received.
|
/// transaction, either offered or received.
|
||||||
///
|
///
|
||||||
/// HTLC transaction may claim multiples offered outputs at same time if we know preimage
|
/// Such a transaction may claim multiples offered outputs at same time if we know the
|
||||||
/// for each at detection. It may be called multtiples time for same output(s) if a fee-bump
|
/// preimage for each when we create it, but only the input at index `input` should be
|
||||||
/// is needed with regards to an upcoming timelock expiration.
|
/// signed for here. It may be called multiple times for same output(s) if a fee-bump is
|
||||||
|
/// needed with regards to an upcoming timelock expiration.
|
||||||
///
|
///
|
||||||
/// Witness_script is either a offered or received script as defined in BOLT3 for HTLC
|
/// Witness_script is either a offered or received script as defined in BOLT3 for HTLC
|
||||||
/// outputs.
|
/// outputs.
|
||||||
///
|
///
|
||||||
/// Input index is a pointer towards outpoint spent, commited by sigs (BIP 143).
|
/// Amount is value of the output spent by this input, committed to in the BIP 143 signature.
|
||||||
///
|
|
||||||
/// Amount is value of the output spent by this input, committed by sigs (BIP 143).
|
|
||||||
///
|
///
|
||||||
/// Per_commitment_point is the dynamic point corresponding to the channel state
|
/// Per_commitment_point is the dynamic point corresponding to the channel state
|
||||||
/// detected onchain. It has been generated by remote party and is used to derive
|
/// detected onchain. It has been generated by our counterparty and is used to derive
|
||||||
/// channel state keys, committed as part of witnessScript by sigs (BIP 143).
|
/// channel state keys, which are then included in the witness script and committed to in the
|
||||||
|
/// BIP 143 signature.
|
||||||
fn sign_remote_htlc_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
|
fn sign_remote_htlc_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
|
||||||
|
|
||||||
/// Create a signature for a (proposed) closing transaction.
|
/// Create a signature for a (proposed) closing transaction.
|
||||||
|
|
|
@ -171,9 +171,11 @@ impl Readable for CounterpartyCommitmentSecrets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derives a per-commitment-transaction private key (eg an htlc key, payment key or delayed_payment
|
/// Derives a per-commitment-transaction private key (eg an htlc key or delayed_payment key)
|
||||||
/// key) from the base.
|
/// from the base secret and the per_commitment_point.
|
||||||
/// private key for that type of key and the per_commitment_point (available in TxCreationKeys)
|
///
|
||||||
|
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||||
|
/// generated (ie our own).
|
||||||
pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
|
pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
|
||||||
let mut sha = Sha256::engine();
|
let mut sha = Sha256::engine();
|
||||||
sha.input(&per_commitment_point.serialize());
|
sha.input(&per_commitment_point.serialize());
|
||||||
|
@ -185,7 +187,13 @@ pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_co
|
||||||
Ok(key)
|
Ok(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
|
/// Derives a per-commitment-transaction public key (eg an htlc key or a delayed_payment key)
|
||||||
|
/// from the base point and the per_commitment_key. This is the public equivalent of
|
||||||
|
/// derive_private_key - using only public keys to derive a public key instead of private keys.
|
||||||
|
///
|
||||||
|
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||||
|
/// generated (ie our own).
|
||||||
|
pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
|
||||||
let mut sha = Sha256::engine();
|
let mut sha = Sha256::engine();
|
||||||
sha.input(&per_commitment_point.serialize());
|
sha.input(&per_commitment_point.serialize());
|
||||||
sha.input(&base_point.serialize());
|
sha.input(&base_point.serialize());
|
||||||
|
@ -195,7 +203,8 @@ pub(crate) fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>,
|
||||||
base_point.combine(&hashkey)
|
base_point.combine(&hashkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derives a revocation key from its constituent parts.
|
/// Derives a per-commitment-transaction revocation key from its constituent parts.
|
||||||
|
///
|
||||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||||
/// generated (ie our own).
|
/// generated (ie our own).
|
||||||
pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
|
pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
|
||||||
|
@ -225,7 +234,13 @@ pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1
|
||||||
Ok(part_a)
|
Ok(part_a)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
|
/// Derives a per-commitment-transaction revocation public key from its constituent parts. This is
|
||||||
|
/// the public equivalend of derive_private_revocation_key - using only public keys to derive a
|
||||||
|
/// public key instead of private keys.
|
||||||
|
///
|
||||||
|
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||||
|
/// generated (ie our own).
|
||||||
|
pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
|
||||||
let rev_append_commit_hash_key = {
|
let rev_append_commit_hash_key = {
|
||||||
let mut sha = Sha256::engine();
|
let mut sha = Sha256::engine();
|
||||||
sha.input(&revocation_base_point.serialize());
|
sha.input(&revocation_base_point.serialize());
|
||||||
|
@ -274,9 +289,9 @@ pub struct ChannelPublicKeys {
|
||||||
/// on-chain channel lock-in 2-of-2 multisig output.
|
/// on-chain channel lock-in 2-of-2 multisig output.
|
||||||
pub funding_pubkey: PublicKey,
|
pub funding_pubkey: PublicKey,
|
||||||
/// The base point which is used (with derive_public_revocation_key) to derive per-commitment
|
/// The base point which is used (with derive_public_revocation_key) to derive per-commitment
|
||||||
/// revocation keys. The per-commitment revocation private key is then revealed by the owner of
|
/// revocation keys. This is combined with the per-commitment-secret generated by the
|
||||||
/// a commitment transaction so that their counterparty can claim all available funds if they
|
/// counterparty to create a secret which the counterparty can reveal to revoke previous
|
||||||
/// broadcast an old state.
|
/// states.
|
||||||
pub revocation_basepoint: PublicKey,
|
pub revocation_basepoint: PublicKey,
|
||||||
/// The public key which receives our immediately spendable primary channel balance in
|
/// The public key which receives our immediately spendable primary channel balance in
|
||||||
/// remote-broadcasted commitment transactions. This key is static across every commitment
|
/// remote-broadcasted commitment transactions. This key is static across every commitment
|
||||||
|
|
Loading…
Add table
Reference in a new issue