[dup-mnemonic] cli mnemotic passphrase generator

Ça me démangeais, alors j’ai codé un utilitaire en ligne de commande permettant de générer des passphrases mnemotic :

Utilisation sur debian x86 :

$ wget  https://git.duniter.org/tools/dup-mnemonic-rs/-/jobs/35241/artifacts/file/package/dup-mnemotic-0.1.0-linux-x64.deb
$ sudo dpkg -i dup-mnemotic-0.1.0-linux-x64.deb
$ dup-mnemonic -l fr -w 9 -o monfichier.txt
$ cat monfichier.txt
narquois horde estrade banlieue vigueur poumon subvenir entier chercher

C’est internationalisé, la liste des langues supportées est indiquée dans le README.

Cela m’a demandé environ 4h de travail, si cet outils peut vous servir, n’hésitez pas a me faire un dons en G1 sur la clé D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx :slight_smile:

Les paquets debian pour architecture x86 et armv8 sont disponibles sur la page releases du projet :

7 Likes

:heart: MERCI

Je n’ai pas pu encore essayer à cause d’un soucis de paquet deb.

Je n’ai pas de armv8 pour tester l’autre release.
J’utilise pluto armv7 (Rpi3B+) et armv6 (RpiZero)

Ensuite on se sert de ces 9 mots pour faire des clefs .ed25519 ( Définir un format sécurisé pour les trousseaux de clés Ğ1) ?

Avec python, on fait…

from sys import argv
from duniterpy.key import SigningKey

# path to save to
path = "PubSec.dunikey"

key = SigningKey.from_credentials(argv[1], argv[2], None)
key.save_pubsec_file(path)
print(
    "Authentication file '", path, "' generated and stored in current\
folder for following public key:",
    key.pubkey,
)

Oui je viens de voir ça, je m’étais pourtant fait chi** a faire un paquet de test avant, j’ai répuloader le paquet tu peut réésayer @Frederic_Renault ?

Ok dans ce cas il te faut compiler toi même car je n’ai pas d’armv7 (ni v6), heureusement c’est infiniment plus simple qu’en C/C++, pas besoin de lib externes. Voici comment compiler :

Prérequis : le compilateur rust… et c’est tout ! S’installe en une seule commande :

curl https://sh.rustup.rs -sSf | sh -s -- -y

Choisi la réponse par défaut a toutes les questions.

Ensuite pour compiler :

git clone https://git.duniter.org/tools/dup-mnemonic-rs
cd dup-mnemonic-rs
cargo build --release

Le binaire final se nomme dup-mnemonic et il se trouve dans target/release/.

la compilation prendra plus de 5 min, heureusement tu n’a a le faire qu’une seule fois. Tu peut ensuite copier le fichier binaire dup-mnemonic sur n’importe-quelle machine de même architecture :slight_smile:

Le fichier binaire dup-mnemonic est un exécutable qui contiens tout, il n’a besoin de rien.

Oui je vais proposer une RFC. Je pense a qqch comme :
salt: “mnemotic” ++ sha256(mnemotic phrase)
password: mnemotic phrase

La doc de SigningKey.from_credentials doit indiquer quel argument correspond au salt et au password, si tel n’est pas le cas il faut ouvrir un ticket pour doc incomplete :wink:

1 Like

deb OK! Mais tu as nommé le package DEB ‹ dup-mnemotic-0.1.0-linux-x64.deb › et l’EXE ‹ dup-mnemonic › ça m’a planté en recopiant l’exemple que tu donnes (j’ai cru à un pb de PATH).

Donc x64 OK!

  • Tu conseilles d’utiliser « sha256(phrase) » comme salt et « phrase » comme password pour faire la dunikey?

  • Allez, je me lance sur le test RpiZero. Il faut une quantité de RAM minimum pour faire tourner l’algo?
    Je pars sur une base https://github.com/tomeshnet/prototype-cjdns-pi

1 Like

Bien vu c’est le nom du paquet deb qui est mauvais, le terme correct est bien mnemonic :slight_smile:

Pour le salt je propose plutôt: « mnemonic » ++ sha256(mnemonic phrase)

++ signifiant “concaténer”, pour ne pas le confondre avec l’addition.

Tout dépend des paramètres scrypt qu’on choisira pour les mnemonic, ça te parait déconnant d’exiger au moins 128 Mo par exemple ?

OK ++ = concaténer. Les mots de la phrase dans le login aussi?
Je trouve ça plus joli, mais la machine s’en fout, tu me diras…

