Private Key Tools

Private key → P2PKH address (compressed)

The classic 1… address: hash the 33-byte compressed public key into 20 bytes, prepend the mainnet version byte 0x00, append a 4-byte double-SHA256 checksum and Base58-encode the result. Every intermediate value is shown so you can follow the construction byte by byte.

The compressed public key is derived from this value and then hashed. Accepts an optional 0x prefix, spaces and upper case; shorter values are left-padded. Must be in [1, n−1].
No input yet

Enter a value above and press Convert. Not sure what to type? Press “Use example” to load the sample from the placeholder.

How it works

What this page computes

One 256-bit private key goes in; one classic 1… address comes out. The address is not a second key and not a hash of the private key — it is a Base58Check encoding of a 20-byte commitment to the compressed public key:

address = Base58Check( 0x00 ‖ RIPEMD160(SHA256(pubkey_compressed)) )
private key k→ k · G→ 33-byte compressed pubkey→ SHA-256→ RIPEMD-160→ hash160 (20 B)→ 0x00 ‖ hash160 ‖ checksum→ 1… address

Every intermediate value is shown in the result panel, because the point of this page is to make each step visible rather than to hide it behind a black box.

1. What "P2PKH" actually means

A Bitcoin output is not an account with a balance. It is an amount plus a small program called the locking script (scriptPubKey). To spend that output, the next transaction supplies an unlocking script / witness that makes the program finish with a single TRUE on the stack. P2PKH stands for pay to public key hash, and its locking script is:

OP_DUP  OP_HASH160  <20-byte pubkey hash>  OP_EQUALVERIFY  OP_CHECKSIG

The order matters: the script first re-derives the hash of the public key that the spender supplied, compares it to the committed hash, and only then verifies the signature. Hashing first is what lets the address stay short and keeps the public key off the chain until the coins move.

The Unix-style shorthand <pubkeyhash> OP_CHECKSIG describes the older P2PK ("pay to public key") form, whose locking script pushes the whole public key instead of a hash of it. That form is what Satoshi's first transactions used, and its outputs are bigger:

P2PK (legacy, 2009)P2PKH (this page)
Locking script<pubkey> OP_CHECKSIGOP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
scriptPubKey size35 bytes (compressed) / 67 bytes (uncompressed)25 bytes
Public key on chain before spendingyes — visible from day oneno — revealed only when spent
Typical use todayrare; mostly unmoved 2009–2010 coinsthe default single-key format for a decade

Executing the script, step by step

The spender's unlocking script is <sig> <pubkey>. Here is exactly what the interpreter does, with the demo key's real values:

#OperationStack afterwards
1push signature from scriptSig[sig]
2push compressed pubkey from scriptSig[sig, 02ff812e…ee80]
3OP_DUP — copy the top item[sig, pub, pub]
4OP_HASH160 — hash the copy[sig, pub, 21f57b6d…9012]
5push the hash committed in the script[sig, pub, 21f57b6d…9012, 21f57b6d…9012]
6OP_EQUALVERIFY — compare, drop both, abort if unequal[sig, pub]
7OP_CHECKSIG — verify the signature with the pubkey[TRUE]

So the hash is not a convenience: it is the identity check. If the spender hands over a public key that hashes to something else, OP_EQUALVERIFY fails and the spend is rejected before any signature math is done.

2. The construction, byte by byte

Base58Check is fed 25 bytes. Nothing else is in there — no chain code, no key index, no checksum of the private key:

OffsetLengthFieldDemo value
01 byteversion byte 0x00 = mainnet P2PKH00
1 – 2020 byteshash160 = RIPEMD160(SHA256(compressed pubkey))21f57b6debcfc5b67182dfb4af1641f0a8189012
21 – 244 byteschecksum = first 4 bytes of SHA256(SHA256(bytes 0–20))cbd7667e
—25 bytes total200 bits, the entire content of a 1… address0021f57b…9012cbd7667e

25 bytes is 200 bits. Because Base58 carries log₂(58) ≈ 5.858 bits per character, the encoded string is 33 or 34 characters long (200 / 5.858 ≈ 34.1). The demo address is exactly 34 characters.

Why the address starts with "1"

Base58 is a big-integer base conversion, and a pure conversion would erase leading zero bytes. So the encoding has an extra rule: every leading 0x00 byte in the input becomes a literal 1 character at the front of the output. The version byte of a mainnet P2PKH address is 0x00, so the first character is always 1. Change the version byte and the leading character changes with it — that single byte is the whole reason 1…, 3… and m… look the way they do.

"Starts with 1" is a hint, not a proof

A valid mainnet P2PKH address always starts with 1, but the reverse is not guaranteed: a decoder must check the version byte, the payload length and the checksum. Never treat a prefix as validation — the demo testnet address below starts with m for exactly this reason.

3. Why hash160 = RIPEMD160(SHA256(x))

Two different hash functions are applied in sequence, and the reason is defence in depth. A collision in SHA-256 alone is useless to an attacker, because the 32-byte digest is then fed to a second, structurally different function: to produce two public keys with the same hash160 you need a collision in the composition, which means breaking both designs. Hashing twice also shortens the result to 20 bytes, which makes every address, script and output smaller.

