The drunken bishop

How do you make ASCII art from a fingerprint?

For a change, we're going to be fairly timely with this. Not with the subject of this post, but at least with the thing that sparked it. In October 2026, it came to light that the certificate authority eMudhra had been using remarkably secure private keys such as 4.

That's how I came across this wonderful illustration:

The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|                 |
|        4        |
|                 |
|                 |
|                 |
|                 |
+----[SHA256]-----+

Joking aside, the image is obviously far from reality, since these aren't actually generated from the private key, but from the public key's (SHA256) fingerprint/hash. Still, it was enough to get me wondering how they actually work.

Let's look at a few real examples and see if we can get anywhere with them:

+--[ED25519 256]--+     +--[ED25519 256]--+     +--[ED25519 256]--+
|                 |     |o ..E.    .o..   |     |B=o+++o          |
|   .             |     |..  = . .....    |     |Bo+.+ +..        |
|  . o   .        |     |.  . = ..+..     |     |*@ o o +..       |
|...+ +   +       |     |.   . =+o.o      |     |@.o . ..o.       |
|.=.o+.. S o      |     | .   ..+S..      |     |= +  .  S.       |
|* *  .o  .       |     |... + .+   o o   |     |== .E            |
|=.o* .ooo o      |     |.+.  =. o o = .  |     |B...             |
|.=ooEo.+=* o     |     |ooo   .  o = +   |     |+o+              |
|+..o.o====*      |     |o=....      Oo   |     |o=.              |
+----[SHA256]-----+     +----[SHA256]-----+     +----[SHA256]-----+

The dimensions are 17*9 characters, so 153 characters in total. Much of the image is left blank, and the rest appears to use a fixed character set. Something else you might notice is that there's always an S in the middle of the image, and an E somewhere in there too. That's about as far as I got before I grew tired of thinking and decided to look up how it actually works instead.

The algorithm is referred to as the Drunken Bishop because our cursor starts in the middle and moves diagonally in various directions based on the incoming data. As it moves, it also keeps track of how many times it has visited each cell.

To keep things simpler, let's look at an example that's shorter than a SHA256 hash:

Hello.

If we take the character values, we get the following hexadecimal numbers:

48 65 6c 6c 6f 2e

Which look like this in binary:

01001000 01100101 01101100 01101100 01101111 00101110

We group the binary digits into pairs:

01 00 10 00
01 10 01 01
01 10 11 00
01 10 11 00
01 10 11 11
00 10 11 10

Two bits of data can take four possible values, to which we can assign four directions:

00 ↖
01 ↗
10 ↙
11 ↘

This gives us the following sequence of moves:

↗ ↖ ↙ ↖
↗ ↙ ↗ ↗
↗ ↙ ↘ ↖
↗ ↙ ↘ ↖
↗ ↙ ↘ ↘
↖ ↙ ↘ ↙

We process the bytes one after another, from top to bottom, but within each byte we go from the least significant bits to the most significant bits (so, from right to left). This gives us the following execution order:

↖ ↙ ↖ ↗ ↗ ↗ ↙ ↗ ↖ ↘ ↙ ↗ ↖ ↘ ↙ ↗ ↘ ↘ ↙ ↗ ↙ ↘ ↙ ↖

Starting in the middle, we can dance our way through this choreography. If we hit a wall, we only carry out the part of the diagonal move that we can. We're not allowed to leave the box. In a corner, we might end up staying put, but we still increment the cell's value. In the end, if I've counted correctly, we get the following pattern:

+-----------------+
|       22        |
|       24        |
|      12 1       |
|     1 1  2      |
|      1 12       |
|        1 1      |
|         1       |
|                 |
|                 |
+-----------------+

The numbers show how many times we've visited each cell (empty cells are not visited). We still need to replace them with characters from the .o+=*BOX@%&#/^ character set used by the algorithm. On top of that, S marks our starting point, and E marks the point where we ended up. The S doesn't change if we pass through it, but it becomes an E if we finish our dance there.

+-----------------+
|       oo        |
|       o=        |
|      .o .       |
|     . .  o      |
|      . So       |
|        E .      |
|         .       |
|                 |
|                 |
+-----------------+

And... that's pretty much it. A SHA256 hash is a little longer (32 bytes) than our starting data (6 bytes), so it can produce somewhat more interesting images, but the basic principle is the same. The implementation used by SSH can be viewed here.

Ez a bejegyzés magyar nyelven is elérhető: A részeg futó

Have a comment?

Send an email to the blog at deadlime dot hu address.

Want to subscribe?

We have a good old fashioned RSS feed if you're into that.