Skip to content

Injectable RNG for the constant-time EC scalar multipliers - #202

Merged
Xor-el merged 1 commit into
masterfrom
injectable-rng-ct-multipliers
Sep 23, 2026
Merged

Xor-el merged 1 commit into
masterfrom
injectable-rng-ct-multipliers

Conversation

@Xor-el

@Xor-el Xor-el commented Sep 23, 2026

Copy link
Copy Markdown
Owner

What

The constant-time EC scalar multipliers lazily created their own TSecureRandom
for the scalar blind and projective-coordinate randomizer, ignoring any
caller-supplied ISecureRandom. This adds injectable-RNG overloads so a caller
can own that randomness with a single DRBG rather than one instantiated per operation.

Changes

  • IECCTMultiplierFactory: CreateCTMultiplier(const ARandom: ISecureRandom; ABlindBits)
    (overload) and CreateBasePointCTMultiplier(const ARandom: ISecureRandom); implemented by
    the four Fp custom curves (secp256r1/k1, secp384r1, secp521r1).
  • TEphemeralECDHAgreement and TFpAffineCombMultiplier: random-accepting constructors.
  • Key generation and ECDSA signing thread their injected RNG into the fixed-base comb.
    Deterministic (RFC 6979) signing has no injected RNG, so it keeps the curve's cached
    multiplier instead of building a fresh DRBG per signature.
  • The injected-RNG entry points reject a nil random rather than silently degrading.
  • The curve's lazily-cached default/base-point multipliers are now created under the existing
    lock (pre-existing race on the interface field).

Behaviour

Additive and backward-compatible: the existing non-RNG constructors and factory methods are
unchanged; the blind stays transparent to the result.

The constant-time scalar multipliers — the variable-base CT multiplier and
the fixed-base comb — drew their scalar blind and projective randomizer from
a TSecureRandom they lazily created, bypassing any caller-supplied
ISecureRandom. Thread a caller-owned RNG through both so a caller can supply
one DRBG for every constant-time multiplication instead of each multiplier
instantiating its own.

- IECCTMultiplierFactory gains CreateCTMultiplier(ARandom, ABlindBits) and
  CreateBasePointCTMultiplier(ARandom); the four Fp custom curves implement both.
- TEphemeralECDHAgreement and TFpAffineCombMultiplier gain random-accepting
  constructors.
- Key generation and ECDSA signing route the fixed-base blind through their
  injected RNG. Deterministic signing has no injected RNG, so it keeps the
  curve's shared multiplier rather than building a fresh DRBG-backed comb per
  signature.
- The injected-RNG entry points reject a nil random instead of silently
  degrading, and the curve's lazily-cached multipliers are now built under the
  existing lock.

The blind remains transparent to the result (checked against a WNAF reference
on secp256r1, secp256k1, secp384r1 and secp521r1), and a counting RNG proves
both randomness draws come from the injected source.
@Xor-el
Xor-el merged commit ecb0dd6 into master Sep 23, 2026
28 checks passed
@Xor-el
Xor-el deleted the injectable-rng-ct-multipliers branch September 23, 2026 16:45
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