Skip to main content
Your Compiler Might Be Unmasking SecretsData Protection Methods
5 min readFor Payment Security Engineers

Your Compiler Might Be Unmasking Secrets

You've implemented masking to protect cryptographic operations from side-channel attacks. You've verified the algorithm and tested the source code. Then, the compiler rewrites your carefully protected implementation, and suddenly, shares that should never touch are sitting in adjacent registers or sharing stack slots.

This gap between source-level security and compiled binary behavior creates a persistent blind spot in payment system cryptography. Most teams either simulate power traces after compilation (expensive and model-dependent) or verify source code before compilation (missing what register allocation actually does). Neither approach catches leakage introduced during the compilation process itself.

The myths below reflect common assumptions about where masking protection breaks down and when you can trust your countermeasures.

Myth 1: If Your Masking Implementation Passes Source-Level Verification, It's Secure

Reality: Formal verification of source code doesn't account for what happens during register allocation and stack allocation.

Your source might correctly separate shares across variables, but the compiler treats those variables as allocation targets. When register pressure forces spills to stack, the compiler may place shares from the same secret in adjacent memory locations. When optimizing register usage, it may reuse a register that held one share for another share moments later, creating temporal adjacency that leaks through microarchitectural state.

The Jasmin leakage detection pass operates on the intermediate representation before register and stack allocation specifically to catch these issues. It tracks contact between shares, secrets, random values, and public values at the point where the compiler still has allocation decisions ahead of it. This positioning matters because once allocation happens, you're analyzing the damage rather than preventing it.

If you're verifying masked implementations, verify at the IR level or after allocation, not just at source. The transformations in between introduce the leakage.

Myth 2: Power Trace Simulation Catches All Compiler-Introduced Leakage

Reality: Leakage simulation is tied to a specific power model and becomes computationally prohibitive for large codebases.

Simulating power consumption after compilation requires you to choose a leakage model (Hamming weight, Hamming distance, toggle count). Each model captures certain physical behaviors but misses others. You're also running simulation on every build, which doesn't scale when you're compiling cryptographic libraries with hundreds of masked operations.

More importantly, simulation tells you that leakage exists but obscures why. You see elevated correlation in a power trace but must reverse-engineer which compiler decision created the problem. Was it register reuse? Stack slot adjacency? Instruction scheduling that placed dependent operations too close together?

The microarchitecture-oriented leakage model in the Jasmin pass makes root causes explicit. It doesn't simulate power; it tracks data flow relationships that create leakage conditions. When it flags a problem, it identifies which shares contacted each other and where in the allocation process that contact occurred. This specificity enables fixes rather than just detection.

Use simulation to validate final binaries against specific threat models. Use compiler-integrated detection to prevent leakage from being introduced in the first place.

Myth 3: Masking Order Reduction Only Happens in Algorithm Design

Reality: The compiler can reduce masking order through seemingly innocuous optimizations.

You design a second-order masking scheme requiring three shares. The algorithm never combines more than two shares in any operation. Then the compiler's instruction scheduler reorders operations to improve pipeline utilization, and suddenly three shares are live in registers simultaneously with a data dependency between them. The effective masking order just dropped.

Or the compiler eliminates a redundant move instruction that was actually serving as a separation barrier between shares. Or it folds a constant into an instruction that previously operated only on masked values, creating a contact point between a share and public data.

The Jasmin pass detects masking-order reductions by tracking not just pairwise contacts but the cumulative effect of multiple contacts across the program's execution. It models how shares, secrets, random values, and public values interact through the microarchitecture's state (registers, memory, flags).

If you're implementing higher-order masking, audit your compiled output for order reduction. The compiler doesn't understand your security invariants.

Myth 4: Side-Channel Leakage Is a Hardware Problem, Not a Compilation Problem

Reality: Hardware creates the channel, but compilation decisions determine what information flows through it.

Yes, CMOS transistors consume power proportional to bit transitions. Yes, cache timing depends on physical memory architecture. But which bit transitions occur and which memory addresses get accessed depends entirely on how the compiler allocated your variables and scheduled your instructions.

Consider two shares of a masked AES S-box lookup. In source code, they're separate variables. After compilation, they might be in adjacent stack slots, meaning the memory bus carries both values in rapid succession. Or they might share a cache line, meaning loading one prefetches the other. These spatial relationships are compiler artifacts, not hardware limitations.

The Jasmin approach integrates leakage detection into the compilation pipeline because that's where the decisions get made. Operating before register and stack allocation means the pass can influence those decisions or at least flag when they create leakage conditions.

Treat compilation as a security-critical phase, not just a translation step. The compiler has enough information to avoid dangerous allocations if you give it the right constraints.

Myth 5: You Can Fix Leakage by Adding More Randomness

Reality: Additional randomness doesn't help if the compiler is creating contact points between shares.

Adding random masks increases the algorithmic security of your masking scheme. It doesn't prevent the compiler from allocating masked values in ways that leak. If register pressure forces shares into adjacent stack slots, adding a third random mask just means you now have three values leaking instead of two.

The Jasmin pass validated on 60 test snippets covering different leakage sources and category combinations demonstrates that leakage comes from specific patterns: share-to-share contact, secret-to-public contact, insufficient randomness separation. More randomness addresses the third pattern but not the first two.

Fix leakage by controlling allocation, not by adding masks. If your compiler is creating dangerous adjacencies, you need allocation constraints or a different compilation strategy.

What to Do Instead

Integrate leakage detection into your build pipeline, not just your testing phase. If you're using a verified compiler like Jasmin, use passes that operate on intermediate representations where you can still influence allocation decisions.

For other toolchains, audit compiled binaries for share adjacency in both registers and stack frames. Write allocation constraints that enforce separation between shares from the same secret. Test with multiple compiler optimization levels because aggressive optimization often trades security properties for performance.

Document your masking scheme's security assumptions and verify they survive compilation. If your design requires that shares never occupy adjacent registers, state that explicitly and check it in your build verification.

The gap between algorithmic security and compiled binary security won't close by accident. Close it by treating compilation as a security-critical transformation that requires the same rigor you apply to cryptographic algorithm design.

You Might Also Like