You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2026/03/17 10:37:14 UTC

(camel) 02/02: PQC docs

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch task-29
in repository https://gitbox.apache.org/repos/asf/camel.git

commit a847fbe9cac78d4de64792755868e759dcdcab74
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Tue Mar 17 11:34:19 2026 +0100

    PQC docs
    
    Signed-off-by: Andrea Cosentino <an...@gmail.com>
---
 .../camel-pqc/src/main/docs/pqc-component.adoc     | 129 ++++++++++++++++++++-
 1 file changed, 125 insertions(+), 4 deletions(-)

diff --git a/components/camel-pqc/src/main/docs/pqc-component.adoc b/components/camel-pqc/src/main/docs/pqc-component.adoc
index d5e1fbeaf1d3..3d4f8c9caf53 100644
--- a/components/camel-pqc/src/main/docs/pqc-component.adoc
+++ b/components/camel-pqc/src/main/docs/pqc-component.adoc
@@ -1880,7 +1880,7 @@ from("direct:sign")
 
 **Hybrid Signature Wire Format:**
 
-The hybrid signature is encoded as: `[4 bytes: classical sig length][classical sig][pqc sig]`
+Since Camel 4.19, hybrid signatures use wire format v2 which includes a magic number, version, and algorithm identifiers (see <<Wire Format v2 and Algorithm Identification>>). The v1 format `[4 bytes: classical sig length][classical sig][pqc sig]` is still accepted on input for backward compatibility.
 
 **Headers set by hybrid signature operations:**
 
@@ -1950,7 +1950,7 @@ from("direct:encapsulate")
 
 **Hybrid KEM Wire Format:**
 
-The hybrid encapsulation is encoded as: `[4 bytes: classical encap length][classical encap][pqc encap]`
+Since Camel 4.19, hybrid encapsulations use wire format v2 which includes a magic number, version, and algorithm identifiers (see <<Wire Format v2 and Algorithm Identification>>). The v1 format `[4 bytes: classical encap length][classical encap][pqc encap]` is still accepted on input for backward compatibility.
 
 **Headers set by hybrid KEM operations:**
 
@@ -2022,6 +2022,123 @@ Based on NIST recommendations for the transition period:
 
 5. **Algorithm agility**: Design your system to allow algorithm upgrades as standards evolve.
 
