iop_keyvault/multicipher/
mod.rs

1//! A type-erased version of [`AsymmetricCrypto`] and [`KeyDerivationCrypto`]. Serialized versions
2//! of crypto concepts, like [`KeyId`], [`PublicKey`], [`PrivateKey`], [`Signature`],
3//! [`ExtendedPrivateKey`] and [`ExtendedPublicKey`] can be all deserialized into
4//! their [`MultiCipher`] versions.
5//! This allows multiple cryptographic algorithms to co-exist in a software, which is needed
6//! during migration of a single software to a new cryptography, or which is the status quo in
7//! larger software ecosystems.
8//!
9//! [`MultiCipher`] can be thought of a variant of multiple incompatible cipher suits, which are
10//! strongly typed, but are chosen at run-time.
11//!
12//! [`MultiCipher`]: struct.MultiCipher.html
13//! [`AsymmetricCrypto`]: ../trait.AsymmetricCrypto.html
14//! [`KeyDerivationCrypto`]: ../trait.KeyDerivationCrypto.html
15//! [`KeyId`]: ../trait.AsymmetricCrypto.html#associatedtype.KeyId
16//! [`PublicKey`]: ../trait.PublicKey.html
17//! [`PrivateKey`]: ../trait.PrivateKey.html
18//! [`Signature`]: ../trait.AsymmetricCrypto.html#associatedtype.Signature
19//! [`ExtendedPrivateKey`]: ../trait.ExtendedPrivateKey.html
20//! [`ExtendedPublicKey`]: ../trait.ExtendedPublicKey.html
21
22mod id;
23mod pk;
24mod sig;
25mod sk;
26
27use super::*;
28
29use std::hash::Hash;
30
31use crate::ed25519::{EdKeyId, EdPrivateKey, EdPublicKey, EdSignature};
32use crate::secp256k1::{SecpKeyId, SecpPrivateKey, SecpPublicKey, SecpSignature};
33use crate::{AsymmetricCrypto, PrivateKey, PublicKey};
34
35pub use id::MKeyId;
36pub use pk::MPublicKey;
37pub use sig::MSignature;
38pub use sk::MPrivateKey;
39
40/// A suite type that is used to keep the type-safety of the erased types in [`multicipher`]
41///
42/// [`multicipher`]: index.html
43#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
44pub enum CipherSuite {
45    /// The object tagged with this variant belongs to the [`ed25519`] module
46    ///
47    /// [`ed25519`]: ../ed25519/index.html
48    Ed25519,
49    /// The object tagged with this variant belongs to the [`secp256k1`] module
50    ///
51    /// [`secp256k1`]: ../secp256k1/index.html
52    Secp256k1,
53}
54
55impl CipherSuite {
56    fn as_byte(&self) -> u8 {
57        match self {
58            Self::Ed25519 => b'e',
59            Self::Secp256k1 => b's',
60        }
61    }
62
63    fn as_char(&self) -> char {
64        self.as_byte() as char
65    }
66
67    fn from_char(c: char) -> Result<Self> {
68        match c {
69            'e' => Ok(Self::Ed25519),
70            's' => Ok(Self::Secp256k1),
71            _ => bail!("Unknown crypto suite '{}'", c),
72        }
73    }
74}
75
76#[derive(Clone, Debug)]
77/// See the [module-level description](index.html).
78pub struct MultiCipher;
79
80impl AsymmetricCrypto for MultiCipher {
81    type KeyId = MKeyId;
82    type PublicKey = MPublicKey;
83    type PrivateKey = MPrivateKey;
84    type Signature = MSignature;
85}
86
87#[derive(Serialize, Deserialize)]
88struct ErasedBytes {
89    #[serde(rename = "s")]
90    suite: u8,
91    #[serde(rename = "v", with = "serde_bytes")]
92    value: Vec<u8>,
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[test]
100    fn create() {
101        let _cipher = MultiCipher {};
102    }
103}