Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/trailofbits/skills/llms.txt

Use this file to discover all available pages before exploring further.

Analyze cryptographic implementations to detect operations that leak secret data through execution timing variations. Helps prevent timing attacks like KyberSlash by identifying variable-time operations in compiled assembly and bytecode.

Overview

The Constant-Time Analysis plugin detects timing side-channel vulnerabilities by analyzing compiler output and runtime bytecode for dangerous operations:
  • Division on secrets - Hardware division timing varies based on operand values
  • Secret-dependent branches - Different execution paths have different timing
  • Floating-point operations - Variable latency based on inputs
  • Non-constant comparisons - Early-exit string/memory comparison
This tool performs static analysis only - it flags potentially dangerous operations but requires manual verification to confirm whether they process secret data.

Supported Languages

Native Compiled Languages

Analyzes assembly output from compilers:
  • C/C++ - GCC, Clang
  • Go - Go compiler
  • Rust - Rustc
  • Swift - swiftc (iOS/macOS)

VM-Compiled Languages

Analyzes bytecode (JVM/CIL):
  • Java - JVM bytecode via javap
  • Kotlin - JVM bytecode via kotlinc
  • C# - CIL bytecode via ilspycmd

Interpreted/Scripting Languages

Analyzes VM bytecode or opcodes:
  • PHP - VLD extension or opcache
  • JavaScript/TypeScript - V8 bytecode
  • Python - CPython bytecode via dis
  • Ruby - YARV bytecode

Key Features

Multi-Architecture

Supports x86_64, ARM64, ARM, RISC-V, PowerPC, s390x, i386 for cross-platform analysis

Optimization Testing

Test across O0-O3, Os, Oz to catch optimization-induced vulnerabilities

CI Integration

GitHub Actions annotations and JSON output for automated security checks

Real-World Coverage

Detects vulnerability classes from KyberSlash, Lucky Thirteen, and RSA timing attacks

Installation

ct-analyzer --version
If not installed:
uv pip install -e .

Usage

Basic Analysis

ct-analyzer crypto.c

Advanced Options

--arch
string
default:"native"
Target architecture: x86_64, arm64, arm, riscv64, ppc64le, s390x, i386
--opt-level
string
default:"O2"
Optimization level: O0, O1, O2, O3, Os, Oz
--warnings
boolean
Include conditional branch warnings
--func
regex
Filter to specific functions by pattern
--json
boolean
Output JSON format for CI integration

Cross-Architecture Testing

# Test for ARM64 deployment
ct-analyzer --arch arm64 crypto.c

# Test multiple optimization levels
ct-analyzer --opt-level O0 crypto.c
ct-analyzer --opt-level O3 crypto.c

CI Integration

GitHub Actions
name: Constant-Time Check

on: [push, pull_request]

jobs:
  ct-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: Install ct-analyzer
        run: uv pip install -e .
      
      - name: Check constant-time properties
        run: ct-analyzer --github src/crypto/*.c

/ct-check Command

The plugin provides a slash command for quick analysis:
/ct-check <source-file> [--warnings] [--json] [--arch <arch>]
Example:
/ct-check src/sign.c --warnings --arch arm64
This invokes the constant-time-analysis skill with full workflow execution.

Detected Vulnerabilities

Error-Level (Must Fix)

Integer Division: DIV, IDIV, DIVQ, IDIVQFP Division: DIVSS, DIVSD, DIVPS, DIVPDSquare Root: SQRTSS, SQRTSD, SQRTPS, SQRTPD

Warning-Level (Review Needed)

Conditional branches that may leak timing if condition depends on secret data:
  • x86: JE, JNE, JZ, JNZ, JA, JB, JG, JL
  • ARM: BEQ, BNE, CBZ, CBNZ, TBZ, TBNZ
  • RISC-V: BEQ, BNE, BLT, BGE

Interpreting Results

Example Output

============================================================
Constant-Time Analysis Report
============================================================
Source: decompose.c
Architecture: arm64
Compiler: clang
Optimization: O2
Functions analyzed: 4
Instructions analyzed: 88

VIOLATIONS FOUND:
----------------------------------------
[ERROR] SDIV
  Function: decompose_vulnerable
  Reason: SDIV has early termination optimization; execution time depends on operand values

[ERROR] SDIV
  Function: use_hint_vulnerable
  Reason: SDIV has early termination optimization; execution time depends on operand values

----------------------------------------
Result: FAILED
Errors: 2, Warnings: 0

Verifying Results (Critical)

Not every flagged operation is a vulnerability. The tool has no data flow analysis - it flags ALL potentially dangerous operations regardless of whether they involve secrets.
For each flagged violation:
  1. Identify secret inputs - Private keys, plaintext, signatures, tokens
  2. Trace data flow - Does the flagged instruction process secret-derived values?
  3. Apply triage questions:
Likely false positive - Constants don’t leak timing information
// FALSE POSITIVE
int blocks = TOTAL_SIZE / 16;  // Division by constant
Likely false positive - Length/count parameters are usually safe
// FALSE POSITIVE
int num_blocks = data_len / BLOCK_SIZE;  // Length, not content
TRUE POSITIVE - Secret-dependent operations leak timing
// TRUE POSITIVE
int32_t q = secret_coef / GAMMA2;  // secret_coef from private key
TRUE POSITIVE - Attacker-controlled values enable timing attacks
// TRUE POSITIVE
int result = user_input / divisor;  // Timing varies with user_input

Fixing Vulnerabilities

Replace Division with Barrett Reduction

int32_t q = a / divisor;  // Variable-time division

Replace Branches with Constant-Time Selection

if (secret) {
    result = a;
} else {
    result = b;
}

Replace Comparisons

if (memcmp(a, b, len) == 0) {
    // Early-exit comparison leaks timing
}

Language-Specific Detection

PHP Analysis

Detected patterns:
  • Division: ZEND_DIV, ZEND_MOD → Use Barrett reduction
  • String comparison: strcmp(), === on secrets → Use hash_equals()
  • Weak RNG: rand(), mt_rand() → Use random_int()/random_bytes()
  • Cache timing: chr(), ord() → Use pack()/unpack()
Installation:
pecl install vld  # Recommended
# Or use built-in opcache

JavaScript/TypeScript Analysis

Detected patterns:
  • Division: Div, Mod bytecodes → Use constant-time multiply-shift
  • String comparison: === on secrets → Use crypto.timingSafeEqual()
  • Weak RNG: Math.random() → Use crypto.getRandomValues()
  • Variable latency: Math.sqrt(), Math.pow() → Avoid in crypto paths
Requirements:
node --version  # Node.js required
npm install -g typescript  # For .ts files

Python Analysis

Detected patterns:
  • Division: BINARY_OP 11 (/), BINARY_OP 6 (%) → Use Barrett reduction
  • String comparison: == on secrets → Use hmac.compare_digest()
  • Weak RNG: random.random() → Use secrets.token_bytes()
  • Variable latency: math.sqrt(), math.pow() → Avoid in crypto paths

Ruby Analysis

Detected patterns:
  • Division: opt_div, opt_mod → Use constant-time alternatives
  • String comparison: == on secrets → Use Rack::Utils.secure_compare()
  • Weak RNG: rand() → Use SecureRandom.random_bytes()
  • Variable latency: Math.sqrt() → Avoid in crypto paths

Limitations

Important limitations to understand:
  1. Static Analysis Only - Analyzes compiler output, not runtime behavior. Cannot detect:
    • Cache timing attacks from memory access patterns
    • Microarchitectural side-channels (Spectre, Meltdown)
    • Processor-specific optimizations
  2. No Data Flow Analysis - Flags ALL dangerous instructions regardless of whether they operate on secrets. Manual review required to eliminate false positives.
  3. Compiler Variations - Different compilers/versions may produce different assembly. Test with multiple optimization levels and target production architectures.

Real-World Impact

  • KyberSlash (2023) - Division instructions in ML-KEM allowed key recovery
  • Lucky Thirteen (2013) - CBC padding timing enabled plaintext recovery
  • RSA Timing Attacks - Division timing leaked private key bits

References

Author: Scott Arciszewski (Trail of Bits)Version: 0.1.0