Quantum Tofu

A generative art experiment.
True randomness from quantum computers.
256 to be minted on the blockchain.


Quantum Tofu #0

About

Description

Quantum Tofu represents the elegance and fallacies of new technology. An array of 256 unique colors is randomly generated from a quantum computer. The blocks where there is a persistent glow of white are the moments when the quantum computer encountered noise and produced an unlikely output, referencing the likelihood of gaps and errors in advanced technology. Each Quantum Tofu NFT takes a minimum of six hours to generate and, once minted, lives forever on the blockchain as data and is not stored in any third-party cloud or IPFS storage.


Bytes of tofu

256 is a significant number in computing. Computers define color by combining channels of red, green, and blue, of varying values. Each channel is able to store values up to 8-bits, or 256. In blockchain and cryptography, 256 is used in cryptographic hash functions (mathematical algorithms used to encrypt things) such as SHA-256 for Bitcoin, or Keccak-256 for Ethereum, not to mention the encryption of private keys for crypto wallets.

For Quantum Tofu and its colors, each individual block has the possibility of 256^3 (16,777,216) colors. And because there are 256 total blocks, this results in a one in 256^256 (a number with 617 digits) chance for each Quantum Tofu to be generated with the exact same color values in the exact same sequence. This just might be scarcity at its most extreme.


Quantum randomness

Quantum Tofu uses hardware – IBM's quantum computers – to generate unique values for every color. Most random number generators rely on algorithms and are inherently deterministic, which means their outputs actually aren't that random. Quantum Tofu doesn't use algorithms and instead measures the wave function collapse with quantum computers through the phenomenon of superposition (when states of 0 and 1 occur at the same time); this is randomness in its purest form. Imagine opening up the box with Schrödinger's cat 256 times and observing whether the cat is dead or alive each time, when the cat is both dead and alive.

Due to the nature of machines, there are always instances of noise and, consequently, error. For Quantum Tofu, these errors happen when quantum computers measure states of entanglement (another quantum phenomenon when one state, be it a 0 or 1, always measures to be the same as another). An error is revealed if the output is a 0 and 1, or a 1 and 0. Out of 256 conducted experiments to measure these entangled states, Quantum Tofu maps these moments of error to the previously generated array of colors as persistent glows of white, symbolizing the gaps in technology and the result when opposites – colors in this case – are mixed with each other.

Process

Generate array of colors

Random value integers are generated from IBM's quantum computers through Qiskit with the get_random_int function. These values, which range from 0 to 255, are stored as red, green, or blue values. This is the most time-consuming part of this process. Although each job takes around one minute to run, there is a queue to use IBM's quantum computers. One Quantum Tofu, with thousands of circuit executions, might take anywhere from six hours to 20 days to generate.

                          
    def _request_bits(n):
        global _bitCache
        iterations = math.ceil(n/_circuit.width()*2)
        for _ in range(iterations):
            job = qiskit.execute(_circuit, _backend, shots=1)
            _bitCache += _bit_from_counts(job.result().get_counts())

    def get_bit_string(n):
        global _bitCache
        if len(_bitCache) < n:
            _request_bits(n-len(_bitCache))
        bitString = _bitCache[0:n]
        _bitCache = _bitCache[n:]
        return bitString

    def get_random_int(min,max):
        delta = max-min
        n = math.floor(math.log(delta,2))+1
        result = int(get_bit_string(n),2)
        while(result > delta):
            result = int(get_bit_string(n),2)
        return result+min
                          
                          

After a red, green, and blue value is generated, they are converted to hex color codes. Each color is appended onto an array; and once 256 hex color codes are populated, they are written into a JSON.

                          
    for i in range(256):

        r = quantum.get_random_int(0,255)
        g = quantum.get_random_int(0,255)
        b = quantum.get_random_int(0,255)
    
        def rgb_to_hex(r, g, b):
        return ('#{:02x}{:02x}{:02x}').format(r, g, b)
    
        hex = rgb_to_hex(r, g, b)
                          
                          

Generate array of errors

In an entangled Bell State, there is a 50 percent chance of measuring |00⟩ and a 50 percent chance of measuring |11⟩. Errors show up when, measuring a Bell State, the output is |01⟩ or |10⟩. Here a Bell State is measured 256 times on a quantum computer; and each individual output is appended to an array and written as a JSON.

                          
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.measure([0,1], [0,1])
    
    job = execute(circuit, backend, shots=256, memory=True)
    result = job.result()
                          
                          

Draw the tofu

The color array is looped through and each color is injected into an SVG as a block until a 16x16 square is formed. The error array is then looped through and, if the output is |01⟩ or |10⟩, that block is overlayed with white.

                          
    for (var i = 0; i < colorArray.length; i++) {
    
        const rectItem = document.createElementNS("http://www.w3.org/2000/svg", "rect")
    
        if (y >= 25) {
            rectItem.setAttribute("x", x = x+25)
        }
        else {
            rectItem.setAttribute("x", x = x+25)
        }
    
        if (x >= 650) {
            x = 225
            rectItem.setAttribute("x", x = x+25)
            rectItem.setAttribute("y", y = y+25)
        }
        else {
            rectItem.setAttribute("y", y = y)
        }
    
        rectItem.setAttribute("width", width)
        rectItem.setAttribute("height", height)
        rectItem.setAttribute("fill", colorArray[i])
    
        document.getElementById("rectID").appendChild(rectItem)
  
    }


    for (var i = 0; i < errorArray.length; i++) {

        const rectItem = document.createElementNS("http://www.w3.org/2000/svg", "rect")
    
        if (y >= 25) {
            rectItem.setAttribute("x", x = x+25)
        }
        else {
            rectItem.setAttribute("x", x = x+25)
        }
    
        if (x >= 650) {
            x = 225
            rectItem.setAttribute("x", x = x+25)
            rectItem.setAttribute("y", y = y+25)
        }
        else {
            rectItem.setAttribute("y", y = y)
        }
    
        if (errorArray[i] == 10 ||
            errorArray[i] == 01) {

            rectItem.setAttribute("width", "25")
            rectItem.setAttribute("height", "25")
            rectItem.setAttribute("fill", "#ffffff")
            rectItem.setAttribute("fill-opacity", "100%")
            rectItem.setAttribute("filter", "url(#glow)")

            document.getElementById("rectID").appendChild(rectItem)

        }
    }