Skip to content

Commit 8bb12f8

Browse files
committed
Expand zero-dependency roadmap
1 parent b86d990 commit 8bb12f8

2 files changed

Lines changed: 138 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
admission-gated rather than already scheduled functionality.
6060
- Added `docs/DEPENDENCIES.md` to make external crate admission requirements
6161
explicit and packaged with release evidence.
62+
- Expanded the roadmap with a zero-dependency "ultimate crate" backlog covering
63+
MIME/PEM/bcrypt profiles, custom alphabets, line wrapping, validation-only
64+
APIs, stack-backed short outputs, secret wrappers, CWE mapping, and
65+
admission-gated ecosystem integrations.
6266
- Updated security documentation for streaming wrapper buffer cleanup behavior.
6367
- Updated release evidence documentation for stream fuzzing and reserved SIMD
6468
feature-bundle checks.

docs/PLAN.md

Lines changed: 134 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# base64-ng Professional Secure Plan
22

3-
Date: 2026-05-13
3+
Date: 2026-05-14
44

55
## Objective
66

@@ -40,8 +40,15 @@ Allowed without adding dependencies:
4040
External crates require written justification before inclusion:
4141

4242
- `tokio` may be accepted only behind the optional `tokio` feature for async stream wrappers.
43+
- `serde` may be accepted only behind an optional feature after API and dependency review.
44+
- `bytes` may be accepted only behind an optional feature after API and dependency review.
45+
- `zeroize` remains rejected by default; the current direction is an internal
46+
best-effort wiping helper and secret wrapper types before considering a
47+
dependency.
4348
- Fuzzing crates may live only in a future `fuzz/` workspace or tool-specific harness, not in normal runtime dependencies.
4449
- Benchmark crates may live only in `dev-dependencies` or an isolated bench workspace.
50+
The default benchmark path should remain dependency-free unless a tool such
51+
as Criterion earns admission with better measurement evidence.
4552
- Kani support must stay feature-gated and must not affect normal users.
4653

4754
Rejected by default:
@@ -50,6 +57,8 @@ Rejected by default:
5057
- Git dependencies.
5158
- Runtime dependencies for the default feature set.
5259
- Dependencies with unclear licensing, advisories, yanked releases, or unnecessary transitive graphs.
60+
- Crates that only replace small, auditable `core`/`alloc`/`std`
61+
implementations.
5362

5463
Any dependency addition must answer:
5564

@@ -95,6 +104,11 @@ Any dependency addition must answer:
95104
- Use zero-sized engines and trait-based alphabets.
96105
- Strict decoding is default.
97106
- Legacy behavior must be opt-in and named.
107+
- Canonical decoding is default.
108+
- Panicking convenience APIs are avoided in favor of checked APIs for
109+
untrusted sizes and untrusted input.
110+
- New profile APIs must expose caller-owned buffer variants before adding
111+
allocation conveniences.
98112

99113
## Security Design
100114

@@ -133,6 +147,89 @@ Phase 3:
133147
- Per-architecture benchmark evidence.
134148
- Release evidence archived under `target/release-evidence`.
135149

