为什么 btclib.mnemonic_from_raw_entropy 声称我传递给它的熵少于 128 位?
Why does btclib.mnemonic_from_raw_entropy claim I passed it less than 128 bits of entropy?
我正在做的是生成 'dummy' 个钱包,从原始熵中检索助记密码和钱包,这是使用 secrets.randbits(128)
生成的——生成有效的 bip39 密钥对。
我得到的错误是这样的:
ValueError: 125 bits provided; expected: (128, 160, 192, 224, 256)
它可以在 122 到 127 位之间变化。它通常对连续多个错误表示相同数量的位,即 125 bits provided
3 次,然后切换到 122 bits provided
2 次,然后在第 6 次尝试时工作。
我正在使用 btclib – 完整的功能是
def create_passphrase():
memo = bip39.mnemonic_from_raw_entropy(secrets.randbits(128) , 'en')
print(mnemo)
return mnemo
抱歉,如果我遗漏了一些明显的东西。
这是 btclib 中的错误。
函数bip39.mnemonic_from_raw_entropy()
calls bip39.entropy_from_raw_entropy()
, which calls entropy.str_from_entropy()
.
当使用整数作为其 entr
参数调用 entropy.str_from_entropy()
时,它会尝试将该整数转换为表示位的字符串,here:
entr = bin(entr)[2:] # remove '0b'
这是错误的:任何传入的整数,如果它真的是随机的,只有大约一半的时间被转换为预期的位数。要了解原因,请考虑这些随机数据示例(为简单起见,我将使用 8 位而不是 128 位,但原理是相同的):
>>> bin(0b10001011)[2:]
'10001011'
>>> bin(0b01010110)[2:]
'1010110'
>>> bin(0b00111011)[2:]
'111011'
如您所见,btclib 使用的转换方法会去除所有前导零,从而导致生成长度错误的字符串。
解决方法可能是自己将 secrets.randbits(128)
的结果转换为适当的字符串,然后传递:
def create_passphrase(bits=128):
bitstring = f'{secrets.randbits(bits):0{bits}b}'
memo = bip39.mnemonic_from_raw_entropy(bitstring , 'en')
print(memo)
return memo
…假设 btclib 中没有其他错误等着咬你。
感谢您的报告。
丢失前导零符合 Electrum entropy->mnemonic 行为,但导致了 BIP39 的错误。
现在在 master 分支上修复了:
https://github.com/dginst/btclib/commit/f0f802ef3e31ae74e84964f0ec04d1180f42da27
我正在做的是生成 'dummy' 个钱包,从原始熵中检索助记密码和钱包,这是使用 secrets.randbits(128)
生成的——生成有效的 bip39 密钥对。
我得到的错误是这样的:
ValueError: 125 bits provided; expected: (128, 160, 192, 224, 256)
它可以在 122 到 127 位之间变化。它通常对连续多个错误表示相同数量的位,即 125 bits provided
3 次,然后切换到 122 bits provided
2 次,然后在第 6 次尝试时工作。
我正在使用 btclib – 完整的功能是
def create_passphrase():
memo = bip39.mnemonic_from_raw_entropy(secrets.randbits(128) , 'en')
print(mnemo)
return mnemo
抱歉,如果我遗漏了一些明显的东西。
这是 btclib 中的错误。
函数bip39.mnemonic_from_raw_entropy()
calls bip39.entropy_from_raw_entropy()
, which calls entropy.str_from_entropy()
.
当使用整数作为其 entr
参数调用 entropy.str_from_entropy()
时,它会尝试将该整数转换为表示位的字符串,here:
entr = bin(entr)[2:] # remove '0b'
这是错误的:任何传入的整数,如果它真的是随机的,只有大约一半的时间被转换为预期的位数。要了解原因,请考虑这些随机数据示例(为简单起见,我将使用 8 位而不是 128 位,但原理是相同的):
>>> bin(0b10001011)[2:]
'10001011'
>>> bin(0b01010110)[2:]
'1010110'
>>> bin(0b00111011)[2:]
'111011'
如您所见,btclib 使用的转换方法会去除所有前导零,从而导致生成长度错误的字符串。
解决方法可能是自己将 secrets.randbits(128)
的结果转换为适当的字符串,然后传递:
def create_passphrase(bits=128):
bitstring = f'{secrets.randbits(bits):0{bits}b}'
memo = bip39.mnemonic_from_raw_entropy(bitstring , 'en')
print(memo)
return memo
…假设 btclib 中没有其他错误等着咬你。
感谢您的报告。
丢失前导零符合 Electrum entropy->mnemonic 行为,但导致了 BIP39 的错误。
现在在 master 分支上修复了: https://github.com/dginst/btclib/commit/f0f802ef3e31ae74e84964f0ec04d1180f42da27