Skip to content

Commit

Permalink
Use TaggedHash in merkle::verify_signature
Browse files Browse the repository at this point in the history
An earlier commit introduced TaggedHash for use in sign_message. For
consistency, use it in verify_signature, too.
  • Loading branch information
jkczyz committed Aug 17, 2023
1 parent 2f41650 commit 106992c
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 24 deletions.
21 changes: 9 additions & 12 deletions lightning/src/offers/invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1175,8 +1175,9 @@ impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Bolt12Invoice {
None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
Some(signature) => signature,
};
let message = TaggedHash::new(SIGNATURE_TAG, &bytes);
let pubkey = contents.fields().signing_pubkey;
merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, pubkey)?;
merkle::verify_signature(&signature, message, pubkey)?;

Ok(Bolt12Invoice { bytes, contents, signature })
}
Expand Down Expand Up @@ -1279,7 +1280,7 @@ mod tests {
use crate::ln::inbound_payment::ExpandedKey;
use crate::ln::msgs::DecodeError;
use crate::offers::invoice_request::InvoiceRequestTlvStreamRef;
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self};
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self};
use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity};
use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
use crate::offers::payer::PayerTlvStreamRef;
Expand Down Expand Up @@ -1391,11 +1392,9 @@ mod tests {
assert_eq!(invoice.fallbacks(), vec![]);
assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
assert!(
merkle::verify_signature(
&invoice.signature, SIGNATURE_TAG, &invoice.bytes, recipient_pubkey()
).is_ok()
);

let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes);
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();
Expand Down Expand Up @@ -1490,11 +1489,9 @@ mod tests {
assert_eq!(invoice.fallbacks(), vec![]);
assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
assert!(
merkle::verify_signature(
&invoice.signature, SIGNATURE_TAG, &invoice.bytes, recipient_pubkey()
).is_ok()
);

let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes);
assert!(merkle::verify_signature(&invoice.signature, message, recipient_pubkey()).is_ok());

assert_eq!(
invoice.as_tlv_stream(),
Expand Down
11 changes: 5 additions & 6 deletions lightning/src/offers/invoice_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,8 @@ impl TryFrom<Vec<u8>> for InvoiceRequest {
None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
Some(signature) => signature,
};
merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, contents.payer_id)?;
let message = TaggedHash::new(SIGNATURE_TAG, &bytes);
merkle::verify_signature(&signature, message, contents.payer_id)?;

Ok(InvoiceRequest { bytes, contents, signature })
}
Expand Down Expand Up @@ -926,11 +927,9 @@ mod tests {
assert_eq!(invoice_request.quantity(), None);
assert_eq!(invoice_request.payer_id(), payer_pubkey());
assert_eq!(invoice_request.payer_note(), None);
assert!(
merkle::verify_signature(
&invoice_request.signature, SIGNATURE_TAG, &invoice_request.bytes, payer_pubkey()
).is_ok()
);

let message = TaggedHash::new(SIGNATURE_TAG, &invoice_request.bytes);
assert!(merkle::verify_signature(&invoice_request.signature, message, payer_pubkey()).is_ok());

assert_eq!(
invoice_request.as_tlv_stream(),
Expand Down
10 changes: 4 additions & 6 deletions lightning/src/offers/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,15 @@ where
Ok(signature)
}

/// Verifies the signature with a pubkey over the given bytes using a tagged hash as the message
/// Verifies the signature with a pubkey over the given message using a tagged hash as the message
/// digest.
///
/// Panics if `bytes` is not a well-formed TLV stream containing at least one TLV record.
pub(super) fn verify_signature(
signature: &Signature, tag: &str, bytes: &[u8], pubkey: PublicKey,
signature: &Signature, message: TaggedHash, pubkey: PublicKey,
) -> Result<(), secp256k1::Error> {
let digest = message_digest(tag, bytes);
let digest = message.as_digest();
let pubkey = pubkey.into();
let secp_ctx = Secp256k1::verification_only();
secp_ctx.verify_schnorr(signature, &digest, &pubkey)
secp_ctx.verify_schnorr(signature, digest, &pubkey)
}

pub(super) fn message_digest(tag: &str, bytes: &[u8]) -> Message {
Expand Down

0 comments on commit 106992c

Please sign in to comment.