Skip to main content

codec_multicodec/
table.rs

1// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2//
3// SPDX-License-Identifier: 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: usize,
52}
53
54/// Variable-length key payload. RSA keys use DER, whose length depends on
55/// modulus size and integer leading-byte normalization.
56pub const VARIABLE_KEY_LENGTH: usize = 0;
57
58/// Fixed length does not apply to this codec.
59pub const FIXED_LENGTH_NOT_APPLICABLE: usize = 0;
60
61/// Single source of truth for multicodec prefixes
62pub static MULTICODEC_TABLE: &[(&str, CodecSpec)] = &[
63    (
64        "sha2-256",
65        CodecSpec {
66            tag: CodecTag::Multihash,
67            key_material: KeyMaterialKind::NotKey,
68            alg: "SHA2-256",
69            codec: &[0x12],
70            key_length: 32,
71        },
72    ),
73    (
74        "sha2-512",
75        CodecSpec {
76            tag: CodecTag::Multihash,
77            key_material: KeyMaterialKind::NotKey,
78            alg: "SHA2-512",
79            codec: &[0x13],
80            key_length: 64,
81        },
82    ),
83    (
84        "sha3-512",
85        CodecSpec {
86            tag: CodecTag::Multihash,
87            key_material: KeyMaterialKind::NotKey,
88            alg: "SHA3-512",
89            codec: &[0x14],
90            key_length: 64,
91        },
92    ),
93    (
94        "sha3-384",
95        CodecSpec {
96            tag: CodecTag::Multihash,
97            key_material: KeyMaterialKind::NotKey,
98            alg: "SHA3-384",
99            codec: &[0x15],
100            key_length: 48,
101        },
102    ),
103    (
104        "sha3-256",
105        CodecSpec {
106            tag: CodecTag::Multihash,
107            key_material: KeyMaterialKind::NotKey,
108            alg: "SHA3-256",
109            codec: &[0x16],
110            key_length: 32,
111        },
112    ),
113    (
114        "sha3-224",
115        CodecSpec {
116            tag: CodecTag::Multihash,
117            key_material: KeyMaterialKind::NotKey,
118            alg: "SHA3-224",
119            codec: &[0x17],
120            key_length: 28,
121        },
122    ),
123    (
124        "sha2-384",
125        CodecSpec {
126            tag: CodecTag::Multihash,
127            key_material: KeyMaterialKind::NotKey,
128            alg: "SHA2-384",
129            codec: &[0x20],
130            key_length: 48,
131        },
132    ),
133    (
134        "aes-128",
135        CodecSpec {
136            tag: CodecTag::Key,
137            key_material: KeyMaterialKind::SymmetricKey,
138            alg: "AES-128",
139            codec: &[0xa0, 0x01],
140            key_length: 16,
141        },
142    ),
143    (
144        "aes-192",
145        CodecSpec {
146            tag: CodecTag::Key,
147            key_material: KeyMaterialKind::SymmetricKey,
148            alg: "AES-192",
149            codec: &[0xa1, 0x01],
150            key_length: 24,
151        },
152    ),
153    (
154        "aes-256",
155        CodecSpec {
156            tag: CodecTag::Key,
157            key_material: KeyMaterialKind::SymmetricKey,
158            alg: "AES-256",
159            codec: &[0xa2, 0x01],
160            key_length: 32,
161        },
162    ),
163    (
164        "chacha-128",
165        CodecSpec {
166            tag: CodecTag::Key,
167            key_material: KeyMaterialKind::SymmetricKey,
168            alg: "ChaCha-128",
169            codec: &[0xa3, 0x01],
170            key_length: 16,
171        },
172    ),
173    (
174        "chacha-256",
175        CodecSpec {
176            tag: CodecTag::Key,
177            key_material: KeyMaterialKind::SymmetricKey,
178            alg: "ChaCha-256",
179            codec: &[0xa4, 0x01],
180            key_length: 32,
181        },
182    ),
183    (
184        "ed25519-pub",
185        CodecSpec {
186            tag: CodecTag::Key,
187            key_material: KeyMaterialKind::PublicKey,
188            alg: "Ed25519",
189            codec: &[0xed, 0x01],
190            key_length: 32,
191        },
192    ),
193    (
194        "x25519-pub",
195        CodecSpec {
196            tag: CodecTag::Key,
197            key_material: KeyMaterialKind::PublicKey,
198            alg: "X25519",
199            codec: &[0xec, 0x01],
200            key_length: 32,
201        },
202    ),
203    (
204        "p256-pub",
205        CodecSpec {
206            tag: CodecTag::Key,
207            key_material: KeyMaterialKind::PublicKey,
208            alg: "P-256",
209            codec: &[0x80, 0x24],
210            key_length: 33,
211        },
212    ),
213    (
214        "p384-pub",
215        CodecSpec {
216            tag: CodecTag::Key,
217            key_material: KeyMaterialKind::PublicKey,
218            alg: "P-384",
219            codec: &[0x81, 0x24],
220            key_length: 49,
221        },
222    ),
223    (
224        "p521-pub",
225        CodecSpec {
226            tag: CodecTag::Key,
227            key_material: KeyMaterialKind::PublicKey,
228            alg: "P-521",
229            codec: &[0x82, 0x24],
230            key_length: 67,
231        },
232    ),
233    (
234        "ed448-pub",
235        CodecSpec {
236            tag: CodecTag::Key,
237            key_material: KeyMaterialKind::PublicKey,
238            alg: "Ed448",
239            codec: &[0x83, 0x24],
240            key_length: 57,
241        },
242    ),
243    (
244        "rsa-pub",
245        CodecSpec {
246            tag: CodecTag::Key,
247            key_material: KeyMaterialKind::PublicKey,
248            alg: "RSA",
249            codec: &[0x85, 0x24],
250            key_length: VARIABLE_KEY_LENGTH,
251        },
252    ),
253    (
254        "secp256k1-pub",
255        CodecSpec {
256            tag: CodecTag::Key,
257            key_material: KeyMaterialKind::PublicKey,
258            alg: "secp256k1",
259            codec: &[0xe7, 0x01],
260            key_length: 33,
261        },
262    ),
263    (
264        "mldsa-44-pub",
265        CodecSpec {
266            tag: CodecTag::Key,
267            key_material: KeyMaterialKind::PublicKey,
268            alg: "ML-DSA-44",
269            codec: &[0x90, 0x24],
270            key_length: 1312,
271        },
272    ),
273    (
274        "mldsa-65-pub",
275        CodecSpec {
276            tag: CodecTag::Key,
277            key_material: KeyMaterialKind::PublicKey,
278            alg: "ML-DSA-65",
279            codec: &[0x91, 0x24],
280            key_length: 1952,
281        },
282    ),
283    (
284        "mldsa-87-pub",
285        CodecSpec {
286            tag: CodecTag::Key,
287            key_material: KeyMaterialKind::PublicKey,
288            alg: "ML-DSA-87",
289            codec: &[0x92, 0x24],
290            key_length: 2592,
291        },
292    ),
293    (
294        "mlkem-512-pub",
295        CodecSpec {
296            tag: CodecTag::Key,
297            key_material: KeyMaterialKind::PublicKey,
298            alg: "ML-KEM-512",
299            codec: &[0x8b, 0x24],
300            key_length: 800,
301        },
302    ),
303    (
304        "mlkem-768-pub",
305        CodecSpec {
306            tag: CodecTag::Key,
307            key_material: KeyMaterialKind::PublicKey,
308            alg: "ML-KEM-768",
309            codec: &[0x8c, 0x24],
310            key_length: 1184,
311        },
312    ),
313    (
314        "mlkem-1024-pub",
315        CodecSpec {
316            tag: CodecTag::Key,
317            key_material: KeyMaterialKind::PublicKey,
318            alg: "ML-KEM-1024",
319            codec: &[0x8d, 0x24],
320            key_length: 1568,
321        },
322    ),
323    (
324        "ed25519-priv",
325        CodecSpec {
326            tag: CodecTag::Key,
327            key_material: KeyMaterialKind::PrivateKey,
328            alg: "Ed25519",
329            codec: &[0x80, 0x26],
330            key_length: 32,
331        },
332    ),
333    (
334        "secp256k1-priv",
335        CodecSpec {
336            tag: CodecTag::Key,
337            key_material: KeyMaterialKind::PrivateKey,
338            alg: "secp256k1",
339            codec: &[0x81, 0x26],
340            key_length: 32,
341        },
342    ),
343    (
344        "x25519-priv",
345        CodecSpec {
346            tag: CodecTag::Key,
347            key_material: KeyMaterialKind::PrivateKey,
348            alg: "X25519",
349            codec: &[0x82, 0x26],
350            key_length: 32,
351        },
352    ),
353    (
354        "rsa-priv",
355        CodecSpec {
356            tag: CodecTag::Key,
357            key_material: KeyMaterialKind::PrivateKey,
358            alg: "RSA",
359            codec: &[0x85, 0x26],
360            key_length: VARIABLE_KEY_LENGTH,
361        },
362    ),
363    (
364        "p256-priv",
365        CodecSpec {
366            tag: CodecTag::Key,
367            key_material: KeyMaterialKind::PrivateKey,
368            alg: "P-256",
369            codec: &[0x86, 0x26],
370            key_length: 32,
371        },
372    ),
373    (
374        "p384-priv",
375        CodecSpec {
376            tag: CodecTag::Key,
377            key_material: KeyMaterialKind::PrivateKey,
378            alg: "P-384",
379            codec: &[0x87, 0x26],
380            key_length: 48,
381        },
382    ),
383    (
384        "p521-priv",
385        CodecSpec {
386            tag: CodecTag::Key,
387            key_material: KeyMaterialKind::PrivateKey,
388            alg: "P-521",
389            codec: &[0x88, 0x26],
390            key_length: 66,
391        },
392    ),
393    (
394        "ed448-priv",
395        CodecSpec {
396            tag: CodecTag::Key,
397            key_material: KeyMaterialKind::PrivateKey,
398            alg: "Ed448",
399            codec: &[0x91, 0x26],
400            key_length: 57,
401        },
402    ),
403    (
404        "mlkem-512-priv",
405        CodecSpec {
406            tag: CodecTag::Key,
407            key_material: KeyMaterialKind::PrivateKey,
408            alg: "ML-KEM-512",
409            codec: &[0x93, 0x26],
410            key_length: 1632,
411        },
412    ),
413    (
414        "mlkem-768-priv",
415        CodecSpec {
416            tag: CodecTag::Key,
417            key_material: KeyMaterialKind::PrivateKey,
418            alg: "ML-KEM-768",
419            codec: &[0x94, 0x26],
420            key_length: 2400,
421        },
422    ),
423    (
424        "mlkem-1024-priv",
425        CodecSpec {
426            tag: CodecTag::Key,
427            key_material: KeyMaterialKind::PrivateKey,
428            alg: "ML-KEM-1024",
429            codec: &[0x95, 0x26],
430            key_length: 3168,
431        },
432    ),
433    (
434        "aes-gcm-256",
435        CodecSpec {
436            tag: CodecTag::Encryption,
437            key_material: KeyMaterialKind::NotKey,
438            alg: "AES-256-GCM",
439            codec: &[0x80, 0x40],
440            key_length: FIXED_LENGTH_NOT_APPLICABLE,
441        },
442    ),
443    (
444        "chacha20-poly1305",
445        CodecSpec {
446            tag: CodecTag::Multikey,
447            key_material: KeyMaterialKind::NotKey,
448            alg: "ChaCha20-Poly1305",
449            codec: &[0x80, 0xc0, 0x02],
450            key_length: FIXED_LENGTH_NOT_APPLICABLE,
451        },
452    ),
453];