En tout cas, hyper merci. Si c’est sécure et qu’au final l’utilisateur n’a que 9 mots à retenir c’est parfait !!!

Ah c’est la RAM que défini ce paramètre! Y’a 512Mo minimum sur les machines pas chères du début XXIe. On peut partir sur 128

1 Like

Rust sur Rpi3b+ raspbian stretch - S01-E01

J’ai laissé le terminal… en revenant dessus, la machine avait rebooté…
A cause du watchdog ou de l’install rust, je ne sais pas encore ?

Enfin, en reprenant, voila ce que j’ai

cargo build --release
error: no default toolchain configured

Bon je vois pourquoi j’ai rebooté…avant de relancer l’install

Cela signifie que l’installation a été interrompue de force en plein milieu, ce n’est pas bon :confused:

Tu peut essayer les deux commandes suivantes :

rustup install stable
rustup default stable

Si ça marche tant mieux, si ça ne marche pas alors il faudra reprendre l’install de rust de zéro.

L’install de rust ne fait jamais rebooter, la cause est ailleurs.

@Frederic_Renault si tu réinstalle tu peut ajouter l’option -y pour ne pas a voir a répondre aux questions :

curl https://sh.rustup.rs -sSf | sh -s -- -y

Houra, tout s’est bien passé, la compilation prend un bout de temps… J’ose pas imaginer sur RpiZero…
Mais je ne maitrise pas la sience du “cross compile”, alors je ferai ça patiemment…
Mais en fait, fabriquer ces clefs sera réservé aux terminaux “amd64” et “armv7” minimum :wink:
En attendant si tu veux ajouter au dépot la version armv7, je te l’envoi…

Je vais le publier dans mon flux ssb? Ces 3,4Mo me semblent important

1 Like

Je ne prend pas le binaire final, seulement le paquet debian, si tu veut le builder ça ce fait en une seule commande (il faut installer cargo-deb une fois au préalable).

Prérequis: installer cargo-deb (a ne faire qu’une seule fois) :

cargo install cargo-deb

Créer le paquet debian (a la racine du dépot git):

cargo deb --manifest-path "cli/Cargo.toml" --output "dup-mnemonic-0.1.0-linux-x64.deb"

@Frederic_Renault si tu fait ça dans le même repo ou tu a déjà compilé, cargo deb vas reprendre le binaire existant sans recompiler :wink:


Ça serai plus léger de publier le paquet debian car il est compressé :slight_smile:

Parfait, j’ai fait le package… C’est pas rapide… Mais ça a fonctionné…

dup-mnemonic-0.1.0-linux-armv7.deb se retrouve archivé dans ma chaine ssb publique à l’adresse de son sha256 &gEjDRqT7q3pO33dqBK+r38l/hUipZN+hI1lgNY03lwc=.sha256

{
  "key": "%NrOivKXWJLuOjWurV3S0AUK0u2g6xLJsLb0play/Ydg=.sha256",
  "value": {
    "previous": "%sIakTa2RdWWFY5WffPm8Xg2mjzwQi8ZJFaDSEBKHmAY=.sha256",
    "sequence": 214,
    "author": "@9BbJwPDjcyIqrOUPNn0nJZBduWdIrpMk3Cjz5MP361s=.ed25519",
    "timestamp": 1581909170891,
    "hash": "sha256",
    "content": {
      "type": "post",
      "text": "I am publishing some #rust code for #mnemonic #passphrase creation\nhttps://git.duniter.org/tools/dup-mnemonic-rs/ [dup-mnemonic-0.1.0-linux-armv7.deb](&gEjDRqT7q3pO33dqBK+r38l/hUipZN+hI1lgNY03lwc=.sha256) \n\n**\"Mnemonic code for generating deterministic keys\" based on #bip39**\nhttps://iancoleman.io/bip39/\nhttps://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki\nIs it similar to #manyverse backup 42 words passphrase generator?\n\nI am using it to generate #duniter and ~/.ssb/secret .ed25519 keys credentials for #g1 wallet and #ssb-accounting\n\nAttached armv7 deb package (for raspbian on Rpi3B+)\n [dup-mnemonic-0.1.0-linux-armv7.deb](&gEjDRqT7q3pO33dqBK+r38l/hUipZN+hI1lgNY03lwc=.sha256) ",
      "mentions": [
        {
          "link": "#rust"
        },
        {
          "link": "#mnemonic"
        },
        {
          "link": "#passphrase"
        },
        {
          "link": "&gEjDRqT7q3pO33dqBK+r38l/hUipZN+hI1lgNY03lwc=.sha256",
          "name": "dup-mnemonic-0.1.0-linux-armv7.deb",
          "type": "application/x-debian-package",
          "size": 304044
        },
        {
          "link": "#bip39"
        },
        {
          "link": "#manyverse"
        },
        {
          "link": "#duniter"
        },
        {
          "link": "#g1"
        },
        {
          "link": "#ssb-accounting"
        },
        {
          "link": "&gEjDRqT7q3pO33dqBK+r38l/hUipZN+hI1lgNY03lwc=.sha256",
          "name": "dup-mnemonic-0.1.0-linux-armv7.deb",
          "type": "application/x-debian-package",
          "size": 304044
        }
      ]
    },
    "signature": "evadt8xufZz/M71v1nEVPmqUwSA5VFBXbc9SVnYQJp91vL04XXaVTUORir/xI1uqEL/P/vfv/Zvz+xLixt8VAQ==.sig.ed25519"
  },
  "timestamp": 1581909171340,
  "rts": 1581909170891
}

