Pitfalls in generating random numbers on quantum computers

One of the first things many beginning quantum practitioners do is try to exploit the random nature of quantum measurements to build a basic random number generator. Typically they do this via one or more Hadamard gates, and then quickly post an issue saying they do not observe the expected 50/50 outcome of 0’s and 1’s. Taking this a step further, many companies are looking to commercializing quantum random number generation (QRNG) as a service. These services usually are marketed with words like “true randomness” or “quantum certified”. Recently news spread of a new QRNG service from Cambridge Quantum Computing (CQC) called Quantum Origin. CQC is now part of Quantinuum, a joint venture with Honeywell Quantum Solutions. This service even has a collection of Partners attributed to it.

The materials available from CQC suggest that this is essentially the same service as that introduced by CQC and IBM over a year ago. This service has been a part of Qiskit since the announcement has the qiskit-rng module. Given that this is open source software, we can play around with the code to see why the underlying QRNG method can never be truly “certified” as being quantum in origin.


The theoretical underpinnings of the CQC QRNG service can be found in arXiv:2009.06551. The basic idea is that a quantum computer executes single-shot three qubit GHZ states followed by random X- and Y-basis measurements. If the state is tripartite entangled, as measured by the Mermin inequality:

\[ 𝑀_{\rm obs}=\langle 𝐴_{1}𝐵_{1}𝐶_{1}\rangle−\langle 𝐴_{1}𝐵_{2}𝐶_{1}\rangle−\langle 𝐴_{2}𝐵_{1}𝐶_{2}\rangle−\langle 𝐴_{2}𝐵_{2}𝐶_{1}\rangle \ge 2, \]

then the measured output is said to be “certified quantum random”. The maximum value is \(M_{\rm obs}=4\) which indicates maximum randomness, and and that the measurement outcomes are uniformly random. Values that fall below this need post-processing by an “extractor” step in order to be uniform. This necessarily reduces the number of bits at the end of the process. Below we will see if an IBM Quantum system can generate the necessary Mermin values, and if there are any surprises in store.


Let us load the needed modules, including pieces of the qiskit-rng module. The module itself does not work well with newer version of Qiskit so we just grab the needed internal components here.

import numpy as np
import qiskit
from qiskit import IBMQ, transpile
from qiskit_rng import Generator, GeneratorJob

Load account and select a target system

provider = IBMQ.get_provider(project='internal-test')
backend = provider.backend.ibm_nairobi


Here we run the CQC QRNG algorithm, basically reproducing the tutorial in the documentation. We start by setting the number of raw bits desired and compute the number of circuits and shots needed.

num_raw_bits = 1024
max_shots = backend.configuration().max_shots
num_raw_bits_qubit = int((num_raw_bits + 2)/3)

if num_raw_bits_qubit <= max_shots:
    shots = num_raw_bits_qubit
    num_circuits = 1
    num_circuits = int((num_raw_bits_qubit + max_shots - 1)/max_shots)
    shots = int((num_raw_bits_qubit + num_circuits - 1)/num_circuits)

We now make a Generator object and use a “weak source of random numbers” (wsr), which is nothing but a classical pseudo-random number generator, to seed the selection of random measurements.

gen = Generator(backend)

initial_wsr = gen.wsr_generator(num_circuits * 3)
wsr_bits = gen._get_wsr(num_circuits, initial_wsr)
circuits = gen._generate_all_circuits(num_circuits, wsr_bits)

Next we transpile the circuits, making sure to match the topology exactly, and then run.

trans_qc = transpile(circuits, backend, optimization_level=3, initial_layout=[1,0,2])
job = backend.run(trans_qc, shots=shots, memory=True)

We now wrap the Qiskit job with a GeneratorJob instance so as to extract the desired Mermin value.

gen_job = GeneratorJob(initial_wsr=initial_wsr,
result = gen_job.block_until_ready()

A quick check of the Mermin correlator shows that indeed we have tripartite entanglement, and therefore the algorithm has created “certified quantum random” numbers.


The value is not exactly the ideal value of 4, so an extraction step would need to be run after this (but this is not important). The good news is that we have generated random numbers certified by the laws of quantum mechanics itself! Or have we?

For fun, lets try using a classical simulator to generate the GHZ states. As a Mermin value \(M_{\rm obs} \ge 2\) is a signature of genuine quantum randomness our simulator, being completely classical, should score below this. Lets see (I have to use BasicAer as I am on an M1 Mac):

sim = qiskit.BasicAer.get_backend('qasm_simulator')
job2 = sim.run(trans_qc, shots=shots, memory=True)
gen_job2 = GeneratorJob(initial_wsr=initial_wsr,
result2 = gen_job2.block_until_ready()

Wow. The classical simulator has scored a perfect score! Is it “certified quantum random” then? Of course not. The fundamental limitation of the CQC QRNG service is that you have to trust that the thing running the circuits is an actual quantum system. There is no way to tell this from the results. Therefore it is entirely possible that the thing streaming the numbers to you is a classical simulator with values pre-computed by an adversary. Since you can spoof the QRNG service with a simulator it is kind of a pointless thing to use at this stage. Even if it was certified quantum, the speed at which these random bits can be generated is quite slow, even on superconducting processors. The Quantum Origin service runs on a Honeywell H1, a trapped ion platform. These are typically ~100x slower than superconducting systems, and represents a bottleneck in the service. One could cache the numbers when the processor is idle, but this would again, in principle, allow for someone to break the security.

Now the CQC QRNG service is not the only random number generation service that has these trust issues. Google also demoed a random number service at their 2020 Summer Symposium. This was also claimed to be “certifiable” under the assumption that the quantum computer could sample from random circuit distributions so fast that no classical computer could possibly have generated the output. This is very much a Quantum Supremacy type claim, and as we have all seen, such speed claims can quickly be rendered invalid by crafty classical algorithms. So Google hits the same fundamental roadblock as the CQC service; it is impossible to validate that the “quantumness” of the generated random values.