+== Wire Format v2 and Algorithm Identification
+
+Starting with Camel 4.19, the hybrid signature, hybrid KEM, and PQC DataFormat wire formats include self-describing algorithm metadata. This makes the binary output portable and verifiable without out-of-band knowledge of which algorithms were used.
+
+=== PQCAlgorithmId
+
+The `PQCAlgorithmId` enum maps every supported algorithm — classical signature, PQC signature, classical KEM, PQC KEM, and symmetric — to a unique 16-bit identifier used in the wire format header.
+
+**Algorithm ID ranges:**
+
+|===
+|Range |Category |Examples
+
+|`0x0100–0x01FF`
+|Classical signature
+|SHA256withECDSA (`0x0101`), Ed25519 (`0x0104`), SHA256withRSA (`0x0106`)
+
+|`0x0200–0x02FF`
+|Post-quantum signature
+|ML-DSA (`0x0201`), SLH-DSA (`0x0202`), LMS (`0x0203`), FALCON (`0x0207`)
+
+|`0x0300–0x03FF`
+|Classical KEM / key agreement
+|EC (`0x0301`), X25519 (`0x0303`), X448 (`0x0305`)
+
+|`0x0400–0x04FF`
+|Post-quantum KEM
+|ML-KEM (`0x0401`), BIKE (`0x0402`), NTRU (`0x0407`), KYBER (`0x040A`)
+
+|`0x0500–0x05FF`
+|Symmetric encryption
+|AES (`0x0501`), ARIA (`0x0502`), Camellia (`0x0503`)
+|===
+
+**Lookup by JCA name:**
+
+[source,java]
+--------------------------------------------------------------------------------
+// Resolve from a JCA algorithm string (case-insensitive)
+PQCAlgorithmId algId = PQCAlgorithmId.fromJcaName("ML-DSA");   // ML_DSA (0x0201)
+PQCAlgorithmId kemId = PQCAlgorithmId.fromJcaName("ML-KEM");   // ML_KEM (0x0401)
+PQCAlgorithmId aesId = PQCAlgorithmId.fromJcaName("AES");      // AES    (0x0501)
+
+// Returns UNKNOWN (0x0000) for unrecognized names
+PQCAlgorithmId unknown = PQCAlgorithmId.fromJcaName("FutureAlg"); // UNKNOWN
+--------------------------------------------------------------------------------
+
+**Lookup by wire format ID:**
+
+[source,java]
+--------------------------------------------------------------------------------
+// Resolve from a 16-bit identifier read from the wire
+PQCAlgorithmId alg = PQCAlgorithmId.fromId(0x0201);  // ML_DSA
+int id = alg.getId();           // 0x0201
+String jca = alg.getJcaName();  // "ML-DSA"
+--------------------------------------------------------------------------------
+
+**Inspecting algorithm metadata from a parsed hybrid output:**
+
+[source,java]
+--------------------------------------------------------------------------------
+// After parsing a v2 hybrid signature
+HybridSignature.HybridSignatureComponents components = HybridSignature.parse(hybridSig);
+
+// v2 components carry algorithm identifiers
+PQCAlgorithmId classical = components.classicalAlgorithmId(); // e.g. SHA256_WITH_ECDSA
+PQCAlgorithmId pqc       = components.pqcAlgorithmId();       // e.g. ML_DSA
+int version              = components.version();              // 2
+
+// v1 components (backward-compatible) return null algorithm IDs and version 1
+--------------------------------------------------------------------------------
+
+=== Wire Format v2 Layout
+
+All three output types (hybrid signature, hybrid KEM, PQC DataFormat) share the same 8-byte header:
+
+[source,text]
+--------------------------------------------------------------------------------
+[2 bytes: magic 0x50 0x51 ("PQ")]
+[1 byte:  version — 0x02]
+[1 byte:  format type]
+[2 bytes: first algorithm ID]
+[2 bytes: second algorithm ID]
+[4 bytes: first payload length]
+[N bytes: first payload]
+[M bytes: second payload]
+--------------------------------------------------------------------------------
+
+**Format types:**
+
+|===
+|Value |Type |First algorithm ID |Second algorithm ID
+
+|`0x01`
+|Hybrid signature
+|Classical signature algorithm
+|PQC signature algorithm
+
+|`0x02`
+|Hybrid KEM
+|Classical KEM algorithm
+|PQC KEM algorithm
+
+|`0x03`
+|KEM DataFormat
+|KEM algorithm
+|Symmetric algorithm
+|===
+
+=== Backward Compatibility
+
+Wire format v2 is fully backward-compatible with v1:
+
+* **Writing** — `sign()`, `encapsulate()`, and `marshal()` always produce v2 output.
+* **Reading** — `parse()`, `verify()`, `extract()`, and `unmarshal()` auto-detect the format by checking the first two bytes for the magic number `0x50 0x51`. If absent, they fall back to v1 parsing.
+* **Safety** — The magic bytes `0x50 0x51`, interpreted as the first two bytes of a big-endian 32-bit integer, produce values above 1.3 billion. No valid v1 payload has a classical signature or encapsulation of that size, so false positives are impossible in practice.
+
 == PQC DataFormat
 
 The PQC component also provides a DataFormat for quantum-resistant encryption and decryption of message payloads using Key Encapsulation Mechanisms (KEM).
@@ -2046,14 +2163,18 @@ This approach provides **defense-in-depth**: even if the symmetric algorithm is
 
 === Wire Format
 
-The encrypted message format is:
+Since Camel 4.19, the PQC DataFormat uses wire format v2 which includes a magic number, version, and algorithm identifiers (see <<Wire Format v2 and Algorithm Identification>>). The v1 format `[4 bytes: encapsulation length][N bytes: encapsulation][M bytes: encrypted data]` is still accepted on input for backward compatibility.
+
+The v2 encrypted message format is:
 
 [source,text]
 --------------------------------------------------------------------------------
+[2 bytes: magic "PQ"] [1 byte: version] [1 byte: format type]
+[2 bytes: KEM algorithm ID] [2 bytes: symmetric algorithm ID]
 [4 bytes: encapsulation length] [N bytes: encapsulation] [M bytes: encrypted data]
 --------------------------------------------------------------------------------
 
-This format allows the receiver to extract the encapsulation, decapsulate the shared secret using their private key, and decrypt the data.
+This format allows the receiver to identify the algorithms used, extract the encapsulation, decapsulate the shared secret using their private key, and decrypt the data.
 
 === Basic Usage