From 9f1c9062db3278597429751c00b3cc7b0ef277e0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Apr 2024 00:36:52 +0000 Subject: [PATCH] Use `Sha256`s for tweaks in `sign` to enforce randomness We assume that tweaks are the output of a SHA-256 hash function (and thus that failing to create a private key from the has negligible probability) in `add_public_key_tweak` and elsewhere. Thus, we really shouldn't be taking byte arrays in the public API but rather `Sha256` objects, and communicating in the docs for `add_public_key_tweak` that we can panic if its not the output of a hash function, both of which we do here. --- lightning/src/ln/channel_keys.rs | 12 +++++++----- lightning/src/sign/mod.rs | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lightning/src/ln/channel_keys.rs b/lightning/src/ln/channel_keys.rs index 76dc1e42b..eaa14f27f 100644 --- a/lightning/src/ln/channel_keys.rs +++ b/lightning/src/ln/channel_keys.rs @@ -45,11 +45,11 @@ macro_rules! basepoint_impl { /// /// This calculates the hash part in the tweak derivation process, which is used to /// ensure that each key is unique and cannot be guessed by an external party. - pub fn derive_add_tweak(&self, per_commitment_point: &PublicKey) -> [u8; 32] { + pub fn derive_add_tweak(&self, per_commitment_point: &PublicKey) -> Sha256 { let mut sha = Sha256::engine(); sha.input(&per_commitment_point.serialize()); sha.input(&self.to_public_key().serialize()); - Sha256::from_engine(sha).to_byte_array() + Sha256::from_engine(sha) } } @@ -166,18 +166,20 @@ fn derive_public_key( let mut sha = Sha256::engine(); sha.input(&per_commitment_point.serialize()); sha.input(&base_point.serialize()); - let res = Sha256::from_engine(sha).to_byte_array(); + let res = Sha256::from_engine(sha); add_public_key_tweak(secp_ctx, base_point, &res) } /// Adds a tweak to a public key to derive a new public key. +/// +/// May panic if `tweak` is not the output of a SHA-256 hash. pub fn add_public_key_tweak( - secp_ctx: &Secp256k1, base_point: &PublicKey, tweak: &[u8; 32], + secp_ctx: &Secp256k1, base_point: &PublicKey, tweak: &Sha256, ) -> PublicKey { let hashkey = PublicKey::from_secret_key( &secp_ctx, - &SecretKey::from_slice(tweak) + &SecretKey::from_slice(tweak.as_byte_array()) .expect("Hashes should always be valid keys unless SHA-256 is broken"), ); base_point.combine(&hashkey) diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 43acc67af..8148c88e1 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -401,7 +401,7 @@ impl SpendableOutputDescriptor { subtype: 0, key: "add_tweak".as_bytes().to_vec(), }, - add_tweak.to_vec(), + add_tweak.as_byte_array().to_vec(), )] .into_iter() .collect() -- 2.39.5