ddn.crypto.ct

Constant-Time Arithmetic Utilities for Side-Channel Resistance.

This module provides constant-time operations that do not leak information through timing side-channels. All operations execute in the same amount of time regardless of the values of their operands.

Security

Note

These functions are designed to prevent timing

attacks but do not protect against other side-channel attacks such as power analysis or electromagnetic emanation. Additionally, the compiler and CPU may introduce timing variations through optimizations or speculative execution.

Types 2

aliasctEqual = safeEqual

Compares two byte arrays in constant time.

This function always examines all bytes regardless of whether a mismatch is found, preventing timing attacks that could determine the position of the first differing byte.

This is an alias of safeEqual from ddn.api.crypto.common, so the two names can never drift apart.

Parameters

aFirst byte array to compare.
bSecond byte array to compare.

Returns

true if the arrays have the same length and content,

false otherwise.

Side-Channel Resistance Guidelines

This module provides building blocks for constant-time cryptographic implementations. To properly use these functions:

  1. Always use safeEqual (aliased as ctEqual) instead of `==`

    for secret comparisons.

  2. Use ctSelect and ctSwap instead of conditional branches

    when the condition depends on secret data.

  3. Ensure loop bounds do not depend on secret values.
  4. Be aware that BigInt operations like `%` and `*` may not be

    fully constant-time; use Montgomery multiplication for modular arithmetic when timing is critical.

  5. Memory access patterns should not depend on secrets; use

    constant-time table lookups or avoid tables entirely.

Limitations:

  • Compiler optimizations may introduce timing variations.
  • CPU features like branch prediction, caching, and speculative

    execution can leak information.

  • These functions protect against timing attacks but not against

    other side-channel attacks like power analysis.

Functions 10

fnT ctSelect(T)(uint condition, T a, T b) if (is(T == ubyte) || is(T == ushort) || is(T == uint) || is(T == ulong)) pure nothrow @nogc @safeSelects between two values in constant time.
fnvoid ctSwap(T)(uint doSwap, ref T a, ref T b) if (is(T == ubyte) || is(T == ushort) || is(T == uint) || is(T == ulong)) pure nothrow @nogc @safeSwaps two values conditionally in constant time.
fnvoid ctSwapBigInt(uint doSwap, ref BigInt a, ref BigInt b) pure nothrow @safeSwaps two BigInt values conditionally in constant time.
fnBigInt ctSelectBigInt(uint condition, BigInt a, BigInt b) pure nothrow @safeSelects between two BigInt values in constant time.
fnvoid ctSwapBytes(uint doSwap, ubyte[] a, ubyte[] b) pure nothrow @nogc @safeSwaps two byte arrays conditionally in constant time.
fnvoid ctCopyBytes(uint doCopy, ubyte[] dst, const(ubyte)[] src) pure nothrow @nogc @safeCopies `src` to `dst` conditionally in constant time.
fnuint ctLessThan(T)(T a, T b) if (is(T == ubyte) || is(T == ushort) || is(T == uint) || is(T == ulong)) pure nothrow @nogc @safeCompares two unsigned integers in constant time, returning 1 if a < b.
fnuint ctEquals(T)(T a, T b) if (is(T == ubyte) || is(T == ushort) || is(T == uint) || is(T == ulong)) pure nothrow @nogc @safeCompares two unsigned integers in constant time, returning 1 if a == b.
fnuint ctGetBit(const(ubyte)[] data, size_t bitIndex) pure nothrow @nogc @safeExtracts a bit from a byte array in constant time.
fnuint ctGetBitBigInt(BigInt scalar, size_t bitIndex) pure nothrow @safeExtracts a bit from a BigInt scalar in constant time.