Generating random bits, passwords, recovery phrases and Bitcoin private keys / addresses (including QR codes) from text seed and salt.
Switch branches/tags
Nothing to show
Clone or download

README.md

Krypta

Generating random bits, passwords, recovery phrases and Bitcoin private keys / addresses (including QR codes) from text seed and salt. Deliberately implemented in single file pure LuaJIT (including crypto routines and hashing functions) without any external dependencies. This is useful for generating passwords / private keys etc for the most important stuff you have. This software is ugly, not user friendly and not meant for computer illiterate. If you don't understand what is written in this document, then Krypta is very probably not for you and using it might be dangerous.

Run it without arguments to see the basic explanation of options.

Krypta is a less traditional way to keep your important passwords / codes / wordlists safe. Extremely important things. Like the private keys from your 100 BTC Bitcoin address. Instead of keeping this info in the physical safe or hardware device (e.g. Trezor), you have to remember one long super-secret passphrase and all your other secret info is derived from this passphrase using this script and your notes which you don't have to keep especially secret.

You might think this sounds dangerously similar to the infamous "memory wallets" but bear with me.

When you start Krypta, you enter your secret passphrase which you have to remember exactly and never forget. This passphrase should have sufficient entropy to generate 256 bits checksum and not be something that can be found using brute force or dictionary attacks. Note that this definition if rather vague and it's not easy to evaluate the suitability of any given passphrase. But it's very very important to choose something that cannot be easily guessed / cracked (and, again, "easily" is very vague term here). One acceptable way MIGHT BE for example to take first 50 characters from the middle of your favorite song, for example "NoStopSignsSpeedLimitNobodysGonnaSlowMeDownLikeAWh" (from "Highway to Hell"). In this specific example, note that 50 ASCII characters are still not enough for full 256 bits of entropy and that you have to be sure to remember whether you used "NobodysGonna...", "NobodySGonna..." or "NobodyIsGonna...". This is not an easy decision and it cannot be underestimated!

