mod.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. //! NUT-11: Pay to Public Key (P2PK)
  2. //!
  3. //! <https://github.com/cashubtc/nuts/blob/main/11.md>
  4. use std::collections::{HashMap, HashSet};
  5. use std::str::FromStr;
  6. use std::{fmt, vec};
  7. use bitcoin::hashes::sha256::Hash as Sha256Hash;
  8. use bitcoin::hashes::Hash;
  9. use bitcoin::secp256k1::schnorr::Signature;
  10. use serde::de::Error as DeserializerError;
  11. use serde::ser::SerializeSeq;
  12. use serde::{Deserialize, Deserializer, Serialize, Serializer};
  13. use thiserror::Error;
  14. use super::nut00::Witness;
  15. use super::nut01::PublicKey;
  16. use super::{Kind, Nut10Secret, Proof, Proofs, SecretKey};
  17. use crate::nuts::nut00::BlindedMessage;
  18. use crate::secret::Secret;
  19. use crate::util::{hex, unix_time};
  20. pub mod serde_p2pk_witness;
  21. #[derive(Debug, Error)]
  22. pub enum Error {
  23. /// Incorrect secret kind
  24. #[error("Secret is not a p2pk secret")]
  25. IncorrectSecretKind,
  26. /// Incorrect secret kind
  27. #[error("Witness is not a p2pk witness")]
  28. IncorrectWitnessKind,
  29. /// P2PK locktime has already passed
  30. #[error("Locktime in past")]
  31. LocktimeInPast,
  32. /// Witness signature is not valid
  33. #[error("Invalid signature")]
  34. InvalidSignature,
  35. /// Unknown tag in P2PK secret
  36. #[error("Unknown Tag P2PK secret")]
  37. UnknownTag,
  38. /// Unknown Sigflag
  39. #[error("Unknown Sigflag")]
  40. UnknownSigFlag,
  41. /// P2PK Spend conditions not meet
  42. #[error("P2PK Spend conditions are not met")]
  43. SpendConditionsNotMet,
  44. /// Pubkey must be in data field of P2PK
  45. #[error("P2PK Required in secret data")]
  46. P2PKPubkeyRequired,
  47. /// Unknown Kind
  48. #[error("Kind not found")]
  49. KindNotFound,
  50. /// HTLC hash invalid
  51. #[error("Invalid Hash")]
  52. InvalidHash,
  53. /// Witness Signatures not provided
  54. #[error("Witness Signatures not provided")]
  55. SignaturesNotProvided,
  56. /// Parse Url Error
  57. #[error(transparent)]
  58. UrlParseError(#[from] url::ParseError),
  59. /// Parse int error
  60. #[error(transparent)]
  61. ParseInt(#[from] std::num::ParseIntError),
  62. /// From hex error
  63. #[error(transparent)]
  64. HexError(#[from] hex::Error),
  65. /// Serde Json error
  66. #[error(transparent)]
  67. SerdeJsonError(#[from] serde_json::Error),
  68. /// Secp256k1 error
  69. #[error(transparent)]
  70. Secp256k1(#[from] bitcoin::secp256k1::Error),
  71. /// NUT01 Error
  72. #[error(transparent)]
  73. NUT01(#[from] crate::nuts::nut01::Error),
  74. /// Secret error
  75. #[error(transparent)]
  76. Secret(#[from] crate::secret::Error),
  77. }
  78. /// P2Pk Witness
  79. #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  80. pub struct P2PKWitness {
  81. pub signatures: Vec<String>,
  82. }
  83. impl P2PKWitness {
  84. #[inline]
  85. pub fn is_empty(&self) -> bool {
  86. self.signatures.is_empty()
  87. }
  88. }
  89. impl Proof {
  90. /// Sign [Proof]
  91. pub fn sign_p2pk(&mut self, secret_key: SecretKey) -> Result<(), Error> {
  92. let msg: Vec<u8> = self.secret.to_bytes();
  93. let signature: Signature = secret_key.sign(&msg)?;
  94. let signatures = vec![signature.to_string()];
  95. match self.witness.as_mut() {
  96. Some(witness) => {
  97. witness.add_signatures(signatures);
  98. }
  99. None => {
  100. let mut p2pk_witness = Witness::P2PKWitness(P2PKWitness::default());
  101. p2pk_witness.add_signatures(signatures);
  102. self.witness = Some(p2pk_witness);
  103. }
  104. };
  105. Ok(())
  106. }
  107. /// Verify P2PK signature on [Proof]
  108. pub fn verify_p2pk(&self) -> Result<(), Error> {
  109. let secret: Nut10Secret = self.secret.clone().try_into()?;
  110. let spending_conditions: Conditions =
  111. secret.secret_data.tags.unwrap_or_default().try_into()?;
  112. let msg: &[u8] = self.secret.as_bytes();
  113. let mut valid_sigs = 0;
  114. let witness_signatures = match &self.witness {
  115. Some(witness) => witness.signatures(),
  116. None => None,
  117. };
  118. let witness_signatures = witness_signatures.ok_or(Error::SignaturesNotProvided)?;
  119. let mut pubkeys = spending_conditions.pubkeys.clone().unwrap_or_default();
  120. if secret.kind.eq(&Kind::P2PK) {
  121. pubkeys.push(PublicKey::from_str(&secret.secret_data.data)?);
  122. }
  123. for signature in witness_signatures.iter() {
  124. for v in &pubkeys {
  125. let sig = Signature::from_str(signature)?;
  126. if v.verify(msg, &sig).is_ok() {
  127. valid_sigs += 1;
  128. } else {
  129. tracing::debug!(
  130. "Could not verify signature: {sig} on message: {}",
  131. self.secret.to_string()
  132. )
  133. }
  134. }
  135. }
  136. if valid_sigs >= spending_conditions.num_sigs.unwrap_or(1) {
  137. return Ok(());
  138. }
  139. if let (Some(locktime), Some(refund_keys)) = (
  140. spending_conditions.locktime,
  141. spending_conditions.refund_keys,
  142. ) {
  143. // If lock time has passed check if refund witness signature is valid
  144. if locktime.lt(&unix_time()) {
  145. for s in witness_signatures.iter() {
  146. for v in &refund_keys {
  147. let sig = Signature::from_str(s).map_err(|_| Error::InvalidSignature)?;
  148. // As long as there is one valid refund signature it can be spent
  149. if v.verify(msg, &sig).is_ok() {
  150. return Ok(());
  151. }
  152. }
  153. }
  154. }
  155. }
  156. Err(Error::SpendConditionsNotMet)
  157. }
  158. }
  159. /// Returns count of valid signatures
  160. pub fn valid_signatures(msg: &[u8], pubkeys: &[PublicKey], signatures: &[Signature]) -> u64 {
  161. let mut count = 0;
  162. for pubkey in pubkeys {
  163. for signature in signatures {
  164. if pubkey.verify(msg, signature).is_ok() {
  165. count += 1;
  166. }
  167. }
  168. }
  169. count
  170. }
  171. impl BlindedMessage {
  172. /// Sign [BlindedMessage]
  173. pub fn sign_p2pk(&mut self, secret_key: SecretKey) -> Result<(), Error> {
  174. let msg: [u8; 33] = self.blinded_secret.to_bytes();
  175. let signature: Signature = secret_key.sign(&msg)?;
  176. let signatures = vec![signature.to_string()];
  177. match self.witness.as_mut() {
  178. Some(witness) => {
  179. witness.add_signatures(signatures);
  180. }
  181. None => {
  182. let mut p2pk_witness = Witness::P2PKWitness(P2PKWitness::default());
  183. p2pk_witness.add_signatures(signatures);
  184. self.witness = Some(p2pk_witness);
  185. }
  186. };
  187. Ok(())
  188. }
  189. /// Verify P2PK conditions on [BlindedMessage]
  190. pub fn verify_p2pk(&self, pubkeys: &Vec<PublicKey>, required_sigs: u64) -> Result<(), Error> {
  191. let mut valid_sigs = 0;
  192. if let Some(witness) = &self.witness {
  193. for signature in witness
  194. .signatures()
  195. .ok_or(Error::SignaturesNotProvided)?
  196. .iter()
  197. {
  198. for v in pubkeys {
  199. let msg = &self.blinded_secret.to_bytes();
  200. let sig = Signature::from_str(signature)?;
  201. if v.verify(msg, &sig).is_ok() {
  202. valid_sigs += 1;
  203. } else {
  204. tracing::debug!(
  205. "Could not verify signature: {sig} on message: {}",
  206. self.blinded_secret
  207. )
  208. }
  209. }
  210. }
  211. }
  212. if valid_sigs.ge(&required_sigs) {
  213. Ok(())
  214. } else {
  215. Err(Error::SpendConditionsNotMet)
  216. }
  217. }
  218. }
  219. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  220. pub enum SpendingConditions {
  221. /// NUT11 Spending conditions
  222. P2PKConditions {
  223. data: PublicKey,
  224. conditions: Option<Conditions>,
  225. },
  226. /// NUT14 Spending conditions
  227. HTLCConditions {
  228. data: Sha256Hash,
  229. conditions: Option<Conditions>,
  230. },
  231. }
  232. impl SpendingConditions {
  233. /// New HTLC [SpendingConditions]
  234. pub fn new_htlc(preimage: String, conditions: Option<Conditions>) -> Result<Self, Error> {
  235. let htlc = Sha256Hash::hash(&hex::decode(preimage)?);
  236. Ok(Self::HTLCConditions {
  237. data: htlc,
  238. conditions,
  239. })
  240. }
  241. /// New P2PK [SpendingConditions]
  242. pub fn new_p2pk(pubkey: PublicKey, conditions: Option<Conditions>) -> Self {
  243. Self::P2PKConditions {
  244. data: pubkey,
  245. conditions,
  246. }
  247. }
  248. /// Kind of [SpendingConditions]
  249. pub fn kind(&self) -> Kind {
  250. match self {
  251. Self::P2PKConditions { .. } => Kind::P2PK,
  252. Self::HTLCConditions { .. } => Kind::HTLC,
  253. }
  254. }
  255. pub fn num_sigs(&self) -> Option<u64> {
  256. match self {
  257. Self::P2PKConditions { conditions, .. } => conditions.as_ref().and_then(|c| c.num_sigs),
  258. Self::HTLCConditions { conditions, .. } => conditions.as_ref().and_then(|c| c.num_sigs),
  259. }
  260. }
  261. pub fn pubkeys(&self) -> Option<Vec<PublicKey>> {
  262. match self {
  263. Self::P2PKConditions { data, conditions } => {
  264. let mut pubkeys = vec![*data];
  265. if let Some(conditions) = conditions {
  266. pubkeys.extend(conditions.pubkeys.clone().unwrap_or_default());
  267. }
  268. Some(pubkeys)
  269. }
  270. Self::HTLCConditions { conditions, .. } => conditions.clone().and_then(|c| c.pubkeys),
  271. }
  272. }
  273. pub fn locktime(&self) -> Option<u64> {
  274. match self {
  275. Self::P2PKConditions { conditions, .. } => conditions.as_ref().and_then(|c| c.locktime),
  276. Self::HTLCConditions { conditions, .. } => conditions.as_ref().and_then(|c| c.locktime),
  277. }
  278. }
  279. pub fn refund_keys(&self) -> Option<Vec<PublicKey>> {
  280. match self {
  281. Self::P2PKConditions { conditions, .. } => {
  282. conditions.clone().and_then(|c| c.refund_keys)
  283. }
  284. Self::HTLCConditions { conditions, .. } => {
  285. conditions.clone().and_then(|c| c.refund_keys)
  286. }
  287. }
  288. }
  289. }
  290. impl TryFrom<&Secret> for SpendingConditions {
  291. type Error = Error;
  292. fn try_from(secret: &Secret) -> Result<SpendingConditions, Error> {
  293. let nut10_secret: Nut10Secret = secret.try_into()?;
  294. nut10_secret.try_into()
  295. }
  296. }
  297. impl TryFrom<Nut10Secret> for SpendingConditions {
  298. type Error = Error;
  299. fn try_from(secret: Nut10Secret) -> Result<SpendingConditions, Error> {
  300. match secret.kind {
  301. Kind::P2PK => Ok(SpendingConditions::P2PKConditions {
  302. data: PublicKey::from_str(&secret.secret_data.data)?,
  303. conditions: secret.secret_data.tags.and_then(|t| t.try_into().ok()),
  304. }),
  305. Kind::HTLC => Ok(Self::HTLCConditions {
  306. data: Sha256Hash::from_str(&secret.secret_data.data)
  307. .map_err(|_| Error::InvalidHash)?,
  308. conditions: secret.secret_data.tags.and_then(|t| t.try_into().ok()),
  309. }),
  310. }
  311. }
  312. }
  313. impl From<SpendingConditions> for super::nut10::Secret {
  314. fn from(conditions: SpendingConditions) -> super::nut10::Secret {
  315. match conditions {
  316. SpendingConditions::P2PKConditions { data, conditions } => {
  317. super::nut10::Secret::new(Kind::P2PK, data.to_hex(), conditions)
  318. }
  319. SpendingConditions::HTLCConditions { data, conditions } => {
  320. super::nut10::Secret::new(Kind::HTLC, data.to_string(), conditions)
  321. }
  322. }
  323. }
  324. }
  325. /// P2PK and HTLC spending conditions
  326. #[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
  327. pub struct Conditions {
  328. #[serde(skip_serializing_if = "Option::is_none")]
  329. pub locktime: Option<u64>,
  330. #[serde(skip_serializing_if = "Option::is_none")]
  331. pub pubkeys: Option<Vec<PublicKey>>,
  332. #[serde(skip_serializing_if = "Option::is_none")]
  333. pub refund_keys: Option<Vec<PublicKey>>,
  334. #[serde(skip_serializing_if = "Option::is_none")]
  335. pub num_sigs: Option<u64>,
  336. pub sig_flag: SigFlag,
  337. }
  338. impl Conditions {
  339. pub fn new(
  340. locktime: Option<u64>,
  341. pubkeys: Option<Vec<PublicKey>>,
  342. refund_keys: Option<Vec<PublicKey>>,
  343. num_sigs: Option<u64>,
  344. sig_flag: Option<SigFlag>,
  345. ) -> Result<Self, Error> {
  346. if let Some(locktime) = locktime {
  347. if locktime.lt(&unix_time()) {
  348. return Err(Error::LocktimeInPast);
  349. }
  350. }
  351. Ok(Self {
  352. locktime,
  353. pubkeys,
  354. refund_keys,
  355. num_sigs,
  356. sig_flag: sig_flag.unwrap_or_default(),
  357. })
  358. }
  359. }
  360. impl From<Conditions> for Vec<Vec<String>> {
  361. fn from(conditions: Conditions) -> Vec<Vec<String>> {
  362. let Conditions {
  363. locktime,
  364. pubkeys,
  365. refund_keys,
  366. num_sigs,
  367. sig_flag,
  368. } = conditions;
  369. let mut tags = Vec::new();
  370. if let Some(pubkeys) = pubkeys {
  371. tags.push(Tag::PubKeys(pubkeys.into_iter().collect()).as_vec());
  372. }
  373. if let Some(locktime) = locktime {
  374. tags.push(Tag::LockTime(locktime).as_vec());
  375. }
  376. if let Some(num_sigs) = num_sigs {
  377. tags.push(Tag::NSigs(num_sigs).as_vec());
  378. }
  379. if let Some(refund_keys) = refund_keys {
  380. tags.push(Tag::Refund(refund_keys).as_vec())
  381. }
  382. tags.push(Tag::SigFlag(sig_flag).as_vec());
  383. tags
  384. }
  385. }
  386. impl TryFrom<Vec<Vec<String>>> for Conditions {
  387. type Error = Error;
  388. fn try_from(tags: Vec<Vec<String>>) -> Result<Conditions, Self::Error> {
  389. let tags: HashMap<TagKind, Tag> = tags
  390. .into_iter()
  391. .map(|t| Tag::try_from(t).unwrap())
  392. .map(|t| (t.kind(), t))
  393. .collect();
  394. let pubkeys = match tags.get(&TagKind::Pubkeys) {
  395. Some(Tag::PubKeys(pubkeys)) => Some(pubkeys.clone()),
  396. _ => None,
  397. };
  398. let locktime = if let Some(tag) = tags.get(&TagKind::Locktime) {
  399. match tag {
  400. Tag::LockTime(locktime) => Some(*locktime),
  401. _ => None,
  402. }
  403. } else {
  404. None
  405. };
  406. let refund_keys = if let Some(tag) = tags.get(&TagKind::Refund) {
  407. match tag {
  408. Tag::Refund(keys) => Some(keys.clone()),
  409. _ => None,
  410. }
  411. } else {
  412. None
  413. };
  414. let sig_flag = if let Some(tag) = tags.get(&TagKind::SigFlag) {
  415. match tag {
  416. Tag::SigFlag(sigflag) => sigflag.clone(),
  417. _ => SigFlag::SigInputs,
  418. }
  419. } else {
  420. SigFlag::SigInputs
  421. };
  422. let num_sigs = if let Some(tag) = tags.get(&TagKind::NSigs) {
  423. match tag {
  424. Tag::NSigs(num_sigs) => Some(*num_sigs),
  425. _ => None,
  426. }
  427. } else {
  428. None
  429. };
  430. Ok(Conditions {
  431. locktime,
  432. pubkeys,
  433. refund_keys,
  434. num_sigs,
  435. sig_flag,
  436. })
  437. }
  438. }
  439. // P2PK and HTLC Spending condition tags
  440. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
  441. #[serde(rename_all = "lowercase")]
  442. pub enum TagKind {
  443. /// Signature flag
  444. SigFlag,
  445. /// Number signatures required
  446. #[serde(rename = "n_sigs")]
  447. NSigs,
  448. /// Locktime
  449. Locktime,
  450. /// Refund
  451. Refund,
  452. /// Pubkey
  453. Pubkeys,
  454. /// Custom tag kind
  455. Custom(String),
  456. }
  457. impl fmt::Display for TagKind {
  458. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  459. match self {
  460. Self::SigFlag => write!(f, "sigflag"),
  461. Self::NSigs => write!(f, "n_sigs"),
  462. Self::Locktime => write!(f, "locktime"),
  463. Self::Refund => write!(f, "refund"),
  464. Self::Pubkeys => write!(f, "pubkeys"),
  465. Self::Custom(kind) => write!(f, "{}", kind),
  466. }
  467. }
  468. }
  469. impl<S> From<S> for TagKind
  470. where
  471. S: AsRef<str>,
  472. {
  473. fn from(tag: S) -> Self {
  474. match tag.as_ref() {
  475. "sigflag" => Self::SigFlag,
  476. "n_sigs" => Self::NSigs,
  477. "locktime" => Self::Locktime,
  478. "refund" => Self::Refund,
  479. "pubkeys" => Self::Pubkeys,
  480. t => Self::Custom(t.to_owned()),
  481. }
  482. }
  483. }
  484. #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord, Hash)]
  485. pub enum SigFlag {
  486. #[default]
  487. SigInputs,
  488. SigAll,
  489. }
  490. impl fmt::Display for SigFlag {
  491. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  492. match self {
  493. Self::SigAll => write!(f, "SIG_ALL"),
  494. Self::SigInputs => write!(f, "SIG_INPUTS"),
  495. }
  496. }
  497. }
  498. impl FromStr for SigFlag {
  499. type Err = Error;
  500. fn from_str(tag: &str) -> Result<Self, Self::Err> {
  501. match tag {
  502. "SIG_ALL" => Ok(Self::SigAll),
  503. "SIG_INPUTS" => Ok(Self::SigInputs),
  504. _ => Err(Error::UnknownSigFlag),
  505. }
  506. }
  507. }
  508. pub fn enforce_sig_flag(proofs: Proofs) -> (SigFlag, HashSet<PublicKey>) {
  509. let mut sig_flag = SigFlag::SigInputs;
  510. let mut pubkeys = HashSet::new();
  511. for proof in proofs {
  512. if let Ok(secret) = Nut10Secret::try_from(proof.secret) {
  513. if secret.kind.eq(&Kind::P2PK) {
  514. if let Ok(verifying_key) = PublicKey::from_str(&secret.secret_data.data) {
  515. pubkeys.insert(verifying_key);
  516. }
  517. }
  518. if let Some(tags) = secret.secret_data.tags {
  519. if let Ok(conditions) = Conditions::try_from(tags) {
  520. if conditions.sig_flag.eq(&SigFlag::SigAll) {
  521. sig_flag = SigFlag::SigAll;
  522. }
  523. if let Some(pubs) = conditions.pubkeys {
  524. pubkeys.extend(pubs);
  525. }
  526. }
  527. }
  528. }
  529. }
  530. (sig_flag, pubkeys)
  531. }
  532. #[derive(Debug, Clone, Hash, PartialEq, Eq)]
  533. pub enum Tag {
  534. SigFlag(SigFlag),
  535. NSigs(u64),
  536. LockTime(u64),
  537. Refund(Vec<PublicKey>),
  538. PubKeys(Vec<PublicKey>),
  539. }
  540. impl Tag {
  541. pub fn kind(&self) -> TagKind {
  542. match self {
  543. Self::SigFlag(_) => TagKind::SigFlag,
  544. Self::NSigs(_) => TagKind::NSigs,
  545. Self::LockTime(_) => TagKind::Locktime,
  546. Self::Refund(_) => TagKind::Refund,
  547. Self::PubKeys(_) => TagKind::Pubkeys,
  548. }
  549. }
  550. /// Get [`Tag`] as string vector
  551. pub fn as_vec(&self) -> Vec<String> {
  552. self.clone().into()
  553. }
  554. }
  555. impl<S> TryFrom<Vec<S>> for Tag
  556. where
  557. S: AsRef<str>,
  558. {
  559. type Error = Error;
  560. fn try_from(tag: Vec<S>) -> Result<Self, Self::Error> {
  561. let tag_kind: TagKind = match tag.first() {
  562. Some(kind) => TagKind::from(kind),
  563. None => return Err(Error::KindNotFound),
  564. };
  565. match tag_kind {
  566. TagKind::SigFlag => Ok(Tag::SigFlag(SigFlag::from_str(tag[1].as_ref())?)),
  567. TagKind::NSigs => Ok(Tag::NSigs(tag[1].as_ref().parse()?)),
  568. TagKind::Locktime => Ok(Tag::LockTime(tag[1].as_ref().parse()?)),
  569. TagKind::Refund => {
  570. let pubkeys = tag
  571. .iter()
  572. .skip(1)
  573. .flat_map(|p| PublicKey::from_str(p.as_ref()))
  574. .collect();
  575. Ok(Self::Refund(pubkeys))
  576. }
  577. TagKind::Pubkeys => {
  578. let pubkeys = tag
  579. .iter()
  580. .skip(1)
  581. .flat_map(|p| PublicKey::from_str(p.as_ref()))
  582. .collect();
  583. Ok(Self::PubKeys(pubkeys))
  584. }
  585. _ => Err(Error::UnknownTag),
  586. }
  587. }
  588. }
  589. impl From<Tag> for Vec<String> {
  590. fn from(data: Tag) -> Self {
  591. match data {
  592. Tag::SigFlag(sigflag) => vec![TagKind::SigFlag.to_string(), sigflag.to_string()],
  593. Tag::NSigs(num_sig) => vec![TagKind::NSigs.to_string(), num_sig.to_string()],
  594. Tag::LockTime(locktime) => vec![TagKind::Locktime.to_string(), locktime.to_string()],
  595. Tag::PubKeys(pubkeys) => {
  596. let mut tag = vec![TagKind::Pubkeys.to_string()];
  597. for pubkey in pubkeys.into_iter() {
  598. tag.push(pubkey.to_string())
  599. }
  600. tag
  601. }
  602. Tag::Refund(pubkeys) => {
  603. let mut tag = vec![TagKind::Refund.to_string()];
  604. for pubkey in pubkeys {
  605. tag.push(pubkey.to_string())
  606. }
  607. tag
  608. }
  609. }
  610. }
  611. }
  612. impl Serialize for Tag {
  613. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  614. where
  615. S: Serializer,
  616. {
  617. let data: Vec<String> = self.as_vec();
  618. let mut seq = serializer.serialize_seq(Some(data.len()))?;
  619. for element in data.into_iter() {
  620. seq.serialize_element(&element)?;
  621. }
  622. seq.end()
  623. }
  624. }
  625. impl<'de> Deserialize<'de> for Tag {
  626. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  627. where
  628. D: Deserializer<'de>,
  629. {
  630. type Data = Vec<String>;
  631. let vec: Vec<String> = Data::deserialize(deserializer)?;
  632. Self::try_from(vec).map_err(DeserializerError::custom)
  633. }
  634. }
  635. #[cfg(test)]
  636. mod tests {
  637. use std::str::FromStr;
  638. use super::*;
  639. use crate::nuts::Id;
  640. use crate::secret::Secret;
  641. use crate::Amount;
  642. #[test]
  643. fn test_secret_ser() {
  644. let data = PublicKey::from_str(
  645. "033281c37677ea273eb7183b783067f5244933ef78d8c3f15b1a77cb246099c26e",
  646. )
  647. .unwrap();
  648. let conditions = Conditions {
  649. locktime: Some(99999),
  650. pubkeys: Some(vec![
  651. PublicKey::from_str(
  652. "02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904",
  653. )
  654. .unwrap(),
  655. PublicKey::from_str(
  656. "023192200a0cfd3867e48eb63b03ff599c7e46c8f4e41146b2d281173ca6c50c54",
  657. )
  658. .unwrap(),
  659. ]),
  660. refund_keys: Some(vec![PublicKey::from_str(
  661. "033281c37677ea273eb7183b783067f5244933ef78d8c3f15b1a77cb246099c26e",
  662. )
  663. .unwrap()]),
  664. num_sigs: Some(2),
  665. sig_flag: SigFlag::SigAll,
  666. };
  667. let secret: Nut10Secret = Nut10Secret::new(Kind::P2PK, data.to_string(), Some(conditions));
  668. let secret_str = serde_json::to_string(&secret).unwrap();
  669. let secret_der: Nut10Secret = serde_json::from_str(&secret_str).unwrap();
  670. assert_eq!(secret_der, secret);
  671. }
  672. #[test]
  673. fn sign_proof() {
  674. let secret_key =
  675. SecretKey::from_str("99590802251e78ee1051648439eedb003dc539093a48a44e7b8f2642c909ea37")
  676. .unwrap();
  677. let signing_key_two =
  678. SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000001")
  679. .unwrap();
  680. let signing_key_three =
  681. SecretKey::from_str("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f")
  682. .unwrap();
  683. let v_key: PublicKey = secret_key.public_key();
  684. let v_key_two: PublicKey = signing_key_two.public_key();
  685. let v_key_three: PublicKey = signing_key_three.public_key();
  686. let conditions = Conditions {
  687. locktime: Some(21000000000),
  688. pubkeys: Some(vec![v_key_two, v_key_three]),
  689. refund_keys: Some(vec![v_key]),
  690. num_sigs: Some(2),
  691. sig_flag: SigFlag::SigInputs,
  692. };
  693. let secret: Secret = Nut10Secret::new(Kind::P2PK, v_key.to_string(), Some(conditions))
  694. .try_into()
  695. .unwrap();
  696. let mut proof = Proof {
  697. keyset_id: Id::from_str("009a1f293253e41e").unwrap(),
  698. amount: Amount::ZERO,
  699. secret,
  700. c: PublicKey::from_str(
  701. "02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904",
  702. )
  703. .unwrap(),
  704. witness: Some(Witness::P2PKWitness(P2PKWitness { signatures: vec![] })),
  705. dleq: None,
  706. };
  707. proof.sign_p2pk(secret_key).unwrap();
  708. proof.sign_p2pk(signing_key_two).unwrap();
  709. assert!(proof.verify_p2pk().is_ok());
  710. }
  711. #[test]
  712. fn test_verify() {
  713. // Proof with a valid signature
  714. let json: &str = r#"{
  715. "amount":1,
  716. "secret":"[\"P2PK\",{\"nonce\":\"859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"sigflag\",\"SIG_INPUTS\"]]}]",
  717. "C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904",
  718. "id":"009a1f293253e41e",
  719. "witness":"{\"signatures\":[\"60f3c9b766770b46caac1d27e1ae6b77c8866ebaeba0b9489fe6a15a837eaa6fcd6eaa825499c72ac342983983fd3ba3a8a41f56677cc99ffd73da68b59e1383\"]}"
  720. }"#;
  721. let valid_proof: Proof = serde_json::from_str(json).unwrap();
  722. valid_proof.verify_p2pk().unwrap();
  723. assert!(valid_proof.verify_p2pk().is_ok());
  724. // Proof with a signature that is in a different secret
  725. let invalid_proof = r#"{"amount":1,"secret":"[\"P2PK\",{\"nonce\":\"859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"3426df9730d365a9d18d79bed2f3e78e9172d7107c55306ac5ddd1b2d065893366cfa24ff3c874ebf1fc22360ba5888ddf6ff5dbcb9e5f2f5a1368f7afc64f15\"]}"}"#;
  726. let invalid_proof: Proof = serde_json::from_str(invalid_proof).unwrap();
  727. assert!(invalid_proof.verify_p2pk().is_err());
  728. }
  729. #[test]
  730. fn verify_multi_sig() {
  731. // Proof with 2 valid signatures to satifiy the condition
  732. let valid_proof = r#"{"amount":0,"secret":"[\"P2PK\",{\"nonce\":\"0ed3fcb22c649dd7bbbdcca36e0c52d4f0187dd3b6a19efcc2bfbebb5f85b2a1\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"02142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"n_sigs\",\"2\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"83564aca48c668f50d022a426ce0ed19d3a9bdcffeeaee0dc1e7ea7e98e9eff1840fcc821724f623468c94f72a8b0a7280fa9ef5a54a1b130ef3055217f467b3\",\"9a72ca2d4d5075be5b511ee48dbc5e45f259bcf4a4e8bf18587f433098a9cd61ff9737dc6e8022de57c76560214c4568377792d4c2c6432886cc7050487a1f22\"]}"}"#;
  733. let valid_proof: Proof = serde_json::from_str(valid_proof).unwrap();
  734. assert!(valid_proof.verify_p2pk().is_ok());
  735. // Proof with only one of the required signatures
  736. let invalid_proof = r#"{"amount":0,"secret":"[\"P2PK\",{\"nonce\":\"0ed3fcb22c649dd7bbbdcca36e0c52d4f0187dd3b6a19efcc2bfbebb5f85b2a1\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"02142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"n_sigs\",\"2\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"83564aca48c668f50d022a426ce0ed19d3a9bdcffeeaee0dc1e7ea7e98e9eff1840fcc821724f623468c94f72a8b0a7280fa9ef5a54a1b130ef3055217f467b3\"]}"}"#;
  737. let invalid_proof: Proof = serde_json::from_str(invalid_proof).unwrap();
  738. // Verification should fail without the requires signatures
  739. assert!(invalid_proof.verify_p2pk().is_err());
  740. }
  741. #[test]
  742. fn verify_refund() {
  743. let valid_proof = r#"{"amount":1,"id":"009a1f293253e41e","secret":"[\"P2PK\",{\"nonce\":\"902685f492ef3bb2ca35a47ddbba484a3365d143b9776d453947dcbf1ddf9689\",\"data\":\"026f6a2b1d709dbca78124a9f30a742985f7eddd894e72f637f7085bf69b997b9a\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"03142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"locktime\",\"21\"],[\"n_sigs\",\"2\"],[\"refund\",\"026f6a2b1d709dbca78124a9f30a742985f7eddd894e72f637f7085bf69b997b9a\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","witness":"{\"signatures\":[\"710507b4bc202355c91ea3c147c0d0189c75e179d995e566336afd759cb342bcad9a593345f559d9b9e108ac2c9b5bd9f0b4b6a295028a98606a0a2e95eb54f7\"]}"}"#;
  744. let valid_proof: Proof = serde_json::from_str(valid_proof).unwrap();
  745. assert!(valid_proof.verify_p2pk().is_ok());
  746. let invalid_proof = r#"{"amount":1,"id":"009a1f293253e41e","secret":"[\"P2PK\",{\"nonce\":\"64c46e5d30df27286166814b71b5d69801704f23a7ad626b05688fbdb48dcc98\",\"data\":\"026f6a2b1d709dbca78124a9f30a742985f7eddd894e72f637f7085bf69b997b9a\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"03142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"locktime\",\"21\"],[\"n_sigs\",\"2\"],[\"refund\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","witness":"{\"signatures\":[\"f661d3dc046d636d47cb3d06586da42c498f0300373d1c2a4f417a44252cdf3809bce207c8888f934dba0d2b1671f1b8622d526840f2d5883e571b462630c1ff\"]}"}"#;
  747. let invalid_proof: Proof = serde_json::from_str(invalid_proof).unwrap();
  748. assert!(invalid_proof.verify_p2pk().is_err());
  749. }
  750. }