150+
## Ultimate Zero-Dependency Backlog
151+
152+
The following backlog captures the remaining features that can make
153+
`base64-ng` a high-assurance, general-purpose replacement without weakening
154+
the zero-runtime-dependency stance.
155+
156+
### Already Established
157+
158+
- Standard and URL-safe alphabets.
159+
- Padded and unpadded engines.
160+
- Strict-by-default canonical decoding.
161+
- Explicit legacy/forgiving decode mode for whitespace-tolerant inputs.
162+
- Caller-owned slice APIs.
163+
- Allocation convenience APIs behind `alloc`.
164+
- In-place encode and decode APIs.
165+
- `std::io` streaming adapters.
166+
- Constant-time-oriented decode APIs for sensitive caller-owned buffers.
167+
- Clear-tail APIs and streaming buffer cleanup for best-effort data retention
168+
reduction.
169+
- Detailed decode errors with offsets.
170+
- `no_std` scalar core.
171+
- Const encode support into caller-sized arrays.
172+
- Runtime backend reports and high-assurance scalar-only policy checks.
173+
- Reserved SIMD backends that must prove scalar equivalence before admission.
174+
175+
### Missing Secure Core Features
176+
177+
- Add built-in MIME and PEM profiles with strict line-length handling, custom
178+
line endings, and profile-specific whitespace policy.
179+
- Add a built-in bcrypt alphabet/profile if its non-RFC behavior can be
180+
represented clearly without weakening RFC 4648 defaults.
181+
- Add custom alphabet/profile constructors with duplicate-character rejection,
182+
padding-character conflict checks, and deterministic error reporting.
183+
- Add line-wrapping encode APIs for 64-column PEM, 76-column MIME, and
184+
caller-selected line endings.
185+
- Add validate-only APIs:
186+
- `validate(input) -> bool` for quick sanitization.
187+
- `validate_result(input) -> Result<(), DecodeError>` for diagnostics.
188+
- profile-aware validation for strict, legacy, MIME, PEM, and constant-time
189+
paths.
190+
- Add zero-dependency small-output helpers for common short values, such as a
191+
stack-backed encoded buffer type that avoids heap allocation without forcing
192+
callers to hand-roll arrays.
193+
- Add internal best-effort wipe primitives for crate-owned temporary buffers,
194+
using volatile writes and compiler fences where appropriate. This must be
195+
documented as retention reduction, not a hard zeroization guarantee.
196+
- Add secret wrapper types for sensitive decoded/encoded material with redacted
197+
`Debug`/`Display`, explicit reveal APIs, and drop-time best-effort wiping for
198+
owned buffers.
199+
- Expand panic-free policy checks for non-test scalar code, replacing unchecked
200+
indexing and unwrap-like operations where practical or proving their bounds
201+
where replacement would harm clarity.
202+
- Add a CWE/security-control mapping document that explains which classes of
203+
misuse the crate mitigates and which remain caller responsibilities.
204+
- Add a README trust dashboard covering dependencies, audit status, Miri,
205+
fuzzing, Kani status, unsafe inventory, MSRV, SBOM, reproducibility, and
206+
scalar-only policy.
207+
208+
### Missing Performance Features
209+
210+
- Admit real AVX2, AVX-512, NEON, SSSE3/SSE4.1, and wasm `simd128` paths only
211+
after scalar differential tests, fuzz evidence, target-feature checks, unsafe
212+
inventory updates, and benchmark evidence are complete.
213+
- Keep alignment and prefetch work internal and evidence-driven. Public
214+
alignment APIs are not admitted unless benchmarks show practical value and
215+
the API cannot cause unsafe caller assumptions.
216+
- Keep scalar as the correctness reference and mandatory fallback for every
217+
accelerated backend.
218+
- Maintain dependency-free benchmark harnesses first; only admit external
219+
benchmark tooling if the added dependency graph is justified.
220+
221+
### Admission-Gated Ecosystem Features
222+
223+
- Async/Tokio wrappers remain gated by `docs/ASYNC.md` and the dependency
224+
admission policy.
225+
- `serde` integration remains optional and rejected by default until a concrete
226+
wrapper API and security story are reviewed.
227+
- `bytes` integration remains optional and rejected by default until the
228+
dependency and trait surface are justified.
229+
- Property-test crates remain outside the runtime dependency graph. The current
230+
preferred path is deterministic exhaustive tests and fuzz harnesses; add
231+
property-testing only in an isolated dev/harness context if it earns review.
232+
136233
## Roadmap
137234

138235
### v0.1
@@ -230,6 +327,19 @@ Phase 3:
230327

231328
### v0.6
232329

