1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! Layer 3 — Fragmentation.
//!
//! The [`FragmentStrategy`] trait splits a [`RawKey`] into a number of opaque
//! [`Fragments`] that the vault stores separately in mlock'd, non-contiguous
//! memory. Reassembly is the inverse operation, performed only when the caller
//! needs to use the key.
//!
//! In this phase the trait surface is defined; concrete implementations
//! (`StandardFragmenter`, `InterleavedFragmenter`, `RandomFragmenter`,
//! `LayeredFragmenter`) arrive in Phases 0.3 and 0.5.
use Cow;
use Vec;
use fmt;
use crateResult;
use crateRawKey;
/// Opaque container for the fragmented representation of a key.
///
/// `Fragments` is intentionally a black box from the public API's point of
/// view. Its internal layout is the [`FragmentStrategy`] implementation's
/// concern; the vault treats it as a token that you hand to the same strategy
/// to recover the original key.
///
/// In this phase the type carries no payload — strategies have not been
/// implemented yet. Phase 0.3 introduces the real storage (variable-size
/// chunks, position maps, mlock'd allocations).
/// Strategy for splitting and reassembling a key.
///
/// # Implementor contract
///
/// - **Round-trip.** For every `key`,
/// `self.defragment(&self.fragment(&key)?)?` must produce a [`RawKey`] equal
/// to `key` byte-for-byte. This invariant is the basis of all property tests
/// in later phases.
/// - **Variable layout per call.** Two consecutive calls to `fragment` on the
/// same input must produce [`Fragments`] with distinct internal layouts. If a
/// strategy is deterministic it should document the threat trade-off
/// explicitly.
/// - **No allocation beyond the produced [`Fragments`].** Hot-path defragment
/// should write into a caller-supplied scratch buffer rather than allocate.
/// - **`Send + Sync`.** A strategy may be invoked from any thread.