Quantum Computing in Java

If you are new to quantum computing, then the title of this post will not sound suspicious or provocative to you. However, if you are a seasoned quantum user then you will know that something must be off here. After all, your language of choice is most likely Python, or maybe C if you are working on high-performing solutions. 

The majority of frameworks and libraries in the field of quantum computing are written in Python, and made for this language. I am thinking of Qiskit, Ocean, and cirq, among others. There is a big ongoing effort by IBM to develop a parallel Qiskit framework for the C language, and one can even try Q# from Microsoft. What they have in common is comprehensive functionality, big company backing, and integration with real quantum hardware (to different extents, though).

But what about Java? Is it even possible to do any useful quantum development in this language? For a big part of my career I have been a Java/Kotlin developer, so this question is somewhat personal to me. And the answer is… it is complicated. There are two libraries that I have managed to find, and two JEPs that are focused on quantum computing. How useful are they? Let us find out.

JQuantum

The first library we are going to take a look at is called JQuantum. If you click on the link the first thing you will notice is that it has not been updated since 30th July 2018. Being so outdated does not make it a candidate for any production project. Can it be of any use anyway?

JQuantum contains implementation of basic quantum computing concepts. You can find there classes for qubits, gates, circuits, and even the most famous algorithms like Grover’s algorithm or Shor’s algorithm.

Sadly, the library does not have any form of a simulator, not to mention the possibility to run the code against a real QPU. You can run your programs and output their results, but what JQuantum does behind the scenes is just linear algebra on vectors and matrices. Since the amount of memory necessary to contain multidimensional matrices scales exponentially, the amount of qubits you can use in JQuantum is severely limited. After all, even the simplest gates are two-dimensional matrices, and adding each qubit effectively doubles the number of dimensions in the matrix that represents such a system.

Okay, so the library is outdated, and its functionality is quite limited. Can we put it to any use then? In fact, we can. Let us take a look at a sample code.

class JQuantumExample implements Example {
    @Override
    public void show() {
        var qubitValue = 0;
        var quantumRegister = new QubitRegister(1, qubitValue);
       
        var notGate = QuantumGate.X;
        notGate.accept(quantumRegister);
        var measurement = quantumRegister.measure();
       
        System.out.println("JQuantum Example");
        System.out.println("----------------");
        System.out.println("Applied X gate to |" + qubitValue + "⟩; result is |" + measurement +"⟩.");
        System.out.println();
    }
}

In the code snippet above, we first create a qubit in the |0⟩ (read 0-ket) state. If you do not know what kets are, please read my post about them. Then, we create a quantum register (processor’s memory) with one qubit. We instantiate a NOT gate, often called an X gate. Then, we apply the X gate to the register, effectively flipping the value of the qubit from |0⟩ to |1⟩. Finally, we measure.

The measurement in quantum computing is an act of “translating” the result of the computation from quantum encoding to classical (i.e. binary) encoding. Thus, whatever is yielded by the program, ends up as either |0⟩ or |1⟩. Any other quantum state (and there is an infinite number of them) cannot be processed then by classical computers.

This code may not earn you any money, but it can still demonstrate basic principles of quantum programs. And this is what the JQuantum library is great for: education. If you have never written a line of code in any language other than Java, you can still learn a solid piece of quantum computing with this library.

If you would like to run this program you must add the Quantum.jar file to your classpath. You can find it in the root tree in the JQuantum’s repository.

Strange

If you are a Marvel fan, then you may be disappointed that I will not be writing about your favourite doctor here. Instead, Strange is the name of a quantum library written for the book Quantum Computing in Action by Johan Vos.

Strange is an open-source learning resource that can be used alongside the aforementioned book, or by itself. It is available via Maven Central, so no manual installation is needed like it was the case with JQuantum.

It has somewhat similar functionality to that library. You will find abstractions for qubits, gates, circuits (under the name of programs), and quantum algorithms. The collection is a bit smaller than in JQuantum, though.

On the upside, Strange does contain a quantum simulator. It is a simple one, without any sophisticated features of modern-day simulators (like noise or hardware-specific characteristics), but it can still be pretty useful. There are traces in the code that cloud integration was in progress, but it has never been finished. Thus, you cannot run code written with Strange on any actual quantum hardware.

Let us take a look at a code example.

public class StrangeExample implements Example {
   @Override
   public void show() {
       var qubitValue = 0;
       var program = new Program(1);
       var x = new X(qubitValue);

       var negationStep = new Step();
       negationStep.addGate(x);
       program.addStep(negationStep);

       var executionEnvironment = new SimpleQuantumExecutionEnvironment();
       var result = executionEnvironment.runProgram(program);
       var measurement = result.getQubits()[0].measure();
       
       System.out.println("Strange Example");
       System.out.println("---------------");
       System.out.println("Applied X gate to |" + qubitValue + "⟩; result is |" + measurement +"⟩.");
       System.out.println();
   }
}

