Summary
Most device-to-device transfer assumes a bidirectional radio link. We remove that assumption. A sender renders a file as a stream of animated QR codes; a receiver reads them with a camera. Because a camera cannot talk back, retransmission is impossible, so we use a rateless code instead. RaptorQ (RFC 6330) sends the file's source symbols first and then an unbounded run of repair symbols, and any sufficient set of distinct symbols, in any order, reconstructs the file. A missed frame costs time, never correctness.
Every frame carries a 24-byte self-describing header, and the RaptorQ parameters are derived at both ends from that header rather than transmitted. The file travels inside a KCF1 container with its name, media type and a SHA-256 digest, and every transfer is verified before it is offered.
Findings
- On physical light, RaptorQ completed at exactly K distinct symbols in every recorded device run: five runs in device sessions two to four and all 64 replication runs, every delivery SHA-256 verified. An earlier LT-coded mode, since removed, needed 1.262 and 1.308 times K on the same kind of hardware.
- An uncoded sender that cycles the source blocks, evaluated on each run's measured read rate, would have had to show 3.4 to 5.5 times as many frames as the rateless sender needed.
- A MacBook Pro sending to an iPhone 12 Pro Max at QR version 27 reached 30.5 KB/s, 90% of the 33.8 KB/s ceiling set by 24 frames per second and 1,440-byte symbols. The receiver's decoder pass, timed directly inside the transfer, was 23.8 ms at the median and 41.3 ms at the 95th percentile.
- Across 64 runs on three device pairings, version 40 cost 1.59 to 1.67 times the version 27 decoder pass, with no detectable difference in hit rate. Its goodput gain was 1.21 to 1.44 times, below the 1.7 criterion set in advance and significant in one pairing.
- Low Power Mode lengthened the median decoder pass in every pairing, by a factor of 1.34 to 1.59 at version 27 and 1.41 pooled at version 40, with no thermal transition in any of the 64 runs. An earlier single-run reading that it halved throughput did not survive repetition.
- The comparisons were made within one sitting only, with the run as the unit of analysis. Two earlier conclusions were corrected by better instrumentation and three more by repetition.
The performance page gives the conditions behind each number, and the wire format page gives the frame and container byte by byte.
Status
Shipping in Air Kalon 2.1 for macOS, iPhone and iPad. The wire bytes are pinned by golden vectors generated from the Rust core at specification freeze and compared byte for byte on every test run, and the repository holds 251 automated tests: 89 in the Rust core and 162 in the Swift package.