Security Maintenance Process — krypteia
This document describes how the krypteia workspace is maintained for
security. It is the orientation page for any developer working on
the project (whether on the post-quantum side quantica or the
classical side arcana) and it is the canonical reference for the
common directives, the shared skills, and the lifecycle
that keep the workspace coherent and evaluation-ready across
multiple parallel sessions.
1. Mission and target
The krypteia workspace is being prepared for a lab-class third-party evaluation / certification of its cryptographic implementations. Both crates target the same evaluation:
Crate |
Scope |
|---|---|
|
Post-quantum: ML-KEM, ML-DSA, SLH-DSA |
|
Classical: RSA, ECDSA/ECDH, EdDSA, X25519/X448, AES, MACs, hashes |
The intended evaluation profile assumes a moderate-effort attacker in a 25-35 person-day window. Both crates must therefore share the same threat-model assumptions, the same verification methodology, the same documentation skeleton, and the same paper-trail discipline.
2. Three pillars — veille, doc, code
The maintenance process rests on three interlocking activities:
┌───────────────────────┐
│ VEILLE │
│ literature review, │
│ new attacks, new CMs │
└─────┬─────────────┬───┘
│ │
feeds │ │ triggers
▼ ▼
┌──────────────────┐ ┌───────────────────────┐
│ DOC │ │ CODE │
│ threat model, │◄┤ implementation + │
│ countermeasures, │ │ countermeasure + │
│ bibliography │►│ verification │
└──────────────────┘ └───────────────────────┘
Veille → identifies new attacks and refines the threat model.
Doc → records the threat model, the countermeasures, and the reasoning. Updated before code, so it is also a roadmap.
Code → implements the documented countermeasures, verified by ctgrind and dudect; the asm-level branch counting is the day-to-day CT regression indicator.
Dropping any one of the three produces brittle code: code without veille is one paper away from being broken; code without doc is unauditable; doc without code is empty.
4. Common directives
These rules apply identically on both sides of the workspace:
4.1 Code
Directive |
Where it lives |
Notes |
|---|---|---|
Pure Rust, zero external crates |
|
|
Constant-time on the data path |
|
No secret-dependent branches, no secret-indexed memory, no variable-latency ops on secrets. Validated by ctgrind + dudect. |
|
|
Single audit surface for |
|
|
Statistical timing test (Reparaz-Balasch-Verbauwhede 2017). |
|
|
Valgrind memcheck client requests ( |
Tier-based hardening plan |
|
T1 = active vuln → critical; T2 = standard hardening; T3 = verification tooling; T4 = deferred (beyond current evaluation scope); T5 = documentation pass. |
Bare-metal target validation |
|
All quantica primitives compile clean for |
Three Cargo profiles |
workspace |
|
|
wherever a CT mask is derived from a secret |
Without it, LLVM (rustc 1.84+) recovers branches over |
4.2 Documentation
Directive |
Where it lives |
Notes |
|---|---|---|
README structure contract |
doc/TOC.md |
17 mandatory H2 chapters in fixed order, plus per-chapter sub-section contract. Both |
Per-crate ownership of |
|
Each crate owns its papers/, analysis/, sca/, specs/. The workspace-level |
|
identical structure on both sides |
|
Tier item naming |
|
The leading |
Apache-2.0 license |
every README footer + per-crate |
Single line |
Bibliographic discipline |
|
Key convention: |
HTML doc pack via |
gendoc.sh |
Three modes: |
4.3 Veille
Directive |
Notes |
|---|---|
Continuous veille is mandatory |
A new SCA paper that touches a primitive we ship is an audit trigger, not a deferred item. |
Primary-source citations only |
ePrint ID / venue+year / spec section. No Wikipedia, no blog posts as primary evidence. |
Veille discipline for test corpora |
A Wycheproof / CAVP / ACVP refresh that adds vectors for a primitive we implement is a regression-test trigger — import vectors, rerun suite, note corpus version in the changelog. Missing a corpus update is the same class of risk as missing an attack paper. |
4.4 Verification
Method |
Coverage |
Owner |
|---|---|---|
ctgrind (Valgrind memcheck) |
Control-flow + memory-access CT (host CI). |
Driver in |
dudect (statistical timing) |
Microarchitectural timing on target hardware. |
Shared |
release-asm branch counting |
Day-to-day CT regression indicator. |
Manual |
Wycheproof + CAVP + ACVP |
Functional + edge-case + negative testing. |
Per-crate |
Bare-metal cross-build |
Catch |
|
5. Per-crate ownership
The workspace is two parallel sessions that share the rules above but maintain their own state. The split is deliberate so that unrelated work can advance in parallel without merge conflicts.
krypteia/
├── doc/ ← workspace shared (this is what `gendoc.sh` builds)
│ ├── TOC.md ← README structure contract (canonical)
│ ├── conf.py / Makefile ← Sphinx config
│ ├── index_*.rst ← TOC roots (mode-specific)
│ ├── infra/ ← cross-cutting runbooks (ctgrind, gitea, …)
│ ├── _gen/ ← gendoc-staged READMEs (gitignored)
│ ├── quantica/ ← gendoc-staged crate doc (gitignored)
│ └── arcana/ ← gendoc-staged crate doc (gitignored)
│
├── quantica/ ← post-quantum side (own session)
│ ├── README.md ← follows doc/TOC.md
│ ├── doc/ ← crate-owned source-of-truth
│ │ ├── papers/ ← cited PDFs (file-stem = bib key)
│ │ ├── analysis/ ← memory / timing notes
│ │ ├── specs/ ← FIPS 203/204/205
│ │ └── sca/ ← threat model + countermeasures + biblio
│ ├── src/
│ ├── tests/
│ └── examples/
│
├── arcana/ ← classical side (own session)
│ ├── README.md ← follows doc/TOC.md
│ ├── doc/ ← crate-owned source-of-truth (mirrors quantica)
│ │ ├── papers/
│ │ ├── analysis/
│ │ └── sca/ ← same skeleton as quantica/doc/sca/
│ ├── src/
│ ├── tests/
│ └── examples/
│
├── silentops/ ← shared CT primitives + dudect + ctgrind
├── quantica_ffi/ ← C FFI for quantica
├── arcana_ffi/ ← C FFI for arcana
├── quantica_bench/ ← memcheck + ctgrind drivers (quantica)
├── tools/ ← stack-sizes.sh, ctgrind.sh, …
└── gendoc.sh ← unified HTML doc-pack generator
What’s per-crate: code, tests, examples, the README, the doc/
sub-tree.
What’s workspace-shared: the rules in this document, the Sphinx
config, the gendoc.sh generator, the silentops crate, the
tools/ scripts, the doc/TOC.md README contract, and the
doc/infra/ cross-cutting runbooks.
A change to a per-crate concern stays in that crate’s session. A
change to a shared concern goes through this workspace-level doc/
or tools/ directory.
6. Lifecycle of a security item
The flow from “we found a paper / a CVE / an evaluator comment” to “the countermeasure is shipped and verified” is:
1. Veille run (skill: crypto-research)
│
▼
2. Add paper to <crate>/doc/papers/<key>.pdf (key = author<year>_topic)
3. Add bib entry to <crate>/doc/sca/biblio.bib
4. Add a Tier item (T<n>-<id>) to the relevant
<crate>/doc/sca/countermeasures/<algo>.rst
│
▼
5. Implement the countermeasure in <crate>/src/…
6. Bump the asm-branch-count expectation in
<crate>/doc/sca/countermeasures/<algo>.rst
7. Add ctgrind + dudect harness entries
│
▼
8. Update Code path summary table from `today`
to `target` for the just-shipped item
9. Append a row to <crate>/doc/sca/index.rst
change log
10. Commit, ./gendoc.sh validates the pack
Steps 1-4 are doc-only and serve as a roadmap entry; the item
sits as planned until the code lands. Steps 5-7 are the
implementation. Steps 8-10 close the loop.
7. Where to find what
You want to know… |
Look at… |
|---|---|
The big picture of either crate |
README.md (workspace), |
The README chapter contract |
doc/TOC.md |
The threat model & countermeasure plan for a crate |
|
The bibliography for either crate |
|
The PDFs of cited papers |
|
The shared CT primitives |
silentops/src/ct/ |
How to run ctgrind |
doc/infra/ctgrind.md |
How to build the HTML pack |
gendoc.sh (`./gendoc.sh [all |
The cross-cutting tooling |
tools/ |
The veille / impl / audit workflow itself |
|
8. Vulnerability reporting
The krypteia v0.1 line ships publicly on
codeberg.org/cslashm/krypteia
and crates.io (silentops, memory, quantica, arcana). The
disclosure process below applies to every published crate.
8.1 Reporting channel
Send a private report to cedric.mesnil@pm.me before
opening any public Codeberg issue or PR. Reports may be encrypted
to the maintainer’s GPG key (fingerprint published in the
maintainer’s Codeberg profile when available); plain email is
also accepted.
A report should include:
a clear description of the issue,
the affected crate(s) and version range (or git commit if reporting against
main),a proof-of-concept (PoC) or reproducer if available,
an assessment of impact (information disclosure, timing oracle, fault injection vector, …),
whether the reporter wishes to be credited in the fix and under which name.
Maintainer is cedric.mesnil@pm.me for v0.1. The
roster will expand in v0.2 once additional reviewers join.
8.2 Initial response
Acknowledgment within 5 working days of receipt.
Triage verdict (in-scope / out-of-scope, severity estimate) within 15 working days.
A heads-up that the report is being looked at will land within the first window even if the verdict requires more time.
8.3 Coordinated disclosure window
The default embargo window is 90 calendar days from acknowledgment to public disclosure, mirroring the industry norm (Google Project Zero, CERT/CC). Within that window:
the maintainer prepares a fix on a private dev branch;
a CVE is requested via the MITRE CNA process if the finding meets CVE criteria;
the reporter is kept informed of the fix timeline;
the patch lands in a tagged release (
v0.X.Ypatch bump orv0.X+1.0minor bump depending on impact) AT the end of the embargo, NOT before.
The window can be shortened by mutual agreement (e.g. for a trivially-exploitable issue where a partial fix is already public) and extended if the fix has significant cross-crate impact and needs additional validation time. The maintainer will not unilaterally extend past 120 days.
8.4 Public advisory
When the patched release ships, the maintainer publishes a Codeberg security advisory describing the issue, the affected versions, the CVE (if assigned), the fix commit, and credit to the reporter (unless anonymity is requested).
8.5 Out of scope
Findings against unmaintained branches (only
mainand the latest tagged release receive fixes — older releases are end-of-life).Findings that require an attacker model strictly beyond the per-crate threat model documented in
<crate>/doc/sca/threat_model.rst(e.g., a physical attacker with EM-probe access on an algorithm whose SCA chapter explicitly defers DPA hardening to T4 in v0.1) — these are filed as roadmap items in the relevant tier, not as vulnerabilities. The maintainer will redirect such reports to the appropriate roadmap row.Reports against
*_ffi,*_wasm,*_bench,tests-embedded,tools/vector-runner, and the placeholder cratesarcana_bench/arcana_wasm. These ship aspublish = falseworkspace-internal previews in v0.1; the v0.2 release that publishes them will extend this policy.
8.6 Safe harbour
Good-faith vulnerability research conducted under this policy will not trigger any legal action by the maintainer. The maintainer agrees not to pursue civil claims, criminal referrals, or DMCA takedowns against reporters who comply with the disclosure window above.
9. License
Apache-2.0.