Expand description
Memory-hardened key storage: 128 indistinguishable arrays with decoy writes.
The real 32-byte key is XOR-split into 4 shares (16 usize values on 64-bit),
scattered across 128 static arrays of 4,096 entries each. 123 arrays are pure
decoys — provably indistinguishable from the 5 real arrays.
Defense layers:
- Secret splitting: key XOR-split into 4 shares
- 128 indistinguishable arrays: 5 real + 123 decoy, all same size, all OsRng-initialized, all modified identically during set()/clear()
- No heap allocations: zero pointers, zero fingerprints, zero mlock
- Scattered positions: seed, multipliers, and share data each placed at (array, slot) positions derived from ASLR instance address. The slot dimension is partitioned into LANE_COUNT disjoint lanes; each live key owns one lane (chosen at set() to differ from other live keys), so two keys can never share a slot — cross-key writes are collision-safe.
- Decoy writes: during set(), ALL 128 arrays receive ~16 random writes, making real writes indistinguishable via snapshot diffing
- Zero side-channel:
AtomicUsize::loadduring get() — zero writes - Zero searchable constants: all multipliers derived from ASLR addresses, all modular arithmetic uses power-of-2 AND masks. The vault code compiles to generic LDR + MUL + AND + EOR + LSR — indistinguishable from the thousands of hash/cipher/RNG functions in the binary.
Security tiers: Without source code (info-stealers, forensic tools): immune. Arrays are information-theoretically indistinguishable.
With source code + memory dump: attacker must brute-force the ASLR instance address (~2.5M candidates on macOS, ~268M on Linux). Computational hardening makes each attempt ~25 μs. Estimated: ~1 min (macOS) to ~2 hrs (Linux), single-core.
The vault is the second layer — anti-debug protections (PT_DENY_ATTACH, PR_SET_DUMPABLE, DACL) prevent obtaining the dump in the first place.
Structs§
- Guarded
Key - Memory-hardened key vault backed by 128 indistinguishable static arrays.