RANNTA PQ CloudOpen Console
Menu

Canonical Payload

ML-DSA-65 verification binds to deterministic canonical bytes. The signer and PQ Cloud must verify the same byte sequence; JSON formatting, field order or an application-side reconstruction must not silently change what was signed.

V1 field order

domain
project_id
subject
action
key_version
nonce
body_sha256
claims

The current implementation serializes the payload in this order:

domain=<value>|project_id=<value>|subject=<value>|action=<value>|key_version=<value>|nonce=<value>|body_sha256=<value>|claims=<sorted key=value pairs>

claims are ordered by key before serialization. The ML-DSA-65 context used by the current verifier is RANNTA-PQ-CLOUD-ML-DSA-65-V1.

String and delimiter boundary

V1 serializes application string values as UTF-8 text and does not add an escaping layer. The characters |, , and = are structural delimiters in the canonical form. Integrators should therefore supply delimiter-free identifiers or encode arbitrary application values into an unambiguous representation such as hex or base64url before placing them in canonical fields or claims. PQ Cloud does not reinterpret or normalize those application values after signing.

Required negative test — recorded PASS

A one-byte change in the signed canonical message must fail verification. The final Phase 2 run verified the original payload locally and in production, then changed the payload without re-signing. Both the customer-side verifier and production /v1/hybrid/verify rejected the mutation.

Local original
Valid · PASS
Local one-byte mutation
Rejected · PASS
Production original
Valid · PASS
Production one-byte mutation
Rejected · PASS

Versioning

The canonical format and signing context are explicitly V1. A breaking change to field order, delimiters or signing context must be introduced as a new canonical/signing version rather than silently changing V1 bytes.

Implementation identity

  • Canonicalizer source: crates/pq-core/src/lib.rs.
  • Commit that introduced the current canonicalizer: 9089fe8839ebcd26b7bf0a8634041163cde3890f.
  • Release build ID: RANNTA-PQ-CLOUD-PHASE2-20260911-01.
  • Final E2E harness commit: 0ddce50395b6b9ffd6e03d4aa882e1fe50d5d4b4.

Integrator requirements

  • Do not sign a display string and submit a separately reconstructed payload.
  • Bind project_id, subject, action, key_version and a unique nonce to the authorization attempt.
  • If request-body integrity matters, place the application-defined SHA-256 value in body_sha256 before signing.
  • Treat canonicalization mismatch as Rejected; do not retry by weakening or dropping fields.