Almost a year ago, I blogged about the drunken bishop algorithm for OpenSSH key random art. Towards the end of the post, I mentioned that I would be building an OpenPGP implementation. I started doing so in Python, but eventually got sidetracked with other things. Well, I hosted the Scale 12x PGP keysigning party, and after the fact wished that I had finished the OpenPGP drunken bishop implementation. Well, I'll be hosting another PGP keysigning party at OpenWest 2014 next month, and couldn't risk missing another keysigning party where I could introduce the drunken bishop to attendees there.
The OpenPGP implementation follows ALMOST the exact algorithm. The only differences are this:
- OpenSSH key fingerprints are MD5 checksums while OpenPGP key fingerprints are SHA1 checksums. As such, a larger board is introduced.
- The algorithm for OpenSSH key fingerprints reads the fingerprint in little endian. I felt that this unnecessarily complicates the codebase, so I read the fingerprint in big edian.
- For the ASCII art output, the PDF paper mentions that as the bishop visits a square more often, the ASCII character should increase in weight gradually. Unfortunately, it appears this wasn't strictly observed. I've changed the characters that are shown in the art to more accurately reflect the frequency of visits to each square. The starting 'S' and the ending 'E' remain the same.
- I added an extra label at the bottom of the random art to depict the 8-bit OpenPGP key ID for that art.
Because it's written in Python, it is slower than its C counterpart for OpenSSH. If I were motivated enough to care, I'd write it in C. But, it's plenty fast for what it's doing, and I'm sure there are performance optimizations I can make to speed things up in the Python script.
I took 9 random keys from my GnuPG public keyring, and am showing them here, as a screenshot, rather than the horrible rendering that is web browsers:
As with OpenSSH, these random art images for each public key exists to make verifying OpenPGP keys a bit easier. No doubt that there exist collisions, where more than one key produce the same artwork. When in doubt, verify the hex fingerprint. However, this may be a good alternate method for speeding up keysigning parties, by having each individual verify their key individually, then only speaking up if they feel their key is in error. This way, parties can go straight to identification checking, this eliminating 1/2 to 2/3 of the party. During identification checking, each individual could verify the key random art, fingerprint, etc. while checking photo identification.
A possible handout format for the random art images could look something like this:
+----[DSA 1024]-----+ |l^ . ^^?^. | 1) ID: 22EEE0488086060F |l. . .l:.? | UID: Aaron Toponce
|^ E ...ll | Fingerprint: E041 3539 273A 6534 |^. . ^:. | A3E1 9259 22EE E048 |^ . . .. | Size/Type: 1024/DSA | . . . S | | . . . . | Matches? | . . | Fingerprint: ____ ID: ____ Signed: ____ | | | | | | +----[8086060F]-----+
Of course, this is less efficient on paper usage than the traditional table, but it could be improved.
The source code for generating the OpenPGP random art is at https://github.com/atoponce/scripts/blob/master/art.py. It requires an OpenPGP public key file as an argument when executing the script, like so:
$ ./art.py 8086060F.pgp
Hopefully, PGP keysigning party organizers find this useful in streamlining the keysigning process. If not, at least it could be entertaining.