mod.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //! NUT-14: Hashed Time Lock Contacts (HTLC)
  2. //!
  3. //! <https://github.com/cashubtc/nuts/blob/main/14.md>
  4. use std::str::FromStr;
  5. use bitcoin::hashes::sha256::Hash as Sha256Hash;
  6. use bitcoin::hashes::Hash;
  7. use bitcoin::secp256k1::schnorr::Signature;
  8. use serde::{Deserialize, Serialize};
  9. use thiserror::Error;
  10. use super::nut00::Witness;
  11. use super::nut10::Secret;
  12. use super::nut11::valid_signatures;
  13. use super::{Conditions, Proof};
  14. use crate::util::unix_time;
  15. pub mod serde_htlc_witness;
  16. /// NUT14 Errors
  17. #[derive(Debug, Error)]
  18. pub enum Error {
  19. /// Incorrect secret kind
  20. #[error("Secret is not a HTLC secret")]
  21. IncorrectSecretKind,
  22. /// HTLC locktime has already passed
  23. #[error("Locktime in past")]
  24. LocktimeInPast,
  25. /// Hash Required
  26. #[error("Hash required")]
  27. HashRequired,
  28. /// Hash is not valid
  29. #[error("Hash is not valid")]
  30. InvalidHash,
  31. /// Preimage does not match
  32. #[error("Preimage does not match")]
  33. Preimage,
  34. /// Witness Signatures not provided
  35. #[error("Witness did not provide signatures")]
  36. SignaturesNotProvided,
  37. /// Secp256k1 error
  38. #[error(transparent)]
  39. Secp256k1(#[from] bitcoin::secp256k1::Error),
  40. /// NUT11 Error
  41. #[error(transparent)]
  42. NUT11(#[from] super::nut11::Error),
  43. #[error(transparent)]
  44. /// Serde Error
  45. Serde(#[from] serde_json::Error),
  46. }
  47. /// HTLC Witness
  48. #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  49. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  50. pub struct HTLCWitness {
  51. /// Primage
  52. pub preimage: String,
  53. /// Signatures
  54. #[serde(skip_serializing_if = "Option::is_none")]
  55. pub signatures: Option<Vec<String>>,
  56. }
  57. impl Proof {
  58. /// Verify HTLC
  59. pub fn verify_htlc(&self) -> Result<(), Error> {
  60. let secret: Secret = self.secret.clone().try_into()?;
  61. let conditions: Option<Conditions> =
  62. secret.secret_data.tags.and_then(|c| c.try_into().ok());
  63. let htlc_witness = match &self.witness {
  64. Some(Witness::HTLCWitness(witness)) => witness,
  65. _ => return Err(Error::IncorrectSecretKind),
  66. };
  67. if let Some(conditions) = conditions {
  68. // Check locktime
  69. if let Some(locktime) = conditions.locktime {
  70. // If locktime is in passed and no refund keys provided anyone can spend
  71. if locktime.lt(&unix_time()) && conditions.refund_keys.is_none() {
  72. return Ok(());
  73. }
  74. // If refund keys are provided verify p2pk signatures
  75. if let (Some(refund_key), Some(signatures)) =
  76. (conditions.refund_keys, &self.witness)
  77. {
  78. let signatures = signatures
  79. .signatures()
  80. .ok_or(Error::SignaturesNotProvided)?
  81. .iter()
  82. .map(|s| Signature::from_str(s))
  83. .collect::<Result<Vec<Signature>, _>>()?;
  84. // If secret includes refund keys check that there is a valid signature
  85. if valid_signatures(self.secret.as_bytes(), &refund_key, &signatures).ge(&1) {
  86. return Ok(());
  87. }
  88. }
  89. }
  90. // If pubkeys are present check there is a valid signature
  91. if let Some(pubkey) = conditions.pubkeys {
  92. let req_sigs = conditions.num_sigs.unwrap_or(1);
  93. let signatures = htlc_witness
  94. .signatures
  95. .as_ref()
  96. .ok_or(Error::SignaturesNotProvided)?;
  97. let signatures = signatures
  98. .iter()
  99. .map(|s| Signature::from_str(s))
  100. .collect::<Result<Vec<Signature>, _>>()?;
  101. if valid_signatures(self.secret.as_bytes(), &pubkey, &signatures).lt(&req_sigs) {
  102. return Err(Error::IncorrectSecretKind);
  103. }
  104. }
  105. }
  106. if secret.kind.ne(&super::Kind::HTLC) {
  107. return Err(Error::IncorrectSecretKind);
  108. }
  109. let hash_lock =
  110. Sha256Hash::from_str(&secret.secret_data.data).map_err(|_| Error::InvalidHash)?;
  111. let preimage_hash = Sha256Hash::hash(htlc_witness.preimage.as_bytes());
  112. if hash_lock.ne(&preimage_hash) {
  113. return Err(Error::Preimage);
  114. }
  115. Ok(())
  116. }
  117. /// Add Preimage
  118. #[inline]
  119. pub fn add_preimage(&mut self, preimage: String) {
  120. self.witness = Some(Witness::HTLCWitness(HTLCWitness {
  121. preimage,
  122. signatures: None,
  123. }))
  124. }
  125. }