dpp/identity/identity_public_key/
purpose.rs

1use crate::identity::Purpose::{
2    AUTHENTICATION, DECRYPTION, ENCRYPTION, OWNER, SYSTEM, TRANSFER, VOTING,
3};
4use anyhow::bail;
5use bincode::{Decode, Encode};
6#[cfg(feature = "cbor")]
7use ciborium::value::Value as CborValue;
8use serde_repr::{Deserialize_repr, Serialize_repr};
9use std::convert::TryFrom;
10
11#[repr(u8)]
12#[derive(
13    Debug,
14    PartialEq,
15    Eq,
16    Clone,
17    Copy,
18    Hash,
19    Serialize_repr,
20    Deserialize_repr,
21    Ord,
22    PartialOrd,
23    Encode,
24    Decode,
25    Default,
26    strum::EnumIter,
27)]
28pub enum Purpose {
29    /// at least one authentication key must be registered for all security levels
30    #[default]
31    AUTHENTICATION = 0,
32    /// this key cannot be used for signing documents
33    ENCRYPTION = 1,
34    /// this key cannot be used for signing documents
35    DECRYPTION = 2,
36    /// this key is used to sign credit transfer and withdrawal state transitions
37    /// this key can also be used by identities for claims and transfers of tokens
38    TRANSFER = 3,
39    /// this key cannot be used for signing documents
40    SYSTEM = 4,
41    /// this key cannot be used for signing documents
42    VOTING = 5,
43    /// this key is used to prove ownership of a masternode or evonode
44    OWNER = 6,
45}
46
47impl From<Purpose> for [u8; 1] {
48    fn from(purpose: Purpose) -> Self {
49        [purpose as u8]
50    }
51}
52
53impl From<Purpose> for &'static [u8; 1] {
54    fn from(purpose: Purpose) -> Self {
55        match purpose {
56            AUTHENTICATION => &[0],
57            ENCRYPTION => &[1],
58            DECRYPTION => &[2],
59            TRANSFER => &[3],
60            SYSTEM => &[4],
61            VOTING => &[5],
62            OWNER => &[6],
63        }
64    }
65}
66
67impl TryFrom<u8> for Purpose {
68    type Error = anyhow::Error;
69    fn try_from(value: u8) -> Result<Self, Self::Error> {
70        match value {
71            0 => Ok(AUTHENTICATION),
72            1 => Ok(ENCRYPTION),
73            2 => Ok(DECRYPTION),
74            3 => Ok(TRANSFER),
75            4 => Ok(SYSTEM),
76            5 => Ok(VOTING),
77            6 => Ok(OWNER),
78            value => bail!("unrecognized purpose: {}", value),
79        }
80    }
81}
82
83impl TryFrom<i32> for Purpose {
84    type Error = anyhow::Error;
85    fn try_from(value: i32) -> Result<Self, Self::Error> {
86        match value {
87            0 => Ok(AUTHENTICATION),
88            1 => Ok(ENCRYPTION),
89            2 => Ok(DECRYPTION),
90            3 => Ok(TRANSFER),
91            4 => Ok(SYSTEM),
92            5 => Ok(VOTING),
93            6 => Ok(OWNER),
94            value => bail!("unrecognized purpose: {}", value),
95        }
96    }
97}
98
99#[cfg(feature = "cbor")]
100impl Into<CborValue> for Purpose {
101    fn into(self) -> CborValue {
102        CborValue::from(self as u128)
103    }
104}
105impl std::fmt::Display for Purpose {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        write!(f, "{self:?}")
108    }
109}
110
111impl Purpose {
112    /// The full range of purposes
113    pub fn full_range() -> [Purpose; 6] {
114        [
115            AUTHENTICATION,
116            ENCRYPTION,
117            DECRYPTION,
118            TRANSFER,
119            VOTING,
120            OWNER,
121        ]
122    }
123    /// Just the authentication and withdraw purposes
124    pub fn searchable_purposes() -> [Purpose; 3] {
125        [AUTHENTICATION, TRANSFER, VOTING]
126    }
127    /// Just the encryption and decryption purposes
128    pub fn encryption_decryption() -> [Purpose; 2] {
129        [ENCRYPTION, DECRYPTION]
130    }
131}