Skip to main content

codec_multicodec/
table.rs

1// SPDX-FileCopyrightText: 2026 ReallyMe LLC
2//
3// SPDX-License-Identifier: MIT OR Apache-2.0
4
5/// Multicodec table tag.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum CodecTag {
9    /// `encryption` table tag.
10    Encryption,
11    /// `hash` table tag.
12    Hash,
13    /// `key` table tag.
14    Key,
15    /// `multihash` table tag.
16    Multihash,
17    /// `multikey` table tag.
18    Multikey,
19}
20
21/// Key-material class for codecs that carry raw key bytes.
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23#[non_exhaustive]
24pub enum KeyMaterialKind {
25    /// The codec is not raw key material.
26    NotKey,
27    /// Public key material that is safe for `multikey` verification methods.
28    PublicKey,
29    /// Private key material. The codec is known, but `multikey` must reject it.
30    PrivateKey,
31    /// Symmetric key material. The codec is known, but `multikey` must reject it.
32    SymmetricKey,
33}
34
35/// Static metadata for one multicodec entry.
36#[derive(Debug, Clone)]
37pub struct CodecSpec {
38    /// Multicodec table tag.
39    pub tag: CodecTag,
40
41    /// Key-material class for `key` codecs.
42    pub key_material: KeyMaterialKind,
43
44    /// Human-readable algorithm name
45    pub alg: &'static str,
46
47    /// Multicodec varint prefix bytes
48    pub codec: &'static [u8],
49
50    /// Expected raw public key length AFTER prefix
51    pub key_length: KeyLength,
52}
53
54/// Expected payload length without conflating variable keys and non-key codecs.
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub enum KeyLength {
57    /// A payload with an exact byte length.
58    Fixed(usize),
59    /// A nonempty variable-length payload, such as an RSA key.
60    Variable,
61    /// This codec does not represent a key payload.
62    NotApplicable,
63}
64
65/// Single source of truth for multicodec prefixes
66pub static MULTICODEC_TABLE: &[(&str, CodecSpec)] = &[
67    (
68        "sha2-256",
69        CodecSpec {
70            tag: CodecTag::Multihash,
71            key_material: KeyMaterialKind::NotKey,
72            alg: "SHA2-256",
73            codec: &[0x12],
74            key_length: KeyLength::Fixed(32),
75        },
76    ),
77    (
78        "sha2-512",
79        CodecSpec {
80            tag: CodecTag::Multihash,
81            key_material: KeyMaterialKind::NotKey,
82            alg: "SHA2-512",
83            codec: &[0x13],
84            key_length: KeyLength::Fixed(64),
85        },
86    ),
87    (
88        "sha3-512",
89        CodecSpec {
90            tag: CodecTag::Multihash,
91            key_material: KeyMaterialKind::NotKey,
92            alg: "SHA3-512",
93            codec: &[0x14],
94            key_length: KeyLength::Fixed(64),
95        },
96    ),
97    (
98        "sha3-384",
99        CodecSpec {
100            tag: CodecTag::Multihash,
101            key_material: KeyMaterialKind::NotKey,
102            alg: "SHA3-384",
103            codec: &[0x15],
104            key_length: KeyLength::Fixed(48),
105        },
106    ),
107    (
108        "sha3-256",
109        CodecSpec {
110            tag: CodecTag::Multihash,
111            key_material: KeyMaterialKind::NotKey,
112            alg: "SHA3-256",
113            codec: &[0x16],
114            key_length: KeyLength::Fixed(32),
115        },
116    ),
117    (
118        "sha3-224",
119        CodecSpec {
120            tag: CodecTag::Multihash,
121            key_material: KeyMaterialKind::NotKey,
122            alg: "SHA3-224",
123            codec: &[0x17],
124            key_length: KeyLength::Fixed(28),
125        },
126    ),
127    (
128        "sha2-384",
129        CodecSpec {
130            tag: CodecTag::Multihash,
131            key_material: KeyMaterialKind::NotKey,
132            alg: "SHA2-384",
133            codec: &[0x20],
134            key_length: KeyLength::Fixed(48),
135        },
136    ),
137    (
138        "aes-128",
139        CodecSpec {
140            tag: CodecTag::Key,
141            key_material: KeyMaterialKind::SymmetricKey,
142            alg: "AES-128",
143            codec: &[0xa0, 0x01],
144            key_length: KeyLength::Fixed(16),
145        },
146    ),
147    (
148        "aes-192",
149        CodecSpec {
150            tag: CodecTag::Key,
151            key_material: KeyMaterialKind::SymmetricKey,
152            alg: "AES-192",
153            codec: &[0xa1, 0x01],
154            key_length: KeyLength::Fixed(24),
155        },
156    ),
157    (
158        "aes-256",
159        CodecSpec {
160            tag: CodecTag::Key,
161            key_material: KeyMaterialKind::SymmetricKey,
162            alg: "AES-256",
163            codec: &[0xa2, 0x01],
164            key_length: KeyLength::Fixed(32),
165        },
166    ),
167    (
168        "chacha-128",
169        CodecSpec {
170            tag: CodecTag::Key,
171            key_material: KeyMaterialKind::SymmetricKey,
172            alg: "ChaCha-128",
173            codec: &[0xa3, 0x01],
174            key_length: KeyLength::Fixed(16),
175        },
176    ),
177    (
178        "chacha-256",
179        CodecSpec {
180            tag: CodecTag::Key,
181            key_material: KeyMaterialKind::SymmetricKey,
182            alg: "ChaCha-256",
183            codec: &[0xa4, 0x01],
184            key_length: KeyLength::Fixed(32),
185        },
186    ),
187    (
188        "ed25519-pub",
189        CodecSpec {
190            tag: CodecTag::Key,
191            key_material: KeyMaterialKind::PublicKey,
192            alg: "Ed25519",
193            codec: &[0xed, 0x01],
194            key_length: KeyLength::Fixed(32),
195        },
196    ),
197    (
198        "x25519-pub",
199        CodecSpec {
200            tag: CodecTag::Key,
201            key_material: KeyMaterialKind::PublicKey,
202            alg: "X25519",
203            codec: &[0xec, 0x01],
204            key_length: KeyLength::Fixed(32),
205        },
206    ),
207    (
208        "p256-pub",
209        CodecSpec {
210            tag: CodecTag::Key,
211            key_material: KeyMaterialKind::PublicKey,
212            alg: "P-256",
213            codec: &[0x80, 0x24],
214            key_length: KeyLength::Fixed(33),
215        },
216    ),
217    (
218        "p384-pub",
219        CodecSpec {
220            tag: CodecTag::Key,
221            key_material: KeyMaterialKind::PublicKey,
222            alg: "P-384",
223            codec: &[0x81, 0x24],
224            key_length: KeyLength::Fixed(49),
225        },
226    ),
227    (
228        "p521-pub",
229        CodecSpec {
230            tag: CodecTag::Key,
231            key_material: KeyMaterialKind::PublicKey,
232            alg: "P-521",
233            codec: &[0x82, 0x24],
234            key_length: KeyLength::Fixed(67),
235        },
236    ),
237    (
238        "ed448-pub",
239        CodecSpec {
240            tag: CodecTag::Key,
241            key_material: KeyMaterialKind::PublicKey,
242            alg: "Ed448",
243            codec: &[0x83, 0x24],
244            key_length: KeyLength::Fixed(57),
245        },
246    ),
247    (
248        "rsa-pub",
249        CodecSpec {
250            tag: CodecTag::Key,
251            key_material: KeyMaterialKind::PublicKey,
252            alg: "RSA",
253            codec: &[0x85, 0x24],
254            key_length: KeyLength::Variable,
255        },
256    ),
257    (
258        "secp256k1-pub",
259        CodecSpec {
260            tag: CodecTag::Key,
261            key_material: KeyMaterialKind::PublicKey,
262            alg: "secp256k1",
263            codec: &[0xe7, 0x01],
264            key_length: KeyLength::Fixed(33),
265        },
266    ),
267    (
268        "mldsa-44-pub",
269        CodecSpec {
270            tag: CodecTag::Key,
271            key_material: KeyMaterialKind::PublicKey,
272            alg: "ML-DSA-44",
273            codec: &[0x90, 0x24],
274            key_length: KeyLength::Fixed(1312),
275        },
276    ),
277    (
278        "mldsa-65-pub",
279        CodecSpec {
280            tag: CodecTag::Key,
281            key_material: KeyMaterialKind::PublicKey,
282            alg: "ML-DSA-65",
283            codec: &[0x91, 0x24],
284            key_length: KeyLength::Fixed(1952),
285        },
286    ),
287    (
288        "mldsa-87-pub",
289        CodecSpec {
290            tag: CodecTag::Key,
291            key_material: KeyMaterialKind::PublicKey,
292            alg: "ML-DSA-87",
293            codec: &[0x92, 0x24],
294            key_length: KeyLength::Fixed(2592),
295        },
296    ),
297    (
298        "mlkem-512-pub",
299        CodecSpec {
300            tag: CodecTag::Key,
301            key_material: KeyMaterialKind::PublicKey,
302            alg: "ML-KEM-512",
303            codec: &[0x8b, 0x24],
304            key_length: KeyLength::Fixed(800),
305        },
306    ),
307    (
308        "mlkem-768-pub",
309        CodecSpec {
310            tag: CodecTag::Key,
311            key_material: KeyMaterialKind::PublicKey,
312            alg: "ML-KEM-768",
313            codec: &[0x8c, 0x24],
314            key_length: KeyLength::Fixed(1184),
315        },
316    ),
317    (
318        "mlkem-1024-pub",
319        CodecSpec {
320            tag: CodecTag::Key,
321            key_material: KeyMaterialKind::PublicKey,
322            alg: "ML-KEM-1024",
323            codec: &[0x8d, 0x24],
324            key_length: KeyLength::Fixed(1568),
325        },
326    ),
327    (
328        "ed25519-priv",
329        CodecSpec {
330            tag: CodecTag::Key,
331            key_material: KeyMaterialKind::PrivateKey,
332            alg: "Ed25519",
333            codec: &[0x80, 0x26],
334            key_length: KeyLength::Fixed(32),
335        },
336    ),
337    (
338        "secp256k1-priv",
339        CodecSpec {
340            tag: CodecTag::Key,
341            key_material: KeyMaterialKind::PrivateKey,
342            alg: "secp256k1",
343            codec: &[0x81, 0x26],
344            key_length: KeyLength::Fixed(32),
345        },
346    ),
347    (
348        "x25519-priv",
349        CodecSpec {
350            tag: CodecTag::Key,
351            key_material: KeyMaterialKind::PrivateKey,
352            alg: "X25519",
353            codec: &[0x82, 0x26],
354            key_length: KeyLength::Fixed(32),
355        },
356    ),
357    (
358        "rsa-priv",
359        CodecSpec {
360            tag: CodecTag::Key,
361            key_material: KeyMaterialKind::PrivateKey,
362            alg: "RSA",
363            codec: &[0x85, 0x26],
364            key_length: KeyLength::Variable,
365        },
366    ),
367    (
368        "p256-priv",
369        CodecSpec {
370            tag: CodecTag::Key,
371            key_material: KeyMaterialKind::PrivateKey,
372            alg: "P-256",
373            codec: &[0x86, 0x26],
374            key_length: KeyLength::Fixed(32),
375        },
376    ),
377    (
378        "p384-priv",
379        CodecSpec {
380            tag: CodecTag::Key,
381            key_material: KeyMaterialKind::PrivateKey,
382            alg: "P-384",
383            codec: &[0x87, 0x26],
384            key_length: KeyLength::Fixed(48),
385        },
386    ),
387    (
388        "p521-priv",
389        CodecSpec {
390            tag: CodecTag::Key,
391            key_material: KeyMaterialKind::PrivateKey,
392            alg: "P-521",
393            codec: &[0x88, 0x26],
394            key_length: KeyLength::Fixed(66),
395        },
396    ),
397    (
398        "ed448-priv",
399        CodecSpec {
400            tag: CodecTag::Key,
401            key_material: KeyMaterialKind::PrivateKey,
402            alg: "Ed448",
403            codec: &[0x91, 0x26],
404            key_length: KeyLength::Fixed(57),
405        },
406    ),
407    (
408        "mlkem-512-priv",
409        CodecSpec {
410            tag: CodecTag::Key,
411            key_material: KeyMaterialKind::PrivateKey,
412            alg: "ML-KEM-512",
413            codec: &[0x93, 0x26],
414            key_length: KeyLength::Fixed(1632),
415        },
416    ),
417    (
418        "mlkem-768-priv",
419        CodecSpec {
420            tag: CodecTag::Key,
421            key_material: KeyMaterialKind::PrivateKey,
422            alg: "ML-KEM-768",
423            codec: &[0x94, 0x26],
424            key_length: KeyLength::Fixed(2400),
425        },
426    ),
427    (
428        "mlkem-1024-priv",
429        CodecSpec {
430            tag: CodecTag::Key,
431            key_material: KeyMaterialKind::PrivateKey,
432            alg: "ML-KEM-1024",
433            codec: &[0x95, 0x26],
434            key_length: KeyLength::Fixed(3168),
435        },
436    ),
437    (
438        "aes-gcm-256",
439        CodecSpec {
440            tag: CodecTag::Encryption,
441            key_material: KeyMaterialKind::NotKey,
442            alg: "AES-256-GCM",
443            codec: &[0x80, 0x40],
444            key_length: KeyLength::NotApplicable,
445        },
446    ),
447    (
448        "chacha20-poly1305",
449        CodecSpec {
450            tag: CodecTag::Multikey,
451            key_material: KeyMaterialKind::NotKey,
452            alg: "ChaCha20-Poly1305",
453            codec: &[0x80, 0xc0, 0x02],
454            key_length: KeyLength::NotApplicable,
455        },
456    ),
457];