This program does exactly the same thing as the previous one, and the first three steps are almost identical. The difference starts from the definition of a step. Steps are phases of a circuit, which is called a program in Strange. So in order to code the negation, we must first define a step for it (negationStep) and then add it to the program with the addStep method. Next, we have to instantiate the simulator in the form of executionEnvironment. Finally, we can run it, and obtain a measurement from the result.

Though JQuantum and Strange are very alike, the functionality of Strange is somewhat more robust. Both, however, are great learning resources for quantum computing newbies. Unfortunately, doing any real-life project with Strange is as unfeasible, as with JQuantum.

Post-quantum Cryptography

Believe it or not, but quantum computers are going to break all the cryptography that we use on an everyday basis. SHA, RSA, Diffie-Helman, and related protocols are useless against the codebreaking capabilities of future quantum computers. Luckily, they are not here yet. Even more luckily, I will spare you all the difficult math related to this issue.

Although quantum computers with enough qubits to run Shor’s algorithm for the inputs of size of nowadays use cryptographic keys are still at least a couple of years away, cryptographers have already started working on cryptographic protocols that are quantum-safe. By this they mean that they cannot be cracked by any kind of quantum computer or algorithm (at least for now). Why do they do this? There is an old attack pattern that relies on evasedropping the data now for later decryption. If an attacker follows it it can for example steal the packets in which you authenticate with your bank in hope of decrypting them whenever possible and obtaining your credentials. It may seem futile at first, but if a feasible quantum computer arrives in two years, then a lot of this data may still be valid. After all, how often do you rotate your bank password?

I mentioned that the cryptographers have already begun working on a solution. It arrived in the form of NIST standards in August 2024. Shortly after that, two JEPs were published: 496 and 497. The first one provides implementation for cryptographical keys creation and encapsulation. The second one is very similar, but can be used for signing, not encrypting keys. They can be used in the following way.

class PostQuantumCryptographyExample implements Example {
   @Override
   public void show() {
       try {
           var mlKem = "ML-KEM";
           var encryptionKeyGenerator = KeyPairGenerator.getInstance(mlKem);
           encryptionKeyGenerator.initialize(NamedParameterSpec.ML_KEM_512);
           var encryptionKeys = encryptionKeyGenerator.generateKeyPair();

           System.out.println("Post-Quantum Cryptography Example");
           System.out.println("---------------------------------");

           var publicEncryptionKey = encryptionKeys.getPublic().getEncoded();
           String publicKeyBase64 = Base64.getEncoder().encodeToString(publicEncryptionKey);
           System.out.println("Public key generated with " + mlKem + ": " + publicKeyBase64);

           var mlDsa = "ML-DSA";
           var signingKeyGenerator = KeyPairGenerator.getInstance(mlDsa);
           var signingKeys = signingKeyGenerator.generateKeyPair();
           var privateSigningKey = signingKeys.getPrivate();

           var helloWorld = "Hello World";
           byte[] message = helloWorld.getBytes();
           Signature signature = Signature.getInstance(mlDsa);
           signature.initSign(privateSigningKey);
           signature.update(message);
           byte[] signedMessage = signature.sign();

           System.out.println("Message \"" + helloWorld + "\" signed with " + mlDsa + ": " + Base64.getEncoder().encodeToString(signedMessage));
       } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | InvalidKeyException |
                SignatureException e) {
           throw new RuntimeException(e);
       }
   }
}

If you have ever used other cryptographic keys in Java, then I am quite sure this code feels familiar to you. I will not describe it in detail here, since there is nothing related to quantum computing in it. We cannot use these implementations for working with qubits, gates or circuits. In fact, they do not even require a quantum computer to run. Instead, they rely on lattice structures that are immune to Shor’s algorithm since they do not use big primes multiplication.

Conclusion

While Java may not be the first choice for quantum computing due to the lack of robust, up-to-date libraries and frameworks, there are still learning resources available for those interested. The JQuantum and Strange libraries, although outdated or limited in functionality, can serve as valuable educational tools for beginners.

Moreover, with the impending threat of post-quantum cryptography being broken by future quantum computers, Java has already started addressing this challenge through JEPs 496 and 497. These provide implementations for creating and encapsulating cryptographic keys, ensuring our data remains secure even in a post-quantum world. Although they cannot be used for general quantum computing, they should at least provide a cornerstone for reliability of Java application in the quantum era.

While Java may not be the language of choice for quantum computing today, it is still possible to learn basic principles and prepare for a future where quantum-safe cryptography becomes the norm.

