# Implementation of diceware: do I have to simulate dice roll?

I am creating a small utility for generating passwords based on the diceware method. At the moment I am very close to the algorithm of real diceware - i.e. I simulate rolling dice n-times to get a single word from the list.

I am wondering though if this is really necessary. Wouldn't it be sufficient to just get a random number between 0 and length(diceware_list) -1 to obtain a single word?

Would such a simplified approach affect security of generated password? (I am using cryptographically secure source of random numbers so this is not a concern).

I think that the simplified method should be ok, but I am unsure. Could anyone help with that, please?

The reason Diceware advocates using dice to select a password is that it ensures the password the user gets is generated randomly. So no, as long as you are certain your program is selecting the password in an unpredictable (cryptographically secure random selection with a uniform distribution) manner, it doesn't matter how the password is actually generated.

There are other reasons for using dice that are impossible to replicate in any program:

1. It's completely transparent to the user. They don't have to trust a computer program to use an appropriate cryptographically random number generator or to not leak their password to malicious actors.
2. 100% malware-proof. Unless you have a webcam pointed at your table while you're rolling the dice, it's physically impossible for a malicious program on your PC to observe or influence the password you're generating.

Unless your users are particularly paranoid though, there's a good chance they'll be okay with forgoing these benefits in favor of the added convenience of generating a new password instantly.

• 3. Forensic recovery of which dice you rolled and what the result was is next to impossible. No one will know that you have rolled that dice or what the result was unless they watched you do it. It is far more possible for computers to contain artifacts that make easier to reproduce the previous rolls. – Adonalsium May 21 at 15:52
• how is it malware proof? you have to type in the number don't you? that would allow a key catcher or even fake login screen to fool the user, regardless of secret rolls, right? – dandavis May 21 at 19:14
• @dandavis The generation process is malware-proof. Obviously if you go to evil-site.net and enter your password there, the process you used to generate the password is irrelevant. – Ajedi32 May 21 at 19:18
• While dice are useful, loaded dice are a thing. A superior solution would be to flip a coin twice. If they both come up the same side, flip them again. Once the first and second flip differ, use the second flip's value. You now have one bit of entropy. Repeat as many times as necessary. This prevents a weighted coin from being problematic. Of course, as others have mentioned, the risk of a loaded dice or coin is likely very low for this threat model. – forest May 22 at 4:47
• @forest Loaded dice are much easier to identify than loaded random number generators. No special knowledge required; just roll it a hundred times or so and check that the distribution of results isn't obviously skewed. – Ajedi32 May 22 at 4:55

Yes, this is perfectly fine to do. With a good PRNG, each element will have exactly the same odds of being chosen, if you do the limitation (1 to n) correctly. (I have personally done a diceware implementation that does exactly that.)

There are two simple reasons multiple dice is used in a physical diceware process:

1. 6 sided dice are ubiquitous and cheap.
2. A 7776 sided die (6^5) does not, to my knowledge, exist. It would also be awkward to roll if large enough to read, or difficult to read if small enough to roll in the traditional fashion.

Please note that I said "if you do the limitation (1 to n) correctly." If your random number generation library does not offer a primitive for 1 to n, do not simply take a larger value and modulo n! While this will give answers in the correct range, they will not be uniformly distributed. You should either:

