geph5_broker_protocol/
signed.rs1use std::marker::PhantomData;
2
3use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey};
4
5use serde::{de::DeserializeOwned, Deserialize, Serialize};
6use serde_with::serde_as;
7use stdcode::StdcodeSerializeExt;
8use thiserror::Error;
9
10#[serde_as]
11#[derive(Serialize, Deserialize, Clone, Debug)]
12pub struct StdcodeSigned<T> {
14 pub inner: T,
15
16 pub signature: Signature,
17 pub pubkey: VerifyingKey,
18}
19
20impl<T: Serialize> StdcodeSigned<T> {
21 pub fn new(inner: T, domain: &str, seckey: &SigningKey) -> Self {
23 let to_sign =
24 blake3::keyed_hash(blake3::hash(domain.as_bytes()).as_bytes(), &inner.stdcode());
25 let signature = seckey.sign(to_sign.as_bytes());
26 StdcodeSigned {
27 inner,
28 signature,
29 pubkey: seckey.verifying_key(),
30 }
31 }
32
33 pub fn verify(
35 self,
36 domain: &str,
37 is_valid_pk: impl FnOnce(&VerifyingKey) -> bool,
38 ) -> Result<T, VerifyError> {
39 if !is_valid_pk(&self.pubkey) {
40 return Err(VerifyError::InvalidPublicKey);
41 }
42 let to_sign = blake3::keyed_hash(
43 blake3::hash(domain.as_bytes()).as_bytes(),
44 &self.inner.stdcode(),
45 );
46 self.pubkey
47 .verify_strict(to_sign.as_bytes(), &self.signature)
48 .ok()
49 .ok_or(VerifyError::InvalidSignature)?;
50 Ok(self.inner)
51 }
52}
53
54#[serde_as]
55#[derive(Serialize, Deserialize, Clone, Debug)]
56pub struct JsonSigned<T> {
58 inner_literal: String,
59
60 signature: Signature,
61 pubkey: VerifyingKey,
62
63 _phantom: PhantomData<T>,
64}
65
66impl<T: Serialize + DeserializeOwned> JsonSigned<T> {
67 pub fn new(inner: T, domain: &str, seckey: &SigningKey) -> Self {
69 let inner_literal = serde_json::to_string(&inner).unwrap();
70 let to_sign = blake3::keyed_hash(
71 blake3::hash(domain.as_bytes()).as_bytes(),
72 inner_literal.as_bytes(),
73 );
74 let signature = seckey.sign(to_sign.as_bytes());
75 JsonSigned {
76 inner_literal,
77 signature,
78 pubkey: seckey.verifying_key(),
79
80 _phantom: PhantomData,
81 }
82 }
83
84 pub fn pubkey(&self) -> VerifyingKey {
86 self.pubkey
87 }
88
89 pub fn verify(
91 self,
92 domain: &str,
93 is_valid_pk: impl FnOnce(&VerifyingKey) -> bool,
94 ) -> Result<T, VerifyError> {
95 if !is_valid_pk(&self.pubkey) {
96 return Err(VerifyError::InvalidPublicKey);
97 }
98 let to_sign = blake3::keyed_hash(
99 blake3::hash(domain.as_bytes()).as_bytes(),
100 self.inner_literal.as_bytes(),
101 );
102 self.pubkey
103 .verify_strict(to_sign.as_bytes(), &self.signature)
104 .ok()
105 .ok_or(VerifyError::InvalidSignature)?;
106 serde_json::from_str(&self.inner_literal).map_err(|_| VerifyError::CannotDeserialize)
107 }
108}
109
110#[derive(Error, Debug)]
111pub enum VerifyError {
112 #[error("Invalid public key")]
113 InvalidPublicKey,
114
115 #[error("Invalid signature")]
116 InvalidSignature,
117
118 #[error("Could not deserialize interior value")]
119 CannotDeserialize,
120}