Je me disais, ça vaut le coup de signaler cet outil là, dans la section Rust de BIP39 :wink:

1 Like

Non car ce n’est pas une impl de bip39, j’ai repris uniquement la partie génération de la passphrase, il n’y a pas toute la partie générations des hiérarchical keys de bitcoin, or ça fait parti intégrante des spec de bip39, ce serait un mensonge de citer mon dev la dedans.

Alors que je comprenne bien
dup-mnemonic génère une suite de mots avec assez d’entropie pour ensuite (avec BIP39) fabriquer une seed qui sera (associée à ses paramètres de génération, taille mémoire et un autre).
Pour moi SigningKey.from_credentials transforme en paire de clefs ed25519 (pub/sec il faut les 2 parce qu’on chiffre ou on signe) compatible dunikey et scuttlebutt dans mon cas.

En fait, à priori, dup-mnemonic est mieux que le diceware utilisé actuellement… (il y des accents déjà)
Enfin, je réfléchissais à ta proposition

Le sha rends la saisie par l’utilisateur impossible (ce qui peut être bien pour un portefeuille)
Que se passe-t-il si je crée à partir de la passphrase de 9 mots, des comptes avec 3 mots login, 6 mots password? Réservés à un usage humain…

En fait, je crois qu’il me faut 2 classes de clefs, une pour humain (peu de mots) qui signe celles des machines (sha dedans), et les laisse opéré par un tiers (node ipfs)… je sens qu’il va falloir utiliser scuttlebut pour s’envoyer les trucs à signer…

bref, voila où j’en suis de ma réflexion sur les clefs… Et La clef qui les contient toutes (celle de notre compte membre me semble toute désignée)

Pas tout a fait, BIP39 est une spec qui décrit l’utilisation des mnemotic pour les trousseaux de clés bitcoin, qui ne sont pas en ed25519, bitcoin utilise un autre algo (secp256k1), avec des seed basées sur 64 octets, ils utilisent également une autre KDF (PBKDF2, l’ancètre de “scrypt” en quelque sorte).

BIP39 est juste une spec, pas un outils, ça ne fait rien,c’est juste une convention qui décrit :

  1. Comment générer une passphrase mnemonic
  2. Comment générer un trousseau de clés bitcoin a partir de cette passphrase mnemonic

Dans le programme dup-mnemonic j’ai uniquement implémenté le point 1.
A nous de définir ensemble le point 2. pour nos algos de crypto. (Après quoi je pourrais l’implémenter)

Le whitepaper de scrypt indique que le salt doit faire a minima 128bits (16 octets) https://eprint.iacr.org/2015/387.pdf (voir section 3).

Donc oui pourquoi pas, a condition de placer a minima 6 mots dans le salt (et tout le reste dans le password).
Il faut penser aux langues de type Japonais/Coréen/Chinois, où un mot est souvent un seul caractère qui ne pèse que 3 octets en utf-8 (d’où 6 mots au moins).

Je m’imprègne de l’état de l’art…
https://crackstation.net/hashing-security.htm

1 Like

Oui voila c’est déjà ce que fait script :slight_smile:

Et pour la génération aléatoire sécurisée c’est évidemment déjà géré en Rust via ring : https://docs.rs/ring/0.16.9/ring/rand/index.html

Un message a été fusionné à un sujet existant : Votez pour les propositions de sécurité de la Ǧ1

Oui c’est ça :slight_smile: