common.rs
 1  use std::fmt::Debug;
 2  
 3  use bitcoin_hashes::{sha256, Hash};
 4  use fedimint_core::encoding::{Decodable, Encodable};
 5  use fedimint_core::secp256k1;
 6  use secp256k1::{Keypair, Message, PublicKey, Secp256k1, Signing, Verification, SECP256K1};
 7  use serde::{Deserialize, Serialize};
 8  
 9  #[derive(Debug, Serialize, Deserialize, Encodable, Decodable)]
10  pub struct BackupRequest {
11      pub id: PublicKey,
12      #[serde(with = "fedimint_core::hex::serde")]
13      pub payload: Vec<u8>,
14      pub timestamp: std::time::SystemTime,
15  }
16  
17  impl BackupRequest {
18      fn hash(&self) -> sha256::Hash {
19          self.consensus_hash()
20      }
21  
22      pub fn sign(self, keypair: &Keypair) -> anyhow::Result<SignedBackupRequest> {
23          let signature =
24              SECP256K1.sign_schnorr(&Message::from_digest(*self.hash().as_ref()), keypair);
25  
26          Ok(SignedBackupRequest {
27              request: self,
28              signature,
29          })
30      }
31  }
32  
33  #[derive(Debug, Serialize, Deserialize)]
34  pub struct SignedBackupRequest {
35      #[serde(flatten)]
36      request: BackupRequest,
37      #[serde(with = "::fedimint_core::encoding::as_hex")]
38      pub signature: fedimint_core::secp256k1::schnorr::Signature,
39  }
40  
41  impl SignedBackupRequest {
42      pub fn verify_valid<C>(&self, ctx: &Secp256k1<C>) -> Result<&BackupRequest, secp256k1::Error>
43      where
44          C: Signing + Verification,
45      {
46          ctx.verify_schnorr(
47              &self.signature,
48              &Message::from_digest_slice(&self.request.hash().to_byte_array()).expect("Can't fail"),
49              &self.request.id.x_only_public_key().0,
50          )?;
51  
52          Ok(&self.request)
53      }
54  }