With modern day laptops, often there are backlit keys on certain media keys like mute sound, mute mic, airplane mode and so on. The light being switched on, for obvious reasons indicates that the particular function is in operation. This is easy on Windows for which these machines are always tested against^{[1]}. Similarly, macOS works well on Apple devices. With GNU/Linux^{[2]} however, almost all machines work but the tiny quality of life improvements like those media key lights can be a hit or miss.

As usual, I went ahead and installed Arch Linux on my machine with dwm as my window manager. After the installation and a test drive of my laptop, I see this...

At first I thought perhaps it's a driver issue but all my drivers were up-to-date. Looking through the Arch wiki didn't help with the issue. Knowing the vibrant thinkpad community, I ended up posting about my problem on r/thinkpad.

I'd much rather have the backlight fully off than have it functional. So, a fellow redditor let me know to check for the output in a particular system file:

```
~: $ cat /sys/class/leds/platform::micmute/brightness
1
```

'1' here represents the light in the ON state, which is exactly the problem!
~~Changing the value to '0' in the file instantly fixes the problem!~~
Changing it to '0' only fixes it temporarily until the next time the machine is booted up. A rather simple "hack" is to make this change everytime the user logs into the machine. This is done simply through the `.xprofile`

or `.xinitrc`

file (most people would use `.xinitrc`

) by adding the following line in said file:

`echo "0" > /sys/class/leds/platform::micmute/brightness`

This line simply replaces whatever the file previously had, with '0'. This works rather well until I find a more permanent solution.

[1] | The travesty being that laptop manufacturers being the profit oriented businesses that they are, cater to the masses which unfortunately sides with malicious, proprietary garbage like Windows. |

[2] | Technically Linux is the kernel and not the operating system (the rest is supplied by the GNU operating system sans its own kernel). Here is a better explanation. |

Qiskit [kiss-kit] is an open-source SDK for working with quantum computers at the level of pulses, circuits and application modules.

I plan on writing a series of tutorials on getting started with quantum computing using qiskit, as I learn as well. Like any other programming tutorial, we start with a simple "Hello, world" program.

With conventional computers, the simplest program that one could perhaps make is printing out "hello, world". However, in contrast to this, in quantum systems, we go ahead and measure a quantum state (this seems to be the most rudimentary but complete program in quantum terms). Let's proceed to do just that!

We import the necessary modules from Qiskit for this operation. To define a quantum circuit, we require the classes `QuantumCircuit`

, `QuantumRegister`

, `ClassicalRegister`

and define a state variable `psi`

as

Notice that the state \(| \psi \rangle\) is normalized. This is important, otherwise we'll end up with an error.

```
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from math import sqrt# define an initial state
psi = [1/sqrt(2), 1/sqrt(2)]
```

We then define a function `prepare()`

which takes two parameters: a `QuantumCircuit`

object named `qc`

and the initial state `psi`

. Remember that the quantum circuit that we define, only uses 1 qubit (notice the vector representation of \(| \psi \rangle\)).

```
def prepare(qc, psi):
qc.initialize(psi, [0]) # [0] indicates the zeroth index (or) the first qubit
```

Python by default, calls by reference, so we don't have to worry about returning anything from `prepare()`

.

Let's proceed with making an actual quantum circuit. For this, we define a `QuantumRegister`

object `qr`

, which stores the qubits and a `ClassicalRegister`

object `cr`

which stores the measured values of those qubits.

```
qr = QuantumRegister(1)
cr = ClassicalRegister(1)
```

Combining the two registers, we now make a quantum circuit:

`qc = QuantumCircuit(qr, cr)`

We then call our function `prepare()`

to initialize the first qubit (the only qubit) of our quantum circuit `qc`

.

`prepare(qc, psi)`

How do we go about measuring our state? That's where the `ClassicalRegister`

object `cr`

comes in. We use the `measure`

method under the `qc`

object to actually measure the qubit.

`qc.measure(qr[0], cr[0])`

The above syntax generally means that we're measuring the state of `qr[0]`

(the first qubit) onto the classical register `cr[0]`

where we store the measured value.

Ok so all of this is nice, but one can only describe so much. Let's see how our circuit actually looks like after applying the above operations. For this, we use the `draw()`

method with the `matplotlib`

backend.

`>>> qc.draw(output='mpl')`

To measure the qubit and store the result in the classical register `cr`

, we use the `qasm_simulator`

backend. As we know from basic quantum mechanics,

```
from qiskit import Aer
backend = Aer.get_backend('qasm_simulator')
```

We then transpile our circuit for the `qasm_simulator`

backend to understand and execute the circuit.

```
from qiskit import transpile
qc_compiled = transpile(qc, backend)
```

Now, we simply execute the circuit and gather the measurement results.

```
job = backend.run(qc_compiled, shots=1024) # shots is the number of times we run the experiment
results = job.result()
```

We store the value of the `result`

object and can further access the number of times we end up with a certain value of expected outcome with the `get_counts()`

method.

```
counts = results.get_counts(qc_compiled)
print(counts)
```

`{'0': 518, '1': 506}`

Here we end up with a dictionary of key values `'0'`

