Skip to main content

cesr/core/matter/code/
seed.rs

1use super::cesr_code::CesrCode;
2use super::matter_code::MatterCode;
3use super::sealed::Sealed;
4use super::verkey::VerKeyCode;
5use crate::core::matter::error::ValidationError;
6#[cfg(feature = "alloc")]
7#[allow(
8    unused_imports,
9    reason = "alloc prelude items; subset used per cfg/feature combination"
10)]
11use alloc::string::ToString;
12
13/// CESR codes for supported private key (seed) types.
14#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
15pub enum SeedCode {
16    /// Ed25519 32-byte private key seed.
17    Ed25519Seed,
18    /// secp256k1 (ECDSA) 32-byte private key seed.
19    ECDSA256k1Seed,
20    /// Ed448 56-byte private key seed.
21    Ed448Seed,
22    /// secp256r1 / P-256 (ECDSA) 32-byte private key seed.
23    ECDSA256r1Seed,
24}
25
26impl SeedCode {
27    /// Returns the corresponding [`VerKeyCode`] for the public key derived from this seed.
28    #[must_use]
29    pub const fn verkey_code(&self) -> VerKeyCode {
30        match self {
31            Self::Ed25519Seed => VerKeyCode::Ed25519,
32            Self::ECDSA256k1Seed => VerKeyCode::ECDSA256k1,
33            Self::Ed448Seed => VerKeyCode::Ed448,
34            Self::ECDSA256r1Seed => VerKeyCode::ECDSA256r1,
35        }
36    }
37}
38
39impl Sealed for SeedCode {}
40
41impl CesrCode for SeedCode {
42    fn to_matter_code(&self) -> MatterCode {
43        match self {
44            Self::Ed25519Seed => MatterCode::Ed25519Seed,
45            Self::ECDSA256k1Seed => MatterCode::ECDSA256k1Seed,
46            Self::Ed448Seed => MatterCode::Ed448Seed,
47            Self::ECDSA256r1Seed => MatterCode::ECDSA256r1Seed,
48        }
49    }
50
51    fn as_str(&self) -> &'static str {
52        match self {
53            Self::Ed25519Seed => "A",
54            Self::ECDSA256k1Seed => "J",
55            Self::Ed448Seed => "K",
56            Self::ECDSA256r1Seed => "Q",
57        }
58    }
59}
60
61impl TryFrom<MatterCode> for SeedCode {
62    type Error = ValidationError;
63
64    fn try_from(code: MatterCode) -> Result<Self, Self::Error> {
65        match code {
66            MatterCode::Ed25519Seed => Ok(Self::Ed25519Seed),
67            MatterCode::ECDSA256k1Seed => Ok(Self::ECDSA256k1Seed),
68            MatterCode::Ed448Seed => Ok(Self::Ed448Seed),
69            MatterCode::ECDSA256r1Seed => Ok(Self::ECDSA256r1Seed),
70            _ => Err(ValidationError::UnknownMatterCode(code.to_string())),
71        }
72    }
73}
74
75impl From<SeedCode> for MatterCode {
76    fn from(code: SeedCode) -> Self {
77        code.to_matter_code()
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84    use crate::core::matter::code::MatterCode;
85    use crate::core::matter::code::VerKeyCode;
86
87    #[test]
88    fn seed_code_to_matter_code_roundtrip() {
89        let codes = [
90            (SeedCode::Ed25519Seed, MatterCode::Ed25519Seed),
91            (SeedCode::ECDSA256k1Seed, MatterCode::ECDSA256k1Seed),
92            (SeedCode::Ed448Seed, MatterCode::Ed448Seed),
93            (SeedCode::ECDSA256r1Seed, MatterCode::ECDSA256r1Seed),
94        ];
95        for (sc, mc) in codes {
96            assert_eq!(sc.to_matter_code(), mc);
97            assert_eq!(SeedCode::try_from(mc).unwrap(), sc);
98            assert_eq!(MatterCode::from(sc), mc);
99        }
100    }
101
102    #[test]
103    fn seed_code_rejects_non_seed() {
104        assert!(SeedCode::try_from(MatterCode::Ed25519).is_err());
105        assert!(SeedCode::try_from(MatterCode::Blake3_256).is_err());
106        assert!(SeedCode::try_from(MatterCode::Short).is_err());
107    }
108
109    #[test]
110    fn seed_code_as_str() {
111        assert_eq!(SeedCode::Ed25519Seed.as_str(), "A");
112        assert_eq!(SeedCode::ECDSA256k1Seed.as_str(), "J");
113        assert_eq!(SeedCode::Ed448Seed.as_str(), "K");
114        assert_eq!(SeedCode::ECDSA256r1Seed.as_str(), "Q");
115    }
116
117    #[test]
118    fn seed_code_verkey_relationship() {
119        assert_eq!(SeedCode::Ed25519Seed.verkey_code(), VerKeyCode::Ed25519);
120        assert_eq!(
121            SeedCode::ECDSA256k1Seed.verkey_code(),
122            VerKeyCode::ECDSA256k1
123        );
124        assert_eq!(SeedCode::Ed448Seed.verkey_code(), VerKeyCode::Ed448);
125        assert_eq!(
126            SeedCode::ECDSA256r1Seed.verkey_code(),
127            VerKeyCode::ECDSA256r1
128        );
129    }
130}