Skip to content

Optimize TCipherKernelRegistry for allocation-free reads and EC multipliers - #169

Merged
Xor-el merged 5 commits into
masterfrom
feature/perf-optimizations
Aug 14, 2026
Merged

Optimize TCipherKernelRegistry for allocation-free reads and EC multipliers#169
Xor-el merged 5 commits into
masterfrom
feature/perf-optimizations

Conversation

@Xor-el

@Xor-el Xor-el commented Aug 14, 2026

Copy link
Copy Markdown
Owner

No description provided.

Xor-el added 5 commits August 12, 2026 18:22
The read path (Snapshot/GetSnapshot/TryAcquire*) allocated and refcounted
a fresh factory array on every call. Register/Unregister now rebuild an
immutable copy-on-write snapshot under the write lock; the read takes a
single reference load of it - no per-call allocation.

The lock is held only for that reference load (not the copy, not the
factory TryCreate), so it stays uncontended and, unlike a lock-free read,
keeps runtime registration concurrent with acquisition thread-safe -
matching the guarantee the external-registration API implies.
Replace the array-based constant-time EC point multiplier with an
allocation-free, value-type implementation over stack records, wired as
the default multiplier for P-256, secp256k1, P-384 and P-521.

Core layer (Math/EC/Multiplier):
- ClpCTFieldValue: TFe/TFeExt/TFePoint fixed-size stack records (no heap).
- ClpCTFieldOps: TCTFieldOpsBase, virtual/abstract class-method field ops
  overridden per curve — the one dispatch form that is refcount-free on
  FPC x86_64/i386 and Delphi.
- ClpCTLadder: generic TCTLadder<TOps> — RCB2016 complete add/double
  (Algorithms 1 & 3) over TFePoint.
- ClpFpCTMultiplier: generic TFpCTMultiplier<TOps> (IECMultiplier) — the
  hot loop (fixed 4-bit window, masked table lookup, one unconditional add
  per window, scalar blinding, randomized projective coords). Curve context
  (order, affine conversion, inverse) via IFpFieldOps.

SIMD Fp multiply/square kernel (Simd/Facade + Simd/Backend + Include/Simd):
- Width-general 64-bit-limb schoolbook mul/sqr for x86_64, i386, aarch64,
  behind an arch-neutral TFpKernelSimd.TryMul/TrySqr facade; scalar bridge
  in the caller when unavailable.

Per-curve field ops gained TFe overloads over PUInt32 cores (kernel path
alloc-free); TNat/TNat256 gained PUInt32 overloads (Add/Sub/Gte/Inc/Dec/
Eq/AddTo/ShiftDownBits/Mul33*/IncAt/DecAt/Add33To/Sub33From) with every
array form delegating to the pointer core.

P-521 mixed-width: no new asm — the 17 real limbs are padded to 18 uint32
(= 9 uint64) with a zeroed top limb so the even-width kernel applies;
W[17] kept zero on every field-op output.

Cleanup: retire the now-dead array multiplier and its math.
- Delete ClpFixedWindowCTMultiplier and ClpHomogeneousPoint (TCTHomogeneous-
  Math); remove from all FPC and Delphi manifests.
- Slim IFpFieldOps: drop Square/Add/MulByA/MulByB3 (unused after the move).
- Retarget the exceptional-formula test to the live TCTLadder and the
  blind-bits test to TFpCTMultiplier.
- Extend the dudect harness to all four prime curves.
…ayer refactor

Continues the committed value-type constant-time scalar multiplier (44a951a)
for the Fp prime curves.

Fixed-base comb (ECDSA signing)
- Add TFpCombMultiplier<TOps>: a value-type Lim-Lee comb over stack TFePoint via
  the RCB complete formulas, reusing TFixedPointUtilities' generator table and
  caching the value-type table on the precomp-info object. Constant-time: masked
  table lookup, branchless recoding, fixed loop length.
- Wire it in through a base-point hook rather than the variable-base default:
  IECCurve.GetBasePointMultiplier + TECCurve.CreateBasePointMultiplier (default
  TFixedPointCombMultiplier), overridden per custom curve; TECDsaSigner consumes
  it. Beats OpenSSL's generic [k]G on secp256k1/384/521.

a = -3 / a = 0 field specialization
- Fold the curve coefficient into MulByA: -(x+x+x) via field adds on
  P-256/384/521, zero on secp256k1 (a=0), instead of a full field multiply by a
  constant. ~1.2-1.4x on [k]G; the RCB add/double formulas are unchanged. Drop
  the now-dead FFa constant from all four curves.

Constant-time point-layer refactor
- Merge the group law and the point-representation helpers into a single
  TCTPoint<TOps> (ClpCTLadder -> ClpCTPoint); "Ladder" was a misnomer for the
  RCB group law and clashed with the real TLopezDahabLadder on F2m.
- Rename the value-type arithmetic ClpCTFieldOps/TCTFieldOpsBase ->
  ClpCTFieldArith/TCTFieldArithBase and per-curve TSecXXXOps -> TSecXXXFieldArith
  to end the name collision with the array-based IFpFieldOps adapter. The core is
  now a clean Value -> Arith -> Point trio.
- ClpFpCombMultiplier: hold the fixed-point precomp info as a TWeakRef to break
  the curve <-> comb reference cycle that leaked the curve/comb/adapter/table.
- ClpPkixPolicyNode: use the implicit TWeakRef operators, matching convention.
- ClpX509Certificate: thread-safe lazy caches (SigAlgName/PublicKey/
  CachedEncoding) + Equals fast-path via a class-level critical section with
  double-checked locking.
@Xor-el
Xor-el merged commit 9b726e5 into master Aug 14, 2026
28 checks passed
@Xor-el
Xor-el deleted the feature/perf-optimizations branch August 14, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant