Design Blog 2: Identicons

How can users easily recognize addresses?

What is an Identicon?

An Identicon is a visual representation of a hash value. In the words of the originator:

I originally came up with this idea to be used as an easy means of visually distinguishing multiple units of information, anything that can be reduced to bits. It’s not just IPs but also people, places, and things. IMHO, too much of the web what we read are textual or numeric information which are not easy to distinguish at a glance when they are jumbled up together. So I think adding visual identifiers will make the user experience much more enjoyable. — Don Park,

Today Identicons are used in a broad spectrum of applications such as Github’s default avatars:

Github use Identicons as default Avatar

or to visualize addresses in Ethereum wallets:

Ethereum Wallets use Identicons to represent addresses

Do they have to look so weird?

Since Nimiq aims for better usability than conventional cryptocurrencies we weren’t satisfied with state-of-the-art Identicons. They seem to be designed for more tech-savvy audiences and look neither nice nor well distinguishable for the average user. Let’s not even speak of memorability.

So we’ve done lots of research on various Identicon libraries and the only one generating appealing results was Robohash. Instead of generating abstract shapes, Robohash assembles random robots from a predefined set of bodies, heads, eyes, mouths and accessories. This approach decreases the total amount of possible Identicons, but it increases the amount of distinguishable and memorizable Identicons:

Robohash of a random address

Are they secure?

Lets calculate the number of different robots we can generate:

There are 5 different body parts

There are 10 different shapes for each body part

There are 10 different robot colors

There are 10 different background colors

In total that’s 10⁵ * 10 * 10 = 10 000 000 different robots. That’s not even close to the number of different addresses which is ~2²⁵⁶ = 10⁷⁷. Though it’s probably impossible to generate anything close to 10⁷⁷ different, well distinguishable, well memorizable Identicons on a 128x128 pixel canvas, just because humans capacity in processing images is limited. Therefore Identicons can never be a security measurement and they can never replace the need to carefully check an address before confirming a critical transfer. Even though their entropy is neglectable in comparison to the address space, to quickly get an overview of your transaction history or to distinguish your own accounts, Identicons are very valuable.

Client-Side Rendering

The original Robohash library is designed to run on a server. Though for an wallet application you don’t want to call a server to render your Identicon, because that would violate your privacy since you’d have to tell that server your address. Therefore we needed to port the rendering code from the server to the browser.

The original library layers multiple PNGs of body parts on top of each other to assemble a robot. The database of body parts is about 3.5MB which is way too large to ship it in a web app. So to port the library we wanted to compress the image database by a factor of hundred down to about 35kB.

Compressing the PNGs that much would look horrible so we took a different approach and converted the PNGs to SVGs and compressed them with SVGO even below our target to about 24 KB gziped SVG+JS which creates perfectly scalable, well distinguishable and well memorizable Identicons:

SVG-based Robohashs

Can we make it faster?

In our first naive implementation the image database was just a bunch of multiline svg strings in a huge JavaScript file. This is inefficient because the JavaScript interpreter needs to parse the ~70kb of strings before another script can compile them into an SVG to then give that to the SVG parser.

Way cleaner is to leverage SVG’s “use” tag to link into an external SVG file which contains the database. This way we just need a tiny amount of Javascript building an svg containing a use tag for each body part and then all the heavy lifting is done directly by the SVG parser which is built for nothing else than handling SVGs as fast as possible.