and `'1'`

, which indicate the following quantum states:

As expected, we get a 50-50 distribution of the states \(|0\rangle\) and \(|1\rangle\), since our starting state was \(|\psi\rangle\). We can also calculate this probability via the inner-product,

\[ |\langle 0 | \psi \rangle|^2 = \frac{1}{2} \qquad |\langle 1 | \psi \rangle|^2 = \frac{1}{2} \]Let's visualize this in the form of a histogram. For this, we import the `plot_histogram`

function.

```
>>> from qiskit.visualization import plot_histogram
>>> plot_histogram(counts)
```

You can find the entire script in this gist.

]]>Recently I had made the switch from firefox to brave, for the naive reason that fonts were just rendered better (and LaTeX looks like it) on it (being a chromium based browser). However, I really missed the customizability and other nifty features of firefox. It just felt like home. I knew for sure that I'm missing something, because surely firefox couldn't be responsible for messing fonts, right? (atleast I hoped).

On firefox, you may have come across the font settings that look something like this:

My past self would unselect the option * Allow pages to choose their own fonts, instead of your selections above*, just so that I can have my custom fonts rendered. But oh boy, would that turn out disastrous to say the least. I visit a good number of websites that render math equations in TeX, but with this setting turned off, LaTeX looked more like some flunky '90s PC trying to render math.

What was the fix you might ask? Well, just select the option that I had unselected earlier. But this would bring that the atrocious fonts back on many websites.

I later came across this blog post where I got to know that firefox depends on an OS-level font configuration called fontconfig and is located at `~/.config/fontconfig/fonts.conf`

.

If you don't have one, just create it at the specific location.

```
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<alias>
<family>Helvetica</family>
<prefer><family>IBM Plex Sans</family></prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer><family>IBM Plex Sans</family></prefer>
</alias>
<alias>
<family>monospace</family>
<prefer><family>DejaVu Sans Mono</family></prefer>
</alias>
</fontconfig>
```

A lot of websites these days use Helvetica as their serif font, and firefox will fallback to a specific font if Helvetica is not found. By default, this fallback seems to be Nimbus Sans, which is not pretty to say the least. This is where fontconfig comes in.

The above XML file tells firefox that, "Hey! If you're trying to render Helvetica, just use IBM Plex Sans", and similar font rules for sans-serif and monospace fonts.

I was really happy when I came across this fix! and I hope this has helped you as well.

]]>An operator \(U\) is unitary if

\[ U U^\dagger = U^\dagger U = I \]where \(U^\dagger\) is the complex conjugate (interchange rows & columns and replace \(i\) with \(-i\)) of \(U\).

Let there be 2 matrices \(A\) and \(B\) where

\[ A = \begin{pmatrix} a_{00} & a_{01} \\ a_{10} & a_{11} \\ \end{pmatrix} \] \[ B = \begin{pmatrix} b_{00} & b_{01} \\ b_{10} & b_{11} \\ \end{pmatrix} \]The tensor product of \(A\) and \(B\) is represented as \(A \otimes B\) and is evaluated as

\[ A \otimes B = \begin{pmatrix} a_{00} \cdot \begin{pmatrix} b_{00} & b_{01} \\ b_{10} & b_{11} \\ \end{pmatrix} & a_{01} \cdot \begin{pmatrix} b_{00} & b_{01} \\ b_{10} & b_{11} \\ \end{pmatrix} \\ a_{10} \cdot \begin{pmatrix} b_{00} & b_{01} \\ b_{10} & b_{11} \\ \end{pmatrix} & a_{11} \cdot \begin{pmatrix} b_{00} & b_{01} \\ b_{10} & b_{11} \\ \end{pmatrix} \\ \end{pmatrix} \]I have used the term unitary transform and unitary operation interchangeably (since they mean the same thing).

Given a quantum state \(\left| \psi \right> = \alpha \left| 0 \right> + \beta \left| 1 \right>\) with unknown complex coefficients \(\alpha\) and \(\beta\), is it possible to replicate the state onto another qubit? In other words, is it possible to go from \(\left| \psi \right>\) to \(\left| \psi \right> \otimes \left| \psi \right>\)? Let us form a hypothesis.

Given an unknown quantum state \(\left| \psi \right>\), there exists a unitary transform \(U\) such that it replicates the state \(\left| \psi \right>\) to \(\left| \psi \right> \otimes \left| \psi \right>\).

From the postulates of quantum mechanics, any transformation of a quantum system must be unitary. Hence, we are trying to look for a unitary operation \(U\) to make the following transform:

\[ U \left| \psi \right> \otimes \left| 0 \right> = \left| \psi \right> \otimes \left| \psi \right> \]Here the inputs are \(\left| \psi \right>\) and an ancilla qubit (in our case \(\left | 0 \right>\)).

The no cloning theorem tells us that such a unitary transform does not exist. Let us see how this is true, algebraically. We will do this by disproving the hypothesis. Let us look at the cases when \(\left| \psi \right> = \left| 0 \right>\) and when \(\left| \psi \right> = \left| 1 \right>\). On applying the operation \(U\), the 2-qubit state becomes,

