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 1

Side-Channel Resistance Guidelines

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

  1. Always use 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 11

fnbool ctEqual(const(ubyte)[] a, const(ubyte)[] b) pure nothrow @nogc @safeCompares two byte arrays in constant time.
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.