iop_morpheus_proto/crypto/
sign.rs1use super::*;
2
3use crate::{
4 crypto::hash::{Content, ContentId},
5 data::*,
6};
7use iop_keyvault::{
8 multicipher::{MKeyId, MPrivateKey, MPublicKey, MSignature},
9 PrivateKey, PublicKey,
10};
11
12pub trait Signable: Content {
13 fn content_to_sign(&self) -> Result<Vec<u8>> {
14 Ok(self.content_id()?.into_bytes())
15 }
16}
17
18impl Signable for serde_json::Value {}
19
20impl Signable for Box<[u8]> {
21 fn content_to_sign(&self) -> Result<Vec<u8>> {
22 Ok(self.as_ref().to_owned())
23 }
24}
25
26impl Signable for Vec<u8> {
27 fn content_to_sign(&self) -> Result<Vec<u8>> {
28 Ok(self.to_owned())
29 }
30}
31
32#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
34#[serde(from = "SignatureSerializationFormat<T>", into = "SignatureSerializationFormat<T>")]
35pub struct Signed<T>
36where
37 T: Signable,
38{
39 content: T,
40 public_key: MPublicKey,
41 signature: MSignature,
42 nonce: Option<Nonce264>,
43 }
46
47impl<T> Signed<T>
48where
49 T: Signable,
50{
51 pub fn new(public_key: MPublicKey, content: T, signature: MSignature) -> Self {
52 Self { public_key, content, signature, nonce: None }
53 }
54
55 pub fn from_parts(
56 public_key: MPublicKey, content: T, signature: MSignature, nonce: Option<Nonce264>,
57 ) -> Self {
58 Self { public_key, content, signature, nonce }
59 }
60
61 pub fn into_parts(self) -> (MPublicKey, T, MSignature, Option<Nonce264>) {
62 (self.public_key, self.content, self.signature, self.nonce)
63 }
64
65 pub fn content(&self) -> &T {
66 &self.content
67 }
68
69 pub fn public_key(&self) -> &MPublicKey {
70 &self.public_key
71 }
72
73 pub fn signature(&self) -> &MSignature {
74 &self.signature
75 }
76
77 pub fn validate(&self) -> bool {
78 match self.content.content_to_sign() {
79 Ok(content) => self.public_key.verify(content, &self.signature),
80 Err(_) => false,
81 }
82 }
83
84 pub fn validate_with_keyid(&self, signer_id: Option<&MKeyId>) -> bool {
85 let mut valid = self.validate();
86 if let Some(id) = signer_id {
87 valid &= self.public_key.validate_id(id);
88 }
89 valid
90 }
91
92 pub fn validate_with_did_doc(
94 &self, on_behalf_of: &DidDocument, from_inc: Option<BlockHeight>,
95 until_exc: Option<BlockHeight>,
96 ) -> Result<ValidationResult> {
97 let from = from_inc.unwrap_or(1);
98 let until = until_exc.unwrap_or(on_behalf_of.queried_at_height);
99
100 let auth = Authentication::PublicKey(self.public_key.to_owned());
101 let mut issues = on_behalf_of.validate_right(&auth, Right::Impersonation, from, until)?;
102
103 if !self.validate() {
104 issues.add_issue(ValidationIssueSeverity::Error, "Signature is invalid");
105 }
106 Ok(issues)
107 }
108}
109
110#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
111struct SignatureTuple {
112 #[serde(with = "serde_str", rename = "publicKey")]
113 public_key: MPublicKey,
114 #[serde(with = "serde_str")]
115 bytes: MSignature,
116}
117
118#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
119pub struct SignatureSerializationFormat<T> {
120 signature: SignatureTuple,
121 content: T,
122 #[serde(skip_serializing_if = "Option::is_none", default)]
123 nonce: Option<Nonce264>,
124}
125
126impl<T: Signable> From<Signed<T>> for SignatureSerializationFormat<T> {
127 fn from(src: Signed<T>) -> Self {
128 SignatureSerializationFormat {
129 content: src.content,
130 signature: SignatureTuple { public_key: src.public_key, bytes: src.signature },
131 nonce: src.nonce,
132 }
133 }
134}
135
136impl<T: Signable> From<SignatureSerializationFormat<T>> for Signed<T> {
137 fn from(src: SignatureSerializationFormat<T>) -> Self {
138 Signed {
139 content: src.content,
140 public_key: src.signature.public_key,
141 signature: src.signature.bytes,
142 nonce: src.nonce,
143 }
144 }
145}
146
147pub trait SyncMorpheusSigner {
148 fn sign(&self, data: &[u8]) -> Result<(MPublicKey, MSignature)>;
149
150 fn sign_witness_request(&self, request: WitnessRequest) -> Result<Signed<WitnessRequest>> {
151 let content_to_sign = request.content_to_sign()?;
152 let (public_key, signature) = self.sign(&content_to_sign)?;
153 Ok(Signed::new(public_key, request, signature))
154 }
155
156 fn sign_witness_statement(
157 &self, statement: WitnessStatement,
158 ) -> Result<Signed<WitnessStatement>> {
159 let content_to_sign = statement.content_to_sign()?;
160 let (public_key, signature) = self.sign(&content_to_sign)?;
161 Ok(Signed::new(public_key, statement, signature))
162 }
163
164 fn sign_claim_presentation(
165 &self, presentation: ClaimPresentation,
166 ) -> Result<Signed<ClaimPresentation>> {
167 let content_to_sign = presentation.content_to_sign()?;
168 let (public_key, signature) = self.sign(&content_to_sign)?;
169 Ok(Signed::new(public_key, presentation, signature))
170 }
171}
172
173impl<T: SyncMorpheusSigner + Sized> SyncMorpheusSigner for Box<T> {
174 fn sign(&self, data: &[u8]) -> Result<(MPublicKey, MSignature)> {
175 self.as_ref().sign(data)
176 }
177}
178
179pub struct PrivateKeySigner {
180 private_key: MPrivateKey,
181}
182
183impl PrivateKeySigner {
184 pub fn new(private_key: MPrivateKey) -> Self {
185 Self { private_key }
186 }
187}
188
189impl SyncMorpheusSigner for PrivateKeySigner {
190 fn sign(&self, data: &[u8]) -> Result<(MPublicKey, MSignature)> {
191 let signature = self.private_key.sign(data);
192 Ok((self.private_key.public_key(), signature))
193 }
194}
195
196pub type BlockHash = ContentId;
197
198#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
199pub struct AfterProof {
200 #[serde(rename = "blockHash")]
201 block_hash: BlockHash,
202 #[serde(rename = "blockHeight")]
203 block_height: BlockHeight,
204}
205
206#[derive(Clone, Debug, Deserialize, Serialize)]
211pub struct AfterEnvelope<T: Signable> {
212 content: T,
215 proof: AfterProof, }
217
218