Papers
Topics
Authors
Recent
Search
2000 character limit reached

DALC-CT: Dynamic Analysis of Low-Level Code Traces for Constant-Time Verification

Published 18 Apr 2026 in cs.CR and cs.PL | (2604.16832v1)

Abstract: Timing side-channel attacks exploit variations in program execution time to recover sensitive information. Cryptographic implementations are especially vulnerable to these attacks, since even small timing differences in operations such as modular exponentiation or key comparisons can be exploited to extract highly sensitive information, such as secret keys. To mitigate this threat, implementations of programs that handle sensitive information are often expected to adhere to constant-time principles, ensuring that execution behavior does not depend on secret inputs. However, validating the constant-time property of programs remains a major challenge in cryptography development. Formal method approaches to verify constant-time implementations rely on abstractions that often fail to capture real execution behavior, while timing-based measurement techniques are highly sensitive to noise from other programs and even hardware environments. In this work, we propose a novel approach for verifying constant-time programs based on dynamic analysis of low-level execution traces. Our method measures instruction sequences across multiple input values for any given binary and targeted function. Any variations in the instruction mix distribution for any given pair of traces indicate a deviation from the constant-time principle and behavior. We developed an open-source tool called DALC-CT, for the constant-time verification of programs using this approach. We evaluated it on a set of well-known constant-time and non-constant-time examples, achieving a perfect detection of issues. Our results demonstrate that analyzing the logical execution of programs via instruction trace comparisons provides a lightweight and reliable way to verify the constant-time property of programs.

Summary

  • The paper introduces DALC-CT, a dynamic analysis framework that verifies constant-time execution by ensuring invariant low-level instruction traces across secret inputs.
  • It employs Valgrind-based instrumentation and a 13-category instruction classification system to detect variations caused by secret-dependent operations.
  • Evaluation on cryptographic benchmarks demonstrates that DALC-CT effectively distinguishes constant-time and vulnerable implementations across different compilers and optimization levels.

Dynamic Analysis of Low-Level Code Traces for Constant-Time Verification

Motivation and Problem Statement

Timing side-channel attacks exploit minute variations in program execution characteristics, especially execution time, to exfiltrate sensitive data from high-assurance code such as cryptographic implementations. The traditional defense—constant-time programming—requires that code execution be completely insensitive to secret input values, guaranteeing that different secrets cannot result in diverging program paths, differential instruction mix, or secret-dependent data-dependent memory and control flow. Despite the importance of this property, practical and accurate verification remains unsolved. Existing methods either oversimplify (by analyzing source-level abstractions or intermediate representations) or are unreliable due to environmental noise (timing-based measurement). This paper introduces DALC-CT, a new framework that addresses these weaknesses by performing direct dynamic analysis over low-level binary instruction traces.

Approach

DALC-CT verifies constant-time execution by instrumenting binaries using Valgrind's Dynamic Binary Instrumentation (DBI) engine. Given a compiled program binary, a target function, and a set of secret input values, DALC-CT executes the function across the input space, records the instruction-level traces, and classifies each executed instruction into one of thirteen architecture-relevant categories (covering memory access, ALU, and control-flow, with subdivision by operation type and data width).

For each execution, DALC-CT logs a vector of per-class instruction counts—its “instruction mix.” Execution traces are collected for all secret input values, generating a multi-dimensional map of program execution. DALC-CT defines constant-time as trace invariance: for all secret input pairs, the trace vectors must be equivalent. Any difference signals a violation of constant-time logic and a potential side-channel vulnerability. Figure 1

Figure 1: DALC-CT system architecture: input program, secrets, and target function are processed through DBI and instruction analysis to produce a formal verification report.

Implementation Details

DALC-CT is implemented as an open-source tool leveraging Valgrind for heavyweight dynamic instrumentation. For each function invocation, instructions are grouped and counted post-execution. Critical design decisions include the instruction classification system—partitioned by class and data type to account for operations with both uniform and varied latencies—and a lightweight fuzzer for secret input generation.

The classification system comprises 13 distinct classes split over memory loads/stores, ALU (light and heavy), and control-flow (conditional/unconditional), for integer, floating-point, and vector datatypes. Light ALU refers to single-cycle operations (e.g., addition, subtraction), while heavy ALU denotes multi-cycle operations (e.g., multiplication, division). This abstraction provides high diagnostic power while keeping analysis tractable, as exact instruction enumeration is infeasible on modern ISAs.

