+/// Error when signing messages.
+#[derive(Debug, PartialEq)]
+pub enum SignError<E> {
+ /// User-defined error when signing the message.
+ Signing(E),
+ /// Error when verifying the produced signature using the given pubkey.
+ Verification(secp256k1::Error),
+}
+
+/// Signs a message digest consisting of a tagged hash of the given bytes, checking if it can be
+/// verified with the supplied pubkey.
+///
+/// Panics if `bytes` is not a well-formed TLV stream containing at least one TLV record.
+pub(super) fn sign_message<F, E>(
+ sign: F, tag: &str, bytes: &[u8], pubkey: PublicKey,
+) -> Result<Signature, SignError<E>>
+where
+ F: FnOnce(&Message) -> Result<Signature, E>
+{
+ let digest = message_digest(tag, bytes);
+ let signature = sign(&digest).map_err(|e| SignError::Signing(e))?;
+
+ let pubkey = pubkey.into();
+ let secp_ctx = Secp256k1::verification_only();
+ secp_ctx.verify_schnorr(&signature, &digest, &pubkey).map_err(|e| SignError::Verification(e))?;
+
+ Ok(signature)
+}
+