Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ All notable changes to this project are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.5.0] - 2026-09-14

### Deprecated

- All 36 Classic McEliece codec variants (`mceliece*` and `x25519-mceliece348864`) now carry `#[deprecated]` attributes. Key-recovery attacks now solve the TII McEliece challenges; see [tii-solved](https://github.com/mjosaarinen/tii-solved) for the recovered keys. Uses of these variants emit compiler warnings. The variants remain compiled, matchable, and decodable so stored multicodec-tagged data keeps working.

## [1.4.0] - 2026-09-03

### Added

- Three new codec entries for the proof-of-possession framework: `multiproof` (`0xd01330`, multiformat), `wacc-script-with-pop` (`0xd01331`, multiformat), and `xeddsa-msig` (`0xd01332`, multisig).
- The `Codec` enum now has 885 variants (up from 882).

### Notes

- This is a minor version bump. The `Codec` enum is `#[non_exhaustive]`, so new variants are additive and do not break downstream match expressions.

## [1.3.0] - 2026-09-01

### Added
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "multi-codec"
version = "1.3.0"
version = "1.5.0"
edition = "2024"
rust-version = "1.85"
authors = ["Benjamin Kampmann <ben@gnunicorn.org>", "Dave Grantham <dwg@linuxprogrammer.org>"]
Expand Down Expand Up @@ -48,7 +48,7 @@ name = "uvi"
path = "examples/uvi.rs"

[build-dependencies]
convert_case = "0.6"
convert_case = "0.12"
csv = "1.3"
serde = { version = "1.0", features = ["serde_derive"] }
serde_derive = "1.0"
17 changes: 16 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,22 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

// Generate enum variant
let variant_name = conv.convert(&rec.name);
writeln!(f, "\t{} => ({}, \"{}\"),", code_str, variant_name, rec.name)?;
// Classic McEliece key material is deprecated. Key-recovery attacks now
// solve the TII McEliece challenges, so every McEliece variant carries a
// deprecation attribute; uses emit a compiler warning. The variants stay
// compiled and decodable so stored multicodec-tagged data keeps working.
// See https://github.com/mjosaarinen/tii-solved for the recovered keys.
// The attribute precedes the variant name inside the tuple so the
// macro's `expr` fragment stays unambiguous.
if rec.name.contains("mceliece") {
writeln!(
f,
"\t{} => (#[deprecated(since = \"1.5.0\", note = \"Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved\")] {}, \"{}\"),",
code_str, variant_name, rec.name
)?;
} else {
writeln!(f, "\t{} => ({}, \"{}\"),", code_str, variant_name, rec.name)?;
}

record_count += 1;
}
Expand Down
19 changes: 17 additions & 2 deletions src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,20 @@ use core::{
use multi_trait::{EncodeInto, Null, TryDecodeFrom};

macro_rules! build_codec_enum {
{$( $val:expr => ($i:ident, $s:expr), )*} => {
{$( $val:expr => ( $(#[$vattr:meta])* $i:ident, $s:expr), )*} => {

/// Codecs from the multicodec table
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)]
#[non_exhaustive]
pub enum Codec {
#[default]
$( $i, )*
$( $(#[$vattr])* $i, )*
}

/// Convert from the canonical string name of the multicodec to the
/// associated enum/value.
#[allow(deprecated)]
impl TryFrom<&str> for Codec {
type Error = Error;

Expand All @@ -56,6 +57,7 @@ macro_rules! build_codec_enum {
}

/// Convert a Codec into a type that implements `AsRef<str>`
#[allow(deprecated)]
impl From<Codec> for &str {
fn from(codec: Codec) -> &'static str {
match codec {
Expand All @@ -65,6 +67,7 @@ macro_rules! build_codec_enum {
}

/// Convert from the value of the multicodec to the associated enum/value.
#[allow(deprecated)]
impl TryFrom<u64> for Codec {
type Error = Error;

Expand All @@ -77,6 +80,7 @@ macro_rules! build_codec_enum {
}

/// Convert a Codec into a u64
#[allow(deprecated)]
impl From<Codec> for u64 {
fn from(codec: Codec) -> u64 {
match codec {
Expand Down Expand Up @@ -285,6 +289,17 @@ mod tests {
assert_eq!("ed25519-pub", Codec::Ed25519Pub.as_str());
}

#[test]
#[allow(deprecated)]
fn test_mceliece_roundtrip() {
// The McEliece variants are deprecated but stay compiled and decodable
// so stored multicodec-tagged data keeps working.
let codec = Codec::try_from(0x1220).unwrap();
assert_eq!(Codec::Mceliece348864Pub, codec);
assert_eq!("mceliece348864-pub", codec.as_str());
assert_eq!(0x1220_u64, codec.code());
}

#[test]
fn test_from_str() {
assert_eq!(Codec::Ed25519Pub, Codec::try_from("ed25519-pub").unwrap());
Expand Down
75 changes: 39 additions & 36 deletions src/table_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,23 +190,23 @@ build_codec_enum! {
0x121d => (SlhDsaShake256FPub, "slh-dsa-shake256f-pub"),
0x121e => (SlhDsaShake256SPub, "slh-dsa-shake256s-pub"),
0x121f => (Sntrup761Pub, "sntrup761-pub"),
0x1220 => (Mceliece348864Pub, "mceliece348864-pub"),
0x1221 => (Mceliece460896Pub, "mceliece460896-pub"),
0x1250 => (Mceliece460896FPub, "mceliece460896f-pub"),
0x1251 => (Mceliece460896PcPub, "mceliece460896pc-pub"),
0x1252 => (Mceliece460896PcfPub, "mceliece460896pcf-pub"),
0x1253 => (Mceliece6688128Pub, "mceliece6688128-pub"),
0x1254 => (Mceliece6688128FPub, "mceliece6688128f-pub"),
0x1255 => (Mceliece6688128PcPub, "mceliece6688128pc-pub"),
0x1256 => (Mceliece6688128PcfPub, "mceliece6688128pcf-pub"),
0x1257 => (Mceliece6960119Pub, "mceliece6960119-pub"),
0x1258 => (Mceliece6960119FPub, "mceliece6960119f-pub"),
0x1259 => (Mceliece6960119PcPub, "mceliece6960119pc-pub"),
0x125a => (Mceliece6960119PcfPub, "mceliece6960119pcf-pub"),
0x125b => (Mceliece8192128Pub, "mceliece8192128-pub"),
0x125c => (Mceliece8192128FPub, "mceliece8192128f-pub"),
0x125d => (Mceliece8192128PcPub, "mceliece8192128pc-pub"),
0x125e => (Mceliece8192128PcfPub, "mceliece8192128pcf-pub"),
0x1220 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece348864Pub, "mceliece348864-pub"),
0x1221 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896Pub, "mceliece460896-pub"),
0x1250 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896FPub, "mceliece460896f-pub"),
0x1251 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896PcPub, "mceliece460896pc-pub"),
0x1252 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896PcfPub, "mceliece460896pcf-pub"),
0x1253 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128Pub, "mceliece6688128-pub"),
0x1254 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128FPub, "mceliece6688128f-pub"),
0x1255 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128PcPub, "mceliece6688128pc-pub"),
0x1256 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128PcfPub, "mceliece6688128pcf-pub"),
0x1257 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119Pub, "mceliece6960119-pub"),
0x1258 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119FPub, "mceliece6960119f-pub"),
0x1259 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119PcPub, "mceliece6960119pc-pub"),
0x125a => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119PcfPub, "mceliece6960119pcf-pub"),
0x125b => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128Pub, "mceliece8192128-pub"),
0x125c => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128FPub, "mceliece8192128f-pub"),
0x125d => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128PcPub, "mceliece8192128pc-pub"),
0x125e => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128PcfPub, "mceliece8192128pcf-pub"),
0x1222 => (Rsa2048Pub, "rsa-2048-pub"),
0x1223 => (Rsa3072Pub, "rsa-3072-pub"),
0x1224 => (Rsa4096Pub, "rsa-4096-pub"),
Expand All @@ -221,7 +221,7 @@ build_codec_enum! {
0x1230 => (X25519Sntrup761Pub, "x25519-sntrup761-pub"),
0x1243 => (X25519Frodokem640AesPub, "x25519-frodokem640aes-pub"),
0x1244 => (X25519Frodokem640ShakePub, "x25519-frodokem640shake-pub"),
0x1245 => (X25519Mceliece348864Pub, "x25519-mceliece348864-pub"),
0x1245 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] X25519Mceliece348864Pub, "x25519-mceliece348864-pub"),
0x1246 => (Bls12381G1Mldsa65Pub, "bls12381-g1-mldsa65-pub"),
0x1247 => (Bls12381G1Fndsa512Pub, "bls12381-g1-fndsa512-pub"),
0x1248 => (Bls12381G1Mayo1Pub, "bls12381-g1-mayo1-pub"),
Expand Down Expand Up @@ -283,23 +283,23 @@ build_codec_enum! {
0x1326 => (SlhDsaShake256FPriv, "slh-dsa-shake256f-priv"),
0x1327 => (SlhDsaShake256SPriv, "slh-dsa-shake256s-priv"),
0x1328 => (Sntrup761Priv, "sntrup761-priv"),
0x1329 => (Mceliece348864Priv, "mceliece348864-priv"),
0x132a => (Mceliece460896Priv, "mceliece460896-priv"),
0x135d => (Mceliece460896FPriv, "mceliece460896f-priv"),
0x135e => (Mceliece460896PcPriv, "mceliece460896pc-priv"),
0x135f => (Mceliece460896PcfPriv, "mceliece460896pcf-priv"),
0x1360 => (Mceliece6688128Priv, "mceliece6688128-priv"),
0x1361 => (Mceliece6688128FPriv, "mceliece6688128f-priv"),
0x1362 => (Mceliece6688128PcPriv, "mceliece6688128pc-priv"),
0x1363 => (Mceliece6688128PcfPriv, "mceliece6688128pcf-priv"),
0x1364 => (Mceliece6960119Priv, "mceliece6960119-priv"),
0x1365 => (Mceliece6960119FPriv, "mceliece6960119f-priv"),
0x1366 => (Mceliece6960119PcPriv, "mceliece6960119pc-priv"),
0x1367 => (Mceliece6960119PcfPriv, "mceliece6960119pcf-priv"),
0x1368 => (Mceliece8192128Priv, "mceliece8192128-priv"),
0x1369 => (Mceliece8192128FPriv, "mceliece8192128f-priv"),
0x136a => (Mceliece8192128PcPriv, "mceliece8192128pc-priv"),
0x136b => (Mceliece8192128PcfPriv, "mceliece8192128pcf-priv"),
0x1329 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece348864Priv, "mceliece348864-priv"),
0x132a => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896Priv, "mceliece460896-priv"),
0x135d => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896FPriv, "mceliece460896f-priv"),
0x135e => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896PcPriv, "mceliece460896pc-priv"),
0x135f => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece460896PcfPriv, "mceliece460896pcf-priv"),
0x1360 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128Priv, "mceliece6688128-priv"),
0x1361 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128FPriv, "mceliece6688128f-priv"),
0x1362 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128PcPriv, "mceliece6688128pc-priv"),
0x1363 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6688128PcfPriv, "mceliece6688128pcf-priv"),
0x1364 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119Priv, "mceliece6960119-priv"),
0x1365 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119FPriv, "mceliece6960119f-priv"),
0x1366 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119PcPriv, "mceliece6960119pc-priv"),
0x1367 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece6960119PcfPriv, "mceliece6960119pcf-priv"),
0x1368 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128Priv, "mceliece8192128-priv"),
0x1369 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128FPriv, "mceliece8192128f-priv"),
0x136a => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128PcPriv, "mceliece8192128pc-priv"),
0x136b => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] Mceliece8192128PcfPriv, "mceliece8192128pcf-priv"),
0x132b => (Rsa2048Priv, "rsa-2048-priv"),
0x132c => (Rsa3072Priv, "rsa-3072-priv"),
0x132d => (Rsa4096Priv, "rsa-4096-priv"),
Expand All @@ -314,7 +314,7 @@ build_codec_enum! {
0x1340 => (X25519Sntrup761Priv, "x25519-sntrup761-priv"),
0x1350 => (X25519Frodokem640AesPriv, "x25519-frodokem640aes-priv"),
0x1351 => (X25519Frodokem640ShakePriv, "x25519-frodokem640shake-priv"),
0x1352 => (X25519Mceliece348864Priv, "x25519-mceliece348864-priv"),
0x1352 => (#[deprecated(since = "1.5.0", note = "Classic McEliece key recovery attacks: see https://github.com/mjosaarinen/tii-solved")] X25519Mceliece348864Priv, "x25519-mceliece348864-priv"),
0x1353 => (Bls12381G1Mldsa65Priv, "bls12381-g1-mldsa65-priv"),
0x1354 => (Bls12381G1Fndsa512Priv, "bls12381-g1-fndsa512-priv"),
0x1355 => (Bls12381G1Mayo1Priv, "bls12381-g1-mayo1-priv"),
Expand Down Expand Up @@ -866,6 +866,9 @@ build_codec_enum! {
0xd0132d => (XmssSha216256Msig, "xmss-sha2-16-256-msig"),
0xd0132e => (XmssSha220256Msig, "xmss-sha2-20-256-msig"),
0xd0132f => (Ed448Msig, "ed448-msig"),
0xd01332 => (XeddsaMsig, "xeddsa-msig"),
0xd01330 => (Multiproof, "multiproof"),
0xd01331 => (WaccScriptWithPop, "wacc-script-with-pop"),
0xd01400 => (BsMessage, "bs-message"),
0xd02000 => (Scion, "scion"),
0xd03000 => (Ed25519ThreshPrivShare, "ed25519-thresh-priv-share"),
Expand Down
3 changes: 3 additions & 0 deletions table.csv
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,9 @@ xmss-sha2-10-256-msig, multisig, 0xd0132c, draft, XMSS
xmss-sha2-16-256-msig, multisig, 0xd0132d, draft, XMSS-SHA2_16_256 signature as Multisig; RFC 8391
xmss-sha2-20-256-msig, multisig, 0xd0132e, draft, XMSS-SHA2_20_256 signature as Multisig; RFC 8391
ed448-msig, multisig, 0xd0132f, draft, Ed448 (EdDSA) signature as Multisig; RFC 8032
xeddsa-msig, multisig, 0xd01332, draft, XEdDSA signature over an X25519 key
multiproof, multiformat, 0xd01330, draft, Multiproof proof-of-possession object
wacc-script-with-pop, multiformat, 0xd01331, draft, WACC script with proof-of-possession envelope
bs-message, multiformat, 0xd01400, draft, BetterSign signed+encrypted message multiformat
scion, multiaddr, 0xd02000, draft, SCION Internet architecture
ed25519-thresh-priv-share, key, 0xd03000, draft, Ed25519 FROST DKG threshold private key share
Expand Down
Loading