Random Beacon
Version 2 of Random Beacon has been retired and can no longer be run.
This page is kept as a historical description of how Version 2 worked.
The current beacon (Version 3) is described at Random Beacon.
Version 2 built a fresh beacon inside every page request. On each full page load the server, under a process-wide lock, fetched live public feeds, qualified them, and derived that request's beacon.
It kept no scheduled cadence and produced no digital signature, and its unpredictability depended on the changing feeds and a private server nonce rather than on a dedicated secure random source.
Because that expensive generation ran on the request thread, repeated loads could tie up server threads and slow the whole site — the reason Version 3 moved generation to a scheduled background producer, added a cryptographically secure random core, and signed each pulse.
How Version 2 Qualified Data
- Sources were grouped into families (seismic, observatory, weather, and so on); for each request a family's try-order was set by a SHA-256 hash keyed with the private server nonce, and each family was fetched in small parallel batches until three sources qualified or the family was exhausted.
- A stream qualified only when it supplied at least 768 usable UTF-8 characters, differed from that stream's previous fetch by SHA-256 fingerprint, and yielded three contiguous 256-character buffers that were all different from one another.
- Only the second buffer from each qualifying stream entered the beacon calculation.
- Streams that were unreachable, too short, repeating, or unchanged since their prior fetch were reported as not used, with the reason.
- If no stream qualified for a request, the app showed a graceful no-beacon state instead of manufacturing fallback entropy.
How the Version 2 Beacon Was Formed
- The beacon digest was SHA-256 over the concatenated SHA-256 hashes of the private server nonce, the request counter, the previous beacon digest, the selected output language, each qualifying second buffer, and a summary of all fetch fingerprints.
- The digest was expanded to a 256-byte output stream by repeatedly hashing it together with a fixed context label and a block counter.
- The new digest was stored and chained into the next request, so every beacon was linked to the history before it.
- The output was shown as language-selected UTF-8 characters, base 16, base 8, and base 2, with each representation reporting its character length.
Why Version 2 Was Retired
- Generation ran on the request thread under a process-wide lock, so repeated page loads could exhaust the server's thread pool and degrade the whole site — a denial-of-service exposure.
- Each page load triggered a fresh sweep of outbound feed fetches, amplifying inbound traffic into outbound load.
- Pulses were not digitally signed, so outputs could not be independently verified as coming from this server.
- Unpredictability rested on the feeds and nonce alone, with no dedicated cryptographically secure random source per pulse.
Privacy and Transparency
The page reported which pseudonymous buffers qualified, which did not, why, and a source page link for each pseudonym.
It deliberately avoided showing raw feed URLs, raw source buffers, private state values, stack traces, or implementation code to the browser.
Prior Random Beacons