View on GitHub
Open this notebook in GitHub to run it yourself
Fuzzing
Fuzzing is a dynamic code testing technique that provides random data, known as “fuzz,” to the inputs of a program. The goal is to find bugs, security loopholes, or other unexpected behavior in the software. By feeding the program various input combinations, a fuzzer aims to uncover weaknesses that might be exploited maliciously.Whitebox Fuzzing
Whitebox fuzzing, in particular, involves accessing the internal structure and code of the program. It combines static and dynamic analysis to not only execute the program with random inputs but also to achieve maximum code coverage, ensuring that all possible execution paths are tested. This allows for more targeted and efficient testing. It usually consists of a “symbolic execution” part: emulating the program to explore various branches and gathering them into a set of constraints. The constraints are solved by a constraint solver, generating new fuzzing input to the program.Toy Example
This example emphasizes the importance of whitebox testing. First, trigger all code flows for this function:foo in a black-box way, e.g., by sampling random inputs:

foo.
However, by following the flow of foo, you can generate these constraints to the function:
- “a”:
- “b”:
- “c”:
- “d”:
- “e”:
Here Comes the Quantum Part!
Grover’s Algorithm
The physical nature of a quantum computer can be harnessed to generate inputs to the function. Specifically, you can create a ‘superposition’ of all different inputs: a physical state that holds all the possible assignments to the function inputs, for which to compute whether the constraints are fulfilled. The quantum computer allows only a single classical output of the variable. This is where Grover’s algorithm [1,2] is useful: it can generate “good” samples with a high probability, achieving a quadratic(!) speedup over a classical brute force approach.Oracle Function
In the heart of the algorithm, implement an oracle that computes for each state: O |x\rangle = \begin\{cases\} -|x\rangle & \text\{if \} f(x) = 1 \\ |x\rangle & \text\{otherwise\} \end\{cases\} Classiq has a built-in arithmetic engine for computing such oracles. Specifically, take the hardest constraint:- “c”:
Output:

Full Grover’s Circuit
Now create the full circuit implementation of Grover’s algorithm.State Preparation
Load the uniform superposition state over all possible input assignments tofoo using the hadamard_transform:
Grover Operator
Grover Repetitions
The algorithm includes applying a quantum oracle in repetition, such that the probability to sample a good state “rotates” from low to high. Without knowing the concentration of solutions beforehand (which is the common case), one might overshoot with too many repetitions and not arrive at a solution. Fixed Point Amplitude Amplification (FFPA) (4), for example, is a modification to the basic Grover algorithm, which does not suffer from the overshoot issue. However, here, for simplicity, use the basic Grover’s algorithm. Assume that this specific state is only satisfied for a specific input, and calculate the number of oracle repetitions required:Output:
Synthesizing the Model
Synthesize the circuit using the Classiq synthesis engine. The synthesis takes the high level model definition and creates a quantum circuit implementation within a few seconds:Showing the Resulting Circuit
When the Classiq synthesis engine finishes the job, display the resulting circuit in the interactive GUI:Output:
Executing the Circuit
Lastly, execute the resulting circuit in the Classiq interface using theexecute function:
x and y values from the sampling results to determine if you have inputs for “c”:
Output:

Notes
- While “black-box” fuzzing can also potentially benefit from quantum computers, a large quantity of quantum resources is generally required to emulate the state of the classical program. On the other hand, the “white-box” case is lower hanging fruit, requiring fewer resources for a hybrid quantum-classical approach.
- This example shows quadratic improvement in comparison to a classical “brute force” solver. However, in reality, there are much faster classical solvers. As a basic example, a solver can “prune” branches of a search by backtracking if a partial assignment is not satisfiable.