keri_core/prefix/
attached_signature.rs

1use super::error::Error;
2use super::SelfSigningPrefix;
3use cesrox::{
4    conversion::from_text_to_bytes,
5    derivation_code::DerivationCode,
6    primitives::{
7        codes::{
8            attached_signature_code::AttachedSignatureCode, self_signing::SelfSigning,
9            PrimitiveCode,
10        },
11        CesrPrimitive,
12    },
13};
14use core::str::FromStr;
15use serde::{Deserialize, Deserializer, Serialize, Serializer};
16
17#[derive(Debug, PartialEq, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
18#[rkyv(compare(PartialEq), derive(Debug))]
19pub enum Index {
20    CurrentOnly(u16),
21    BothSame(u16),
22    BothDifferent(u16, u16),
23}
24
25impl Index {
26    pub fn current(&self) -> u16 {
27        *match self {
28            Index::CurrentOnly(current) => current,
29            Index::BothSame(current) => current,
30            Index::BothDifferent(current, _prev_next) => current,
31        }
32    }
33
34    pub fn previous_next(&self) -> Option<u16> {
35        match self {
36            Index::CurrentOnly(_) => None,
37            Index::BothSame(prev_next) => Some(*prev_next),
38            Index::BothDifferent(_, prev_next) => Some(*prev_next),
39        }
40    }
41}
42#[derive(Debug, PartialEq, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
43#[rkyv(compare(PartialEq), derive(Debug))]
44pub struct IndexedSignature {
45    pub index: Index,
46    pub signature: SelfSigningPrefix,
47}
48
49impl IndexedSignature {
50    pub fn new_both_same(signature: SelfSigningPrefix, index: u16) -> Self {
51        Self {
52            signature,
53            index: Index::BothSame(index),
54        }
55    }
56
57    pub fn new_both_diffrent(
58        signature: SelfSigningPrefix,
59        curr_index: u16,
60        prev_next_index: u16,
61    ) -> Self {
62        Self {
63            signature,
64            index: Index::BothDifferent(curr_index, prev_next_index),
65        }
66    }
67
68    pub fn new_current_only(signature: SelfSigningPrefix, curr_index: u16) -> Self {
69        Self {
70            index: Index::CurrentOnly(curr_index),
71            signature,
72        }
73    }
74}
75
76impl FromStr for IndexedSignature {
77    type Err = Error;
78
79    fn from_str(s: &str) -> Result<Self, Self::Err> {
80        let code = AttachedSignatureCode::from_str(s)?;
81
82        if (s.len()) == code.full_size() {
83            let lead = if code.code_size() % 4 != 0 {
84                code.code_size() % 4
85            } else {
86                0
87            };
88            let s_vec = from_text_to_bytes(s[code.code_size()..].as_bytes())?[lead..].to_vec();
89            let ssp = SelfSigningPrefix::new(code.code, s_vec);
90
91            Ok(Self {
92                index: code.index.into(),
93                signature: ssp,
94            })
95        } else {
96            Err(Error::IncorrectLengthError(s.into()))
97        }
98    }
99}
100
101impl CesrPrimitive for IndexedSignature {
102    fn derivative(&self) -> Vec<u8> {
103        self.signature.derivative()
104    }
105    fn derivation_code(&self) -> PrimitiveCode {
106        let code: SelfSigning = self.signature.get_code();
107        PrimitiveCode::IndexedSignature(AttachedSignatureCode::new(code, (&self.index).into()))
108    }
109}
110
111/// Serde compatible Serialize
112impl Serialize for IndexedSignature {
113    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
114    where
115        S: Serializer,
116    {
117        serializer.serialize_str(&self.to_str())
118    }
119}
120
121/// Serde compatible Deserialize
122impl<'de> Deserialize<'de> for IndexedSignature {
123    fn deserialize<D>(deserializer: D) -> Result<IndexedSignature, D::Error>
124    where
125        D: Deserializer<'de>,
126    {
127        let s = String::deserialize(deserializer)?;
128
129        IndexedSignature::from_str(&s).map_err(serde::de::Error::custom)
130    }
131}
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136
137    #[test]
138    fn deserialize() -> Result<(), Error> {
139        let attached_ed_1 = "ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
140        let attached_secp_2 = "BCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
141        let attached_448_3 = "0AADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
142
143        let pref_ed_1 = IndexedSignature::from_str(attached_ed_1)?;
144        let pref_secp_2 = IndexedSignature::from_str(attached_secp_2)?;
145        let pref_448_3 = IndexedSignature::from_str(attached_448_3)?;
146
147        assert_eq!(1, pref_ed_1.index.current());
148        assert_eq!(2, pref_secp_2.index.current());
149        assert_eq!(0, pref_448_3.index.current());
150        assert_eq!(Some(3), pref_448_3.index.previous_next());
151
152        assert_eq!(SelfSigning::Ed25519Sha512, pref_ed_1.signature.get_code());
153        assert_eq!(SelfSigning::Ed25519Sha512, pref_secp_2.signature.get_code());
154        assert_eq!(SelfSigning::Ed448, pref_448_3.signature.get_code());
155        Ok(())
156    }
157
158    #[test]
159    fn serialize() -> Result<(), Error> {
160        let pref_ed_2 =
161            IndexedSignature::new_both_same(SelfSigningPrefix::Ed25519Sha512(vec![0u8; 64]), 2);
162        let pref_ed_2_3 = IndexedSignature::new_both_diffrent(
163            SelfSigningPrefix::Ed25519Sha512(vec![0u8; 64]),
164            2,
165            3,
166        );
167        let pref_secp_6 = IndexedSignature::new_both_same(
168            SelfSigningPrefix::ECDSAsecp256k1Sha256(vec![0u8; 64]),
169            6,
170        );
171        let pref_448_4 =
172            IndexedSignature::new_both_diffrent(SelfSigningPrefix::Ed448(vec![0u8; 114]), 0, 4);
173
174        assert_eq!(88, pref_ed_2.to_str().len());
175        assert_eq!(88, pref_secp_6.to_str().len());
176        assert_eq!(156, pref_448_4.to_str().len());
177
178        assert_eq!("ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", pref_ed_2.to_str());
179        assert_eq!("2AACADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", pref_ed_2_3.to_str());
180        assert_eq!("CGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", pref_secp_6.to_str());
181        assert_eq!("0AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", pref_448_4.to_str());
182        Ok(())
183    }
184}