You are reading content from Scuttlebutt
@kas %AzQDjYgtLuMPU/sLXAdkFDpkM2XmawIMOMlfhBwsQjw=.sha256

SSB key #recovery — a suggestion

I have just installed the latest #ManyVerse, and to my delight it is now possible to backup the key. However, the user experience when doing so was far from delightful: I missed a word when writing down the 48 words, and I forgot a single line with words and mispelled a word when trying to confirm that I had actually written down all of the words. And I found it tedious to tap in the words on my phone without the help of the usual word suggestions. Imagine if my English were poorer than it is…

To remedy the situation, I would like to suggest a method that reduces the necessary number of words to 25 (which is still a lot, I think) and is able to complete the correct word when just 3 characters from every word that is rung in.

To reduce the number of words from 48 to 25, we make use of the fact that the thing we call the private key is actually 32 bytes of random data + the 32 bytes public key derived from that noise. Altogether 64 bytes.

To be able to complete the words, we use EFF's short word list with words that have unique three-character prefixes: 1296 words.

So what we do is:

  • Backup
    1. Take the first 32 bytes of the private key.
    2. Encode these 32 bytes to ‘Base1296’, using EFF's wordlist as ‘digits‘.
  • Restore
    1. Decode the Base1296 passphrase to an array of 32 bytes.
    2. Calculate the ‘full’ private key from these 32 bytes.

Proof of concept

Let's say the user @fake has these keys:

  • Private key: mc9Apn3jiKbrqnivbzCW9EkDCXmwf+LLhsU0RMue4DJ9ooSQDBWImC0I7491D8psie61Ngsc5+CjvjpOUWuA4A==.ed25519
  • Public key: faKEkAwViJgtCO+PdQ/KbInutTYLHOfgo746TlFrgOA=.ed25519

Here we first generate the backup phrase, then recombine them to get the original keys:

$ # first we generate the backup phrase
$ secret2words.py mc9Apn3jiKbrqnivbzCW9EkDCXmwf+LLhsU0RMue4DJ9ooSQDBWImC0I7491D8psie61Ngsc5+CjvjpOUWuA4A==.ed25519
almanac osmosis sugar helmet atom
unjustly tidbit romancer occupation wifeless
vulnerable acrobat tastebud widow cuddly
nullify juggle unpaved hugeness elk
enigmatic listless length saltshaker egomaniac
$ # then we recreate the original keys from the backup
$ secret2words.py | words2secret.py
Private key: mc9Apn3jiKbrqnivbzCW9EkDCXmwf+LLhsU0RMue4DJ9ooSQDBWImC0I7491D8psie61Ngsc5+CjvjpOUWuA4A==.ed25519
 Public key: faKEkAwViJgtCO+PdQ/KbInutTYLHOfgo746TlFrgOA=.ed25519

Q.E.D.

The backup words may look unwieldy, but remember that as soon as the app sees alm it knows that the word is almanac and can complete it on behalf of the user. Same procedure for all the words.


Download

📎 secret2words.py
📎 words2secret.py

NB: You will need the nacl module for the recovery part. The scripts are simple proofs of concept and doesn't really have error checking or anything fancy.


See also

User has not chosen to be hosted publicly
@kas %8/G713hO3ML5UpRbzhVCa9Mhx7TUCBeQwfSKenKdZRo=.sha256

I think I learned about it back in 2018 when I wrote a python script to generate vanity IDs, which was really just a rewrite of a similar vanity address generator I'd written for the NXT crypto currency (now ARDOR), that uses curve25519 rather than ed25519.

I believe that the idea of concatenating the private key proper and the public key into a so called private key, is so that you don't have to calculate the public key repeatedly. Instead you just separate the ‘private key’ in two halves, and there you have it: a 256 bits private key proper, which is really just 256 bits of entropy, and an equally sized public key that is calculated using elliptic curve maths.

I can't be arsed to find the posts now, but I know I have written about it several times before when the talks have been about backup of ~/.ssb/secret file: using Samir's Secret Sharing Scheme (is that what it's called?) to backup just 32 bytes is much more convenient than backing up 64 bytes or more.

The concept is being used in ssb-{export,import,vanitygen} from ssb-utils from your's truly: https://github.com/kseistrup/ssb-utils (hopelessly unmaintained and outdated, so take it as a proof of concept only).

@kas %ZFuLpeRHMc9WfvQ+IG/fB53npPdDZkuNv1ULnBkGQeg=.sha256

Turned out I could be arsed a little. Here are a couple of posts that describe the private/public key anatomy:

@andrestaltz %IJ878tFo3pl0My5/zi1ebHpiJKDPo8l+2WcjTPtFkCM=.sha256

@kas Thanks for this. I just published ssb-keys-mnemonic@0.3.0 that requires only 24 words, and plan to use this in Manyverse ASAP.

@kas %5IRZmQmaF22EuFSHvXfziPsYlniBlHSWdO5/YCaDFE0=.sha256

@andrestaltz

Those were good news! 🙏

User has not chosen to be hosted publicly
@kas %YQVmKRNpszHqFfsXMLkEE0Nzin7ZxhsAUc91+plaT+A=.sha256

@rainbowmoon

It makes sense, but I don't know how easy is will be.

$ rexx haiku.rexx
Damp, silver, even,
The monk stinks. Gichin declines,
Enchanting, shining.

😸

@andrestaltz %k3Snqixpn/55mncPkT6pRrmUclegyo/ykComRXDu5XI=.sha256

@月光虹 That would be awesome, but it's huge challenge because you have to balance the combinatorics (you want there to be a huge amount of valid poems so that the average length of the poem is short, otherwise the poems would get huge) and aesthetics (the poems have to be "good"). I think if you (or someone) builds this, it would be useful as a standalone library (like bip39 for node.js is generic for any purpose), not SSB specific.

@Daan Patchwork %68Ct5pCrGSmwwW/RhCYSu5FkeAhiNftFP09/iDx47G4=.sha256

@andrestaltz UI-wise, if there'd be a way to coax the underlying OS into only giving typing suggestions from the right vocabulary, that would be super helpful too I guess. Not sure if react(native) or android/iOS expose that sort of thing of course.

@Anders %M0rMnFma5OmM6JISmgEg/TrSuGMkfGNk1CJB01cNV4A=.sha256
Voted [@kas](@RuNxm8SRujPcJx6GjtTQHp6hprAFv5voEkcvoAkB8Pk=.ed25519) Thanks for th
@Fred %q75eJll5pyKmU5JOAEjYyiKTwS7kF6yYL7aKmulXHcw=.sha256

Being able to backup/restore our key in human readable way is important for me. It is better to write down a word list than an scrumbled hexadecimal string...
For my keys, I like to use diceware as salt/pepper #duniterpy (base58) key generator. Converted it in base64 to be used in SSB.

@andrestaltz
How diceware differ from BIP39 mnemonic? Do you think manyverse can generate french words?

@andrestaltz %ChqqTIhq9R8yJhB0lh4tN2wKfMgLRboE96qc6prgT/8=.sha256

@Fred BIP39 supports multiple languages (currently Chinese, French, Italian, Japanese, Korean, Spanish), so it should theoretically be possible to support that in Manyverse, but currently it's not built in. I think the biggest challenge for that is the size. Each language adds a large file as a runtime dependency, so if there are ~30 languages, it will be heavy. But this kind of stuff is up for consideration, obviously.

Join Scuttlebutt now