Skip to main content
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

If not installed:

Usage

Basic Analysis

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

CI Integration

GitHub Actions

/ct-check Command

The plugin provides a slash command for quick analysis:
Example:
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

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
Likely false positive - Length/count parameters are usually safe
TRUE POSITIVE - Secret-dependent operations leak timing
TRUE POSITIVE - Attacker-controlled values enable timing attacks

Fixing Vulnerabilities

Replace Division with Barrett Reduction

Replace Branches with Constant-Time Selection

Replace Comparisons

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:

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:

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