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
use super::priv_state::{PlaintextEntry, TermBuilder};
use super::SteVecPendingEncryption;
use crate::encryption::{
json_indexer::{
path_values::{PathSegment, PathValue},
prefix_mac::{PrefixMac, UpdatePrefixMac},
},
EncryptionError,
};
#[cfg_attr(test, derive(Debug))]
pub struct StePlaintextVec<'p>(Vec<PlaintextEntry<'p>>);
impl<'p> StePlaintextVec<'p> {
pub fn new() -> Self {
Self(Vec::new())
}
/// Build a SteVec from a StePlaintextVec with selector length `N`.
///
/// Threads two MACs through the build pipeline:
/// - `selector_macca` (Blake3) tokenizes the JSON path into the entry's
/// path selector AND the (path, value) pair into its value selector.
/// Always Blake3 regardless of mode.
/// - `term_macca` (HMAC-SHA256) feeds the orderable-key derivation.
/// Always HMAC regardless of mode.
///
/// The mode-dependent piece is the orderable primitive (ORE vs OPE) —
/// selected by the `TB: TermBuilder` type parameter, not by the MAC
/// flavour.
///
/// ## Output layout
///
/// Every JSON node contributes two entries: a **path entry** (ciphertext +
/// optional orderable term) and a presence-only **value entry** (see
/// [`super::priv_state::EntryWithTokenizedSelector`]). All path entries
/// come first, in traversal order — the root `$` entry MUST stay at index
/// 0, since decryption reads only the root ciphertext — with every value
/// entry appended after them.
pub fn index<const N: usize, TB, MSel, MTerm>(
self,
selector_macca: &mut MSel,
term_macca: &mut MTerm,
) -> Result<SteVecPendingEncryption<N>, EncryptionError>
where
TB: TermBuilder,
for<'u> MSel: PrefixMac
+ UpdatePrefixMac<PathSegment<'p>>
+ UpdatePrefixMac<[u8; N]>
+ UpdatePrefixMac<&'u str>
+ UpdatePrefixMac<String>,
for<'u> MTerm: PrefixMac + UpdatePrefixMac<&'u str> + UpdatePrefixMac<[u8; N]>,
{
let node_count = self.0.len();
let mut path_entries = Vec::with_capacity(node_count * 2);
let mut value_entries = Vec::with_capacity(node_count);
for entry in self.0 {
let (path_entry, value_entry) = entry
.build_selector::<N, MSel>(selector_macca)
.build_terms::<TB, _>(term_macca)?;
path_entries.push(path_entry);
value_entries.push(value_entry);
}
path_entries.append(&mut value_entries);
Ok(SteVecPendingEncryption(path_entries))
}
fn push(&mut self, PathValue(path, value): PathValue<'p>) {
self.0.push(PlaintextEntry::new(path, value));
}
}
impl<'p> FromIterator<PathValue<'p>> for StePlaintextVec<'p> {
fn from_iter<I: IntoIterator<Item = PathValue<'p>>>(iter: I) -> Self {
let mut ste_vec = StePlaintextVec::new();
for entry in iter {
ste_vec.push(entry);
}
ste_vec
}
}