This blog post delves into the foundational process of generating Ethereum wallet addresses, a critical component of interacting with the Ethereum blockchain. We'll demystify the process by breaking it down into three essential steps: creating a private key, deriving the public key, and finally, generating the Ethereum public address.
The journey begins with the generation of a private key, a random and unique string of numbers that serves as the user's secret access to their funds. We'll explore how cryptographically secure pseudorandom number generators (CSPRNGs) ensure the randomness and security of this vital component.
Next, we transition from the private key to its corresponding public key through elliptic curve cryptography (ECC), specifically focusing on the ECDSA (Elliptic Curve Digital Signature Algorithm) on the secp256k1
curve. This step is crucial for the security and functionality of Ethereum transactions, as the public key serves as the foundation for the final piece of the puzzle.
Finally, we arrive at the creation of the Ethereum public address. By applying the Keccak-256 hashing algorithm to the public key and extracting specific portions of the resultant hash, we generate a unique address that participants can use to send and receive Ethereum and other tokens on the network.
This blog post aims to illuminate the technical elegance and security considerations behind Ethereum wallet creation, providing readers with a deeper understanding of how their digital assets are managed and protected on the blockchain.
Private Keys
A private key is simply a number, picked at random. Ownership and control of the private key is the root of user control over all funds associated with the corresponding Ethereum address, as well as access to contracts that authorize that address. The private key is used to create signatures required to spend ether by proving ownership of funds used in a transaction. Note that the private key generation process is an offline one; it does not require any communication with the Ethereum network, or indeed any communication with anyone at all. 1
Cryptographically secure pseudorandom number generators (CSPRNGs)
A random private key of 64 (hex) characters (256 bits / 32 bytes) is generated first.The generation of a random private key of 64 hexadecimal characters (256 bits or 32 bytes) is a foundational aspect of cryptographic systems, including Ethereum. This process involves creating a securely generated random number that will serve as the private key. The first step is to generate a random 256-bit number. This is crucial for the security of the private key, as it must be unpredictable. Cryptographically secure pseudorandom number generators (CSPRNGs) are used for this purpose. CSPRNGs are designed to be unpredictable, fulfilling the requirements for cryptographic applications.
{
privateKey, err := crypto.GenerateKey()
if err != nil {
log.Fatal(err)
}
ECDSA (Elliptic Curve Digital Signature Algorithm)
ECDSA is a cryptographic algorithm used for creating digital signatures. It's an adaptation of the Digital Signature Algorithm (DSA) to work with elliptic curve mathematics. A CSPRNG is first used to generate a private key. This private key is a random number d chosen from within a specific range defined by the elliptic curve's parameters. The randomness and unpredictability of d
are vital for the security of the ECDSA key pair.
Then we can convert it to bytes by importing the golang crypto/ecdsa
package and using the FromECDSA
method.
privateKeyBytes := crypto.FromECDSA(privateKey)
fmt.Println("SAVE BUT DO NOT SHARE THIS (Private Key):", hexutil.Encode(privateKeyBytes))
Here's an overview of the steps involved in generating such a private key:
(Private Key 64 hex characters): 0x371c9e8214f0af4fe8f009a7984723fe10463b0edf56af16d302002788558cdb
Public Key
An Ethereum public key is a point on an elliptic curve, meaning it is a set of x and y coordinates that satisfy the elliptic curve equation. In simpler terms, an Ethereum public key is two numbers, joined together. These numbers are produced from the private key by a calculation that can only go one way. That means that it is trivial to calculate a public key if you have the private key, but you cannot calculate the private key from the public key.2
The public key is calculated from the private key using elliptic curve multiplication, which is practically irreversible: K = k * G, where k is the private key, G is a constant point called the generator point, K is the resulting public key, and * is the special ellip‐tic curve “multiplication” operator. Elliptic curve multiplication is a type of function that cryptographers call a “one-way” function: it is easy to do in one direction (multiplication) and impossible to do in the reverse direction (division). The owner of the private key can easily create the public key and then share it with the world, knowing that no one can reverse the function and calculate the private key from the public key. This mathematical trick becomes the basis for unforgeable and secure digital signatures that prove ownership of Ethereum funds and control of contracts.3
A 128 (hex) character (64 bytes) public key is then derived from the generated private key using Elliptic Curve Digital Signature Algorithm (ECDSA).
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
fmt.Println("Public Key:", hexutil.Encode(publicKeyBytes))
Public Key: 0x04caad623d04e822705458c5748bdf45b66d446cbf3eff60d8d4f90f697e67a28a2a0c6fe5a40c33d046f3c23d292db4f1ec570750a0378b348273acde67cdea33
Public(Ethereum) Address
Public (Ethereum) addresses are unique identifiers that are derived from public keys or contracts using the Keccak-256 one-way hash function.
Now that we have the public key we can easily generate the public address which is what you're used to seeing. In order to do that, the go-ethereum crypto package has a PubkeyToAddress
method which accepts an ECDSA public key, and returns the public address.
address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
fmt.Println("Address:", address)
To derive an Ethereum public address from the Keccak-256 hash of a public key, you follow these steps:
Take the Keccak-256 hash of the uncompressed public key (excluding the
0x04
prefix if present, which is already done in our case).Extract the last 40 characters (20 bytes) of the hash. This represents the rightmost 160 bits of the Keccak-256 hash.
Add the
0x
prefix to these 40 characters. This is your Ethereum public address.
Address: 0xcDA4d74b609529Da25402bF2bA62D4B8d1DFb783
Source
How to generate the private key, Link
Go code and playground , Link
Go wallet, Link
Engin YILMAZ (
Veridelisi
1
Mastering Ethereum,Andreas M. Antonopoulos and Dr. Gavin Wood, Link
2
Mastering Ethereum,Andreas M. Antonopoulos and Dr. Gavin Wood, Link
3
Mastering Ethereum,Andreas M. Antonopoulos and Dr. Gavin Wood, Link