Polkadot.js multilang mnemonic?

Attention, à l’attention des codeurs python :bangbang:

En travaillant sur la création de compte avec mnémonique en langue non anglaise, avec le module keypair du client python substrateinterface j’obtenais toujours la même adresse entre un mnémonique français et son équivalent en anglais (équivalent selon notre bidouille). Ce qui ne devrait pas être selon le protocole bip39…

J’ai donc découvert avec stupeur que le module keypair de substrateinterface fait aussi et déjà ce que nous avons décidé de faire, en utilisant la lib rust compilée pour python bip39.

Pour générer l’adresse, la seed n’est pas générée depuis le texte du mnémonique, mais depuis l’entropie (l’équivalent des mots en numéro de 0 à 2048), sans mot de passe. Ils appellent la seed “mini secret”.

.venv/lib/python3.7/site-packages/substrateinterface/keypair.py:211

seed_array = bip39_to_mini_secret(mnemonic, "", language_code)

Exemple avec deux mnémoniques équivalents (les mots ont la même valeur dans les wordlists) :

import bip39
bip39.bip39_to_mini_secret('foil apple tribe renew cry risk same trumpet long destroy glare analyst', '', 'en')
[175, 53, 82, 102, 183, 63, 22, 231, 16, 61, 6, 187, 2, 62, 72, 129, 168, 208, 39, 49, 95, 85, 146, 39, 54, 163, 219, 23, 74, 44, 224, 100]
bip39.bip39_to_mini_secret('esquiver alpaga tasse pénurie coiffer pixel potager teneur intense cubique farceur aider', '', 'fr')
[175, 53, 82, 102, 183, 63, 22, 231, 16, 61, 6, 187, 2, 62, 72, 129, 168, 208, 39, 49, 95, 85, 146, 39, 54, 163, 219, 23, 74, 44, 224, 100]

Je me demande donc si c’est une liberté du client python ou aussi des développeurs qui utilisent la lib rust bip39 ?

1 Like

Ce comportement semble spécifique à cette fonction bip39_to_mini_secret, mais elle ne semble pas faite pour générer la seed, si ?

bip39_to_seed semble plus indiquée, et utiliser la suite de mots.

Serait-il utile d’avoir une bibliothèque à nous implémentant la bidouille, pour assurer une bonne compatibilité ? Étant donnée la simplicité de l’implémentation (un petit wrapper autour d’une lib bip39 quelconque) je me dis que c’est plus simple que chaque langage ait la sienne (plutôt qu’un unique binding Rust qui va compliquer la stack de tout le monde).

Duniter-connect génère la même adresse que le client python substrateinterface :

foil apple tribe renew cry risk same trumpet long destroy glare analyst

V1: LFVtJvBt6dp1vPuy6zejFqCF9Uu1VoGRpLnqXihN17f
V2: 5CBAsoVagE4HpFTBG6KPmdFWBJkBZcnwwuewU1fyb9TscMbH

Donc utilise le mini-secret issu de l’entropie au lieu de la phrase mnémonique… :scream:

Je pense qu’il faut que l’on soit sûr de la seed générée par nos clients pour assurer une compatibilité. Et comprendre pourquoi la communauté substrate et son client javascript utilise le mini-secret pour les SR25519.

1 Like

J’avais vu hier que la lib Rust sp-core utilise les “mini secrets” de Schnorrkel pour générer la seed. Je ne sais pas si ce sont les mêmes, si c’est standardisé.

Dans Schnorrkel, la seed fait 32 octets, la clé privée 64 (32 de clé et 32 de nonce).

En fait c’est vraiment la jungle : des standards de fait, des bibliothèques de crypto écrites par une seule personne avec des commentaires dans lesquels ils se plaignent que tout ça n’a aucun sens, le code pour seule documentation… et tout un écosystème conçu “par des experts” qui repose dessus.

1 Like

Ok, bah dans ce cas walou, rfc bidouille let’s gooo
Puis on mettrà à disposition des phrases de restauration converti pour exporter vers tel ou tel système.

1 Like

Tout est expliqué dans l’encart rouge et confirme ma découverte.

Not all wallets use the same algorithm to convert from mnemonic phrase to private key

Subkey and Polkadot-JS based wallets use the BIP39 dictionary for mnemonic generation, but use the entropy byte array to generate the private key, while full BIP39 wallets (like Ledger) use 2048 rounds of PBKDF2 on the mnemonic. The same mnemonic may generate different private keys on other wallets due to the various cryptographic algorithms used. See Substrate BIP39 Repo for more information.

3 Likes

Ok. Merci d’avoir creusé, ça confirme mon intuition :

Donc il faudra être clair sur l’algo utilisé pour générer les seed et la dérivation des clés. Comme “c’est la jungle”, autant adopter ce qui nous paraît le plus sain. Et pour moi c’est clair que les nombres c’est pour l’ordi et les mots pour l’humain. Ça n’a aucun sens de faire passer du langage naturel en utf8 (les deux étant faits pour l’humain) dans une fonction de hashage pour retrouver un nombre à destination de l’ordi. Autant utiliser directement le nombre.

Et comme il s’agit de nombre entiers naturels plus grands que ce que gère normalement un ordinateur, il faut être clair sur la représentation en byte array qui sera manipulée sur la machine pour pas laisser des ambiguïtés comme l’endianness.

2 Likes

Si c’est la jungle c’est peut être parce que BIP39 a fait n’imp sur ce coup là et que tout le monde préfère faire autrement.

3 Likes