Private key → uncompressed WIF
Base58Check-encode the payload 0x80 ‖ k and get the original 51-character 5… Wallet Import Format string — the format printed on old paper wallets, which implies the uncompressed public key and therefore the legacy 1… address.
Enter a value above and press Convert. Not sure what to type? Press “Use example” to load the sample from the placeholder.
What this page computes
You give it a 256-bit private key and it produces the uncompressed WIF — the
original Wallet Import Format string: 51 characters, beginning with 5, with no compression flag
inside it. This is the format every Bitcoin backup used before mid-2012, and the format still printed on old
paper wallets.
Compare it with the modern form: the compressed WIF is
Base58Check(0x80 ‖ k ‖ 0x01) — one byte longer, one character longer, a different checksum, and a
completely different implied address.
1. The original WIF, from a time when a public key had only one shape
When the first Bitcoin client was written, a public key had exactly one serialization: the 65-byte
04 ‖ X ‖ Y form, produced by OpenSSL without any decision being made about it. There was no
compressed form, no flag, and nothing to choose. A private key, therefore, needed to carry exactly one piece of
metadata — which network (and therefore which coin) the key belonged to — and nothing else.
The design that resulted is minimal and, once seen, obvious:
- One version byte in front,
0x80on mainnet, identifying the string as a private key rather than an address. - The 32 raw key bytes, big-endian, zero-padded to a fixed width.
- A 4-byte checksum appended, so that a human transcription error is caught before a wallet ever tries to use the key.
The result was encoded in Base58 to keep it typeable and to avoid look-alike characters. That is the whole format. The name "Wallet Import Format" arrived later; the encoding itself was there from the early client. Note what is absent: no flag byte, because there was nothing to flag. This is not a "legacy mode" somebody designed for old keys — it is the original format, unchanged, and the 2012 compressed form was built as an extension of it.
0x80 is not the same as the 0x00 that starts a mainnet P2PKH address, nor
the 0x04 that tags an uncompressed public key. Three different one-byte headers appear in one
derivation chain. The version byte tells a wallet "this is a private key, on mainnet, in the original
encoding" — everything else follows from that.
2. Why dropping the flag changes the payload length, the first character and the checksum
The compressed and uncompressed WIFs of one key differ by exactly one byte inside the payload, and that single byte has four visible consequences.
| Consequence | Uncompressed WIF | Compressed WIF |
|---|---|---|
| Payload length | 33 bytes (0x80 ‖ k) | 34 bytes (0x80 ‖ k ‖ 0x01) |
| Bytes fed to Base58 | 37 bytes = 296 bits | 38 bytes = 304 bits |
| String length | 51 characters | 52 characters |
| First character (mainnet) | 5, always | K or L |
| Checksum (demo key) | b6f3d7f5 | 3a0a0417 |
| Implied address (demo key) | 16kR3eis…WG2G | 146ZNjH7…2UqT |
Each of those follows mechanically:
- Length. Base58 encodes a big integer, and each character carries log258 ≈ 5.858 bits. 296 / 5.858 ≈ 50.5, so 37 bytes need at most 51 characters; 304 / 5.858 ≈ 51.9, so 38 bytes need at most 52. One extra byte costs exactly one extra character.
- First character. The leading Base58 digit is
floor(value / 5850)for a 51-character string. A mainnet uncompressed WIF always begins with the byte0x80, so its value lies in[2295, 2295 + 2288); with5850 ≈ 2292.899the quotient is between ≈ 4.29 and ≈ 4.32, which floors to 4 for every possible key — the character5. On testnet the version byte is0xefand the same arithmetic gives9.5is not a convention; it is forced. - Checksum. The checksum is the first four bytes of
SHA256(SHA256(payload)), and the payload is what changed. Any change to the input produces an unrelated hash, so the four checksum characters at the end of the string bear no relation to the compressed version's. - Address. The flag is a promise about which public key the wallet will derive. Without it,
the wallet derives
04 ‖ X ‖ Y, hashes 65 bytes instead of 33, and lands on a different 20-byte commitment — a different address.
3. Full byte layout
| Offset (encoded input) | Length | Field | Demo value | Notes |
|---|---|---|---|---|
| 0 | 1 byte | Version byte 0x80 | 80 | Mainnet private key; testnet is 0xef |
| 1 – 32 | 32 bytes | Private key, big-endian | 0824c31477…07a171ca | Fixed 32 bytes, leading zeros preserved |
| — | 0 bytes | Compression flag — absent | — | This absence is what defines the uncompressed form |
| 33 – 36 | 4 bytes | Checksum | b6f3d7f5 | First 4 bytes of SHA256d(bytes 0–32) |
| 37 bytes | 33-byte payload + 4-byte checksum → 51 Base58 characters | |||
The checksum computation is worth seeing in full for the demo key, because it is the step that ties the string to the key:
| Stage | Value |
|---|---|
| Payload (33 bytes) | 800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca |
| SHA256(payload) | 0f5261d28f2887da16ac302c8f0593c885d57a538afd35f5067322b0e5f2fc96 |
| SHA256(SHA256(payload)) | b6f3d7f5f57bbbced3c64757bda8ac500a5fa6a346c278f65af7f84a865da824 |
| Checksum (first 4 bytes) | b6f3d7f5 |
| Final 37 bytes given to Base58 | 800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171cab6f3d7f5 |
4. Why the 5… format is now considered legacy
Nothing about the format became invalid in 2012. What changed is the economics and the ecosystem:
| Dimension | Uncompressed (5…) | Compressed (K…/L…) |
|---|---|---|
| Public key embedded when spending | 65 bytes | 33 bytes |
| Typical P2PKH scriptSig | 1 + 72 + 1 + 65 = 139 bytes | 1 + 72 + 1 + 33 = 107 bytes |
| Extra fee paid on every input | +32 vbytes versus compressed | baseline |
| SegWit (P2WPKH, P2SH-P2WPKH) | Not possible — witness v0 requires a compressed key | Supported |
| Taproot (BIP340 / BIP86) | Not used; Taproot is defined over a 32-byte x-only key | Standard input |
| Derived wallet support | Imported as an isolated legacy key | Native in every HD wallet |
| Generated by default? | No wallet since 2012 | Yes, everywhere |
So a 5… key is not broken, it is expensive and awkward. It cannot participate in SegWit's fee
discount, it cannot back a Taproot output, and it pays roughly 32 extra virtual bytes of witness-discounted
weight on every single spend for the rest of its life. Wallets therefore stopped producing it, and the address
type it maps to is now labelled "legacy" — a word that describes popularity, not validity.
5. The sweep problem, in detail
This is the practical heart of the page. You have an old paper wallet, printed in 2011, with a
5… WIF and a 1… address, and you want to move the coins into a modern wallet. Three
things can happen:
- The wallet refuses the key outright. Many modern wallets — particularly descriptor-based ones and some hardware-wallet companion apps — only support compressed keys for imported accounts. They answer "invalid private key" or simply nothing. The key is fine; the software has no code path for it.
- The wallet accepts it and shows a zero balance. The dangerously common case. The wallet
imports the 32-byte key, assumes the compressed form (the only form it ever derives), computes
hash160(02/03‖X), watches146ZNjH7…-style addresses and finds nothing, because your coins are at the uncompressed address. Sweeping is impossible for the same reason: the wallet cannot sign for an output whose script commits to the 65-byte key. - The wallet accepts it correctly as a "legacy key" account, deriving and watching the uncompressed address and spending with the 65-byte public key. Some wallets do this properly; the feature is usually called "import legacy key", "sweep paper wallet" or "import uncompressed key".
Outcome 2 is what people experience as "my Bitcoin vanished". It almost never has. The key you hold still controls the uncompressed address; you just need software that derives the uncompressed public key from it. Verify before doing anything drastic: compute the uncompressed address from the key (this page and private key → P2PKH uncompressed address do it), then look that exact address up on a block explorer. If it holds coins, use a tool with a legacy-key or paper-wallet sweep and send the entire balance to a fresh address in your modern wallet in one transaction.
A cousin of outcome 2 is worth calling out: a wallet that accepts the 5… key but silently
"upgrades" it, deriving the compressed address as your receive address. Send coins there and your
old paper-wallet balance and your new balance sit at two different addresses, only one of which the next wallet
you open may watch. Always confirm that the address a wallet displays is the address you expect.
6. How to tell which form actually holds the coins
The first character of a WIF tells you what the exporter intended; it does not tell you where somebody paid. Those are different questions, and only on-chain data answers the second one.
| What you have | What it tells you | What to check |
|---|---|---|
WIF beginning with 5 | The exporter intended the uncompressed form — its checksum and length confirm it | The uncompressed address, and the compressed one too, in case someone paid there |
WIF beginning with K or L | Compressed form intended | The compressed address first; the uncompressed address as a fallback |
An address beginning with 1 | Only that it is a mainnet P2PKH address — both forms produce 1… addresses | Compute both addresses from the key and compare against the one you were given |
| The raw hex private key | Nothing at all about encoding | Both addresses; whichever has the coins is the form you must spend with |
| An empty paper wallet address | The coins were already moved, or never arrived | The other address derived from the same key, and the transaction history |
Two practical heuristics: (a) a paper wallet's printed address and its printed key almost always match in
form — a 5… key goes with an address built from the 65-byte public key; (b) when a restoration looks
empty, never conclude anything from one address. Derive both, check both, and only then decide.
7. Worked example with the real demo values
These are the actual outputs for the sample key shown in the input box:
| Item | Value |
|---|---|
| Private key k | 0824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca |
Payload 0x80 ‖ k (33 bytes) | 800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca |
| SHA256(SHA256(payload)) | b6f3d7f5f57bbbced3c64757bda8ac500a5fa6a346c278f65af7f84a865da824 |
| Checksum | b6f3d7f5 |
| Uncompressed WIF | 5HssbguBnjbaUVZCsH9YuzUG7T4vYQf51iiodi4izdVy6aVNekU |
| Length / first character | 51 characters, begins with 5 |
| Uncompressed public key | 04ff812e26116a9aa140abe629e7f8a38401653caf925119def59ed3758c67ee808f49cde13c7ffd64f1d730bf87a743a578eda4971ddac4a08118160732b424ae |
| hash160 of it | 3f0e966dc089c611a9c1d03bd4f69ea53b0223f9 |
| P2PKH address implied | 16kR3eiswUY6tmGnxZhwQmW6LAvTLGWG2G |
| Contrast: compressed WIF of the same key | KwVYL77Lcs1ckM39NvGjrtfKhU4KKdR2iB9Wq2FSMN6rbGK5tVqG (52 characters, starts with K) |
| Contrast: compressed address | 146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT |
| Testnet uncompressed WIF | 91eWBRijNxfiSZ4VVd3Tnb2Dm7RdhaCGMfakiLRELNF1saLqhym |
| Testnet uncompressed address | mmGNLhorkVyMfskQg8gKEgiRCAXAGnxeBv |
The address is the same Base58Check recipe applied to the 65-byte key, so its own payload can be shown too:
version 00, hash160 3f0e966dc089c611a9c1d03bd4f69ea53b0223f9, checksum
3b0b7cbd, and the 34-character result 16kR3eiswUY6tmGnxZhwQmW6LAvTLGWG2G.
8. Round-trip verification
This page decodes its own output with Btc::wifDecode() and displays every recovered field in the
result panel, so you can see that nothing was lost or invented: the original 32-byte key, false for
the compression flag, version byte 80, mainnet, a valid b6f3d7f5 checksum and the
33-byte payload. Note the elegance of the decoder's rule — there is no explicit "uncompressed marker" byte. The
length of the payload is the marker: 33 bytes means uncompressed, 34 bytes ending in 0x01
means compressed, and anything else is rejected.
9. Compressed vs uncompressed WIF
| Uncompressed WIF (this page) | Compressed WIF | |
|---|---|---|
| Formula | Base58Check(0x80 ‖ k) | Base58Check(0x80 ‖ k ‖ 0x01) |
| Payload / total bytes | 33 B / 37 B | 34 B / 38 B |
| Characters | 51 | 52 |
| First character (mainnet / testnet) | 5 / 9 | K or L / c |
| Introduced | Original 2009 client | Bitcoin 0.6.0, March 2012 |
| Implied public key | 04 ‖ X ‖ Y, 65 bytes | 02/03 ‖ X, 33 bytes |
| Implied address (demo key) | 16kR3eis…WG2G | 146ZNjH7…2UqT |
| SegWit / Taproot capable | No | Yes |
| Fee impact | +32 vbytes per input | Baseline |
| Typical place you meet it | Old paper wallets, pre-2012 backups | Every modern export |
10. Security notes
- A
5…WIF is a plaintext private key. Base58 is an alphabet change, not encryption. Anyone who photographs the paper wallet, reads the QR code or sees your screen can spend the coins. - The checksum protects against typos only. Four bytes of SHA256d catch transcription mistakes; they say nothing about who created the string or whether the key was generated honestly. A "perfectly valid" WIF can belong to an attacker.
- Old keys have had a long time to leak. A key that sat in a 2011 wallet file, an emailed backup or a cloud album has been exposed to many attack surfaces for a decade. When sweeping, move the full balance to a freshly generated address in one transaction, and never reuse the old key.
- Watch out for "sweep" services. Any website offering to sweep a paper wallet is asking you to hand over the private key. That request is the theft vector. Sweep with software you control, offline if possible.
- Sweep to the right form. Make sure the destination is an address you have backed up (a seed-derived one), not the compressed address derived from the very paper key you are retiring.
11. Common mistakes
- Assuming a
5…WIF is invalid because modern wallets reject it. It is original-format, correct and spendable; the software simply lacks support. - Assuming a zero balance means the coins are gone. It usually means the wallet derived the compressed address. Compute both.
- Thinking the key has to be "upgraded". A key has no version and no state; only the coins can be moved. The WIF is just how the key is written down.
- Using the compressed WIF of an old key by mistake. It produces a valid but different address — the cleanest way to make real coins look lost.
- Truncating the WIF to 51 characters by hand. A 33-byte and a 34-byte payload hash differently, so a hand-trimmed string fails its checksum.
- Expecting SegWit from a
5…key. Witness v0 requires a compressed key, sobc1q…addresses are out of reach.
12. Quick reference
| Item | Value |
|---|---|
| Encoding | Base58Check: payload ‖ first 4 bytes of SHA256d(payload) |
| Payload | 0x80 ‖ k(32 B) — no compression flag |
| Payload / encoded length | 33 B / 37 B |
| Output | 51 Base58 characters, first character 5 (mainnet) |
| Testnet variant | 0xef ‖ k, first character 9 |
| Implied public key | 65 bytes, 04 ‖ X ‖ Y |
| Implied address | P2PKH from hash160(04‖X‖Y) |
| Decoded by | Payload length alone (33 = uncompressed, 34 + 0x01 = compressed) |
| Reversible? | Yes — the 32-byte key is recovered exactly |
| Still valid on-chain? | Yes, for legacy P2PKH scripts |