<p>you need to remove python binary denominator '0b' and then zero fill the binary representation of sha256 digest to 256bits --> then it works</p>



<pre><code>checksum = bin(sha256_entropy_int)[2:].zfill(256)[:checksum_bit_length]
</code></pre>

<p>also there is a reference <a href="https://github.com/trezor/python-mnemonic" rel="nofollow noreferrer">implementation</a> mentioned in the bip (must have missed it initially)</p>

CC BY-SA 4.0
2020-03-06T16:52:00.517Z
2020-03-06T16:52:00.517Z
scagbackbone
<p>Trying to convert hexadecimal string of entropy to seed sentence with the below snippet. Failing the first <a href="https://github.com/trezor/python-mnemonic/blob/master/vectors.json" rel="nofollow noreferrer">test</a> with 16 zero bytes. It seems that my function came to conclusion that checksum is '1011' yet it should by '0011' (by <a href="https://iancoleman.io/bip39/" rel="nofollow noreferrer">this</a> page for instance) therefore I do have a mistake in seed sentence where my last word is on index 13 (accuse) and correct word is on index 3 (about). <strong>What is broken in my function?</strong> Also, there is not much of an implementation details in bip39, if you know about some resources (not just core codebase) they'd be warmly welcome!</p>



<pre><code>import hashlib
import requests
import unicodedata

def get_word_list():
    url = "https://raw.githubusercontent.com/"
    uri = "bitcoin/bips/master/bip-0039/english.txt"
    return requests.get(url + uri).text.split()


def checksum_length(entropy_bits: int) -&gt; int:
    return int(entropy_bits / 32)


def mnemonic_from_entropy(entropy: str) -&gt; str:
    word_list = get_word_list()
    entropy_bits = len(entropy) * 4
    entropy_bytes = bytes.fromhex(entropy)
    print(entropy_bytes.hex())
    entropy_int = int.from_bytes(entropy_bytes, byteorder="big")
    sha256_entropy_bytes = hashlib.sha256(entropy_bytes).digest()
    sha256_entropy_int = int.from_bytes(sha256_entropy_bytes, "big")
    checksum_bit_length = checksum_length(entropy_bits=entropy_bits)
    checksum = bin(sha256_entropy_int)[2:2 + checksum_bit_length]
    entropy_checksum = bin(entropy_int)[2:] + checksum
    entropy_checksum = entropy_checksum.zfill(entropy_bits + checksum_bit_length)
    bin_indexes = re.findall("." * 11, entropy_checksum)
    indexes = [int(index, 2) for index in bin_indexes]
    mnemonic_lst = [word_list[index] for index in indexes]
    mnemonic_sentence = unicodedata.normalize("NFKD", " ".join(mnemonic_lst))
    return mnemonic_sentence

if __name__ == "__main__":
    mnemonic_from_entropy("00000000000000000000000000000000")


</code></pre>

CC BY-SA 4.0
2020-03-06T18:58:11.683Z
Your desired test vector can also be calculated as follows: **% echo 00000000000000000000000000000000 | bx mnemonic-new**
`abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about`
skaht
<python>
bip39 converting from entropy to seed failing tests with entropy "00000000000000000000000000000000"
scagbackbone
# bip39 converting from entropy to seed failing tests with entropy "00000000000000000000000000000000"

(Asked by: username_0 on 2020-03-06)

Trying to convert hexadecimal string of entropy to seed sentence with the below snippet. Failing the first [test](https://github.com/trezor/python-mnemonic/blob/master/vectors.json) with 16 zero bytes. It seems that my function came to conclusion that checksum is '1011' yet it should by '0011' (by [this](https://iancoleman.io/bip39/) page for instance) therefore I do have a mistake in seed sentence where my last word is on index 13 (accuse) and correct word is on index 3 (about). **What is broken in my function?** Also, there is not much of an implementation details in bip39, if you know about some resources (not just core codebase) they'd be warmly welcome!

```
import hashlib
import requests
import unicodedata

def get_word_list():
    url = "https://raw.githubusercontent.com/"
    uri = "bitcoin/bips/master/bip-0039/english.txt"
    return requests.get(url + uri).text.split()

def checksum_length(entropy_bits: int) -> int:
    return int(entropy_bits / 32)

def mnemonic_from_entropy(entropy: str) -> str:
    word_list = get_word_list()
    entropy_bits = len(entropy) * 4
    entropy_bytes = bytes.fromhex(entropy)
    print(entropy_bytes.hex())
    entropy_int = int.from_bytes(entropy_bytes, byteorder="big")
    sha256_entropy_bytes = hashlib.sha256(entropy_bytes).digest()
    sha256_entropy_int = int.from_bytes(sha256_entropy_bytes, "big")
    checksum_bit_length = checksum_length(entropy_bits=entropy_bits)
    checksum = bin(sha256_entropy_int)[2:2 + checksum_bit_length]
    entropy_checksum = bin(entropy_int)[2:] + checksum
    entropy_checksum = entropy_checksum.zfill(entropy_bits + checksum_bit_length)
    bin_indexes = re.findall("." * 11, entropy_checksum)
    indexes = [int(index, 2) for index in bin_indexes]
    mnemonic_lst = [word_list[index] for index in indexes]
    mnemonic_sentence = unicodedata.normalize("NFKD", " ".join(mnemonic_lst))
    return mnemonic_sentence

if __name__ == "__main__":
    mnemonic_from_entropy("00000000000000000000000000000000")

```

**Tags:** python

> **Comments:**
> **username_1**: Your desired test vector can also be calculated as follows: **% echo 00000000000000000000000000000000 | bx mnemonic-new** `abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about`  

---

## 1 answers

### Answer by username_0 on 2020-03-06. Score: 0 | Accepted answer

you need to remove python binary denominator '0b' and then zero fill the binary representation of sha256 digest to 256bits --> then it works

```
checksum = bin(sha256_entropy_int)[2:].zfill(256)[:checksum_bit_length]

```

also there is a reference [implementation](https://github.com/trezor/python-mnemonic) mentioned in the bip (must have missed it initially)


---

