Skip to main content
Version: beta_0.0.0

Overview

NTL defines a cryptographic module interface that all signing, verification, encryption, and key exchange operations MUST go through. No cryptographic algorithm is hardcoded into the protocol.

Interface

Implementations MUST provide a module that satisfies this interface:

Module Negotiation

During synapse handshake, nodes exchange their supported crypto module IDs. The synapse MUST use a mutually supported module. If no common module exists, the synapse formation MUST fail. Priority order for module selection:
  1. Both nodes’ preferred module (if same)
  2. Highest-versioned mutually supported module
  3. Failure (no common module)

Modules

An implementation MUST provide classical-v1 — it is the floor that makes two arbitrary nodes able to negotiate anything at all.
pq-v1 is specified but not implemented in the reference implementation, and 0.1.0-draft was wrong to call it the default. A node whose configuration names an unimplemented module MUST fail to start with an error naming the modules it does support. It MUST NOT fall back to a different module silently: an operator who asked for post-quantum signing and got Ed25519 has been told the opposite of the truth about their deployment’s confidentiality horizon.The reference implementation enforces this in NodeConfig::validate, and crypto::supported_modules() is the single list it checks against.
The point of this interface is that the choice is not baked into the protocol — not that any particular module already exists. Post-quantum readiness means a node can adopt pq-v1 without a wire-format change, which holds today.

Key Serialization

Public keys MUST be serializable to bytes for inclusion in signal origin fields and synapse handshakes. The serialization format is module-specific but MUST be deterministic.

Module Registration

Implementations MUST support runtime registration of custom crypto modules:
Last modified on September 11, 2026