How to create an Ethereum address with a bitcoin private key

In the wallet of the blockchain, the private key can generate the public key, and conversely it is impossible to derive the private key from the public key. The information encrypted with the public key can be decrypted with the private key, and the information signed with the private key is verified by the public key. After the verification is passed, the information can be proved to be published by the private key holder. Taking BTC as an example, the most important role in this process is the "elliptic curve encryption algorithm".

Some people think that BTC and ETH are different chains, so the elliptic curve used is not the same, but in fact the two chains use the same secp256k1 curve, so the way to get the public key is exactly the same, the difference is generated from the public key. The process of the address, we will first introduce how to generate the private key securely, and then explain how ETH validates the public key generated by the private key from the address.

Private key specification

The private key must be a positive integer and must be less than the order of the secp256k1 curve (the order of secp256k1 is FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141), each point can be represented by a set of 256 bits, and 256 bits are exactly 32 bytes, so we need to provide 32 curve algorithms. Byte of data.

In other words, the private keys of BTC and ETH are a set of 32-byte strings, but it can also be a binary string, a Base64 string, a WIF key, a mnemonic phrase, hexadecimal. String.

Secure private key generation

Since we all know that they are using the same curve, we can actually use the BTC community to compare the trusted bitaddress.org to generate our private key. (With MEW or Metamask is also a good choice, at least he can not be a The string is exposed to the private key), but if there is good security awareness, we should not even use the browser to generate our important private key (you can look at the discussion on Reddit), so we will design a simpler one with python. Bitaddress.

Understand the principle of Bitaddress

Bitaddress did three things. First, initialize the byte array, then try to get as much entropy as possible from the user's computer, fill the array based on the user's input, and finally generate the private key.

Bitaddress uses a 256-byte array to store entropy. This array is overridden by the loop, so when the array fills up for the first time, the index becomes zero and the overwrite process begins again.

The program generates a 256-byte array from window.crypto. Then write a timestamp to get 4 bytes of entropy. After that, it gets some other data including screen size, time zone, browser extensions, regions, and more. To get another 6 bytes.

After initialization, the user continues to input to overwrite the initial bytes. When the cursor is moved, the program writes the position of the cursor. When the button is pressed, the program writes the character code of the pressed button.

Finally, bitaddress uses the accumulated entropy to generate the private key. Bitaddress uses an RNG algorithm called ARC4. The ARC4 is initialized with the current time and the collected entropy, and then the bytes are fetched one by one, for a total of 32 times.

Initialize our own seed pool

We write some bytes from the encrypted RNG and the timestamp. __seed_int and __seed_byte are two functions that insert entropy into the array of pools, and we use secrets to generate our random numbers.

Populate the seed pool by input

Here we write a timestamp and then write the string entered by the user.

Generate private key

First use our pool to generate a 32-bit number and make sure our private key is in range (1, CURVE_ORDER), then for convenience we convert to hex and remove the 0x part.

Generate an ETH public key

Substituting our private key into an elliptic curve, we get a 64-byte integer, which is two 32-byte integers representing the X and Y points connected together on the elliptic curve.

Checksum (ERC-55)

Bitcoin creates a checksum by hashing the public key and obtaining the first 4 bytes of the return value. If no checksum is added, the valid address cannot be obtained.

However, Ethereum did not have a checksum mechanism to verify the integrity of the public key. It was not until Vitalik Buterin introduced the checksum mechanism in 2016, the EIP-55, which was later adopted by various wallets and exchanges.

Add a checksum to the Ethereum wallet address to make it case sensitive

First, get the Keccak-256 hash of the address. It should be noted that there is no 0x part when passing this address to the hash function.

Second, the bytes of the initial address are iterated sequentially. If the ith byte of the hash value is greater than or equal to 8, the character of the i-th address is converted to uppercase, otherwise it is left in lowercase.

Finally, add back 0x at the beginning of the returned string. If the case is ignored, the checksum address will be the same as the initial address. But using an uppercase address allows anyone to verify that the address is valid.

This checksum has several benefits:

1. Backward compatible with many hexadecimal parsers that accept mixed case, which can be easily introduced in the future;

2. Keep the length to 40 characters;

3. On average, there will be 15 check digits per address. If the input is incorrect, the net probability of randomly generated addresses passing the check will be 0.0247%, although it is not as good as the 4-byte check code, but it is improved by ICAP. 50 times;

to sum up

Creating a wallet address for Ethereum is much simpler than Bitcoin. All we need to do is throw the private key into the elliptic curve, then throw the resulting public key into Keccak-256, and finally extract the last 20 bytes of the hash.

This article reprints the public number: Blockchain Research Laboratory