From 38dfbf99db1bdb40bcaa3bbd7388cd7ed8e734b7 Mon Sep 17 00:00:00 2001 From: Orbital Date: Thu, 2 Nov 2023 19:50:20 -0500 Subject: [PATCH] refactor to remove message_digest We change the Bolt12Invoice struct to carry a tagged hash. Because message_digest is then only used in one place, we can inline it in the TaggedHash constructor. --- lightning/src/offers/invoice.rs | 14 ++++++++------ lightning/src/offers/invoice_request.rs | 4 ++-- lightning/src/offers/merkle.rs | 14 +++++--------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index c6fd5d05..5bd5a95d 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -439,6 +439,7 @@ impl UnsignedBolt12Invoice { bytes: self.bytes, contents: self.contents, signature, + tagged_hash: self.tagged_hash, }) } } @@ -463,6 +464,7 @@ pub struct Bolt12Invoice { bytes: Vec, contents: InvoiceContents, signature: Signature, + tagged_hash: TaggedHash, } /// The contents of an [`Bolt12Invoice`] for responding to either an [`Offer`] or a [`Refund`]. @@ -707,7 +709,7 @@ impl Bolt12Invoice { /// Hash that was used for signing the invoice. pub fn signable_hash(&self) -> [u8; 32] { - merkle::message_digest(SIGNATURE_TAG, &self.bytes).as_ref().clone() + self.tagged_hash.as_digest().as_ref().clone() } /// Verifies that the invoice was for a request or refund created using the given key. Returns @@ -1212,11 +1214,11 @@ impl TryFrom> for Bolt12Invoice { None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)), Some(signature) => signature, }; - let message = TaggedHash::new(SIGNATURE_TAG, &bytes); + let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes); let pubkey = contents.fields().signing_pubkey; - merkle::verify_signature(&signature, message, pubkey)?; + merkle::verify_signature(&signature, &tagged_hash, pubkey)?; - Ok(Bolt12Invoice { bytes, contents, signature }) + Ok(Bolt12Invoice { bytes, contents, signature, tagged_hash }) } } @@ -1431,7 +1433,7 @@ mod tests { assert_eq!(invoice.signing_pubkey(), recipient_pubkey()); let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes); - assert!(merkle::verify_signature(&invoice.signature, message, recipient_pubkey()).is_ok()); + assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok()); let digest = Message::from_slice(&invoice.signable_hash()).unwrap(); let pubkey = recipient_pubkey().into(); @@ -1528,7 +1530,7 @@ mod tests { assert_eq!(invoice.signing_pubkey(), recipient_pubkey()); let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes); - assert!(merkle::verify_signature(&invoice.signature, message, recipient_pubkey()).is_ok()); + assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok()); assert_eq!( invoice.as_tlv_stream(), diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index bd6d5837..9ddd741a 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -876,7 +876,7 @@ impl TryFrom> for InvoiceRequest { Some(signature) => signature, }; let message = TaggedHash::new(SIGNATURE_TAG, &bytes); - merkle::verify_signature(&signature, message, contents.payer_id)?; + merkle::verify_signature(&signature, &message, contents.payer_id)?; Ok(InvoiceRequest { bytes, contents, signature }) } @@ -1013,7 +1013,7 @@ mod tests { assert_eq!(invoice_request.payer_note(), None); let message = TaggedHash::new(SIGNATURE_TAG, &invoice_request.bytes); - assert!(merkle::verify_signature(&invoice_request.signature, message, payer_pubkey()).is_ok()); + assert!(merkle::verify_signature(&invoice_request.signature, &message, payer_pubkey()).is_ok()); assert_eq!( invoice_request.as_tlv_stream(), diff --git a/lightning/src/offers/merkle.rs b/lightning/src/offers/merkle.rs index 7390b58f..cf9a2eff 100644 --- a/lightning/src/offers/merkle.rs +++ b/lightning/src/offers/merkle.rs @@ -30,7 +30,7 @@ tlv_stream!(SignatureTlvStream, SignatureTlvStreamRef, SIGNATURE_TYPES, { /// /// [BIP 340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki /// [BOLT 12]: https://github.com/rustyrussell/lightning-rfc/blob/guilt/offers/12-offer-encoding.md#signature-calculation -#[derive(Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct TaggedHash(Message); impl TaggedHash { @@ -38,7 +38,9 @@ impl TaggedHash { /// /// Panics if `tlv_stream` is not a well-formed TLV stream containing at least one TLV record. pub(super) fn new(tag: &str, tlv_stream: &[u8]) -> Self { - Self(message_digest(tag, tlv_stream)) + let tag = sha256::Hash::hash(tag.as_bytes()); + let merkle_root = root_hash(tlv_stream); + Self(Message::from_slice(&tagged_hash(tag, merkle_root)).unwrap()) } /// Returns the digest to sign. @@ -91,7 +93,7 @@ where /// Verifies the signature with a pubkey over the given message using a tagged hash as the message /// digest. pub(super) fn verify_signature( - signature: &Signature, message: TaggedHash, pubkey: PublicKey, + signature: &Signature, message: &TaggedHash, pubkey: PublicKey, ) -> Result<(), secp256k1::Error> { let digest = message.as_digest(); let pubkey = pubkey.into(); @@ -99,12 +101,6 @@ pub(super) fn verify_signature( secp_ctx.verify_schnorr(signature, digest, &pubkey) } -pub(super) fn message_digest(tag: &str, bytes: &[u8]) -> Message { - let tag = sha256::Hash::hash(tag.as_bytes()); - let merkle_root = root_hash(bytes); - Message::from_slice(&tagged_hash(tag, merkle_root)).unwrap() -} - /// Computes a merkle root hash for the given data, which must be a well-formed TLV stream /// containing at least one TLV record. fn root_hash(data: &[u8]) -> sha256::Hash { -- 2.30.2