DalC-CT's system design ensures platform, compiler, and optimization independence; it operates strictly on the post-compile binary, downstream from all high-level abstractions and transformations, and thus directly reflects the program's real execution characteristics.

Evaluation and Empirical Validation

Evaluation demonstrates two case studies: password checking and modular exponentiation, both central operations in cryptographic libraries, leveraging datasets adopted from ct-tools and contemporary side-channel literature. DALC-CT consistently distinguishes constant-time and non-constant-time variants:

  • Password Checking: Traditional character-wise equality check (with early exit on mismatch) produces instruction trace variations precisely correlated with the length of correct prefix matches, immediately exposing secret leakage. The constant-time version (XOR-based, full-scan) yields invariant trace vectors.
  • Modular Exponentiation: The naive implementation, branching on secret exponent bits, produces trace vectors dependent on the Hamming weight of the exponent. When rewritten to mask and flatten all secret-dependent branches, trace invariance is restored.

Results are robust across compilation toolchains (GCC and Clang) and across optimization settings (O0–O2), confirming that DALC-CT is resilient to compiler-induced differences.

Comparison With Prior Art

Conventional methods fall into three categories: runtime statistical timing analysis (e.g., Dudect [reparaz2017dude]), dynamic (symbolic/concrete) instrumentation on intermediate representations (e.g., CTgrind [langley2010ctgrind], Binsec/Rel [daniel2020binsec]), and formal verification at the source or IR level (e.g., ct-verif [almeida2016verifying]). Each is limited in observability (due to abstraction, optimism, or noise) or in practicality (due to scalability).

DALC-CT’s approach of instruction trace logging overcomes these barriers: it assesses behaviors that directly result from optimizations, link-time arrangements, and platform idiosyncrasies, thereby reflecting the binary's execution as experienced on real hardware.

Limitations and Extensions

While DALC-CT is effective for logical constant-time property detection, it does not account for microarchitectural timing side channels—such as cache behavior, prefetch effects, or speculative execution artifacts—because it focuses on logical (retired) instruction streams rather than performance events. Incorporation of statistical methods or microarchitectural event modeling could address this limitation, but accurate modeling remains an unsolved systems research problem. Furthermore, while DALC-CT efficiently exposes violations on practical secret input sets, full coverage requires expansive input generation strategies (e.g., coverage-guided fuzzing or concolic execution).

The modular system design admits extensibility: the granularity of instruction classes can be increased for higher-resolution diagnostics, and support for new ISAs or environments can be integrated. These properties make DALC-CT a suitable foundation for high-assurance software development pipelines targeting platforms with evolving security requirements.

Theoretical and Practical Implications

Theoretically, DALC-CT unifies low-level program verification with constant-time security analysis via trace vector equivalence—a formalism that is both sound (in detecting secret-dependent control and data divergence) and implementation-aware. This bridges the longstanding divide between source-level theoretical assurance and executable-level empirical assurance.

Practically, DALC-CT equips developers, auditors, and cryptographic library maintainers with a concrete, automatable workflow for binary-level verification, reducing reliance on noisy, non-repeatable, or non-generalizable tests. Its independence from toolchain and platform specifics facilitates reproducible and reliable security auditing essential in high-assurance environments.

Future Directions

Immediate research avenues include tighter integration with advanced fuzzing engines (for improved path coverage), hybridization with symbolic execution for completeness guarantees, and co-analysis with microarchitectural event tracing to detect “second-order” side-channel vulnerabilities. As environments enforce stricter isolation and timing attack mitigations, frameworks like DALC-CT will be core to the development lifecycle.

Conclusion

DALC-CT provides a principled, robust, and scalable method for verifying the constant-time property at the binary execution level via analysis of low-level instruction traces. It eliminates critical blind spots inherent in abstraction- or timing-based approaches, fosters trust in cryptographic and side-channel-sensitive software, and paves the way for future tools with expanded semantic reach.

Paper to Video (Beta)

No one has generated a video about this paper yet.

Whiteboard

No one has generated a whiteboard explanation for this paper yet.

Open Problems

We haven't generated a list of open problems mentioned in this paper yet.

Collections

Sign up for free to add this paper to one or more collections.