This article is a guide on how to generate an ECDSA private key and derives
its Ethereum address.
Use Openssl and keccak-256sum from a terminal.
SHA3 != keccak. Ethereum is using the keccak-256 algorithm and not the
Ethereum use keccak-256, it should be noted that it does not follow the
FIPS-202 based standard(aka. SHA-3), which was finalized in August 2015
web3.utils.sha3 uses keccak-256 web3.sha3(string[, option]): keccak-256
First of all we use Openssl ecparam command to generate an elliptic curve
private key. Ethereum standard is to use the secp256k1 curve. The same curve
is used in Bitcion.
This command will print the private key in BEM format(using the wonderful ASN.1
key structure) on stdout.
> openssl ecparam -name secp256k1 -genkey -noout
On its own this command is not very useful for us, but if you pipe it with the
ec command it will display both private and public part in hexadecimal format,
and this is what we want.
> openssl ecparam -name secp256k1 -genkey -noout | openssl ec -text -noout
This command decodes the ASN.1 structure and derives the public key from the
Sometimes, Openssl is adding a null byte(0x00) in front of the private part, I
don’t know why it does that but you have to trim any leading zero bytes in
order to use it with Ethereum.
The private key must be 32 bytes and not begin with 0x00 and the public
one must be uncompressed and 64 bytes long or 65 with the constant (0x04)
The public key is what we need in order to derive its Ethereum address. Every EC
Public key begins with ‘0x04’ prefix byte in order to hash it correctly.
This prefix represents the encoding of the public key:
- 0x04 - both x and y of the elliptic curve point follows
- 0x02, 0x03 - only x follows (y is either odd or even depending on the
Use any method you like to get it in the form of an hexadecimal string(without
line return nor semicolon)
# Extract the public key and remove the EC prefix 0x04
The pub file now contains the hexadecimal value of the public key without the
An Ethereum address is made of 20 bytes(40 hex characters), it is commonly
represented by adding the 0x prefix. In order to derive it, one should take the
keccak-256 hash of the hexadecimal form of a public key, then keep only the
last 20 bytes (aka get rid of the first 12 bytes)
Simply pass the file containing the public key in hexadecimal format to the
keccak-256sum command. Do not forget to use the ‘-x’ option in order to
interpret it as hexadecimal and not a simple string.
# Generate the hash and take the address part
Which gives us the Ethereum address
CAUTION: if your final address looks like
0xdcc703c0E500B653Ca82273B7BFAd8045D85a470, this means you have hashed an
empty public key. Sending funds to this address will lock them forever.