FunctionOutputBirthday collision boundPreimage boundRole here
SHA-25632 bytes / 256 bits≈ 2128≈ 2256full-strength commitment to the public key
RIPEMD-16020 bytes / 160 bits≈ 280≈ 2160shortens the commitment
hash160 = RIPEMD160∘SHA25620 bytes / 160 bits≈ 280≈ 2160what the address commits to

The relevant threat for a specific address is a second preimage, not a free collision: the attacker must find a public key hashing to your 160-bit value, which costs about 2160 work. An 80-bit collision bound only matters for generating two colliding keys of the attacker's own choosing, so 20 bytes was judged an acceptable trade for smaller scripts — and it is still unbroken today.

4. What the 4-byte checksum protects against

The checksum is SHA256(SHA256(payload))[0..3] — 32 bits appended to the payload before Base58 encoding. Its whole job is to catch accidental transcription errors: a mistyped character changes the decoded integer, and the probability that a random corruption still matches those 32 bits is 1 in 232 ≈ 1 in 4.29 billion. That is why stealing a single character from an address makes almost every wallet reject it loudly.

A checksum is not a signature

The checksum is unkeyed and public: anyone can compute a correct one for any payload they like, including a payload that pays them. It protects you from typos and from truncation, not from a malicious address substituted in an email, a clipboard or a compromised website. Always verify at least the first and last few characters on the device that holds the key.

5. Mainnet vs testnet: one byte changes everything

The version byte is the only difference between a mainnet and a testnet P2PKH address for the same hash160. Same 20 bytes, different first byte, completely different strings:

NetworkP2PKH versionP2PKH prefixP2SH versionP2SH prefixWIF versionBech32 prefix
Mainnet0x001…0x053…0x80bc1
Testnet / signet / regtest*0x6Fm… / n…0xC42…0xEFtb1

* The test networks share the Base58 version bytes shown here; only the bech32 human-readable part differs (bcrt1 on regtest). For the demo key's hash160 the mainnet address is 146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT and the testnet one is micWfnN6LUy38jVRPD2Mw7YMa873zjixGw — the same 20-byte commitment, pointing at different chains.

A testnet address cannot receive mainnet coins

Both strings decode to the same hash160, but the version byte is part of the output script on the receiving chain. Paying mainnet coins to a tb1… or m… address is a transaction to an address whose key you control on the other chain — on mainnet the coins are simply lost. Copy-paste errors like this are irreversible; there is no operator to call.

6. Worked example with the demo key

These are the exact values this page computes for 0824c314…171ca, and the result panel recomputes them live:

StepValue
Private key k0824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca
Compressed public key (33 B)02ff812e26116a9aa140abe629e7f8a38401653caf925119def59ed3758c67ee80
SHA-256 of that (32 B)067eb00a0b9864633b020eef374476142daba913c5481ad6a4741cc8ab702617
hash160 = RIPEMD-160 of that (20 B)21f57b6debcfc5b67182dfb4af1641f0a8189012
Payload = 00 ‖ hash160 (21 B)0021f57b6debcfc5b67182dfb4af1641f0a8189012
Checksum (4 B)cbd7667e
Encoded 25 bytes0021f57b6debcfc5b67182dfb4af1641f0a8189012cbd7667e
P2PKH address146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT (34 characters)
Matching scriptPubKey (25 B)76a91421f57b6debcfc5b67182dfb4af1641f0a818901288ac

Reading the scriptPubKey: 76 = OP_DUP, a9 = OP_HASH160, 14 = "push the next 20 bytes", then the hash, 88 = OP_EQUALVERIFY, ac = OP_CHECKSIG. Five opcodes and one constant — 25 bytes that define who may spend.

7. Why an address is not a public key

A quiet security benefit of hashing

Because the public key stays hidden until the coins move, a P2PKH address that has never spent is protected by two independent problems: the hash preimage (2160) and, for anyone who does see the key later, the elliptic-curve discrete log. Addresses that have already spent expose their key and lose the first layer — a real consideration when thinking about future quantum attackers.

8. Address reuse is a privacy bug, not a consensus bug

The blockchain is a public, permanent ledger, so an address is not an account you can hide behind — it is a permanent label. Every payment to the same address is linked together for anyone to see, together with the amounts and the timing. Two consequences deserve emphasis:

The standard remedy is a hierarchical deterministic wallet (BIP32/BIP44): it derives a fresh address for every payment from the same seed, and sends change to a new address too. Reusing an address costs nothing in fees and is still perfectly valid on-chain — which is precisely why so much software does it anyway.

9. Where this fits in the derivation chain

10. Security notes

Never paste a real private key into a page you do not control

This tool computes everything in PHP on the server that serves it, and nothing is logged or sent anywhere — but that guarantee is only as good as the operator. Anyone who sees your key, even for a second, in a log, a proxy, a screenshot or a browser history, can spend every coin at every address derived from it. For real funds, do this offline with software you built yourself, or use a hardware wallet.

11. Common mistakes

12. Quick reference

ItemValue
FormulaBase58Check(0x00 ‖ hash160(compressed pubkey))
Hash input33-byte compressed public key (66 hex digits)
Hash functionhash160 = RIPEMD160(SHA256(x)), 20 bytes
Version byte0x00 mainnet, 0x6F testnet
Encoded payload25 bytes = 1 version + 20 hash + 4 checksum
Checksumfirst 4 bytes of SHA256(SHA256(payload)), 32 bits
Address length33 or 34 Base58 characters
Locking script size25 bytes
Demo address146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT
Reversible?No — one-way hash commitment