Ce que je fais, c'est générer des portefeuilles «factices», en récupérant à la fois une phrase de passe mnémonique et un portefeuille de l'entropie brute, qui est générée à l'aide de secrets.randbits(128) - résultant en une paire de clés bip39 valide.

L'erreur que j'obtiens est dans ce sens:

ValueError: 125 bits provided; expected: (128, 160, 192, 224, 256)

Il peut varier de 122 à 127 bits. Il indique généralement la même quantité de bits pour plusieurs erreurs consécutives, c'est-à-dire 125 bits provided 3 fois, puis passe à 122 bits provided 2 fois, puis travaille au 6e essai.

J'utilise btclib - la fonction complète est

def create_passphrase():
    memo = bip39.mnemonic_from_raw_entropy(secrets.randbits(128) , 'en')

    print(mnemo) 
    return mnemo

Désolé si je manque quelque chose d'évident.

1
pep 1 17 mars 2019 à 22:54

2 réponses

Meilleure réponse

Il s'agit d'un bogue dans btclib.

La fonction bip39.mnemonic_from_raw_entropy() appelle bip39.entropy_from_raw_entropy(), qui appelle entropy.str_from_entropy().

Lorsque entropy.str_from_entropy() est appelé avec un entier comme argument entr, il tente de convertir cet entier en une chaîne représentant les bits, ici :

        entr = bin(entr)[2:] # remove '0b'

C'est cassé : tout entier transmis ne sera, s'il est vraiment aléatoire, converti qu'au nombre de bits attendus environ la moitié du temps. Pour voir pourquoi, considérons ces exemples de données aléatoires (j'utiliserai 8 bits plutôt que 128 pour des raisons de simplicité, mais le principe est le même):

>>> bin(0b10001011)[2:]
'10001011'
>>> bin(0b01010110)[2:]
'1010110'
>>> bin(0b00111011)[2:]
'111011'

Comme vous pouvez le voir, la méthode de conversion utilisée par btclib supprime tous les zéros non significatifs, ce qui entraîne la production d'une chaîne de longueur incorrecte.

Une solution de contournement peut consister à convertir vous-même le résultat de secrets.randbits(128) en une chaîne appropriée et à la transmettre :

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

… en supposant qu'il n'y ait pas d'autres bogues dans btclib qui attendent de vous mordre.

2
Zero Piraeus 17 mars 2019 à 23:24

Merci pour le rapport.

La perte de zéros non significatifs était conforme au comportement entropique>> mnémonique d'Electrum, mais a entraîné un bogue pour BIP39.

C'est corrigé maintenant sur la branche master : https://github.com/dginst/btclib/commit/f0f802ef3e31ae074e84964d