Transactions on Cryptographic Hardware and Embedded Systems 2026
UP TO 50% OFF:
Efficient Implementation of Polynomial Masking
README
UP TO 50% OFF: Efficient Implementation of Polynomial Masking
This repository contains the implementation, evaluation, and fault simulation for the paper UP TO 50% OFF: Efficient Implementation of Polynomial Masking. For this work, we have implemented an AES Sbox protected with polynomial masking, using the LaOla multiplication. We provide a microcontroller C implementation for the STM32F415 board, a QEMU reference, Sage code for the generation of polynomial masking parameters, fault simulation scripts, and ChipWhisperer notebooks for side-channel evaluation. Using the code and usage instructions in this repository allows you to reproduce our paper's results. The ChipWhisperer evaluation requires physical hardware; the QEMU correctness tests and fault simulations are fully reproducible without it.
ChipWhisperer Scope and Target
For the experiments in this paper we used the following devices:
- ChipWhisperer-Husky
- CW308 UFO
- CW308T-STM32F with the STM32F415RGT6 target
While our codebase can be adapted to other targets and capture scopes with minimal changes, it was designed for and evaluated on these devices. If you adapt to different hardware, you might have to adapt the following:
- We use the STM32F415RGT6 hardware AES to generate randombytes. If you use a different target, the build process will default to the software implementation tinyAES128 as a randomness source. Currently, hal files for STM32F4, STM32F3, and STM32F0 are included in the project under
c_implementation/hal/. - Adjustments to the scope and target need to be included in setup portions of
ChipWhisperer/ChipWhisperer_Evaluation.ipynb.
Usage Instructions
Note: While this setup supports standalone Docker usage, it is primarily designed for VS Code together with the Dev Containers extension. Using those will provide the smoothest experience.
-
Requirements and Preparation: We recommend installing VS Code and the Dev Containers extension before proceeding. The general setup we provide is platform-agnostic, as Dev Containers provide a fully self-contained dependency management, ensuring the reproducibility of our correctness tests and fault simulations. To reproduce the physical evaluation, the ChipWhisperer USB device needs to forwarded into the Dev Container, which is platform and version specific. We provide three options for USB forwarding:
-
Linux Simply install Docker and open the project in VS Code (see Step 2).
-
Windows and macOS
USB access from Docker containers can be challenging because USB/IP support is limited on these platforms. USB forwarding is only required for physical evaluation with a connected ChipWhisperer device, if you are not running measurements on real hardware, you can use the container without USB forwarding. There is a workaround that uses a dedicated container to forward devices to other containers (see https://blog.golioth.io/usb-docker-windows-macos/).
Finally, a common strategy is using a Linux virtual machine (e.g., via Oracle VirtualBox) on a Windows or MacOS host and passing the ChipWhisperer USB device through to the VM. Inside the VM, install Docker and open the repository using VS Code with the Dev Containers extension.
-
-
Open the Project in VSCode:
Open the directory in VS Code and select the pop-up: Reopen in Container.
Or run Ctrl + Shift + P -> Dev Containers: Reopen in Container.
-
Sage Setup Scripts: Use the bash script
cd sage_scripts/ bash generate_vars.shto set up necessary components like polynomial support points, Vandermonde matrices and lookup tables.
-
Run and Evaluate ChipWhisperer Implementation: Select the (discounted-poly-masking) python kernel and run the
ChipWhisperer/ChipWhisperer_Evaluation.ipynbJupyter notebook from top to bottom and follow its instructions to obtain benchmarking and TVLA results. Results of the TVLA are saved toChipWhisperer/t-test/t-test-plots, where the TVLA plots of both the LaOla multiplication with 5M traces, and the full Sbox with 1M traces from our paper can be found. -
Test Implementation Correctness in QEMU: We provide a QEMU implementation in addition to our microcontroller implementation. The correctness of our implementation is tested by comparing masked computations against an unmasked reference function for parameters d={1,...,3}, e={0,...,3}, k=1 with Frobenius endomorphism enabled/disabled and our new zero-encodings, as well as, the zero-encodings from https://eprint.iacr.org/2023/1143.
cd qemu_implementation bash regression_suite.sh -j <NUM_JOBS>Running this will test our components and produce either "All tests passed" or "Some tests failed" upon which
qemu_implementation/make_run_log.txtcan be examined for further detail. -
Fault Simulation of LaOla Multiplication: We also evaluate the fault resistance of polynomial masking, as our QEMU implementation is also augmented with the ability to perform simulated fault injection on any field operation. Specifically, the result of any field operation can be set to a value provided by the adversary, thus enabling set-value fault attacks. The experiments in our paper perform set-zero, as well as, set-random value fault injection on the LaOla multiplication and evaluate if and how the outcome of a faulted and unfaulted run, using the same randomness, differ. We consider a fault effective when the encoded values of both runs differ and a fault detected iff one of the higher-order coefficients of the result are non-zero. We thus classify three types of faults:
- detected faults: one or more higher-order coefficients are non-zero allowing the fault to be detected
- effective undetected faults: fault was not detected and managed to change the encoded secret value
- ineffective undetected faults: fault was not detected but did not change the encoded secret value
Our fault simulation allows performing randomized set-zero/random fault injection by doing the following:
cd fault_simulation bash run_fault_simulation.sh <NUM_FAULT_EXPERIMENTS> <SET_ZERO_FAULTS>Here
NUM_FAULT_EXPERIMENTSspecifies the number of runs to perform per parameter set andSET_ZERO_FAULTSis a bool that selects set-zero faults when true and set-random faults when false. The simulations in our paper perform a sweep across d={1,2}, e={1,2,3}, s={1,...,5}, where s denotes the number of injected faults, with 100M runs per parameter set for both set-zero and set-random faults. Our results are saved underset_random_faults/fault_analysis_report_rand_values_100M.logandset_zero_faults/fault_analysis_report_zero_values_100M.log. The associated.csvtraces are saved underset_{random,zero}_faults/csvand log files are saved in thefault_simulationdirectory. To replicate these experiments run:bash run_fault_simulation.sh 100000000 true bash run_fault_simulation.sh 100000000 falseNote that these experiments and their tracing are computationally heavy and required 8 hours and 500 GB of space on our server-grade machine. We recommend either compressing or deleting the resulting
.csvfiles in the respectiveset_{random,zero}_faults/csvdirectories after runs.Furthermore, our paper includes a more extensive run of the d=1, e=3, s=5 parameter set that supports multithreaded trace acquisition.
bash run_fault_simulation_d1_e3_s5.sh <NUM_FAULT_EXPERIMENTS> <SET_ZERO_FAULTS> <NUM_THREADS>Note: the script spawns NUM_THREADS worker processes for trace generation plus a small amount of auxiliary I/O work. Results depend on NUM_THREADS because the RNG seed is derived from the worker process ID. Our results were produced by merging two runs with 5B traces that were using different, randomly-generated, seeds.
Repository Structure
Here, we outline the general structure of our codebase in case you want to modify or use some of its components:
-
.devcontainer/:Containerfile: Container to be used with the VSCode Dev Container extension or Docker/alternatives.devcontainer.json: Defines the environment and features to be used with VSCode Dev Container.
-
c_implementation/: Contains the C code and its dependencies for the microcontroller.crypto/poly_masked_sbox/: Contains our code for the poly masked Sbox and necessary helper functions/parameter files.simpleserial: ChipWhisperer simpleserial communication protocol.simpleserial-polymasked-sbox-implementation: Our entrypoint for host-to-board communication as a wrapper around the Sbox.
-
ChipWhisperer/: Contains our python notebooks for flashing the implementation, running test cases, collecting traces, and running TVLA:poly_masking_setup/: Python files containing parameter specific values used for polynomial masking setup.Setup_Scripts/: Jupyter notebooks to configure target and capture scope for ChipWhisperer devices.t-test/: Traces, results and plots for TVLA.ChipWhisperer_Evaluation.ipynb: Jupyter notebook containing code for correctness testing, benchmarking and TVLA evaluation.
-
fault_simulation/: Our scripts to perform set-zero and set-random simulated fault injection and analyze the results.set_random_faults: Results of fault injection setting field operation outputs to random values with 100 million runs per parameter set.set_zero_faults: Results of fault injection setting field operation outputs to zero with 100 million runs per parameter set.run_fault_simulation.sh: Bash script that builds the QEMU implementation with fault injection enabled and performs a parameter sweep for the specified set-zero/random fault type and number of runs.run_fault_simulation_d1_e3_s5.sh: Bash script that builds the QEMU implementation with fault injection enabled and multi-threaded fault injection for d=1, e=3, s=5 with specified set-zero/random fault type and number of runs.- **
output_to_csv.pyandanalyse_fault_indices.py: Python code to aggregate and interpret fault simulation traces.
-
qemu_implementation/:src/: Our C implementation closely matching the one inc_implementation/that exhaustively checks correctness usingregression_suite.shand performs simulated fault injection on field operations using experiments defined inlaola_fault_injection_experiments.c. Differences here are the usage of XORSHIFT32 as a PRNG and the additional fault injection capabilities included inpoly_masked_sbox.c.
-
sage_scripts/: Contains our setup scripts for generating:generate_python_variables.sage: Lookup tables and parameter variables for polynomial masking.optimized_log_table.sage: Log and antilog lookup tables for GF(2^8).generate_vars.sh: Generate necessary parameter variables and LUTs forChipWhisperer/ChipWhisperer_Evaluation.ipynb:poly_masking_lib.sage: Provide functions to generate support points stable under the Frobenius endomorphism and other variables used in Laola and BGW.polynomial_masking_reference_implementation_sage.ipynb: Notebook for deriving and validating optimized zero-encoding constructions used in polynomial masking.