Skip to content

Release Notes

wj-diode-quantum 1.0.0 Beta 3 - 4 August 2026

Values are now 1024 bits, nothing is written to disk on either side, and the transport is a stream rather than a series of files. Both sides must be upgraded together — the wire format has changed completely and a diode cannot renegotiate.

Changed

  • Values are 1024 bits, up from 128. Each is 256 lowercase hex characters. How bytes are fetched from ANU is unchanged; only the slicing is. A given request now yields an eighth as many values, each eight times larger.
  • Nothing touches disk. The pool file, its journal, the outbox, the spool and the ingest subcommand are all gone, along with the database, spool_dir, outbox_dir and spool_poll_seconds settings. Values exist only in pipes and in memory. A restart on the serving side starts with an empty pool, which refills from the far side's next cycle.
  • The transport is a stream. diode.send_command is fed values on its standard input and server.receive_command supplies them on its standard output — diodetool stream-send and stream-recv rather than send and auto-recv. send_command no longer takes a {} placeholder, and receive_command is now required.
  • The wire format is JSON Lines, one value per line. Batch framing and batch identifiers are gone. A damaged line costs exactly one value and parsing resumes at the next newline, rather than a damaged batch costing everything in it.
  • Each ANU endpoint has its own schedule. collect.interval_seconds is replaced by interval_seconds on each source, defaulting to eight hours for the keyed API — about 90 requests a month against a quota of roughly 100 — and one hour for the legacy one, which allows a request a minute.
  • stats asks the running server over HTTP instead of reading a file, since there is no longer a file to read. It no longer works with the server stopped.
  • Config files contain no paths at all, so nothing is resolved relative to the config's directory any more.

Added

  • A documentation page at /, with curl examples, an endpoint reference and live pool figures. Self-contained: no JavaScript, no external assets, and readable in light or dark.
  • The number of bytes discarded per fetch is logged, so a length/size pair that wastes a noticeable fraction of a response is visible rather than silent.
  • A warning at startup when send retries can outlast the shortest collection interval.

wj-diode-quantum 1.0.0 Beta 2 - 4 August 2026

A fix for the keyed ANU endpoint, which never worked in the first beta.

Fixed

  • The keyed API at api.quantumnumbers.anu.edu.au could not be used at all. It returns length as a JSON string and omits size entirely, while the legacy endpoint returns both as numbers. anuResponse declared them as ints, so every keyed response failed to decode before the data was reached and the source produced nothing but parse response: json: cannot unmarshal string into Go struct field. Neither field is used for anything — they only echo the request back — so neither is decoded now. Collections from the legacy endpoint were never affected.

Documentation

  • Corrected the yield figures. The two endpoints read size differently despite being sent the same type=hex16 request: the keyed one counts 16-bit values, so a block is twice size in bytes, while the legacy one counts bytes. At length: 1024 that is 20,480 bytes (1,280 values) from the keyed API at size: 10 — twice what was previously documented — and 16,384 bytes (1,024 values) from the legacy API at size: 16. Both measured against the live endpoints.

wj-diode-quantum 1.0.0 Beta - 2 August 2026

First release.

Collects quantum random numbers from the Australian National University, pushes them across a data diode, and serves them one at a time on the far side.

Collecting

  • Draws from both ANU endpoints: the current keyed API at api.quantumnumbers.anu.edu.au and the older unkeyed one at qrng.anu.edu.au. Either or both can be enabled; when both are on, both are used on every cycle and their values are merged into one batch, each tagged with its source.
  • Blocks returned by either API are concatenated and re-sliced into 128-bit values locally, so the differing per-block size limits do not matter. Leftover bytes are discarded rather than padded.
  • Batches wait in an outbox until the send command succeeds, so an interrupted or failed transfer is retried rather than lost. After a configurable number of attempts a batch is moved aside so one bad file cannot block the queue.

Serving

  • One 128-bit value per request over HTTP, with the time it was collected.
  • The pool is a bounded LIFO: newest served first, oldest discarded once it reaches capacity.
  • A value is never served twice. Each take is journalled and flushed to disk before the value reaches the client, so the guarantee survives a crash, not just a clean shutdown.
  • Batches arriving over the diode are validated whole and rejected whole. A batch that arrives twice is recognised and adds nothing.
  • serve can run and supervise the receiving tool, so the protected machine needs one process.

Getting set up

  • setup send and setup recv ask only what cannot be defaulted and write a working config, along with the companion files the diode tool needs. Passwords go to a 0600 file rather than a command line.
  • sample-config prints a config showing every option.
  • stats reports pool depth and age without writing to the database, so it is safe to run against a live server.

Notes

  • The API has no authentication and binds to 127.0.0.1 by default.
  • The legacy ANU endpoint is limited to one request per minute and is being retired by ANU.