perf(crypto): vectorized BLAKE3 / LtHash and cached key parsing #112

Closed
opened 2026-09-24 12:28:55 +00:00 by Grandiras · 0 comments
Owner

Part of the v0.7.0 update cycle. The CPU cost of Spaces syncing and signature verification.

Scope

  • BLAKE3: keep the compression state in locals, precompute the message schedule, and allocate nothing per hash. XOF output blocks are independent, so compress 8 counters at once with Vector256<uint>, with a scalar fallback. A prototype measured 11.9 µs → 0.72 µs (16.6×) for 2048 B of output.
  • LtHash: add and subtract lanes with Vector256<ushort> over MemoryMarshal.Cast of the XOF output (little-endian, with a scalar fallback). A prototype measured LtHash.Add at 13.1 µs → 0.77 µs (17×) with 0 B allocated. A 10k-record SpaceRepoCommit.FromIndex drops from 131 ms to about 8 ms.
  • Signature verification: cache parsed did:key public keys (bounded, keyed by the did:key string). Make the curve parameters static readonly, precompute the square-root exponent, decode Base58 into a span, and stop IsLowS allocating. A P-256 verify measured 90 µs → 41 µs.
  • Internal duplication in AtProtoCrypto: AtProtoKey.GetCompressedPublicKey vs CompressPublicKey; DecompressPoint re-deriving the curve from OIDs; repeated OID literals; FromMultikey repeating MultibaseToBytes; and the curve→JWS alg mapping written twice (ServiceAuthGenerator, SpaceTokens), which becomes one helper.
  • Remove the unused Blake3.KeyLen.

Tests

  • Add the atproto-interop-tests crypto fixtures (w3c_didkey_P256.json, w3c_didkey_K256.json, signature-fixtures.json), including low-S/high-S cases.
  • Fix K256_GenerateAndSign_IfSupported, which passes silently on PlatformNotSupportedException.
  • The existing 27 BLAKE3 reference vectors and the lane-for-lane LtHash tests must stay green. Add input lengths 0…1024 compared against the scalar path.

Acceptance

  • Bit-exact results against all vectors.
  • Before/after BenchmarkDotNet numbers in the PR description.
  • No public API change.
Part of the v0.7.0 update cycle. The CPU cost of Spaces syncing and signature verification. ## Scope - [ ] **BLAKE3:** keep the compression state in locals, precompute the message schedule, and allocate nothing per hash. XOF output blocks are independent, so compress 8 counters at once with `Vector256<uint>`, with a scalar fallback. A prototype measured 11.9 µs → 0.72 µs (16.6×) for 2048 B of output. - [ ] **LtHash:** add and subtract lanes with `Vector256<ushort>` over `MemoryMarshal.Cast` of the XOF output (little-endian, with a scalar fallback). A prototype measured `LtHash.Add` at 13.1 µs → 0.77 µs (17×) with 0 B allocated. A 10k-record `SpaceRepoCommit.FromIndex` drops from 131 ms to about 8 ms. - [ ] **Signature verification:** cache parsed `did:key` public keys (bounded, keyed by the did:key string). Make the curve parameters `static readonly`, precompute the square-root exponent, decode Base58 into a span, and stop `IsLowS` allocating. A P-256 verify measured 90 µs → 41 µs. - [ ] **Internal duplication in `AtProtoCrypto`:** `AtProtoKey.GetCompressedPublicKey` vs `CompressPublicKey`; `DecompressPoint` re-deriving the curve from OIDs; repeated OID literals; `FromMultikey` repeating `MultibaseToBytes`; and the curve→JWS `alg` mapping written twice (`ServiceAuthGenerator`, `SpaceTokens`), which becomes one helper. - [ ] Remove the unused `Blake3.KeyLen`. ## Tests - [ ] Add the `atproto-interop-tests` crypto fixtures (`w3c_didkey_P256.json`, `w3c_didkey_K256.json`, `signature-fixtures.json`), including low-S/high-S cases. - [ ] Fix `K256_GenerateAndSign_IfSupported`, which passes silently on `PlatformNotSupportedException`. - [ ] The existing 27 BLAKE3 reference vectors and the lane-for-lane LtHash tests must stay green. Add input lengths 0…1024 compared against the scalar path. ## Acceptance - Bit-exact results against all vectors. - Before/after BenchmarkDotNet numbers in the PR description. - No public API change.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/ATProto.NET#112
No description provided.