crypto_dispatch/
validation.rs1use crate::AlgorithmError;
6use codec_multikey::{parse_multikey, validate_key_binding, KeyBindingInput};
7use crypto_core::Algorithm;
8
9const SLH_DSA_SHA2_128S_PUBLIC_KEY_LEN: usize = 32;
10
11fn expected_public_key_len(algorithm: Algorithm) -> Result<usize, AlgorithmError> {
12 match algorithm {
13 Algorithm::Ed25519 => {
14 #[cfg(feature = "ed25519")]
15 {
16 Ok(32)
17 }
18 #[cfg(not(feature = "ed25519"))]
19 {
20 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
21 }
22 }
23 Algorithm::X25519 => {
24 #[cfg(feature = "x25519")]
25 {
26 Ok(32)
27 }
28 #[cfg(not(feature = "x25519"))]
29 {
30 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
31 }
32 }
33 Algorithm::P256 => {
34 #[cfg(feature = "p256")]
35 {
36 Ok(33)
37 }
38 #[cfg(not(feature = "p256"))]
39 {
40 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
41 }
42 }
43 Algorithm::P384 => {
44 #[cfg(feature = "p384")]
45 {
46 Ok(crypto_p384::P384_PUBLIC_KEY_COMPRESSED_LEN)
47 }
48 #[cfg(not(feature = "p384"))]
49 {
50 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
51 }
52 }
53 Algorithm::P521 => {
54 #[cfg(feature = "p521")]
55 {
56 Ok(crypto_p521::P521_PUBLIC_KEY_COMPRESSED_LEN)
57 }
58 #[cfg(not(feature = "p521"))]
59 {
60 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
61 }
62 }
63 Algorithm::Secp256k1 => {
64 #[cfg(feature = "secp256k1")]
65 {
66 Ok(33)
67 }
68 #[cfg(not(feature = "secp256k1"))]
69 {
70 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
71 }
72 }
73 Algorithm::MlDsa44 => {
74 #[cfg(feature = "ml-dsa-44")]
75 {
76 Ok(1312)
77 }
78 #[cfg(not(feature = "ml-dsa-44"))]
79 {
80 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
81 }
82 }
83 Algorithm::MlDsa65 => {
84 #[cfg(feature = "ml-dsa-65")]
85 {
86 Ok(1952)
87 }
88 #[cfg(not(feature = "ml-dsa-65"))]
89 {
90 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
91 }
92 }
93 Algorithm::MlDsa87 => {
94 #[cfg(feature = "ml-dsa-87")]
95 {
96 Ok(2592)
97 }
98 #[cfg(not(feature = "ml-dsa-87"))]
99 {
100 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
101 }
102 }
103 Algorithm::SlhDsaSha2_128s => Ok(SLH_DSA_SHA2_128S_PUBLIC_KEY_LEN),
104 Algorithm::MlKem512 => {
105 #[cfg(feature = "ml-kem-512")]
106 {
107 Ok(800)
108 }
109 #[cfg(not(feature = "ml-kem-512"))]
110 {
111 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
112 }
113 }
114 Algorithm::MlKem768 => {
115 #[cfg(feature = "ml-kem-768")]
116 {
117 Ok(1184)
118 }
119 #[cfg(not(feature = "ml-kem-768"))]
120 {
121 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
122 }
123 }
124 Algorithm::MlKem1024 => {
125 #[cfg(feature = "ml-kem-1024")]
126 {
127 Ok(1568)
128 }
129 #[cfg(not(feature = "ml-kem-1024"))]
130 {
131 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
132 }
133 }
134 Algorithm::XWing768 => {
135 #[cfg(feature = "x-wing")]
136 {
137 Ok(crypto_x_wing::X_WING_768_PUBLIC_KEY_LEN)
138 }
139 #[cfg(not(feature = "x-wing"))]
140 {
141 Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
142 }
143 }
144 }
145}
146
147pub fn validate_verification_method_multikey(
155 algorithm: Algorithm,
156 binding_type: &str,
157 public_key_multibase: &str,
158) -> Result<(), AlgorithmError> {
159 let expected_len = expected_public_key_len(algorithm)?;
162
163 let parsed =
164 parse_multikey(public_key_multibase).map_err(|_| AlgorithmError::InvalidKey(algorithm))?;
165
166 validate_key_binding(
168 KeyBindingInput {
169 binding_type,
170 algorithm: Some(algorithm.as_str()),
171 },
172 &parsed,
173 )
174 .map_err(|_| AlgorithmError::InvalidKey(algorithm))?;
175
176 if parsed.public_key.len() != expected_len {
177 return Err(AlgorithmError::InvalidKey(algorithm));
178 }
179
180 Ok(())
181}