|
37 | 37 | digest, separate from the lower digest bytes commonly used for direct visual |
38 | 38 | parameters. |
39 | 39 | - The temporary 256-bit RNG seed copy is stored in `zeroize::Zeroizing`, so the |
40 | | - digest-derived seed copy is scrubbed immediately after seeding the renderer |
41 | | - RNG. |
| 40 | + digest-derived seed copy is scrubbed on scope exit. The final value passed to |
| 41 | + `StdRng::from_seed` is also held in a `Zeroizing` guard before the copy into |
| 42 | + `StdRng`. |
42 | 43 | - The procedural RNG itself is `rand::rngs::StdRng`. Its expanded internal |
43 | 44 | state is not zeroized on drop because `StdRng` does not currently implement |
44 | 45 | `ZeroizeOnDrop`. In the default SHA-512 mode, recovering the original |
|
54 | 55 | short-lived so digest bytes do not remain live in multiple memory locations |
55 | 56 | longer than necessary. |
56 | 57 | - Derived identity digests and temporary hash preimage buffers are zeroized |
57 | | - when dropped. |
| 58 | + when dropped. The intermediate 64-byte digest returned by each hash backend is |
| 59 | + held in `Zeroizing` guards before being copied into `AvatarIdentity`. |
58 | 60 | - The SHA-512 dependency is built with its `zeroize` feature so its block |
59 | | - buffer uses upstream `ZeroizeOnDrop`. The optional BLAKE3 dependency is built |
60 | | - with its `zeroize` feature, and `hashavatar` explicitly zeroizes the BLAKE3 |
61 | | - hasher and XOF reader after deriving the 64-byte digest. Tests assert these |
62 | | - upstream zeroization traits remain available. |
| 61 | + buffer uses upstream `ZeroizeOnDrop`. SHA-512 `finalize()` still returns the |
| 62 | + digest output by value, so the output bytes have the same unavoidable |
| 63 | + by-value-copy caveats as the BLAKE3 and XXH3 paths. `hashavatar` wraps that |
| 64 | + returned digest in `Zeroizing` immediately. The optional BLAKE3 dependency is |
| 65 | + built with its `zeroize` feature, and `hashavatar` explicitly zeroizes the |
| 66 | + BLAKE3 hasher and XOF reader after deriving the 64-byte digest. Tests assert |
| 67 | + these upstream zeroization traits remain available. |
63 | 68 | - Identity hash preimage allocation is sized from the tenant, style-version, |
64 | 69 | and identity input lengths. The crate bounds and zeroizes those temporary |
65 | 70 | buffers, but it does not hide input length from the allocator, OS-level heap |
66 | 71 | profilers, or other same-process memory-observation tools. Very |
67 | 72 | high-assurance callers that treat identifier length as sensitive should |
68 | 73 | normalize or pad identifiers to a fixed length before calling this crate. |
| 74 | +- The optional XXH3-128 mode derives the crate's 64-byte identity digest by |
| 75 | + hashing four domain-separated chunks. Each chunk temporarily copies the |
| 76 | + bounded preimage into a zeroized buffer, so peak preimage memory is higher |
| 77 | + than SHA-512 or BLAKE3. Keep XXH3 for low-stakes, non-adversarial workloads |
| 78 | + where its non-cryptographic collision profile and extra temporary preimage |
| 79 | + copy are acceptable. |
| 80 | +- The crate seeds its own rendering RNG deterministically from identity digest |
| 81 | + bytes and does not use OS entropy for avatar rendering. The `rand` dependency |
| 82 | + may still bring a transitive `getrandom` dependency into the lockfile; WASM |
| 83 | + and embedded applications that use OS-backed randomness elsewhere in the same |
| 84 | + binary must configure and test `getrandom` for their target explicitly. |
69 | 85 | - Encode APIs wrap temporary owned raster buffers in RAII zeroization guards, so |
70 | 86 | pixel data is cleared during normal returns, encoder errors, and unwinding |
71 | 87 | panics. JPEG export also wraps the temporary RGB flattening buffer in |
|
90 | 106 | semaphore wrapper because concurrency primitives belong to the caller's |
91 | 107 | async/runtime boundary. |
92 | 108 | - Internal rectangle helpers use saturating or clamping arithmetic for edge and |
93 | | - intersection calculations. |
| 109 | + intersection calculations. Rectangle size construction promotes zero |
| 110 | + dimensions to a one-pixel rectangle so rounded-down decorative features remain |
| 111 | + non-panicking; minimum-size rendering is covered by regression tests. |
94 | 112 | - Raster frame-shape hit-testing uses integer arithmetic for circle, squircle, |
95 | 113 | hexagon, and octagon masks, reducing platform-specific floating-point |
96 | 114 | rounding in clipping decisions. |
| 115 | +- Decorative raster backgrounds are deterministic. Pattern and gradient modes |
| 116 | + are explicit by design, while the starry background now incorporates identity |
| 117 | + digest bytes in its local deterministic star-position generator. |
97 | 118 | - Polygon rasterization returns immediately for empty polygons and zero-sized |
98 | 119 | images, widens scanline interpolation math before rounding, and is covered by |
99 | 120 | a dedicated fuzz harness for arbitrary image dimensions, degenerate polygons, |
|
0 commit comments