330+
- Add profile-level support for MIME, PEM, and bcrypt-compatible alphabets
331+
where those profiles can remain strict, explicit, and dependency-free.
332+
- Add custom alphabet/profile construction with validation for duplicate
333+
symbols, padding conflicts, ASCII constraints, and deterministic errors.
334+
- Add line-wrapping encode support for PEM/MIME/common caller-selected wrapping
335+
policies, including CRLF and LF output.
336+
- Add validate-only APIs for strict, legacy, profile-aware, and
337+
constant-time-oriented validation use cases.
338+
- Add zero-dependency stack-backed output helpers for short encoded values.
339+
- Add internal best-effort wiping helpers and secret wrapper types with redacted
340+
formatting for sensitive owned buffers.
341+
- Add the README trust dashboard and CWE/security-control mapping
342+
documentation.
233343
- Expand Kani proof coverage for length helpers, in-place decode bounds, and
234344
selected scalar decoder invariants when Kani supports the pinned Rust
235345
toolchain.
@@ -243,11 +353,14 @@ Phase 3:
243353

244354
### v0.7
245355

246-
- Replace inactive SIMD encode prototypes with real candidate implementations
247-
only when scalar differential tests, fuzz evidence, target-feature checks,
248-
unsafe inventory updates, and benchmark evidence are complete.
356+
- Replace inactive SIMD encode prototypes with real AVX2, AVX-512, NEON,
357+
SSSE3/SSE4.1, and wasm `simd128` candidate implementations only when scalar
358+
differential tests, fuzz evidence, target-feature checks, unsafe inventory
359+
updates, and benchmark evidence are complete.
249360
- Keep scalar as the default fallback and require runtime backend policy tests
250361
for every admitted accelerated backend.
362+
- Evaluate alignment and prefetch optimizations only as internal
363+
benchmark-backed experiments, not as public contracts.
251364
- Publish per-architecture benchmark evidence for any performance claim,
252365
including CPU, OS, Rust version, command, and raw output.
253366

@@ -257,8 +370,14 @@ Phase 3:
257370
requirements are met, including dependency review, cancellation behavior,
258371
drop cleanup behavior, chunk-boundary tests, and release evidence with the
259372
async feature enabled.
373+
- Consider optional `serde` and `bytes` integration only if a concrete user
374+
need clears dependency admission; otherwise keep both out of the crate.
375+
- Add native Rust interoperability that needs no dependencies, such as
376+
`TryFrom<&str>` for owned decoded buffer wrappers and redacted formatting for
377+
secret wrapper types.
260378
- If async remains unjustified, keep `tokio` inert and spend this milestone on
261-
stream ergonomics, documentation, and additional framed-protocol tests.
379+
stream ergonomics, documentation, framed-protocol tests, and wasm/no-allocator
380+
portability checks.
262381

263382
### v0.9
264383

@@ -267,12 +386,22 @@ Phase 3:
267386
evidence rehearsal.
268387
- Decide whether constant-time decode is formally guaranteed with supporting
269388
evidence or explicitly documented as constant-time-oriented only.
389+
- Complete the panic-free public API audit for non-test scalar code and document
390+
any remaining bounded internal indexing with proof or test evidence.
391+
- Freeze profile behavior for strict, legacy, MIME, PEM, bcrypt, custom
392+
alphabets, and validation-only APIs.
393+
- Finalize the trust dashboard, CWE mapping, dependency admission outcomes, and
394+
security policy language for enterprise review.
270395
- Freeze dependency policy and feature admission rules for `v1.0`.
271396

272397
### v1.0
273398

274399
- Kani proofs complete for scalar in-place decode.
275400
- Formal or tool-backed evidence for panic-free scalar public APIs.
401+
- Stable profile API for RFC 4648 standard and URL-safe, MIME, PEM, bcrypt, and
402+
custom alphabets.
403+
- Stable validate-only APIs.
404+
- Stable secret-buffer and best-effort cleanup API contracts.
276405
- Published security and migration documentation for strict-by-default adoption.
277406
- Constant-time decode guarantee either formally documented with supporting
278407
verification evidence or explicitly excluded from the stable API contract.

0 commit comments

Comments
 (0)