Lowercase hex encoding of a byte slice. Replaces the old format!("{:x}", …)
over a digest output: RustCrypto digest 0.11 returns hybrid_array::Array,
which no longer implements LowerHex.
In-place L2 normalisation. Zero vectors are left unchanged (all zeros).
Pre-normalising stored vectors lets vector search reduce cosine similarity
to a plain dot product in its O(N) inner loop.