The security of your passphrase is further increased by optional Salt, which is another piece of information that pertains SPECIFICALLY TO YOU, e.g. your e-mail or your phone number or some important date. This information is not secure by itself (at all) but when Krypta combines it with your passphrase, it increases its security significantly (evil people can no longer perform large-scale dictionary and brute-force attacks hoping that they will discover some random person's BTC private key).

The Passphrase and Salt are then used to generate your 256-bit Master key using a hash function. First, SHA256 hash is calculated from Passphrase and Salt and the resulting 256 bits (still not the Master key) are used as a seed for a special generator function that calculates the Master key. This function is specifically designed to take a long time to run. You can select the difficulty of this generator function from 1 to 31, where 1 takes a fraction of second on average computer and each subsequent difficulty takes approximately twice as long (the max difficulty takes many years on current PC). You should select as high difficulty as possible for your computer because it makes any bruteforcing / dictionary attacks much, much harder if the attacker can only try 1 combination in 5 seconds instead in 1 million combinations in 1 second.

The Master key is generated by running a 32 bit XorShift pseudorandom number generator with 128 state bits, clocked by 4 sequentially linked 32bit linear feedback shift registers which cause "skipping" of approximately every 16th PRNG value, making the generator less susceptible to predictive analysis and parallel (multi-CPU) algorithms. Both PRNG and LFSR registers are seeded with the original SHA256 hash (128 bits for PRNG, 4 x 32 bits for LFSRs) and then 32 bit numbers are generated (lots and lots of them) until some specific math conditions are met (many, many times in sequence, depending on the selected Difficulty). The Master key is then taken from 256 PRNG values that immediately follow (one bit from each). Because the PRNG has a period of 2^128 - 1 and each of the 4 LFSRs has a period of 2^32 - 1, the generator's period is exactly (2^32 − 1)^4 × (2^128 − 1), which is a litlle bit under 2^256.

So, the resulting 256 bit Master key is uniquely defined by your Passphrase, your Salt and your Difficulty. Krypta will never actually show you your Master key (although you can see its 12-bit checksum) but it's used to calculate all other keys / passwords that you need. After Krypta takes a bit of time to calculate your Master key (which SHOULD take a while, using high Difficulty), you can then (almost instantly) derive any quantity of secret data from the combination of this Master key and any textual Index (explained below).

For any Index that you enter, Krypta will immediately show you things like password, Bitcoin private key, BIP39 word sequence and other security data you might need to generate. These are different for each Index and cannot be traced back to your Master key, Index or Passphrase. Some examples of Indexes: "BTCColdStorage", "Facebook", "Mycelium" etc...

For each Index, you get full set of security data, e.g. long password, short password, uncompressed BTC private key, compressed private key, long hex number, BIP39 word sequence, etc... To prevent clutter, you can add a Prefix to your Index (all Prefixes are displayed after you enter any non-prefixed Index). For example entering the Index "btcu:ColdStorage" is the same thing as entering just "ColdStorage" and then looking for the line that has prefix "btcu:" (uncompressed BTC key). Because Bitcoin QR codes take lots of screen space, they are displayed only when you enter specific prefix ("btcu:" or "btcc:").

In addition, all Master key / Index combinations generate two "Check words", and all Master key / Prefix / Index combinations generate three "Check words". You can use these as a checksum of sorts.

Note that different Prefixes for the same Index are intentionally closely related to each other! E.g. whoever has the pwd40 password for index XYZ can easily deduce the pwd15 password or the BIP39 wordlist for the same Index. You are not supposed to use two prefixes of the same Index for two different purposes!

At this time, you might be overwhelmed by all this information and you might think that you can never remember all of this. But you don't have to!

The only thing you absolutely, positively have to remember, is your Passphrase. Everything else, i.e. Salt, Difficulty, Master key checksum, Indexes, Prefixes, Check words, can be stored in a text file which you don't have to be extremely paranoid about (of course it IS better if no one else sees it).

So, for example, you can have the following in your "not so secret" file (note that this is just a normal text file in any format, meant to be read by human, not by Krypta or any other software):

passphrase hint: 50 letters from second verse of THAT song, in CamelCase.
difficulty: 8
salt: satan@hell.org
checksum: 0x89A
Main BTC Cold storage: btcc:BTCcold, checkwords "leader author tunnel"
Facebook password: pwd40:Facebook, checkwords "penalty party ritual"
Mycelium wordlist: wrd24:Mycelium, checkwords "enlist enjoy midnight"

IMPORTANT: Do you see something wrong with this? The Passphrase hint in this specific example is UNSAFE and makes you much easier target for someone who sees this hint! Someone can quite easily write a script that downloads song lyrics from some online database, converts the second verse to CamelCase, feeds it to Krypta and repeats this for all existing songs until he finds a Master key with checksum 0x89A, at which point you are completely screwed and all your passwords are compromised. It's all about balance of security and ease of remembering. Do your homework.

You can keep copies of this file in Dropbox, Google Drive, Google Keep and/or your desk drawer. Don't forget to update all copies when you update the file (e.g. add new Indexes). The Check words written down like this are a good way to immediately see if you entered something wrong somewhere. Check words, Prefixes and Indexes are totally safe to be made public and cannot be traced back to your Master key.

You can also use some of this data as a command line options to Krypta (and call it from your Bash script) or enter them directly into Krypta source code (have a look at the first few lines of code). Of course having your Difficulty or Salt in a Bash script alongside Krypta decreases your security a little bit more.

Practical security considerations:

  • If you forget/lose your Passphrase, Salt, Difficulty or relevant Index(es), you are doomed and cannot recover your secure data.
  • If someone guesses and/or steals your Passphrase, Salt, Difficulty and Index(es), you are doomed because he can see your secure data.
  • If you have keylogger in the PC you use to run Krypta, you are very probably doomed.
  • If you have a virus that can see what happens in your PCs memory, you are very probably doomed.
  • Your strings (e.g. Passphrase, Indexes) are not sanitized / converted in any way. They are just binary data for Krypta. If you use non-ASCII characters in them (e.g. diacritics), be very sure that you know their encoding and are able to re-create it e.g. in 5 years, when accessing your secret data.

It's best to run Krypta on a special computer (e.g. old laptop, Raspberry Pi...) with minimal Linux installation and no Internet connection. That's why Krypta runs in text mode, requires only minimal LuaJIT (no dependency on any libraries / apps) and is self-contained in a single script file. After using Krypta, you should immediately shut down / reboot that computer.