Qlasskit - a bridge between Python and Quantum algorithms

Traditionally, creating quantum circuits requires specialized knowledge in quantum programming. This requirement holds true when encoding a classical algorithm inside a quantum circuit, for instance, for an oracle or a black-box component of a quantum algorithm. This often becomes a time wasting job, since we almost always already have a classical implementation in a traditional high level language.

Qlasskit, an open-source Python library developed with the support of a Unitary Fund microgrant, addresses this challenge head-on by allowing direct translation of standard Python code into invertible quantum circuits without any modification to the original code. Furthermore, qlasskit implements some well-known quantum algorithms and offers a comprehensive interface for implementing new ones.

To illustrate qlasskit’s capabilities, we will demonstrate its use in performing a pre-image attack on a cryptographic hash function using Grover’s search algorithm, obtaining a quadratic speedup compared to classical approaches. The beauty of qlasskit lies in its simplicity – you can write the entire software without needing to understand any concept of quantum computing.

A pre-image attack, in cryptography, targets a hash function h(m) with the aim to discover an original message m that corresponds to a specific hash value. On a traditional computer, to perform this attack without any hints, we must run h(m) with every possible input (N=2**n).

Thanks to the Grover search algorithm, we are able to find a pre-image with only pi/2 * sqrt(N) iterations, obtaining the quadratic speedup I mentioned before.

We write a toy hash function hash_simp which operates on messages composed of two 4 bit values and uses bitwise xor to create an 8 bit hash value.

from qlasskit import qlassf, Qint4, Qint8, Qlist

@qlassf
def hash_simp(m: Qlist[Qint4, 2]) -> Qint8:
    hv = 0
    for i in m:
        hv = ((hv << 4) ^ (hv >> 1) ^ i) & 0xff

    return hv

The first things you can notice in this code are:

  • the qlassf decorators, indicating that the function will be translated to a quantum circuit.
  • special bit-sized types Qlist, Qint4, and Qint8. These are required as qubits are a precious resource, and we want to use as few as possible.
  • and, it is normal Python code.

To see the resulting quantum circuit we can export and draw in qiskit:

hash_simp.export('qiskit').draw('mpl')

And this is the resulting circuit, produced by the qlasskit internal compiler:

Thanks to the fact that qlasskit function are standard Python functions, we can call the original_f to perform some kind of analysis and test on the hash function. Since the input space is tiny (it is a toy hash function), we can check if the hash function is uniform (if it maps equally to the output space).

from collections import Counter

d = Counter(hex(hash_simp.original_f((x, y))) for x in range(2**4) for y in range(2**4))

print('Hash function output space:', len(d))

We got that hash_simp is following an uniform distribution.

Now we use our quantum function as an oracle for a Grover search, in order to find which input maps to the value 0xca.

from qlasskit.algorithms import Grover

q_algo = Grover(hash_simp, Qint8(0xca))

Then we use our preferred framework and simulator for sampling the result; this is an example using qiskit with aer_simulator.

from qiskit import Aer, QuantumCircuit, transpile
from qiskit.visualization import plot_histogram

qc = q_algo.export('qiskit')
qc.measure_all()
simulator = Aer.get_backend("aer_simulator")
circ = transpile(qc, simulator)
result = simulator.run(circ).result()
counts = result.get_counts(circ)

counts_readable = q_algo.decode_counts(counts, discard_lower=5)
plot_histogram(counts_readable)

And this is the result of the simulation, where we can see that the pre-image that leads to h(x) = 0xca is the list [12,12].

Using QlassF.original_f we can double check the result without invoking a quantum simulator; calling it with the list [12,12] must result in the hash value 0xca.

print(hex(hash_simp.original_f((12,12))))

Although qlasskit can handle hundreds of qubits, in this post we use a toy hash function because currently, we lack a simulator or quantum computer capable of handling hundreds of qubits. Using these same tools, in the near future we may be able to perform a Grover search on real hash functions like md5 or sha2.

A special thanks to the Unitary Fund that funded this idea. If you have any questions or comments, feel free to reach out to me on twitter dagide, linkedin Davide Gessa and medium @dakk.

Original post on Unitary.fund: https://unitary.fund/posts/2023_qlasskit/

Useful Links:

2024

DQPU, the decentralized quantum simulator

2 minute read

During my Quantum Computing journey, I often needed to simulate some quantum circuits; sometimes they are small, but some other times they are bigger enough ...

The Time I Built a Probabilistic Computer

6 minute read

In early 2023, I embarked on a journey to explore the field of probabilistic computing. This endeavor culminated in the construction of a hardware prototype,...

Back to Top ↑

2023

Expanding the Commodore 64 Quantum Emulator

1 minute read

In a recent article I wrote, “Quantum Computing on a Commodore 64 in 200 Lines of BASIC”, published both on Medium and Hackaday.com, shows a two-qubit quantu...

Back to Top ↑

2020

OCaml and Quantum Computing

1 minute read

Qiskit is a python SDK developed by IBM and allows everyone to create quantum circuits, simulate them locally and also run the quantum circuit on a real quan...

Yallo, a new Tezos language

2 minute read

As someone noticed from the previous post, last weeks I started to write a new programming language for Tezos smart contracts. This project was initially int...

King of Tezos: a smart-ponzi on Tezos

2 minute read

While writing a new programming language, it is often useful to write some real use-cases to test the syntax, the language expressiveness and the code cleann...

Favorite dev quote

less than 1 minute read

Documentation is like sex: when it is good, it is very, very good; and when it is bad, it is better than nothing

New blog

less than 1 minute read

This is my new blog, based on jekyll. I’ll soon import old posts from my old blog.

Back to Top ↑

2016

Contractvm: decentralized applications on Bitcoin

less than 1 minute read

Contractvm is a general-purpose decentralized framework based on blockchain. The framework allows to implement arbitrary decentralized applications in an eas...

Back to Top ↑

2015

Dices provably fair - Nonce overflow vulnerability

less than 1 minute read

Most of bitcoin dice software use a system to prove the fair play of the server for each bet. Most of them implement this mechanism using two seed (server se...

Back to Top ↑

2014

Apache2: redirect different domains to subfolder

less than 1 minute read

In the aim to merge two of my server on digitalocean, today I tried to write a mod_rewrite rule to redirect a secondary domain to a subfolder. After one hour...

Back to Top ↑

2013

MineML: F# miner

less than 1 minute read

MineML is a multithread CPU based bitcoin miner written in F#. At the moment it’s a slow implementation, but the class structure offers the possibility to im...

Back to Top ↑