Beamlet は、Wi-Fi・モバイル回線・Bluetooth・クラウドストレージ・USBケーブルを使わず、2台の端末の画面表示とカメラ撮影だけでファイルを暗号化して受け渡すWebアプリ(PWA)です。iPhone と Windows / Linux PC のように AirDrop や Quick Share が通らない組み合わせや、USBポートの制限・圏外・私物アカウントのログイン禁止が重なる現場で、1セッション最大255個までのファイルを直接渡せます。1回に送れる合計サイズは、選んだ送信モードで約5分間に送れる量(スマートフォン送信の compact で約 3.5 MB、PC送信の standard で約 9.7 MB、fast で約 58 MB、最大 64 MB)です。
単発の静的QRコードは規格上限(ISO/IEC 18004 Version 40-L)でも 2,953バイト(約2.9 KB)しか入らず、平文の連続QR(アニメーションQR)は画面を横から録画されるとファイル名も中身も復元されてしまいます。Beamlet の光学ストリームプロトコル BOS1(Beamlet Optical Stream v1)は、送信開始前に受信画面の使い捨て X25519 公開鍵QRを送信側カメラで1回だけ読み取って鍵を共有し、以後はカラーグリッドの単方向送出だけで暗号化転送と欠損フレームの回復を行います。
仕様範囲と動作条件
| 項目 | Beamlet(BOS1)の仕様 |
|---|---|
| 通信経路 | 画面表示とカメラ撮影のみ(初回読み込み後は外部通信ゼロで動作) |
| 最大容量・ファイル数 | 各モードで約5分間に送れる量まで(compact 約 3.5 MB、standard 約 9.7 MB、fast 約 58 MB、上限 64 MB)、最大 255 ファイル |
| 暗号化と相手確認 | 使い捨て X25519 公開鍵QR + HKDF-SHA256 + 64 KiB単位 ChaCha20-Poly1305 + 6桁確認番号 |
| 秘匿される範囲 | ファイル本体のほか、ファイル名・ファイル種別(MIMEタイプ)・サイズ・サムネイルを含む一覧情報も暗号化 |
| 画像メタデータ保護 | 送信側ブラウザでの画像再エンコードにより EXIF 位置情報を自動除去(「原寸」も選択可) |
| 公開サイト / リポジトリ | Webアプリ:https://simota.github.io/beamlet/ / ソースコード:https://github.com/simota/beamlet |
公開鍵QRの読み取りに送信側カメラ、光学グリッドの撮影に受信側カメラを使うため、カメラのないデスクトップPCやサーバーモニターは送受信どちらにも使えません(カメラ付きのノートPC・タブレット・スマートフォン間であれば双方向に送受信できます)。また、受信側ごとに異なる公開鍵で暗号化する1対1セッションのため、1つの画面を複数人で同時に撮影するブロードキャスト配信には対応していません。
図1: OS標準共有やUSBの可否・ファイル容量(約5分相当・最大64MB)・両端末のカメラ有無から手段を選ぶ判断フロー(右下の公開鍵QRと確認番号 637788 は実出力)
ファイルが暗号化されて届くまでの仕組み
図2: 受信側公開鍵QRの1回読み取り(初期 standard / 計測後 fast 宣言)から、64 KiBチャンク暗号化(最大64MB)・RaptorQ噴水符号化・展開上限(65 MiB)検査とSHA-256検証までのパイプライン
最初に受け取る側の端末で「受信する」画面を開くと、その場限りの X25519 鍵対が作られ、公開鍵とカメラの受信能力(対応フレームレート・色数・最大セル数)を収めた61文字の公開鍵QRコードが表示されます。送る側の端末のカメラでこのQRを1回だけ読み取ると、両方の画面に6桁の確認番号(例:637788)と予想所要時間(分)が出ます。2台の番号が同じであることを目視で確かめてから送信を始めるため、第三者が別画面の公開鍵QRを差し込むすり替えを防げます。
送信が始まると、ファイル一覧と各ファイルは 64 KiB ごとに ChaCha20-Poly1305 で認証付き暗号化され、RaptorQ(RFC 6330)の噴水符号シンボルへ変換されます。送信画面はこれらのシンボルを水平帯の Reed-Solomon タイル(CRC-32検算付き)に詰めたカラーグリッドとして連続表示します。
受信側のカメラがグリッドを撮影すると、ブラウザ内のバックグラウンド処理(Web Worker 上の WebAssembly)が4隅のマーカーから傾き・回転・樽型レンズ歪みを補正します。続けて、上下の基準パレット帯とデータセル自体の色の偏りを使った最小二乗法で、ディスプレイの色温度やピンぼけによる色滲みをフレームごとに補正します。
1フレームが9〜16本の薄い水平帯タイルに分かれており、各タイル自体にデータ番号が入っているため、カメラのローリングシャッターで1枚の画像の上下に別々のフレームが混ざっても、境界線が横切った1本を除く上下両方のタイルをそのまま回収できます。スマートフォンの小画面送信(compact)では白黒2色の stable フレームが段階的に混ぜられます。受信カメラで4色の判別が難しい場合は受信画面に案内が出るため、送信画面の「安定だけで送る」ボタンを押せば、受信済みのシンボルを引き継いだまま白黒2色送出へ切り替えられます。
図3: compact モードの物理フレーム構造(左、シアン・マゼンタ枠は図解用の強調)と、ローリングシャッター断裂時に上下両フレームから無傷な水平帯タイルを回収する仕組み(右)
受信開始から数秒でファイル名・サイズ・80pxサムネイルの一覧が先に復号されます。途中でフレームを取りこぼしたりカメラを一時停止したりしても、必要なシンボル数が揃ったファイルから順に認証タグ・サイズ・SHA-256 ハッシュが検証され、保存リンクが有効になります。
転送速度とファイルサイズ別の所要時間
BOS1 プロトコルには、画面の大きさとカメラ性能に応じた5つの送信モードが定義されています(速度は 1 KB = 1,024 B、上限容量は 1 MB = 1,048,576 B 基準)。Webブラウザ同士では初回はPC・タブレット画面で standard、スマートフォンなどの小画面(短辺 600 px 未満)で compact が選ばれますが、受信側ブラウザが過去の受信セッションで「毎秒60フレーム以上の解析」と「8色(3 bit)タイルの8割以上の読み取り」を計測済みであれば、次回以降の公開鍵QRから自動で fast モードが選ばれます。1回の転送で送れる最大容量は、カメラを手で構え続けられる目安である約5分(300秒)にタイル損失20%を見込んだ実効速度を掛けた値(最大 64 MB)です。
| モード | グリッド(横×縦) | 色数 | 表示レート | 1フレーム容量 | 理論最大速度 (20%損失時) |
1回の送信上限 (約5分相当) |
主な用途 |
|---|---|---|---|---|---|---|---|
stable(安定) |
128×72 | 2色(白黒) | 10 fps | 342 B |
3.3 KB/s(2.7 KB/s) |
約 0.8 MB(801.6 KB) |
ピントや照明が厳しい環境・最終フォールバック |
compact(小画面) |
128×72 | 4色 | 15 fps | 1,026 B |
15.0 KB/s(12.0 KB/s) |
約 3.5 MB
|
スマートフォン等の小画面からの送信 |
standard(標準) |
192×108 | 4色 | 15 fps | 2,832 B |
41.5 KB/s(33.2 KB/s) |
約 9.7 MB
|
PC・タブレット等の標準画面からのブラウザ送信 |
fast(高速) |
256×144 | 8色 | 30 fps | 8,496 B |
248.9 KB/s(199.1 KB/s) |
約 58.3 MB
|
60fps・8色読取が計測されたブラウザまたは手動選択時 |
fastest(最速) |
320×180 | 4色 | 60 fps | 9,027 B |
528.9 KB/s(423.1 KB/s) |
64.0 MB |
大画面×120fpsカメラ向けのプロトコル定義 |
| 送りたいデータの目安 |
standard(上限 9.7 MB) |
compact(上限 3.5 MB) |
stable(上限 0.8 MB) |
fast(上限 58.3 MB) |
運用の目安 |
|---|---|---|---|---|---|
設定ファイル・ログ(10 KB) |
約 0.2 秒 | 約 0.7 秒 | 約 3 秒 | 約 0.1 秒 | 数フレームの撮影で完了 |
圧縮済み写真1枚(約 300 KB) |
約 7.3 秒 (25%欠損: 10.3秒) |
約 20 秒 (25%欠損: 29.0秒) |
約 1分31秒 (25%欠損: 137秒) |
約 1.2 秒 | 4〜8 MBの元写真も画像設定「標準(長辺1280px)」や「軽量(長辺800px)」でこの帯域に収まる |
PDF・写真数枚(2 MB) |
約 50 秒 (20%損失: 約1分) |
約 2分19秒 (20%損失: 約2分50秒) |
上限超過(0.8 MBまで) | 約 8 秒 (20%損失: 約10秒) |
スマートフォン送信時は端末を机やスタンドに置くと安定する |
複数ファイル・資料(9.7 MB) |
約 4分 (20%損失: 約5分) |
上限超過(3.5 MBまで) | 上限超過(0.8 MBまで) | 約 40 秒 (20%損失: 約50秒) |
standard モードでの1セッション上限 |
上表の所要時間は理論値および合成カメラでのシミュレーション値であり、実機ブラウザでの機種別実測値は現時点で未計測です。
用語集
| 用語 | 意味と Beamlet での役割 |
|---|---|
BOS1(Beamlet Optical Stream v1) |
Beamlet が採用している光学ストリームプロトコル。事前の公開鍵QR読み取りと、単方向のカラーグリッド連続表示を組み合わせて暗号転送を行う |
| オフラインPWA(Progressive Web App) | 初回アクセス時にプログラム一式をブラウザ内へ保存し、2回目以降は機内モードや圏外でもサーバー通信なしで起動・動作するWebアプリの仕組み |
X25519 / HKDF-SHA256
|
楕円曲線ディフィー・ヘルマン鍵共有(X25519)と鍵導出関数(HKDF-SHA256)。受信画面に表示した使い捨て公開鍵QRを送信側カメラで1回読み取るだけで、周囲に盗聴されないセッション鍵を2台の間だけで共有する |
ChaCha20-Poly1305(認証付き暗号 / AEAD) |
データの暗号化と改ざん検知タグ(認証タグ)の付与を同時に行う暗号方式。Beamlet ではファイル一覧とファイルを 64 KiB ごとにこの方式で暗号化する |
RaptorQ(噴水符号 / Fountain Code) |
元データから任意の数の符号断片(シンボル)を作り出す誤り訂正符号(RFC 6330)。途中のフレームを取りこぼしても、到着順を問わず必要数のシンボルが集まった時点で元ファイルを復元できる |
Reed-Solomon(リード・ソロモン符号) |
1フレーム内の各水平帯タイルに検査データを付加する誤り訂正符号。カメラのノイズや色滲みで数セルの読み違いが起きてもタイル単位で訂正し、訂正しきれない破損は CRC-32 検算で破棄する |
| ローリングシャッター(Rolling Shutter) | カメラのセンサーが画面の上端から下端へ時間差で走査・露光する仕組み。画面の切り替わりと重なると1枚の撮影画像の上下に別々のフレームが写り込むため、Beamlet は1フレームを9〜16本の独立した水平帯タイルに分けて上下両方を回収している |
| 樽型レンズ歪み(Barrel Distortion) | スマートフォンの広角レンズ等で画面に近づいた際、正方形のグリッドの外周が樽のように丸く膨らんで写る歪み。4隅のマーカーと内部の基準点から座標を逆算して補正する |
| 最小二乗法による色補正 | 画面の上下に配置した基準パレット帯とデータセル全体の色の偏りから、ディスプレイの色温度やピンぼけによる白枠の色滲みを数式で推定し、1フレームごとに色の判定境界を合わせ直す処理 |
EXIF(イグジフ) |
撮影した写真に記録される撮影日時・カメラ機種・GPS位置情報などの付加データ。Beamlet は送信前にブラウザ内で画像を再エンコードすることで位置情報などを自動除去できる |
公開サイト・リポジトリ
- Webアプリ(オフラインPWA):https://simota.github.io/beamlet/
- GitHub リポジトリ:https://github.com/simota/beamlet(Rust / WebAssembly 製のプロトコル実装、静的Webアプリ、光学計測CLIを収録)


