I have been analyzing the source code of a software, and I came across this encoding snippet, I would like to know if it's safe to encode an entropy source this way.

So the entropy source is a 132bit random source, in integer format, so the i is an integer containing 132bits of randomness:

def mnemonic_encode(self, i):
    n = len(self.wordlist)
    words = []
    while i:
        x = i%n
        i = i/n
    return ' '.join(words)

n is the length of a dictionary containing 2048 words and initially n=2048 So we are trying to convert that initial source of entropy into X number of words, and the remaining one is cut away.

So in our case of 132 bit input, it will be converted into 12 words log_2(2048)*12 = 132, if it were 133 bits, then I guess we would have 13 words, however the last word would have only 1 bit of entropy instead of 11.

Similarly it decodes the words like this:

def mnemonic_decode(self, seed):
    n = len(self.wordlist)
    words = seed.split()
    i = 0
    while words:
        w = words.pop()
        k = self.wordlist.index(w)
        i = i*n + k
    return i

And it should return the same i after decoding as the initial i was after encoding.

Now I have run this code in python, and from a programming standpoint it should be correct, however I want to know that from a cryptographical standpoint it's Ok too?

Source: https://github.com/spesmilo/electrum/blob/master/lib/mnemonic.py

  • 1
    $\begingroup$ In what way could it not be okay? $\endgroup$ – user253751 Jan 30 '17 at 22:32

If your concern is "losing information" (e.g., this is used to generate human-friendly passwords), this should be okay, as the encoding is injective — this follows already from the fact that it is invertible. (However, if the goal is to keep the numbers secret from someone getting their hands on the list of words, that is another matter. Note this method is not secure as an "encryption" scheme!)

Generally, injective functions preserve entropy. The proof is simple: Let $X\colon\Omega\to A$ be a discrete random variable and $f\colon A\to B$ an injective function. Then, the definition of entropy states: (with the convention $\log_20=0$) $$ H(f(X)) = \sum_{b\in B} -\Pr[f(X) = b]\cdot\log_2\Pr[f(X) = b] \text. $$ Since only the terms with $b\in f(A)$ contribute to the sum, and since each such $b$ has a unique preimage $a$ under $f$, we may rewrite this as $$ H(f(X)) = \sum_{a\in A} -\Pr[X=a]\cdot\log_2\Pr[X=a] \text, $$ which happens to be nothing but the entropy of $X$.

| improve this answer | |
  • $\begingroup$ It's not encryption, it's just encoding. Thanks for answer. $\endgroup$ – visitor0777 Feb 4 '17 at 0:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.