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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
//! The key package payload, which is how a peer says who it is and what it
//! can parse.
//!
//! This is the body of a [`prefixes::KEY_PACKAGE`] frame, and it is the only
//! channel in this protocol by which capabilities are advertised. A device
//! with no key package to mint has no way to say it understands anything, so
//! every frame sent to it falls to the protocol floor forever. That is the
//! reason a leaf node runs MLS rather than something smaller: not the
//! sealing, the advertising.
//!
//! Both ends must agree on this shape, and they build it with different MLS
//! implementations, so it lives here rather than in the engine.
//!
//! [`prefixes::KEY_PACKAGE`]: crate::prefixes::KEY_PACKAGE
use ;
use ;
/// Payload for key package exchange.
///
/// Every field except `user_id` and `key_package_data` carries
/// `#[serde(default)]`, so a payload written by an older peer that has never
/// heard of a field decodes cleanly with that field empty. Empty selects the
/// floor, by rule and never by error, which is what makes a mixed fleet safe.
/// Compact MLS envelope version advertised in
/// [`KeyPackagePayload::env_versions`]: the [`prefixes::ENCRYPTED`] payload is
/// base64 of [`EncryptedMessage::to_bytes`] instead of the legacy JSON form
/// (whose `ciphertext` field renders as a roughly 3.6x integer array).
/// Receivers distinguish the two by the byte after the prefix: `{` opens the
/// JSON envelope and never occurs in base64.
///
/// [`prefixes::ENCRYPTED`]: crate::prefixes::ENCRYPTED
/// [`EncryptedMessage::to_bytes`]: crate::EncryptedMessage::to_bytes
pub const MLS_ENVELOPE_COMPACT_V1: u8 = 1;
/// Control-frame signing version advertised in
/// [`KeyPackagePayload::ctrl_versions`]: the sender verifies signatures over
/// [`control_signing_payload_v2`], which binds the frame's timestamp and so
/// can be refused for being stale.
///
/// There is no `CTRL_SIGN_V1` constant, and the absence is deliberate: an
/// empty list already means "v1 only", and a named constant for it would
/// invite a peer to advertise `[1]` as though declining the newer payload were
/// a capability rather than the floor.
///
/// [`control_signing_payload_v2`]: crate::canonical::control_signing_payload_v2
pub const CTRL_SIGN_V2: u8 = 2;