以下为本文档的中文说明
constant-time-analysis(常量时间分析)是一个专注于密码学软件实现安全性的静态和动态代码分析技能。时序攻击(Timing Attack)是密码学旁路攻击(Side-Channel Attack)家族中最经典和最具威胁性的攻击方式之一,攻击者通过精密测量和统计分析算法在不同输入下的执行时间差异来反向推断加密密钥、认证令牌或敏感明文等秘密信息。该技能专门检测和预防此类安全风险。使用场景包括:对密码学函数库、TLS/SSL 协议实现和数字签名算法的源码进行常量时间安全性的全面审计扫描;在安全代码审查(Security Code Review)环节自动检测新提交的密码学相关代码中潜在的执行时间信息泄露风险;对密码学教学示例代码或开源密码学库(如 OpenSSL、Libsodium、Bouncy Castle)进行对比安全评估。核心特点包括:深度分析源代码中可能导致执行时间可测量差异的高风险代码模式,重点关注以下几类高危构造:涉及秘密数据(密钥字节、令牌字符)的条件分支语句 if(secret[i] == input[i]) 会导致提前退出(Early Exit)泄露字节正确性信息、以秘密数据值作为索引的数组访问 secret_array[secret_byte] 可能触发 CPU 缓存侧信道泄漏(Cache Timing Leak)、循环迭代次数或递归深度依赖于秘密数据的操作、以及不同代码路径上的计算量差异;提供密码学安全的常量时间编程规范指导和技术方案库,包括使用 XOR 位运算和按位与(Bitwise AND)操作替代依赖秘密数据的分支条件、保证无论比较结果如何都遍历所有字节的固定时间内存比较函数(如 Java 的 MessageDigest.isEqual()、Python 的 hmac.compare_digest()、C 语言的 timingsafe_memcmp())、消除数组访问索引中的秘密依赖;支持对 C/C++、Java、Go、Rust、Python、TypeScript 等主流编程语言的密码学代码进行跨语言分析;最后根据检测到的风险类型和严重程度生成结构化的代码安全审计报告,每个发现都标注风险等级(Critical/High/Medium/Low)、精确到代码行号的位置信息、攻击可行性评估和经过验证的可直接应用的修复代码片段。
Constant-Time Analysis
Analyze cryptographic code to detect operations that leak secret data through execution timing variations.
When to Use
User writing crypto code? ──yes──> Use this skill
│
no
│
v
User asking about timing attacks? ──yes──> Use this skill
│
no
│
v
Code handles secret keys/tokens? ──yes──> Use this skill
│
no
│
v
Skip this skill
Concrete triggers:
- User implements signature, encryption, or key derivation
- Code contains / or % operators on secret-derived values
- User mentions “constant-time”, “timing attack”, “side-channel”, “KyberSlash”
- Reviewing functions named sign, verify, encrypt, decrypt, derive_key
When NOT to Use
- Non-cryptographic code (business logic, UI, etc.)
- Public data processing where timing leaks don’t matter
- Code that doesn’t handle secrets, keys, or authentication tokens
- High-level API usage where timing is handled by the library
Language Selection
Based on the file extension or language context, refer to the appropriate guide:
| C, C++ | .c, .h, .cpp, .cc, .hpp | references/compiled.md |
| Go | .go | references/compiled.md |
| Rust | .rs | references/compiled.md |
| Swift | .swift | references/swift.md |
| Java | .java | references/vm-compiled.md |
| Kotlin | .kt, .kts | references/kotlin.md |
| C# | .cs | references/vm-compiled.md |
| PHP | .php | references/php.md |
| JavaScript | .js, .mjs, .cjs | references/javascript.md |
| TypeScript | .ts, .tsx | references/javascript.md |
| Python | .py | references/python.md |
| Ruby | .rb | references/ruby.md |
Quick Start
# Analyze any supported file type
uv run {baseDir}/ct_analyzer/analyzer.py <source_file>
# Include conditional branch warnings
uv run {baseDir}/ct_analyzer/analyzer.py –warnings <source_file>
# Filter to specific functions
uv run {baseDir}/ct_analyzer/analyzer.py –func 'sign|verify' <source_file>
# JSON output for CI
uv run {baseDir}/ct_analyzer/analyzer.py –json <source_file>
Native Compiled Languages Only (C, C++, Go, Rust)
# Cross-architecture testing (RECOMMENDED)
uv run {baseDir}/ct_analyzer/analyzer.py –arch x86_64 crypto.c
uv run {baseDir}/ct_analyzer/analyzer.py –arch arm64 crypto.c
# Multiple optimization levels
uv run {baseDir}/ct_analyzer/analyzer.py –opt-level O0 crypto.c
uv run {baseDir}/ct_analyzer/analyzer.py –opt-level O3 crypto.c
VM-Compiled Languages (Java, Kotlin, C#)
# Analyze Java bytecode
uv run {baseDir}/ct_analyzer/analyzer.py CryptoUtils.java
# Analyze Kotlin bytecode (Android/JVM)
uv run {baseDir}/ct_analyzer/analyzer.py CryptoUtils.kt
# Analyze C# IL
uv run {baseDir}/ct_analyzer/analyzer.py CryptoUtils.cs
Note: Java, Kotlin, and C# compile to bytecode (JVM/CIL) that runs on a virtual machine with JIT compilation. The analyzer examines the bytecode directly, not the JIT-compiled native code. The –arch and –opt-level flags do not apply to these languages.
Swift (iOS/macOS)
# Analyze Swift for native architecture
uv run {baseDir}/ct_analyzer/analyzer.py crypto.swift
# Analyze for specific architecture (iOS devices)
uv run {baseDir}/ct_analyzer/analyzer.py –arch arm64 crypto.swift
# Analyze with different optimization levels
u
v run {baseDir}/ct_analyzer/analyzer.py –opt-level O0 crypto.swift
Note: Swift compiles to native code like C/C++/Go/Rust, so it uses assembly-level analysis and supports –arch and –opt-level flags.
Prerequisites
| C, C++, Go, Rust | Compiler in PATH (gcc/clang, go, rustc) |
| Swift | Xcode or Swift toolchain (swiftc in PATH) |
| Java | JDK with javac and javap in PATH |
| Kotlin | Kotlin compiler (kotlinc) + JDK (javap) in PATH |
| C# | .NET SDK + ilspycmd (dotnet tool install -g ilspycmd) |
| PHP | PHP with VLD extension or OPcache |
| JavaScript/TypeScript | Node.js in PATH |
| Python | Python 3.x in PATH |
| Ruby | Ruby with –dump=insns support |
macOS users: Homebrew installs Java and .NET as “keg-only”. You must add them to your PATH:
# For Java (add to ~/.zshrc)
export PATH="/opt/homebrew/opt/openjdk@21/bin:$PATH"
# For .NET tools (add to ~/.zshrc)
export PATH="$HOME/.dotnet/tools:$PATH"
See references/vm-compiled.md for detailed setup instructions and troubleshooting.
Quick Reference
| Division on secrets | DIV, IDIV, SDIV, UDIV | Barrett reduction or multiply-by-inverse |
| Branch on secrets | JE, JNE, BEQ, BNE | Constant-time selection (cmov, bit masking) |
| Secret comparison | Early-exit memcmp | Use crypto/subtle or constant-time compare |
| Weak RNG | rand(), mt_rand, Math.random | Use crypto-secure RNG |
| Table lookup by secret | Array subscript on secret index | Bit-sliced lookups |
Interpreting Results
PASSED – No variable-time operations detected.
FAILED – Dangerous instructions found. Example:
[ERROR] SDIV
Function: decompose_vulnerable
Reason: SDIV has early termination optimization; execution time depends on operand values
Verifying Results (Avoiding False Positives)
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, ask: Does this operation’s input depend on secret data?
Identify the secret inputs to the function (private keys, plaintext, signatures, tokens)
Trace data flow from the flagged instruction back to inputs
Common false positive patterns:
// FALSE POSITIVE: Division uses public constant, not secret
int num_blocks = data_len / 16; // data_len is length, not content
// TRUE POSITIVE: Division involves secret-derived value
int32_t q = secret_coef / GAMMA2; // secret_coef from private key
Document your analysis for each flagged item
Quick Triage Questions
| Is the operand a compile-time constant? | Likely false positive | Continue |
| Is the operand a public parameter (length, count)? | Likely false positive | Continue |
| Is the operand derived from key/plaintext/secret? | TRUE POSITIVE | Likely false positive |
| Can an attacker influence the operand value? | TRUE POSITIVE | Likely false |
| positive |
Limitations
Static Analysis Only: Analyzes assembly/bytecode, not runtime behavior. Cannot detect cache timing or microarchitectural side-channels.
No Data Flow Analysis: Flags all dangerous operations regardless of whether they process secrets. Manual review required.
Compiler/Runtime Variations: Different compilers, optimization levels, and runtime versions may produce different output.
Real-World Impact
- KyberSlash (2023): Division instructions in post-quantum ML-KEM implementations allowed key recovery
- Lucky Thirteen (2013): Timing differences in CBC padding validation enabled plaintext recovery
- RSA Timing Attacks: Early implementations leaked private key bits through division timing
References
- Cryptocoding Guidelines – Defensive coding for crypto
- KyberSlash – Division timing in post-quantum crypto
- BearSSL Constant-Time – Practical constant-time techniques





