Configuration
targetPick a puzzle above and its range appears here.
Fill either field — the other one is derived automatically (Base58Check P2PKH / P2SH).
Percentage mode jumps to each scan point above and scans a window there — no full-range sweep.
#66 is the exact position of puzzle 66's published private key inside its own interval, so with
that puzzle's range selected the window is centred on the very key that was found; 0x… takes any
private key the same way, and a plain number is a percentage of the range. Prefilled from
solved_keys.json with one point per solved puzzle (#1–#70 and every fifth puzzle to #130,
each key verified against its published address). Comma-separated or a JSON array. Each scan session covers
one window per point, then advances forward; progress is saved in this browser so a reload resumes exactly
where it stopped. Kangaroo may leave both fields empty: the slice count below then cuts the
interval into equal slices instead, one window inside each.
One job per line: an address (or HASH160) and, optionally, its own start/end range in hex.
Leave the range off to use the Range Start/End above. Every job runs at the same time across the worker
pool, and each candidate key is compared against that job's own target — so several puzzle ranges can be
searched side by side. Lines starting with # are ignored.
Appends one job per puzzle number (a span like 70-75 or a list like
70,72,75), each using that puzzle's own interval [2^(N−1), 2^N − 1] and the target address /
HASH160 entered above — the quick way to scan several puzzle ranges at once.
For a puzzle that is not in the list: fills only [2^(N−1), 2^N − 1], because its private key is not published. Paste its address or public key above to scan it.
How many Web Workers the scan uses. The default is every core the browser reports
(navigator.hardwareConcurrency, or 8 when it withholds the count), because each worker
owns its own window and never waits on another. Running more workers than there are cores does
not make the walk faster — they time-slice on cores that are already busy — so the
count is capped at this device's core count. Applies on the next Start.
Kangaroo only, and only while the Scan points field is empty: the interval is then cut into this many equal slices and one window is drawn at random inside each — up to 2^64 keys, but never more than a quarter of its slice, so the draw can still move. The count is filled in for you from Range Start/End and the window size above — range ÷ (4 × that window), because a window is drawn at a quarter of its slice — so picking a window size and a range already sets the number of windows; type over it to force your own. With scan points entered, the plan is one window per point and this count is not used. Either way a window runs to 4× its expected steps and hands the worker the next, so 16 windows cost √16 = 4× a single run — the price of cutting the interval into pieces small enough to finish, and they run in parallel.
VSCM sweeps the interval one window at a time: each window advances a point by one
window step, tests the low bits of its x against the trap mask, and keeps nothing — the window
coordinate is ephemeral. That is a linear sweep of windows, not a sub-linear solver,
and the dashboard prints its measured rate rather than a promised one. Selecting it pauses the worker
pool and snapshots every checkpoint record before anything else happens; switching back restores
only what went missing, so the block-sweep checkpoint is never rewritten. The engine needs
vscm_ews.js; if that file is absent the switch is refused and the mode stays on Standard.
A block is abandoned after this many times its expected 11.44*sqrt(W) steps. That is a probability, not a proof: a kangaroo collision is a birthday process, so the chance the key really is in the block and is still unmatched after c x expected is about e^-(2.5c)^2 - 3x leaves 3.7e-25, 10x leaves 3.7e-272. Raising it buys almost nothing and costs blocks per hour linearly; lowering it below 3x starts to trade real coverage for speed. The block width follows the window you pick - a picked window is one block, so the whole window is burned in one pass - and typing in that field overrides it until you pick a puzzle again.
Auto sets the density from the interval width and the pool's total herd size.
A point is distinguished when the low bits of its canonical walk invariant (y²) are zero, so {±Q, ±λQ, ±λ²Q} share one trap and a herd meets one roughly every 2^bits steps. This is a table-size knob, not a speed knob: the affine x is recomputed every round for the jump index either way, so a sparser mask saves no field work, and Hash160 is not on this path at all. Auto also accounts for the total herd across every worker and every device in the pool: more kangaroos emit more points, so a pooled run deliberately thins the mask by one bit per doubling of the herd to keep the table the same size. That is the point the reference implementation operates at, not an unsafe setting. Set it too high and a full run may record too few points for a tame/wild pair ever to meet — the dashboard warns when the yield gets that low. Applies on the next Start; existing checkpoints still merge.
No drops yet · next drop: —
Dead windows: —
–
–
The bar cuts Range Start/End into windows of the width on the left (2^70 as shipped) and writes the window it lands on into Sub-range start/end, so both fields are filled as soon as a range is entered — moving the bar and moving the window number do the same thing. The last window is short when the range does not divide evenly. Typing in the hex fields yourself stops the follow until the bar moves again, which is what keeps a hand-picked band from being overwritten. The line under the bar says where that window falls: how far into the range it begins, how many keys it sits from Range Start, and how many windows still follow it.
Off: the tame curtain is spread across the whole block.
No song chosen — the built-in cash-register cha-ching plays on a match.
Pick an audio file (MP3, M4A, OGG, WAV) and it loops from this device when a private key verifies. The file never leaves the browser: it is held as a local object URL, not uploaded. Tap Test Sound once on a phone — mobile browsers only allow a delayed alert to play after the page has played audio from a real tap. With no file chosen, or when playback is blocked, the dashboard plays its own cash-register cha-ching — a struck bell, a shower of falling coins and a rising chord, synthesised with the Web Audio API and looped until you acknowledge the find — and still vibrates and raises a notification.
Kangaroo runs on the Rust/WebAssembly core (one tame and one wild herd per worker, in that worker's own window, with one shared field inversion per round), and falls back to the in-page JS herd walk if the module cannot load. A checkpoint records every herd's exact position plus the distinguished points found so far, and the slices already swept. Export it on one machine and import it on another: the two nodes' tables merge, a collision can be found across them, and the importing node skips the slices the exporter already covered. Points from a window this device is not walking are held for it: import first, press Start, and each set joins the table the moment its own window comes up, because a distinguished point's offset only means something inside the window that recorded it. Clear saved state wipes the stored session, every checkpoint, the herd positions, the distinguished points and the workers' progress, so the next Start always begins a fresh scan.
No public key for the target (for example Puzzle 71, whose P2PKH address has never revealed one)? Leave the public key field empty: an address carries only HASH160(Q), which cannot be turned back into a curve point, so Kangaroo mode then scans the interval key by key — one HASH160 per candidate, run on the same Rust core. That search is linear, with none of the √N kangaroo speed-up, so the interval has to be small enough to be walked.
This device walks alone. Setting the same pool size on every device and a different slot on each one gives them disjoint starting positions, so their distinguished points are new information instead of duplicates.
Leave both at 1 unless you are pooling. Every device must share the interval, the target and the public key, and should use the same density — the jump table is derived from the interval width alone, so points only ever collide between devices walking that same table. Note that this divides the herd, not the interval: splitting an interval of width W into m pieces costs √m·√W in total, so partitioning the range would make the pool slower. Both devices walk the whole interval. Applies on the next Start.
Range size: –
–
Progress saves in this browser every second and on unload — reloading the page restarts a running search exactly where it stopped, until it finds the key or you press Pause / Reset.
Window map
––
–
Collision probe · P100
idleEight Web Workers walk [2^99, 2^100−1] on
kangaroo_test.wasm and post every distinguished point here. Target means a
tame point and a wild point landed on the same compressed point, so the difference of their offsets is
the private key; internal means two walks of the same kind met, which recovers nothing.
A meeting is only counted as a hit after k·G = Q verifies.
—
—
| alpha | mean jump | solves | mean time | mean steps | steps / √247 | passes |
|---|---|---|---|---|---|---|
| No trials yet. | ||||||
- Herd steps
- 0
- Distinguished points
- 0
- DP store
- 0 / 1,000,000
- Rate
- –
- Mean jump
- –
- Steps per pass
- –
- Expected hunt
- –
- Passes
- 0
- Run
- 0
- Elapsed
- 00:00:00
- Candidates checked
- 0
- Pool
- 0 / 8 workers
- Store save
- ok
- Checkpoint
- not yet
0x0
0x0
dp 25 puts a distinguished point every ~33.5M steps, so at nine million steps a second the store grows by about one point every four seconds. A traversal is width ÷ mean jump, and the two scales are not comparable: on Puzzle 100 the 63,161× scale has a mean jump of 2^55, so one traversal is 2^44 ≈ 1.76e13 steps — 22.6 days, not half an hour; on Puzzle 140 the rapid scale is ~4.9e13, mean jump 2^104.5, one traversal 2.43e10 steps, about 45 minutes. The timer and the hunt are different numbers: the calibrator puts the expected hunt at ~2√W herd steps at any scale, so a pass is only a slice of it — 2 passes at 1×, 126 at 63,161×, and ~9.7e10 at the P140 rapid scale. Auto re-seed then draws fresh bases for all eight workers while the store keeps every point it holds. Points live in IndexedDB — 250,000 per hunt, one partition for P100 and one for P140 — and are written in batches every ten seconds or twenty-five points, so the walk never waits on the disk. Export streams the selected hunt's saved points to a timestamped JSON file; Import merges another session's or device's dump back in, deduplicated by compressed point and checked for fresh tame-wild meetings as it lands.
Results & Alerts
waitingNo match yet. Configure a target, press Start, and every derived key is compared against the target HASH160.
- Private key (hex)
-
– - Private key (WIF)
-
– - Address
–- Derived HASH160
–- Matched public key form
- –
Window = one slice of the range, walked start to end. Worker = one thread walking that slice; restarting means the slice is handed to a fresh thread. A warning about a window means that slice was restarted or dropped — it never means the key was found, and never that the whole range has been searched.