\[ \left| 0 \right> \otimes \left| 0 \right> = \left| 00 \right> \xrightarrow[]{U} \left| 00 \right> \] \[ \left| 1 \right> \otimes \left| 0 \right> = \left| 10 \right> \xrightarrow[]{U} \left| 11 \right> \]Now let us apply \(U\) to the original state \(\left| \psi \right> (= \alpha \left| 0 \right> + \beta \left| 1 \right>)\) based on the above transformations.

\[ (\alpha \left| 0 \right> + \beta \left| 1 \right>) \otimes \left| 0 \right> = \alpha \left| 00 \right> + \beta \left| 10 \right> \xrightarrow[]{U} \alpha U \left| 00 \right> + \beta U \left| 10 \right> = \alpha \left| 00 \right> + \beta \left| 11 \right> \]Based on our original hypothesis, the output is

\[ (\alpha \left| 0 \right> + \beta \left| 1 \right>) \otimes (\alpha \left| 0 \right> + \beta \left| 1 \right>) = \alpha ^2 \left| 00 \right> + \alpha \beta \left| 01 \right> + \beta \alpha \left| 10 \right> + \beta ^2 \left| 11 \right> \]In matrix notation this looks like

\[ \begin{pmatrix} \alpha ^2 \\ \alpha \beta \\ \beta \alpha \\ \beta ^2 \\ \end{pmatrix} = U \begin{pmatrix} \alpha \\ 0 \\ \beta \\ 0 \\ \end{pmatrix} \]Now comparing the coefficients of the output states, such a case is only possible if \(\alpha = 1\) or \(\beta = 1\). This disproves the hypothesis, hence proving the no cloning theorem.

Principles of Quantum Mechanics - Shankar

Quantum Computation and quantum information - Nielsen & Chuang

In layman terms, *cryptography* is the study of securing messages between two parties without a third party knowing what the message is. *Encryption* is the process of securing these messages.

Think of encryption as a process which is easy to do in one direction but rather difficult to do in reverse. One such example is **colour mixing**. One can mix various colours and make a mixture out of it. However, if you ask another person, it would be *almost* impossible to tell the constituent colours from the mixture.

The most basic and easy to understand method is the symmetric encryption method. It basically involves the following: Alice, who wants to send a message; Bob, who receives the message; and a secret key used to encrypt the message (essentially turning the message into gibberish).

Alice has a message, encrypts the message using the secret key, sends the message. Bob now decrypts the message using the same secret key and reads the message. This way during the process when the message is sent, even if a third party gets a hold of the message; they cannot read the message since they do not have the secret key.

The above method has a major flaw, which is that both the parties must have a common key. That means that the key to be used for encryption must be decided upon by the two parties beforehand. So the two parties have to meet at a place or send the key to the other through some means which isn't secure, unless one encrypts this key information which requires another key.

Asymmetric encryption AKA *public-key cryptography* involves the same scenario as that of symmetric encryption, the only difference being that instead of one secret key, two keys are used (called a *key pair*). Let them be *key A* and *key B*.

Let us use the same scenario as before: Alice wishes to send a message; she encrypts it with *key A* and sends it to Bob; he receives it and decrypts it using *key B*. Note that there was no exchange regarding the information of the keys themselves. *Key A* cannot be guessed from *key B* and vice-versa however they are linked in such a way that a message encrypted with *key A* can only be decrypted with *key B* and a message encrypted with *key B* can only be decrypted with *key A*.

When using asymmetric encryption, a key-pair is generated i.e. a *public* key and a *private* key.

The public key is made public (who knew!) and is published everywhere, on websites, posters and so on. The private key is kept to yourself. Any messages intended for you could be then encrypted using your public-key that only you can decrypt since you have the private-key.

What about the other way round? You could encrypt a message that you wish to send, using your private-key. But then you might ask, why should I encrypt a message that can be decrypted using my public-key since anyone can decrypt the message? (since you've made your public-key, public)

By encrypting the message using your private-key, one can know that the message is authentic since it can be decrypted using your public-key meaning, it must have been encrypted using your private-key which only you have access to.

So the best way to communicate using this protocol would be as follows: Alice has a key-pair and Bob has a key-pair. Alice wishes to send a message; she encrypts it using her private-key *ensuring that the message is authentic* and then encrypts it again using Bob's public key *ensuring that only Bob can read the message*. Bob upon receiving the gibberish decrypts it using his private-key and then once again using Alice's public-key establishing a secure channel for communication.

Note that in this method no keys were exchanged, in fact, Alice and Bob might not have even met before and this method still works. Isn't that amazing?

I understand that I have over-simplified things. This post is only meant to get a brief overview of encryption. For a better understanding refer the **Crypto 101** textbook linked below.

This post was inspired by the book, Crypto 101 by Laurens Van Houtven and this video from the YouTube channel Computerphile where Dr. Robert Miles explains about public-key encryption.

Lastly, I would like to end this post with a quote from Bruce Schneier:

]]>There are two kinds of cryptography in this world: cryptography that will stop your kid sister from reading your files, and cryptography that will stop major governments from reading your files.