§ 02

§ 02 · Cryptography

Hash functions

A fingerprint for any data, impossible to fake

A hash function takes any data, a word or a whole block, and produces a short fixed-size fingerprint called a hash.

Pearl uses hashes everywhere: to name transactions and blocks, to chain blocks together, to commit to data without revealing it, and to run its mining lottery. It uses two families. SHA-256 comes from Bitcoin. BLAKE3 is Pearl’s addition, and it powers the mining.

Try it

Type anything. Watch the hash change completely when you change a single letter, and compare SHA-256, SHA256d and BLAKE3 side by side.

Hash playground

Change one letter and the whole fingerprint changes

SHA-256 Tagged hashes and Taproot

72bc556112e9538a2433f0a9b87b032eae43c69e367e9dca1b176929dcf20ed5

SHA256d SHA-256 twice: txids, block hashes

2ec32b953f6a93c4a34869c936e7af1e9ca052bad616574340af3f60b184215f

BLAKE3 Mining tickets and matrix commitments

64c73be7ea8de1a1691ea7f2233e2673e195c7ffc51b9789d234d4b2eabcd1c0

Avalanche

135 of 256 bits changed

compared with “pearl”

Runs in your browser · nothing is sent src/lib/hash.ts · raw output order

What makes a good hash function?

Five properties. The first three are easy to see; the last two are what make hashes useful for security.

  1. Deterministic. The same input always gives the same hash, on every computer.
  2. Fixed size. SHA-256 and BLAKE3 (as Pearl uses it) always give 32 bytes, whether you hash one letter or a gigabyte.
  3. Avalanche. A tiny change in the input changes about half the output bits. This is the avalanche effect.
  4. One-way. Given a hash, you can’t find an input that produces it. This is preimage resistance.
  5. No collisions. No one can find two different inputs with the same hash. This is collision resistance.

Here is the avalanche effect with real numbers. “Pearl” and “pearl” differ in one bit: P is 0x50 and p is 0x70.

Input SHA-256
Pearl 72bc556112e9538a2433f0a9b87b032eae43c69e367e9dca1b176929dcf20ed5
pearl 26e3b2a5dc54dd5812fe7e6917172e2c9a70c72a0f5d2e97a5b8eb90434b7ffa

The two hashes differ in 135 of their 256 bits. Nothing about the second hints that its input was almost the same as the first.

Going deeper How hard is “can’t”?

A 256-bit hash has 2²⁵⁶ possible values, about 10⁷⁷. Finding an input for a given hash means trying inputs at random, about 2²⁵⁶ tries. Finding any collision takes about 2¹²⁸ tries, thanks to the birthday paradox. Both are far beyond all the computers on Earth running for the age of the universe. No shortcut is known for SHA-256 or BLAKE3.

What is SHA-256, and what is SHA256d?

SHA-256 is the hash function Bitcoin is built on, standardised by NIST. It chops the input into 64-byte blocks and stirs each one through 64 rounds of mixing. Pearl uses it exactly as Bitcoin does.

SHA256d is SHA-256 applied twice: the hash of the hash. Pearl uses it for transaction IDs, Merkle roots, block hashes and the header’s proof commitment.

Take the real header of block 130,825, all 108 bytes:

  1. Hash the header once

    SHA-256 of the 108 bytes gives 76db48f729868f9da8ff7dbe1aae143f3322cc64c2ce3602e6091a9fb23c842b.

  2. Hash that 32-byte result again

    SHA-256 of those 32 bytes gives ae3355eec8af1f407f0e935739615e375f35bedcd556a75e13a093387651c83f.

  3. Reverse the bytes for display

    3fc851763893a0135ea756d5dcbe355f375e613957930e7f401fafc8ee5533ae, the block hash every explorer shows. The reversal is explained on the byte order page.

