This is rather unusual. Here I’m reviewing someone else’s invention, but I do it because it strikes a geeky chord in me and I just can’t get it off my mind. The product is DiceKeys, which appears to be simply a set of dice and a blue box, but there’s more to it. A lot more.
DiceKeys, developed by Stuart Schechter, who was kind enough to send me three pre-production copies so I could write this review, consists of a set of 25 six-sided dice, each of them marked with a different letter (A to Z, skipping Q), also numbered 1 to 6 on their sides, which end up reading like B6, J1, and so forth. The dice fit into the 25 cells of a waffle-looking plastic tray, with a locking two-part top. You shake the dice inside the supplied bag, pour them onto the waffle, and spread them without looking so all the dice fall into the cells. Then you look at it, and you see something like the picture at the top of this article. The inventor recommends that you also press in the top in order to preserve the combination.
Looks fairly innocuous, but what if I told you that this is one of 25! x 6^25 x 4^25 = 4.965 x 10^59 possible combinations, roughly equivalent to 199 bits of entropy? Impressed yet? No? And what if I told you that this number space is large enough to give a unique ID to every atom in the solar system, a hundred times over?
But this is not what Schechter wants you to use it for. He wants you to use it to generate a master password, and then keep it in a safe place so you don’t forget it. This is why the dice lock into the cells when you press the top on them, and you need to pretty much destroy the device in order to release them. More on this later.
The password is actually generated by an auxiliary program, currently available as a web app at this link, but also promised for Android and iOS. The program looks at the box with the dice in it through the computer or phone camera, figures out the dice positions from the image, and then computes the password. You can generate several passwords, actually, if you tell the program where you are going to use it. I haven’t looked too hard into the code, which consists mostly of a 12.2 MB JavaScript file with nearly 60,000 lines of code that includes two base64-encoded executables, plus a whole bunch of TypeScript files for the web app version, but I imagine you get multiple passwords by concatenating a master code extracted from the dice with the name of the place where you plan to use it, and then taking a hash of it. If well-written, the result should be truncated so its length is proportional to the entropy contained, that is, 197 bits. The program reduces the raw entropy by 2 bits because it “rotates” the box to a standard “canonical” position like, and I’m guessing here, putting the die with the lowest letter in the upper-left corner.
The app outputs the master password as a series of 15 English words. If they wanted to represent faithfully the 197 bits of entropy, that implies 197 / 15 = 13.3 bits per word, or a dictionary size containing 2^13.3 or roughly 9,000 words. I couldn’t find the dictionary among so many files, but the documentation on their Github page talks about 1024 five-letter words, which means 10 bits of entropy per word, or 150 bits of entropy altogether. In other words, the conversion to words squanders some 47 bits of entropy, which could have been used to generate four more words, or could have come from a simpler system.
Had the grid been 4×4, using only 16 dice, the keyspace would have had a raw size of 16! x 6^16 x 4^16 = 2.5 x 10^35, containing 118 bits of entropy, which can be converted into more than 11 five-letter English words using the same dictionary. So it beats me why the program doesn’t generate a longer string. Perhaps the developers thought 150-bit codes were good enough (but 118-bit codes weren’t), and making the word codes longer would have been too hard to use.
I’m hoping they’ll use more of the available entropy in a future version of the app. In any case, the app is supposed to extract all that entropy from the dice within a blink, much like phones today can extract information from a QR code. It’s just a matter of recognizing the letters, numbers, and their orientations from the combined image, made easier by encoded strips at top and bottom of each die face, which presumably contain the letter (for the die) and the number (for the face). I was so thrilled that I didn’t wait for my DiceKeys to arrive, and so I attempted to test the code with the picture of the dice position from their website, shown at the top of this post. It should have worked since everything was the same except for the lines separating the dice being black rather than blue. After all, the set of dice in the box is a flat as the picture, so no 3D effects were to be expected.
But, try as I might, I couldn’t get it to work at first, even after switching to different browsers running on my iMac, which has a better than average camera. The furthest the code got (sometimes) was recognizing some codes and strips, highlighted green and red on the captured image. But I could never get it to settle on a code that would show as an output. I imagine that the calculation of the overall raw code, and the subsequent conversion from raw code to set words is comparatively easy, so the sticking point must have been image recognition. When the sample DiceKeys arrived, I tried them with the app, thinking that perhaps the app expected a specific die size, or a specific color separating the dice. Well, no dice, either. This time I managed to get my iPhone SE to recognize the dice exactly once, but after that the behavior was the same as with the printed image. The iMac didn’t get as far with the actual DiceKeys set as it did (once) with the printed image. A few days later, however, an updated app running on Chrome on my iMac was able to recognize the positions pretty much all the time, and output 15-word codes made from the image (even from a printed copy, which is nice). The same app on my iPhone SE never managed to generate a code, though sometimes it got to the point of recognizing almost all of the dice, and it used up the battery in short order. I’m working with the developer to get this and other issues resolved.
I didn’t want to give up after the first software failure, so I spent a few hours writing an alternative program that would extract all that precious entropy into a raw code, leaving aside the image recognition and the final conversion into words. This is the result, which you can use freely if the official DiceKeys app malfunctions on you. In my code, you enter the dice and their positions by typing them as a case-insensitive code, with the orientations encoded as ^ _ < > for up, down, left, right respectively. The code in the image at the top would be typed as: b6_ u6_ f6> y2_ a5^ x5_ j3_ r3> v4_ c1< n1< m5> s2> w5^ k3> h1^ g4^ l4< i3_ z5> e1^ p4_ o5> t4^ d2< which takes barely a minute.
Not knowing what is the actual algorithm used by the official app to convert the dice positions into a code, I developed my own. My method separates the sequences for letters (a pure permutation), numbers, and orientations and computes a unique code for each (Lehmer code for letters, simple base 6 or base 4 conversion into decimal for numbers or orientations). Then the three decimal codes are combined into a single one assuming they are the units, “tens”, and “hundreds” of a varying-base number. Default is using the letter code for least significant figure, number code for the next, and orientation code for the most significant figure, though the program allows you to change that if you want. You can also ignore any of the components, or consider a 4×4 “mini” set of 16 dice, or a 6×6 “extended” set of 36, if you prefer. Output is decimal, base64, hex, pure alphabetic, or whatever else you want if you just write in the symbols making up the base. I didn’t want to include an additional base conversion into words because, as I said, I couldn’t find the particular dictionary used by the original app. You can use the output codes in any base to function as master password just as easily as a word code, and they don’t lose any entropy, which is 199 bits because my app does not “rotate” the image to a special position.
So now that I have a code, do I still need my DiceKeys set, locked into an invariable position? DiceKeys is being promoted together with a Solokey USB key (similar to YubiKey, but open-source) that presumably stores the generated code and delivers it securely to programs that ask for it the right way. I don’t own either of these, so I’ll take that the app does this automatically, as claimed. This way, once you have read the dice into the USB key you can store the physical DiceKeys in a safe place, to serve as a backup, and use the USB key from then on. In other words, if you do everything right the dice are used only once, after which you could conceivably want to pass them on to someone else since a simple picture of the dice should work just as well as a backup (I tried, and it worked). Or just the code printed on a piece of paper, for that matter. But the DiceKeys locks into a solid block as soon as you press the lid on, never again to come apart. That’s quite a bummer for me, who end up changing master keys from time to time anyway. I’d need to buy a new set every time I do so, because the original set won’t disassemble. This makes me that much less likely to buy it for myself. Or at least, I won’t put the lid on next time.
This will bum you out also if you have a need to generate massive amounts of truly random numbers, because you are a spy who needs unbreakable one-time pads, or her handler at spy headquarters. In the 1950’s the KGB had a small army of women on typewriters for this very purpose. After just drumming on the keyboard for a while to produce an original plus its carbon copy (which was surprisingly effective because different typists settled on different “random” patterns) they were issued drums with numbered balls. They could have used the lower part of the DiceKeys set, minus the locking top, to produce long strings of many digits instead of painstakingly drawing one ball at a time, which then had to be returned so the probabilities of all digits would stay constant. History says that the extreme monotony of their job was the source of many errors, especially when the same digit came out repeatedly and they tended to correct it so the result would be more “random.”
In this scenario, and others that you can surely come up with, you’d want to have your own DiceKeys set and trust that the official app will offer a way to output the whole entropy contained in the dice (or use my app). Let’s say the output is a decimal number. The highest number the set can produce (turning the rotation thing off), is of the order of 4.965 x 10^59, as we saw earlier. That means that, if the number you get has 60 figures and begins with 1, 2, or 3 (or has fewer figures, which can be padded with zeros on the left) all digits but the first come from a set where all results have identical probability. If the number has 60 figures and begins with 4 (it cannot begin with a higher digit), the rest of the digits cannot possibly go all the way to 59 nines, which means they cannot be truly random, and it is best to throw the whole thing away and repeat the draw (or just take the last 58 digits, unless the second digit happens to be a 9, for the same reasons). If the codes are combined in LON or LNO order (as defined in my app), it will be easy to detect right away if a dice position has this problem before you enter it into the app, just by looking at the first few die letters.
The amount of good entropy you can generate is truly enormous, especially with a 6×6 or larger set. How big is it? The 6×6 set maxes out at 36! x 6^36 x 4^36 = 1.81 x 10^91, equivalent to 303 bits of entropy. This is large enough to give a unique ID to each atom in the universe (estimated in various ways as containing around 10^80 atoms). Not only that, you could replace all the IDs with fresh IDs every second, and keep doing this for nearly six thousand years!
You may be overjoyed to hear that I did manage to take my locked DiceKeys apart with the help of a spatula. Then I taped a cardboard fence around the tray, resulting in the device shown in the picture at right. If I put the top on it (which now doesn’t lock on the dice) and shake the thing for a while until the dice settle back on the waffle tray, I’ll be able to snap a picture that will be automatically converted into a 197-bit unique number, and then I can do this as many times as I want. God knows every atom in the universe is waiting to be given a name, or at least a code.
So, in summary:
- What’s cool: Easy way to make lots of high-quality entropy from a pocketable package (if you don’t put on the top).
- What’s not cool: The lid locks so you can set exactly one code, and then you need to buy another DiceKeys if you want to change it or let someone else make a code. The official app does not work on my iPhone, and does not yet output anything except a 15-word code containing only 150 bits of entropy, but I’m sure they’ll fix that yet. In the meantime, I’m giving you an alternative to the official app here.