Commit 63ef2aa
authored
Migrate to whatsapp-rust 0.5 stack (#15)
* chore(deps): bump whatsapp-rust to 0.5 stack and adjust transitive crates
cargo update + dependency configuration changes required for the
whatsapp-rust 0.5 series:
- getrandom 0.3 → 0.4 (transitively required by rand 0.10)
- rand 0.9 → 0.10, with explicit "sys_rng" feature so make_rng falls back
to SysRng on wasm32 (no thread_rng under wasm)
- wacore-binary: opt-out of "default-features" to drop the "simd" feature
it now defaults to (we keep our own simd128 target-feature flag and
don't need its portable_simd-based scalar fallback paths)
- hashify 0.2.9 with "force-32bit" feature, declared as a direct dep so
Cargo unifies features across the tree. Without this, hashify's PHF
proc-macro picks the 64-bit "large" lookup module based on the host's
pointer width, which generates code that does `key_hash as usize`
(64-bit on host but 32-bit on wasm32) — silently truncating the hash
and breaking lookups for some keys (e.g. tokens "receipt", "from",
"id" all returned None on wasm32 while "message" worked). Forcing
32-bit mode keeps all u32 arithmetic and produces consistent lookups.
Drop redundant `#[wasm_bindgen(skip)]` attributes on private cache
fields of `InternalBinaryNode`. The macro already skips private fields,
and wasm-bindgen 0.2.121's accounting for the `skip` attribute on
already-skipped fields trips an `unused_variables` lint via the
generated `let skip: ();` marker — clippy promotes that to an error
under `-D warnings`.
* refactor: migrate to rand 0.10 idiom
In rand 0.10:
- OsRng was removed from rand::rngs (now in getrandom as SysRng)
- TryRngCore trait was renamed to TryRng (in rand_core)
- The .unwrap_err() shorthand on OsRng is gone
Replace `OsRng.unwrap_err()` with `rand::make_rng::<StdRng>()`, which
is the idiom whatsapp-rust 0.5 itself uses. make_rng seeds a StdRng
(ChaCha-based CryptoRng) from SysRng each call. Slightly more overhead
than direct OsRng but functionally equivalent and consistent with
upstream's signal session code.
Update key_helper, curve, group_cipher, session_builder, and
session_cipher to the new idiom.
* refactor(storage_adapter): adapt to SessionStore/SenderKeyStore trait redesign
wacore-libsignal 0.5 reshaped the session storage traits:
- SessionStore gained a non-destructive has_session(&self) probe.
Implemented by delegating to load_session — adequate for our cache,
which uses Rc<RefCell> interior mutability so load doesn't mutate
observable state.
- store_session and store_sender_key now take `record: T` by value
(was `&T`). Owned record means callers can't accidentally retain a
reference after the store returns. We move the record straight into
the cache (saves one CoreSessionRecord/CoreSenderKeyRecord clone per
store — non-trivial since these carry chain keys + message keys).
- load_sender_key now takes `&self` (was `&mut self`). Our cache lookup
already used interior mutability, so the receiver change is a no-op.
* refactor(binary): adapt to wacore-binary 0.5 NodeStr/AttrsRef redesign
wacore-binary 0.5 reshaped the borrowed node types for performance:
- Cow<'a, str> for tag/string fields → NodeStr<'a> { Borrowed(&str),
Owned(CompactString) }. CompactString avoids heap allocation for
strings up to 12 bytes (on 32-bit targets), which covers most
WhatsApp protocol tokens and short JIDs.
- Vec<(Cow<str>, ValueRef)> for attrs → AttrsRef<'a> { Empty,
Slice(Box<[...]>) }. Boxed slice for the populated case; Empty
variant skips the allocation entirely.
- NodeContentRef::Nodes(Box<Vec<NodeRef>>) → Box<[NodeRef]>. Boxed
slice instead of boxed Vec.
- ValueRef::as_str() now returns Cow<'_, str> unconditionally instead
of Option<&str> — the old None branch (for Jid encoded as bytes) is
gone since Jid carries its own decoded form.
Update js_to_node_ref to construct the new types and convert_attrs to
iterate AttrsRef directly.
* fix(noise_session): adapt to wacore-binary/wacore-noise 0.5 renames
- wacore_binary::consts::NOISE_START_PATTERN → NOISE_PATTERN_XX. The
constant was renamed when 0.5 split out separate XX, IK, and
XXfallback handshake patterns.
- NoiseCipher::decrypt_with_counter (allocating, returns Vec) →
decrypt_in_place_with_counter (in-place, takes &mut buffer).
Wrap the input slice in a fresh Vec for the in-place buffer; the
allocation count is unchanged but the AES-GCM path is in-place,
matching the encrypt side's existing pattern.
* perf: avoid intermediate Uint8Array allocations on FFI boundary
Three small wins on the wasm→JS conversion path:
- byte_array.copy_to(&mut vec![0; len]) → byte_array.to_vec() in
js_to_node_ref. Skips the zero-init memset before overwriting the
buffer.
- Uint8Array::new_with_length(n) + result.copy_from(&bytes) →
Uint8Array::from(slice) in encode_node, the Bytes content getter, and
the bytes_to_uint8array helper used by SessionCipher's encrypt and
decrypt return paths. Same FFI semantics, cleaner API.
* fix(bench/signal): give each summary its own session pair
The original bench shared one Alice/Bob pair across Encrypt, Decrypt,
and Round-trip benches. This was always borderline-correct, but became
broken once encrypt got fast enough for mitata to enable batch mode:
- mitata's min_cpu_time = 642ms / encrypt cost
- Pre-migration: ~169µs/iter → ~3800 iterations during the Encrypt bench
- Post-migration: ~17µs/iter (batch-amortised) → ~38000 iterations
When the Encrypt bench advances Alice's chain solo past 25_000 messages
without Bob seeing them, the next Decrypt bench (Alice encrypts → Bob
decrypts) has Bob trying to skip > MAX_FORWARD_JUMPS (25_000) messages
forward in the chain, which libsignal correctly rejects as
InvalidMessage.
Fix: each `summary()` block builds a fresh (Alice, Bob) pair via
make{Wasm,Lib}Pair() helpers. The Encrypt bench can advance its own
Alice's chain freely; the Decrypt and Round-trip benches operate on
independent pairs that start fresh.
Verified: 5/5 runs of `node --expose-gc benches/signal.ts` pass with
consistent timings (~17µs encrypt, 30-250µs decrypt, ~800µs round-trip
on the Rust WASM side).
Reproducer for the underlying limit:
for (let i = 0; i < 25500; i++) await alice.encrypt(typical);
const enc = await alice.encrypt(typical);
await bob.decryptWhisperMessage(enc.body); // throws InvalidMessage
The threshold is exactly libsignal's MAX_FORWARD_JUMPS = 25_000.1 parent 747d01e commit 63ef2aa
11 files changed
Lines changed: 481 additions & 634 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
| 50 | + | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| |||
60 | 61 | | |
61 | 62 | | |
62 | 63 | | |
63 | | - | |
| 64 | + | |
64 | 65 | | |
65 | 66 | | |
| 67 | + | |
66 | 68 | | |
67 | 69 | | |
68 | 70 | | |
| |||
85 | 87 | | |
86 | 88 | | |
87 | 89 | | |
88 | | - | |
| 90 | + | |
89 | 91 | | |
90 | 92 | | |
91 | 93 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
98 | | - | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
99 | 102 | | |
100 | | - | |
101 | | - | |
102 | 103 | | |
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 | | - | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
133 | 107 | | |
134 | 108 | | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
141 | 133 | | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
| 134 | + | |
| 135 | + | |
147 | 136 | | |
148 | | - | |
149 | | - | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
150 | 142 | | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
| 143 | + | |
| 144 | + | |
160 | 145 | | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
167 | 150 | | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
175 | | - | |
| 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 | + | |
176 | 185 | | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
| 186 | + | |
| 187 | + | |
190 | 188 | | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
197 | 193 | | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
| 194 | + | |
| 195 | + | |
206 | 196 | | |
207 | 197 | | |
208 | 198 | | |
| |||
215 | 205 | | |
216 | 206 | | |
217 | 207 | | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
227 | | - | |
228 | | - | |
229 | | - | |
230 | | - | |
231 | | - | |
232 | | - | |
233 | | - | |
234 | | - | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | | - | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
243 | 211 | | |
244 | 212 | | |
245 | | - | |
| 213 | + | |
246 | 214 | | |
| 215 | + | |
| 216 | + | |
247 | 217 | | |
248 | 218 | | |
249 | 219 | | |
250 | 220 | | |
251 | | - | |
| 221 | + | |
252 | 222 | | |
253 | 223 | | |
254 | 224 | | |
255 | 225 | | |
256 | | - | |
| 226 | + | |
257 | 227 | | |
258 | 228 | | |
259 | 229 | | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
260 | 237 | | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
261 | 243 | | |
262 | | - | |
263 | | - | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
270 | 252 | | |
271 | 253 | | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
280 | 264 | | |
281 | 265 | | |
| 266 | + | |
282 | 267 | | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
283 | 275 | | |
284 | | - | |
285 | 276 | | |
286 | | - | |
287 | | - | |
288 | | - | |
289 | | - | |
290 | | - | |
291 | | - | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
292 | 281 | | |
293 | 282 | | |
294 | 283 | | |
295 | 284 | | |
296 | 285 | | |
297 | 286 | | |
298 | 287 | | |
299 | | - | |
300 | | - | |
301 | | - | |
| 288 | + | |
| 289 | + | |
302 | 290 | | |
303 | 291 | | |
304 | | - | |
305 | | - | |
306 | | - | |
| 292 | + | |
| 293 | + | |
307 | 294 | | |
308 | 295 | | |
309 | 296 | | |
| |||
0 commit comments