Block 130,825 · header 108 bytes
00000020 d3221e43dc59c5d0dae1ee53987d6a4abeef42567d682017a6edd6e0de7ac7ab 2a051d25484d57e49a1f3b757685403ed06f558bb06a1804c34fac74ee7f5fab 8393d76a ebd06a17 ce6de312e0e4ca6c862c05835314db00cf02c13a20ea4810940f09b64ed8ba86
Field Bytes Value
Version header.version 4 @0 0x20000000 int32 LE. BIP-9 style 0x20000000 since block 1; no consensus meaning in Pearl.
Previous block header.prevBlock 32 @4 abc77adee0d6eda61720687d5642efbe4a6a7d9853eee1dad0c559dc431e22d3 Hash of the parent block, stored byte-reversed; shown in display order.
Merkle root header.merkleRoot 32 @36 ab5f7fee74ac4fc304186ab08b556fd03e408576753b1f9ae4574d48251d052a Root of the SHA256d Merkle tree of this block’s txids, stored byte-reversed.
Time header.timestamp 4 @68 1792512899 (2026-10-20 16:14:59 UTC) uint32 LE Unix seconds. Must be at least 1 s after the parent and at most 5 min in the future.
Bits header.bits 4 @72 0x176ad0eb Compact target. Difficulty 40208379.91968057. The certificate's jackpot hash (not this header's hash) must meet it.
Proof commitment header.proofCommitment 32 @76 86bad84eb6090f941048ea203ac102cf00db145383052c866ccae4e012e36dce SHA256d(LE32(certificate version) ‖ public data). Replaces Bitcoin’s nonce: Pearl headers have no nonce.
Block hash
3fc851763893a0135ea756d5dcbe355f375e613957930e7f401fafc8ee5533ae
Height
130,825
Time
2026-10-20 16:14:59 UTC
Difficulty
40,208,379.92

Why hash twice? Satoshi never said. The usual explanation is that a second round blocks a weakness of SHA-256 called length extension. Whatever the reason, the double hash is part of the format, and Pearl keeps it.

Why did Pearl add BLAKE3?

Because of what mining needs. A Pearl miner commits to two big integer matrices, sometimes gigabytes of data, and must later prove that a couple of rows belonged to them. BLAKE3 was designed in 2020 and has three features that fit:

  • It’s a tree. BLAKE3 splits its input into 1 KiB chunks, hashes each, then hashes pairs of results up to a single root. So the BLAKE3 hash of a matrix is the root of a Merkle tree, and a few rows can be proven with a short path of sibling hashes.
  • It’s fast and parallel. Chunks can be hashed at the same time on many CPU or GPU cores.
  • It has a keyed mode. Given a 32-byte key, BLAKE3 becomes a different function for every key. Pearl keys its hashes with the job key or a noise seed, so a result from one job means nothing in another. That’s a form of domain separation, like tagged hashes for SHA-256.

The same word gives a different BLAKE3 hash from its SHA-256 hash, of course:

Input BLAKE3
Pearl 64c73be7ea8de1a1691ea7f2233e2673e195c7ffc51b9789d234d4b2eabcd1c0
pearl/cert-v3/noise-seed/A 8249406ca0ed15169616f692fcf076f892dbdb2a7023b852f0d47719c390017b

The second one is real: it’s the salt Pearl’s consensus code has used since block 99,000 to tie matrix A’s noise seed to A’s size. See noise seeds.

Where does Pearl use each hash?

Purpose Hash
Block hash (the block’s ID) SHA256d of the 108-byte header
Proof commitment in the header SHA256d of the certificate version and public data
Transaction IDs and the Merkle root SHA256d
Signatures, Taproot tweaks, script trees SHA-256 tagged hashes
Job key, matrix fingerprints, noise seeds, noise BLAKE3, keyed where noted
The mining ticket (hash_jackpot) BLAKE3 keyed with the A-noise seed
Inside the zero-knowledge proof BLAKE3 and Poseidon (a hash built for proofs)
Wallet seeds and key derivation (BIP-32/39) HMAC-SHA512, PBKDF2-SHA512
Key fingerprints in extended keys RIPEMD-160 of SHA-256 (no Pearl address uses it)
Post-quantum XMSS signatures SHAKE256
Code: hashing in Pearl and in the browser

pearld’s double hash is a thin wrapper over Go’s crypto/sha256, in hashfuncs.go (node/chaincfg/chainhash/hashfuncs.go:25-50 at v1.5.2, on GitHub). The block hash is that applied to the 108 header bytes, in BlockHash() (node/wire/blockheader.go:43-48 at v1.5.2, on GitHub).

In a browser, with the same library this site uses:

JavaScript
import { sha256 } from '@noble/hashes/sha2.js';
import { blake3 } from '@noble/hashes/blake3.js';

const msg = new TextEncoder().encode('Pearl');
sha256(msg);              // 72bc5561…dcf20ed5
sha256(sha256(msg));      // SHA256d: 2ec32b95…b184215f
blake3(msg);              // 64c73be7…eabcd1c0
blake3(msg, { key });     // keyed mode: key must be exactly 32 bytes

The codex

Suggested

Up and down arrows move through the results, Enter opens one, Escape closes. Anywhere on the site, slash or Command K opens this search, and the square brackets [ and ] go to the previous and next page.