@@ -124,3 +124,51 @@ inspiration, never authority.
124124fabrications still on master) · #5 ASG canon spec · #7 ASG-leaf impl (extend
125125` CamPlaneSplat ` , don't reinvent) · ` cam-pq-production-wiring ` (cam_pq shipped, unrouted
126126through ` CamCodecContract ` ) · ` UNUSED_INVENTORY_1.95 ` A1–A9 dead-code.
127+
128+ ## 2026-07-28 — A dependency's SIMD surface is a reachability question, not a porting one (PR #258 )
129+ ** Status:** FINDING (verified — counts + cfg gate + build output all checked live)
130+ ** Scope:** @simd-savant @workspace-primer domain: crypto domain: matryoshka
131+
132+ The same wrong conclusion was reached twice in one arc: "curve25519-dalek's
133+ vector backend carries raw intrinsics (` avx2/field.rs ` reaches around
134+ ` packed_simd.rs ` ), therefore the matryoshka pattern requires removing the
135+ dependency." It got as far as a merged removal commit (` 3694a3c ` ) before the
136+ premise was checked. The counts were right; the conclusion was not:
137+
138+ - ** Counts (verified):** 57 ` _mm* ` intrinsic calls in the AVX2 path
139+ (35 ` backend/vector/avx2/field.rs ` + 22 ` backend/vector/packed_simd.rs ` ),
140+ under 52 ` unsafe ` occurrences in those two files. (` ifma/field.rs ` adds 6
141+ more on a nightly-only path.)
142+ - ** The gate (verified):** ALL of it sits behind ONE cfg —
143+ ` curve25519-dalek-4.1.3/src/backend/mod.rs:42 ` ,
144+ ` #[cfg(curve25519_dalek_backend = "simd")] pub mod vector; ` — and dalek's
145+ build.rs reads that cfg from ` CARGO_CFG_CURVE25519_DALEK_BACKEND ` .
146+ - ** The fix (one line):** ` .cargo/config.toml ` rustflags
147+ ` --cfg curve25519_dalek_backend="serial" ` compiles the entire second SIMD
148+ surface out. Verified after ` cargo clean -p curve25519-dalek ` : the build
149+ emits ` curve25519_dalek_backend="serial" ` only.
150+ - ** ` serial ` costs nothing we use:** X25519's Montgomery ladder
151+ (` montgomery.rs ` ) never references the vector backend; the vector path
152+ serves only Edwards multi-scalar / variable-base multiplication (batch
153+ verification, Ristretto protocols) — neither performed by
154+ ` crates/encryption ` .
155+
156+ ** The rule this mints:** before porting a third-party crate's SIMD onto
157+ ` ndarray::simd ` — and * long* before removing the crate — grep for the
158+ backend's cfg/feature gate. "It contains raw intrinsics" and "raw intrinsics
159+ reach the binary" are different claims; the matryoshka invariant binds the
160+ second, not the first. PR #258 (merged ` b127e25 ` ) is the worked example: the
161+ removal reverted, Ed25519 kept, the surface neutralized by cfg, diff net
162+ additive.
163+
164+ ** Carried tripwire (X25519 port):** ` x448::x448() ` returns ` Option ` and
165+ rejects low-order points; ` x25519_dalek::x25519() ` returns a bare
166+ ` [u8; 32] ` — RFC 7748's contributory check is OPTIONAL, so a mechanical port
167+ drops it silently. The test
168+ ` channel::tests::low_order_peer_keys_are_refused_and_honest_ones_are_not `
169+ (both halves asserted, per the falsifiability rule) fails if it does.
170+
171+ Cross-ref: PR #258 body (the full correction narrative), ` .cargo/config.toml `
172+ comment block (the in-tree record), lance-graph
173+ ` E-VACUOUS-ASSERTION-IS-THE-HOUSE-STYLE-1 ` (the falsifiability rule the
174+ low-order test follows).
0 commit comments