Bitcoin private key encrypted with quantum generated random number

If you just want the code without the explanation, go down towards the bottom of the page.

QRNG Wallet is a bitcoin wallet private key generator that derives a key from a quantum generated random number. The generator will first encrypt user-entered data with a password in an AES file through conventional cryptographic procedures, and then recursively hash it with a quantum random number (QRNG) in a 256 iteration key stretching process. Future versions will extend the QRNG to the k arg of the elliptic curve function, which generates the public key.

The quantum number is generated from quantum computers from the Centre for Quantum Computation and Communication, at the Australian National University (ANU) (details at the bottom of this page.) This is currently done with a straightforward GET call to ANU, but in future versions it will be a derived from a combination of a QRNG from ANU, and a customised series of Hadamard gates and superposition collapses, created with IBM-Q, to produce a number which is not even known server side at the QRNG source.

Although it works (i.e. provides WIF keys derived from a quantum source that are recognised by the bitcoin network), the code has not undergone formal unit testing and should be regarded as a proof of concept only, for anything other than test transactions (i.e. less than $10).

A brief explanation of the theory follows. A longer and broader explanation of quantum processes and computation can be found here.

Background

Quantum random numbers are more secure than conventional random numbers. Conventional random numbers are actually not random at all in a strict sense: they are produced by algorithms that run in a precise deterministic way. If run infinitely, conventional RNG algorithms will actually produce an identical sequence of random numbers, in a repeating loop that goes on forever. If the algorithm is known, the end product can eventually be hacked by running the algorithm on all (or a very large set) of possible values. In fact, there are only a finite number of algorithm styles that can be used, and a much smaller number that actually are used when random numbers are needed in cryptography. This  is all still pretty secure: this kind of security has been widely used in finance, in espionage, and in protecting military secrets, and is computationally difficult to hack.

But it is now widely recognised that quantum generated random numbers (QRNGs) are cryptographically superior to conventional RNGs. QRNGs are also known as true random numbers, as they are not derived from classical, deterministic mathematics and physics at all, but from the mathematics and physics of the quantum world which operates in an entirely different way. Qubits (quantum bits) sent through a Hadamard gate in a quantum computer for example, will enter a superposition in which they are technically in all possible classical states, and then collapse to one particular classical state when measured. The state that they collapse into will be completely random, if performed under certain conditions. When a qubit collapses it becomes a classical bit, and a series of these operations can produce the bits from which can be derived a genuine random number.

Quantum random numbers can protect a wallet against both random guesses of private keys, and attempts to target a particular private key which is known to correspond to a particular address. Both hacking processes attempt to uncover the private key by applying deterministic mathematical procedures, and the odds are necessarily stacked against such mathematical procedures arriving at a key that was not itself derived from classical mathematics at all. In the current version of the program, we seek to protect the private key itself, rather than the derivation pathway from the public key to the private key. Though depending on how the hack was attempted, the current method also provides protection against reverse engineering from the public key to the private key. (Future versions will provide a QRNG derived ‘k argument’ to the elliptic curve discrete logarithm function, and so optimise the entropy in the derivation of the private key from the public key, as well as the derivation of the private key itself.)

The program will also put the key through a stretching process by hashing the concatenation of the current hash and the QRNG in a 256 iteration loop. This will make the key considerably stronger from the perspective of conventional cryptography than the usual wallet private key generation process, even if the QRNG is disregarded.

The overall work flow is like this:

  1. Encrypt .aes with user-entered data (“seed”)
  2. Get user-entered seed from .aes
  3. Get QRNG
  4. hash = SHA256(seed + QRNG)
  5. newhash = SHA256(hash + QRNG)
  6. hash = newhash
  7. Repeat steps 4 and 5 255 more times
  8. Derive WIF and public key in standard manner

The program is split into two parts, orchestrated from command line options, which allows for air gapping of the two sources of data that the private key will be derived from, if this is desired.

Set-up and useage

The app is supplied as a Go program. You will need an installation of Go to run this program, and you will need to set the $GOPATH variable. You will also need to install the non-standard Go packages “x/crypto/ripemd160”, and “x/crypto/scrypt,” available from pkg.go.dev. And the bitcoin tool packages “btcsuite/btcd/btcec” and “btcsuite/btcutil/base58” from github.com/btcsuite. These should be placed in a directory in the $GOPATH.

Enter secret data into a text file called “seed” and place this in the same directory as the code. This secret data should be high entropy – i.e. it should be highly random, although it will be derived from conventional or “pseudo” sources of randomness. Mashing the keyboard with your finger tips is one of the usual ways to produce pseudo random data, a random number generator such as the $RANDOM package on Bash, or some environmental source of entropy derived from the machine hardware. (Note: even mashing the keyboard is not really random, as people have natural preferences for certain keys, such as those closest to the fingers, and hacking algorithms will be savvy to this, hence the need for something more substantial.) Save the file when done.

Run the program by opening terminal, moving to the directory in which the code and file are stored, and typing “go run main.go”. You will then be faced with two options, “e” (encrypt) or “c” (create.) First of all we are going to encrypt the seed file, so press “e.” You will be prompted to enter a password. This password is the password for the encrypted .aes file that we are going to create. Don’t lose the .aes file or forget the password, as you will need this if you ever want to recreate your private key.

Once the password protected .aes file is created, run the program again, and this time enter “c” when asked, and the password in order to unlock the file. The program will make an API call to get the QRNG, concatenate the data from the .aes file and the QRNG and perform a SHA256 hash. It will then re-concatenate the QRNG with the result of the hash, and hash again, repeating this loop 256 times in total, in order to add further entropy by key stretching.

Once this is done, the program will perform standard transformations in line with the bitcoin developer documentation to generate the wallet input format (WIF) key. (Specifically, it will generate an extended key by adding an 0x80 byte to the front of the main net key, hash the key twice and add the first four bytes to the end of the extended key as a checksum, and encode the data in base58 format).

The program will also generate a sample address through the standard elliptic curve discrete logarithm function procedure. Or you can drop the private key into a wallet app such as Electrum to create your own.

Code