Skip to main content

iop_morpheus_proto/crypto/
sign.rs

1use 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// TODO implement Hash for MPublicKey and MSignature
33#[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    // TODO ClaimPresentation might be needed to prove proper right of delegated signing.
44    // on_behalf_of: Did,
45}
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    // TODO add Before/AfterProofs as optional arguments here
93    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//impl Content for AfterProof {}
207//impl Signable for AfterProof {}
208
209// TODO Eq, PartialEq and maybe PartialOrd for AfterEnvelope
210#[derive(Clone, Debug, Deserialize, Serialize)]
211pub struct AfterEnvelope<T: Signable> {
212    // TODO will contentId be fetched from the content or needs a separate field?
213    //      should we just use the contentId here and provide another way to resolve the content from it?
214    content: T,
215    proof: AfterProof, // TODO is a transactionId also needed here?
216}
217
218// impl<T: Signable> MaskableContent for AfterEnvelope<T> {}
219// impl<T: Signable> Signable for AfterEnvelope<T> {}