Bitcoin Keys 101 - From seed phrase to address
This article explains the generation of private keys in Bitcoin until obtaining a public address and the different type of addresses available.
[TOC]
General workflow
The basic worklow is the following
1.Generate the seed phrase
Note: this is not a required step, you can directly generate the private key, but this is a standard practice in Bitcoin Wallets, defined in BIP-39.
More information in my article: Bitcoin Keys 102: How Wallets Generate Seed Phrases and Private Keys
2.Create a private key
3.Compute the public key
4.Derive the Bitcoin address from the public key

Create a Bitcoin address
Create a Legacy Bitcoin Address
Private key generation
- A private key is generated randomly. It is a 256-bit number that serves as the secret key for spending Bitcoin from the address it generates.
- In Bitcoin, this is often done using a secure pseudorandom number generator to ensure privacy and security.

Public key generation
Using Elliptic Curve Cryptography (ECC), specifically the secp256k1 curve in Bitcoin, the private key is used to generate a corresponding public key.
ecp256k1’s elliptic curve
\(\begin{aligned}
y2 = x3 + 7
\end{aligned}\)

- This public key is a 512-bit number (or 64 bytes in hexadecimal format).
Hash
- Perform SHA-256 Hashing on the Public Key:
The public key is hashed using the SHA-256 hashing algorithm, producing a 256-bit hash.
- Apply RIPEMD-160 Hashing:
The result from the SHA-256 hash is then hashed using the RIPEMD-160 hashing algorithm, which produces a 160-bit (20 bytes) output. This is called the Public Key Hash (PKH).
Add a Version Byte
A version byte is added to the beginning of the Public Key Hash. For standard Bitcoin addresses, this version byte is 0x00 (or 00 in hexadecimal). The purpose of the version byte is to help distinguish address types.
| Type | Version prefix (hex) | Base58 result prefix |
|---|---|---|
| Address for pay to public key hash (P2PKH) | 0x00 | 1 |
| Address for pay to script hash (P2SH) | 0x05 | 3 |
| Testnet Address for P2PKH | 0x6F | m or n |
| Testnet Address for P2SH | 0xC4 | 2 |
| Private Key WIF | 0x80 | 5, K, or L |
| BIP32 Extended Public Key | 0x0488B21E | xpub |
Calculate the Checksum
-
The versioned Public Key Hash is then double-hashed using SHA-256.
-
The first 4 bytes of this second hash become the checksum, which is appended to the end of the versioned Public Key Hash.
Encode in Base58
The resulting byte sequence (versioned Public Key Hash + checksum) is encoded using Base58Check encoding, resulting in a human-readable Bitcoin address.
\(Base58Check(Versioned Public Key hash||checksum)\)
This process generates a string, such as 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa, which is the Bitcoin address.
Main reference: bitcoin.it - Technical background of version 1 Bitcoin addresses
P2SH details
From bip-0013
This bitcoin address type is constructed in the same manner as legal bitcoin addresses with Base58Check encoding:
base58-encode: [one-byte version][20-byte hash][4-byte checksum]
-
Version byte is 5 for a main-network address, 196 for a testnet address.
- The 20-byte hash is the hash of the script that will be used to redeem the coins.
- And the 4-byte checksum is the first four bytes of the double SHA256 hash of the version and hash.
Variation
Native SegWit (Bech32)
Bech32 is a segwit address format specified by BIP 0173 (Bech32) and BIP 0350 (Bech32m). This address format is also known as “bc1 addresses”. This type of address is considered as more efficient (so lower fees) than a traditionnal legacy addresss because it uses less block space.
The main difference is that the encodage algorithm used is Bech32 instead of Base58Check for a legacy address.
Format: Starts with bc1q...
How it’s created:
- Same initial steps as Legacy (generate pubkey, hash it with SHA-256 and RIPEMD-160)
- These operation gives an array of 8-bit unsigned integers (base 2^8=256)
Then:
- Encode it using Bech32 which converts the hash value to an array of 5-bit unsigned integers
- Add the witness version byte (
0) in front of the previous step - Compute the checksum by using the data from previous step and the network identifier (bc for MainNet and tb for TestNet) and append it to the previous step
- …and some additional steps explained here
Reference: en.bitcoin.it/wiki/Bech32
Summary Table
| Address Type | BIP | Format Prefix | Script Type | Encoding |
|---|---|---|---|---|
| Legacy | - | 1 |
P2PKH | Base58Check |
| P2SH | bip-0013 | 3 |
P2SH | Base58Check |
| SegWit | BIP_0173 | bc1q... |
P2WPKH / P2WSH | Bech32 |
| Taproot | BIP_0350 | bc1p... |
P2TR | Bech32m |
Reference
- Bitbox - How is a Bitcoin address created?
- Hiro - Understanding the Differences Between Bitcoin Address Formats When Developing Your App
- learnmeabitcoin - ECDSA
- Mastering bitcoin
- en.bitcoin.it/wik - Technical background of version 1 Bitcoin addresses
- mighty block - Seed Phrase vs Private Key: a technical overview
- ChatGPT with the input “Explain how address are created on Bitcoin. Create also a plantuml diagram”, “In bitcoin, you can create a Legacy Bitcoin Address, what are the other type of address and how they are created ?”