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