+) -> Result<Option<KeyPair>, ()> {
+ let hmac = hmac_for_message(metadata, expanded_key, iv_bytes, tlv_stream)?;
+
+ if metadata.len() == Nonce::LENGTH {
+ let derived_keys = KeyPair::from_secret_key(
+ secp_ctx, &SecretKey::from_slice(hmac.as_inner()).unwrap()
+ );
+ if fixed_time_eq(&signing_pubkey.serialize(), &derived_keys.public_key().serialize()) {
+ Ok(Some(derived_keys))
+ } else {
+ Err(())
+ }
+ } else if metadata[Nonce::LENGTH..].len() == Sha256::LEN {
+ if fixed_time_eq(&metadata[Nonce::LENGTH..], &hmac.into_inner()) {
+ Ok(None)
+ } else {
+ Err(())
+ }
+ } else {
+ Err(())
+ }
+}
+
+fn hmac_for_message<'a>(
+ metadata: &[u8], expanded_key: &ExpandedKey, iv_bytes: &[u8; IV_LEN],
+ tlv_stream: impl core::iter::Iterator<Item = TlvRecord<'a>>
+) -> Result<Hmac<Sha256>, ()> {