One-line mission: A fully self-contained, plugin-based C cryptographic library that covers all 776 catalogued algorithms, compiles to any target platform, and allows any algorithm to be included or excluded at build time with zero structural side-effects on the rest of the codebase.
NextSSL / Anon-leyline is a multi-platform cryptographic library with:
- 776 algorithms spanning 22 categories (see
algo.json) - Pure C (C99 minimum) core — no C++, no Rust, no Python at runtime
- Cross-compiled to all platforms in
/bin/via CMake + the build scripts in/build/platform/ - Plugin/plugout algorithm model — every algorithm is an isolated compilation unit; toggling one changes binary size but nothing else
- Flat, hash-addressed source layout (see
job/0004_FLAT_HASH_LAYOUT.md) - Dynamic documentation generated from
algo.json(seeALGORITHM.html,SOURCE_REGISTRY.html,AFTER_BURN.html)
Every algorithm must satisfy all five constraints simultaneously:
An algorithm's source files live in a single directory
(src/<category>/<algo>/). They must not #include anything from a sibling
algorithm directory. Only shared primitives under src/common/ are allowed.
Each algorithm directory contains exactly one <algo>_api.h that declares:
/* capability flags, zero-terminated */
extern const NL_AlgoInfo nl_<algo>_info;
/* canonical function pointers */
extern const NL_AlgoOps nl_<algo>_ops;NL_AlgoInfo carries the category, status (active/legacy/upcoming), key
sizes, output sizes, and feature flags. NL_AlgoOps is the vtable.
Each algorithm defines a single TU-local constructor:
NL_ALGO_REGISTER(nl_<algo>_info, nl_<algo>_ops)The NL_ALGO_REGISTER macro expands to a linker section entry on all
platforms. The core runtime discovers all registered algorithms at startup by
walking that section — no hand-written tables, no #ifdef forests.
To exclude an algorithm, remove its directory from ALGO_SOURCES in the
top-level CMakeLists.txt (or set -DNL_DISABLE_<ALGO>=ON). Nothing else
changes. The registration entry is simply not linked, the runtime sees nothing.
Algorithm directories are grouped by family prefix in CMake. If all members
of a family are excluded, the family's src/<category>/<family>/ directory
produces zero object files and is automatically skipped by the build system.
No CMakeLists.txt changes are needed inside the family directory.
Example:
- Remove
argon2dandargon2id→argon2istill compiles,_argonfamily directory still exists, binary shrinks by exactly those two objects. - Remove all three → CMake skips the
src/password-kdf/argon/subtree entirely. Family directory may be retained in the source tree but produces nothing in the build output.
src/
<category>/ ← one directory per algo.json category key
<family>/ ← optional family grouping (e.g., argon/, sha2/)
<algo>/
<algo>.c ← implementation
<algo>_api.h ← canonical API (see §2.2)
<algo>.h ← internal types (optional)
CMakeLists.txt ← add_library(nl_<algo> OBJECT <algo>.c)
target_include_directories(...)
nl_algo_register(nl_<algo>) ← cmake helper
src/common/
nl_algo_registry.h ← NL_AlgoInfo, NL_AlgoOps, NL_ALGO_REGISTER
nl_platform.h ← endian, rotate, byte-order helpers
nl_mem.h ← secure_zero, constant-time compare
mem/
sanitizer/
examples/
<category>/ ← gathered reference sources (see SOURCE_REFIX.md)
<algo>/
*.c / *.h ← upstream reference
kat.txt ← known-answer test vectors
<algo>_api.h ← generated canonical wrapper
CMakeLists.txt ← ref_<algo> static object library
bin/
<platform>/<arch>/ ← compiled output (libnextssl.a + libnextssl.so)
algo.json is the registry. It drives:
| Consumer | How it uses algo.json |
|---|---|
build/check_algos.py |
validates every src dir matches an entry |
build/check_exports.py |
validates every registered symbol matches an entry |
ALGORITHM.html |
documentation generated from active/legacy/upcoming lists |
SOURCE_REGISTRY.html |
source coverage visualization |
AFTER_BURN.html |
post-merge analysis of coverage gaps |
SOURCE_REFIX.md |
task tracking (this file system) |
CMake ALGO_SOURCES |
generated list of directories to compile |
Source flags (future enhancement): Each entry in algo.json will gain:
"src": true, // reference source gathered in /examples
"impl": true, // production implementation in /src
"tests": true, // KAT tests present
"acvp": true // ACVP validation vectors present- CMake minimum 3.16
- Each
src/<category>/<algo>/CMakeLists.txtcallsnl_algo_register()which appends the object library to a globalNL_ALGO_OBJECTSproperty. - The top-level
CMakeLists.txtcollectsNL_ALGO_OBJECTSand links intolibnextssl. - Platform files in
build/platform/set compiler flags, ABI targets, and feature detection (AES-NI, NEON, AVX2, etc.) — algorithms detect these via CMake feature variables, not#ifdef __ARM_NEONscatter. build/build.pyis the high-level driver that orchestrates cross-compilation across all targets.
-
No monolithic headers. Each algorithm owns its header. One algorithm's change cannot break another's compilation.
-
No global mutable state (except the registration section, which is read-only after startup). Algorithms are stateless objects; callers own all context memory.
-
Constant-time by default. Any algorithm that handles secret material must be constant-time. The sanitizer harness in
src/common/sanitizer/provides VALGRIND_MAKE_MEM_UNDEFINED hooks for CI validation. -
Zero dynamic allocation in the algorithm core. All heap allocation is the caller's responsibility. Algorithms declare their context size via
NL_AlgoInfo.ctx_sizeand accept a caller-provided buffer. -
Test vector first. No implementation merges without a passing KAT. ACVP vectors from
examples/ACVP-Server/are the canonical source. -
One algorithm, one status. An algorithm is exactly one of:
active,legacy, orupcoming.legacymeans it compiles but is flagged deprecated in itsNL_AlgoInfo.upcomingmeans the source directory exists as a stub butNL_ALGO_REGISTERis gated on-DNL_ENABLE_UPCOMING=ON.
The following phases must be completed in order:
| Phase | Description | Key documents |
|---|---|---|
| P0 | Source gathering | SOURCE_REFIX.md — complete all 22 sections |
| P1 | API wrapping | Generate <algo>_api.h for each sourced algo |
| P2 | KAT wiring | Populate kat.txt and wire into test runner |
| P3 | Production impl | Port or write src/<category>/<algo>/ for actives |
| P4 | CI / ACVP | Wire ACVP-Server, run CI across all platforms |
| P5 | Optimization | Add AVX2/NEON/AES-NI paths behind CMake features |
| P6 | Documentation | Regenerate HTML docs from completed algo.json |
Current position: start of P0.
- Not a TLS stack. Protocol primitives are algorithm-level only; no full TLS/DTLS/SSH handshake state machine is in scope.
- Not a PKI CA. Certificate operations are codec + validation only.
- No JavaScript / WASM bindings yet. The WASM target in
/bin/wasm/produces a raw.wasm; JS glue is out of scope for now. - No Go / Python / Rust wrappers in the initial phases. The C ABI is the integration surface.
- Do not break the flat-hash layout. See
job/0004_FLAT_HASH_LAYOUT.mdbefore touching anybuild/flatten_hash.pylogic.