How an Ethereum Address is Generated from a Public Key

·

Many resources explain how Ethereum uses ECDSA (Elliptic Curve Digital Signature Algorithm) to generate private and public key pairs, which ultimately lead to a unique Ethereum address. A common claim is that when generating an address from an uncompressed public key, you simply perform a hash operation and take the last 40 characters. However, the actual process involves more nuanced steps. This article clarifies the precise steps required to generate an Ethereum address from a public key.

Understanding Ethereum Key Fundamentals

Before diving into the address generation process, it's helpful to understand the components involved. A private key is a randomly generated 256-bit number. This private key is used within the secp256k1 elliptic curve to mathematically derive a corresponding public key.

The initial uncompressed public key is 65 bytes long and is typically presented in hexadecimal format with a leading '04' prefix. This prefix indicates that the following data represents both the X and Y coordinates of a point on the elliptic curve.

The Step-by-Step Address Generation Process

The transformation from a public key to a final Ethereum address involves a series of cryptographic operations. Here is the detailed, technical procedure.

Step 1: Prepare the Public Key

The first step is to take the full, uncompressed public key, which starts with the prefix '04'. This prefix must be removed before further processing. For a key represented as a hexadecimal string, this means stripping the first two characters ('04'). If the key includes a '0x' prefix, you would remove the first four characters ('0x04').

Example Input:
0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6

After Removal:
50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6

Step 2: Convert to a Byte Array

The resulting hexadecimal string from Step 1 must be converted into a raw byte array. This conversion is crucial because the subsequent hashing function operates on bytes, not on a string representation of hex characters. Most programming libraries provide utilities for this conversion.

Step 3: Apply the Keccak-256 Hash

Once you have the byte array, the next step is to hash it using the Keccak-256 algorithm. It is critical to note that Ethereum uses the standard Keccak-256, not the NIST-standardized SHA-3, though they are often confused. This operation produces a fixed 256-bit (32-byte) hash output, which is represented as a 64-character hexadecimal string.

Example Keccak-256 Output:
d1e6f6a0c094f0d5727e5ce9a5b0e9b5a9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9

Step 4: Extract the Last 40 Characters

The Ethereum address is derived from this Keccak-256 hash. Take the last 40 characters (20 bytes) of the 64-character hash string and prefix them with '0x' to form a standard Ethereum address format. This address is now a valid, lowercase Ethereum address.

Example Result:
0x3e9003153d9a39d3f57b126b0c38513d5e289c3e

Step 5: Add Checksum (Optional but Recommended)

The address from Step 4 is valid. However, to enhance security and prevent errors in transcription, it is a common practice to apply a checksum mechanism defined by EIP-55. This process creates a mixed-case address where the capitalization of certain letters encodes a checksum of the address. Wallets and explorers use this to verify that an address has been entered correctly. Most Ethereum libraries provide a function to perform this checksum encoding.

Final Checksummed Address:
0x3E9003153d9A39D3f57B126b0c38513D5e289c3E

👉 Explore more blockchain development strategies

Common Pitfalls and Errors

A frequent mistake in manual implementations is hashing the hexadecimal string directly without first converting it to a byte array. Hashing the string representation (the ASCII codes for the characters '5', '0', '8', etc.) will yield a completely different Keccak-256 result than hashing the actual bytes that string represents. This is a critical distinction and a common source of errors for developers.

Always ensure you are operating on the raw byte data, not its string encoding.

Frequently Asked Questions

What is the starting prefix of an uncompressed Ethereum public key?
An uncompressed public key in Ethereum begins with the prefix '04'. This signifies that the following data contains the complete X and Y coordinates of the point on the elliptic curve. This prefix must be removed before the hashing step in the address generation process.

Why is Keccak-256 used instead of SHA-256 for Ethereum?
Ethereum's development began before the NIST standardization of SHA-3 was finalized. The Keccak algorithm was selected as the winner of the SHA-3 competition, and Ethereum adopted the original Keccak-256 variant. While similar, Keccak-256 and the final NIST SHA-3 standard have slight differences in padding rules, making them distinct functions.

Is the checksum in an Ethereum address mandatory?
No, the checksum is not mandatory for an address to be valid on the Ethereum network. A lowercase address will work perfectly fine. However, the checksum (EIP-55) is highly recommended for user-facing applications as it provides a valuable layer of protection against errors when copying or typing addresses manually.

Can I generate an address from a private key without the public key?
Technically, no. The public key is an essential intermediate step. The standard sequence is: Private Key → Public Key → Ethereum Address. While libraries often combine these steps into a single function call, the public key derivation is always happening internally.

What is the difference between a wallet address and a public key?
The public key is derived from the private key and is used in cryptographic operations, like verifying signatures. The wallet address is a shorter, hashed representation of the public key (specifically, the last 20 bytes of the Keccak-256 hash of the public key) and serves as the public identifier for receiving funds.

How can I verify my address generation code is correct?
The best way to verify your implementation is to use a known test vector. Use a known private key, generate the public key and address using a reputable, audited library like ethers.js or web3.js, and then ensure your custom code produces the exact same results for each intermediate step.