1. Keep retrying until a value in the acceptable range is returned (i.e., discard all values >n)
2. Scale linearly: rand_val * n / rand_max (which will require arbitrary precision math to avoid rounding error)
• You only need to discard the upper-range of the output to make modulus uniformly distributed – BlueRaja - Danny Pflughoeft May 21 at 17:18
• For the purpose of keeping each word equally likely, linear scaling isn't really any better (or worse) than modulo. They both make the same number of words more likely than others by the same amount; the only difference is which words those will be. If you really want to make the probabilities exactly equal, you either need to make n divisible by the word list size (in which case either method will give a uniform distribution) or use rejection sampling (i.e. "keep retrying"). But if n is much (say, 1000 times or more) greater than the word list size, the bias will be negligible anyway. – Ilmari Karonen May 21 at 18:36
• @IlmariKaronen: I agree that linear scaling doesn't fix the bias problems, but I think you may have gotten the definition of n mixed up. As I understand it, in this answer, n is the word list size. – user2357112 May 21 at 22:58
• @user2357112: Oops, you're right. I originally had "the range of possible random numbers" instead of "n", but that went over the comment character limit, and I apparently didn't read the answer carefully enough while trying to borrow notation to condense my comment. – Ilmari Karonen May 22 at 7:14
• If you have an rng that returns a number out of $k$ choices, and you want to choose among n choices, define $m$=largest multiple of $n$ $\leq k$. You can keep anything $\leq m$. Anything larger than $m$, instead of discarding, you can combine with other results. If you go over $m$ $j$ times, you can repeat the process with $(k-m)^j$ instead of $k$. – Acccumulation May 22 at 17:33

Ajedi32's answer is a great one. I wanted to emphasize one detail which may help answer your question better. The key to secure password generation is to ensure that your password is unpredictable. Not "random." The idea of random comes later. The goal is unpredictable. If you think about it, the most secure password in existence is not a random one, it's whatever the last password the attacker would guess is. Its the one they couldn't predict.

Now, in practice, there's a cat and mouse game going on here. If you try to come up with the most unpredictable password, they'll try to predict how you generate passwords. This is why passwords like qazxswedc appear random, but once they figure out what you were doing to generate the password, they'll break it easy.

This is where randomness finally comes in. For modern cryptography, we strive to use numbers that are not just unpredictable to the attacker, but unpredictable to anyone, including yourself! Random numbers are numbers that literally cannot be predicted in any way. You can only know what numbers got chosen if you were watching when the numbers were generated. Randomness means you can make mathematical statements about how hard it is to predict a password, because not even you, yourself, were in control of the generation.

For thousands of years, dice have been a "standard" source of random numbers. There are plenty of others (I Ching divination, for instance, traditionally used a bundle of yarrow sticks), but dice have persisted for a long time. If cast properly (no helicoptering!), they are sufficiently good random number sources because the bouncing of the die is highly chaotic and unpredictable. You would need telekenesis to affect the results (think Star Wars: The Phantom Menace).

If you are worried about loaded dice, as mentioned by some in the comments, you can actually do statistical analysis to determine how many bits of entropy per roll you can actually rely on. Password generation is less sensitive to loaded dice than casinos are (you can always make extra rolls, multiplying the number of possibilities. Because casinos dole out cash, they don't get to multiply each round, they have to add. This makes them more sensitive).

So now we can get closer to your question, because we understand what you are trying to accomplish. Simulating the dice actually doesn't work as well as you might think, because the simulation will do the same thing every time unless you have a source of randomness built into the sim, which kind of defeats the point.

The question is: what random source can you trust? This is where you have to understand your threat model. What can your attacker do? Can your attacker read your keystrokes? If so, you're in trouble because you're going to have to type the password in. So, practically speaking, we can assume that the attacker does not have enough control over your machine to be able to read the keystrokes.

You can keep working from there. My guess is that your threat model assumes that your computer is pristine, in which case you can rely on time-tested sources of entropy, like /dev/random. In this case, the best answer is to draw from that source and use it directly (no dice simulation required).

If you are more concerned with security, you can look at other aspects. Some algorithms have trouble with side channel attacks that let an attacker peer into their state in some specialized circumstances, so you might harden your algorithm against those. You might decide that you don't trust the normal sources of entropy on a computer (such as time between keystrokes and network activity), so you might invest in a hardware source of randomness (often built around noise in a resistor network).

But no matter where you go with it, remember that the key is to be unpredictable, and the standard way to make sure your opponent can't predict you is to be so random that you can't predict yourself.

A random number generator is considered 'pseudo random', it is not truly random as it is calculated mathematically. Dice are considered truly random, though I suppose you could argue that physics is no different...

By simulating dice rolling programmatically, you are removing the true randomness that is required by diceware. Thus your confusion between simulated dice and selecting a random word, both are pseudo random.