You can find all the code examples on my GitHub.

Post Scriptum

If you are interested in the prospects of quantum computing in Java and its future, I warmly invite you to join me on JavaZone2025 in Lillestrøm, Norway where I’ll give a lightning talk titled Quantum Leap with Java: An Unrealistic Dream? You can keep an eye on the program here. I am hoping to see you there!

Quantum vs Classical Computing: How Different Are They?

Computation is a core aspect of modern technology, driving innovations across science, engineering, entertainment, and communication. But what exactly is a computation, and how does it differ in classical and quantum contexts?

What is Computation?

At its most fundamental level, computation refers to using technology to perform tasks, solve problems, and manipulate information. Whether it’s simulating physical systems, developing intelligent algorithms, or managing vast data sets, computation is the bedrock of all digital advancements. Classical computing, which powers most of today’s digital systems, has long been the standard. However, quantum computing, a revolutionary paradigm, promises to redefine what’s possible in the field.

Classical vs. Quantum Computation

Classical Computing

Classical computing is rooted in binary logic. The smallest unit of information is a bit, which can exist in one of two possible states: 0 or 1. Every computation a classical computer performs is deterministic, meaning the result is always predictable based on the input. Operations are executed using logic gates, and bits can be copied, stored, and manipulated across various systems and memory registers without loss of information.

To illustrate, consider a light switch. A light switch can only be ON or OFF just like a bit can only be 1 or 0. Classical computers, no matter how complex, are simply massive collections of these switches, manipulating them to perform calculations. While highly effective for many applications, classical computers are limited by their binary nature.

Quantum Computing

Quantum computing, on the other hand, is a game changer because it relies on principles from quantum mechanics, which describe the behaviour of particles at extremely small scales. Instead of bits, quantum computers use qubits as the fundamental unit of information. Unlike classical bits, qubits can exist in an infinite number of states.

The state of a qubit can be visualised using a Bloch sphere. Imagine a globe, with 0 at the South Pole and 1 at the North Pole. While a classical bit is like a light switch, only toggling between ON (1) or OFF (0), a qubit can be any point on the surface of this globe. It can blend 0 and 1 in a continuum of possibilities, opening up a much larger space for computation.

Moreover, quantum operations exploit unique quantum phenomena, such as entanglement and superdense coding, which enable powerful new methods of processing information that classical systems cannot easily replicate.

What Makes Quantum Computation Different?

Quantum computing fundamentally differs from classical computing in several key ways:

  1. Superposition and Infinite States: A single qubit can encode an infinite number of possible states, as opposed to the strict binary options of classical bits. This means quantum computers can process much more information simultaneously.
  2. Measurement and Probability: While qubits can exist in an infinite number of states, any attempt to measure them translates their quantum state into a classical state (either 0 or 1). This process is probabilistic. The quantum state does not yield a fixed answer but rather gives a probability distribution over possible outcomes, which makes quantum computing inherently different from the deterministic operations of classical systems.
  3. No Cloning: A vital distinction between classical and quantum systems is that qubits cannot be copied. In classical computing, data can be duplicated as needed, but in quantum systems, copying qubits requires measurement, which essentially destroys their quantum states. This limitation introduces significant challenges in designing quantum memory and other hardware.
  4. Quantum Speedup: While quantum computers still rely on classical control processors, they can solve certain types of problems far more efficiently. The sheer complexity of operations performed on multiple qubits in superposition provides a level of computational parallelism that classical systems can’t achieve. As a result, quantum computers can solve some problems exponentially faster than classical computers.

Classical vs Quantum: Two Types of Computation

In formal terms, classical computing is a subset of quantum computing. Quantum systems are, by their nature, a more general form of computation. A quantum computer can theoretically perform any task a classical computer can, but the reverse isn’t true.

While classical systems excel at deterministic, straightforward calculations and are still the most practical solution for everyday computing needs, quantum computers promise breakthroughs in fields like cryptography, materials science, and complex simulations. However, the full potential of quantum computing is still in its early stages, with numerous technical challenges remaining.

Conclusion

The advent of quantum computing represents a paradigm shift in how we think about computation. While classical computing remains essential for most of today’s technology, quantum computing opens the door to unprecedented computational power. By leveraging the principles of quantum mechanics, future quantum computers will tackle problems once deemed unsolvable, pushing the boundaries of science, technology, and innovation.

The light switch analogy offers a simple glimpse into the complexity of these two systems: while classical bits are limited to being ON or OFF, qubits, like points on the surface of a sphere, reveal an infinite range of possibilities. This difference is the key to quantum computing’s extraordinary potential. The future of computation lies in the quantum realm, where the probabilistic nature of the universe is harnessed for revolutionary breakthroughs.