
op4 — セキュアターミナルメッセンジャー
Op4 は Rust で書かれたターミナルベースの暗号化メッセージングアプリケーションです。ポスト量子暗号によるエンドツーエンド暗号化プライベートメッセージングを提供し、すべてのトラフィックは Tor ネットワーク経由でルーティングされるため、メッセージの内容も IP アドレスも、通信相手を含む誰にも公開されません。
op4 を使用すると、双方が IP アドレスや実の身元を明かすことなくプライベートメッセージを交換できます。すべてのメッセージは次のようになります。
op4 は完全にターミナル内で動作します。GUI もブラウザコンポーネントもクラウドアカウントもありません。接続する外部プロセスは、自分のマシンで動作している Tor デーモンだけです。
すべてのダウンロード方法 — AppImage、ソース tarball、clone & build、および 自動インストーラー — は ダウンロード & インストールガイド に記載されています。 最新リリースは リリースページ から入手できます。
Debian と Ubuntu では、install/setup.sh が Rust ツールチェーン、ビルド依存関係、Tor、コントロールポート設定、バイナリのコンパイル、システムユーザー、データディレクトリ、AppArmor プロファイルをすべて 1 つのコマンドで処理します。
git clone https://github.com/Opfour/op4.git
cd op4
sudo bash install/setup.sh
スクリプトの実行後、op4 を起動する前に一度ログアウトして 再ログインする必要があります。 インストーラーは Tor クッキーファイルを 読み取れるように、あなたのユーザーを
debian-torグループに追加します。 Linux ではグループ変更は既に開かれているセッションには適用されません — 新しいログインが必要です。この手順を省略すると、起動時に op4 は次のエラーで失敗します:
Permission denied reading /run/tor/control.authcookie
その後、バイナリを信頼する前に、スクリプトが出力したソースハッシュが、あなたのバージョンの公開されたリリースハッシュと一致することを確認してください。
op4 は起動時に、すべての Rust ソースファイル、Cargo.toml、Cargo.lock、build.rs を対象としたソースハッシュを表示します。インストールしたバージョンの以下の値と比較してください。
フルアプリを起動せずに確認することもできます:
op4 --print-hash
ハッシュが一致しない場合は、そのバイナリを使用しないでください — 別のコミットからビルドされたか、改ざんされています。
最初に依存関係をインストールし、その後スクリプトを実行します:
Rust ツールチェーン (rust-toolchain.toml で 1.89.0 に固定):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
Tor とビルド依存関係:
# Fedora
sudo dnf install tor gcc pkg-config openssl-devel
# Arch
sudo pacman -S tor base-devel pkg-config openssl
Tor コントロールポートの設定 — /etc/tor/torrc に追加:
ControlPort 9051
CookieAuthentication 1
sudo systemctl restart tor
ユーザーを Tor グループに追加:
sudo usermod -aG tor $USER # Fedora / Arch
この手順の後、ログアウトして再ログインする必要があります。 グループメンバーシップの変更はアクティブなセッションには適用されません。再ログインするまで、op4 は
Permission denied reading /run/tor/control.authcookieで失敗します。完全なログアウトなしで変更を適用するには、次を実行します:
newgrp tor
ビルドとインストール:
git clone https://github.com/Opfour/op4.git
cd op4
cargo build --release
sudo bash install/setup.sh
op4
# or, without system install:
./target/release/op4
初回起動時に op4 は通常のパスフレーズとデュレスパスフレーズの設定を案内し、その後アイデンティティキーを生成します。ボールトは ~/.local/share/op4/vault.op4 に保存されます。
最小カーネル: 4.15 (5.4+ 推奨)。アーキテクチャ: x86-64 (aarch64 は動作するはずですが未テストです)。
2 人はそれぞれ op4 のインストール、Tor の実行、ボールトのロック解除が必要です。交換は非対称です。一方が先にコンタクトコードを送り、もう一方がそれを追加して最初のメッセージを送信します。そのメッセージは保留中のリクエストとして届き、最初の人が承認します。
初回実行時に op4 は 通常のパスフレーズ と デュレスパスフレーズ を要求し、その後アイデンティティキーを生成します。これは一度だけ行われます。ボールトは ~/.local/share/op4/vault.op4 に保存されます。
$ op4
コンタクトコードには、完全な公開鍵バンドルと .onion アドレスが含まれています。相手があなたに到達するにはこれが必要です。
2 または → を押す)e を押してコンタクトコードをエクスポートしますop4: で始まる長い Base58 文字列ですコンタクトコードは秘密ではありません。公開しても安全です。 公開鍵と onion アドレスのみが含まれており、秘密の情報は一切含まれません。
相手のコンタクトコードを入手したら:
a を押して連絡先を追加しますop4: コンタクトコードを貼り付けて Enter を押します↑/↓ を使用し、その後 Enter)3 または → を押す)この最初のメッセージは暗号化ハンドシェイクを開始し、Tor 経由で相手の .onion アドレスに配信されます。相手には 保留中のコンタクトリクエスト として表示されます。
誰かが最初のメッセージを送信すると、連絡先タブに待機中のリクエスト数を示すバッジが表示されます。
2 を押す)p を押して保留中のリクエストを確認しますEsc を押すと拒否して破棄します)承認すると Double Ratchet が初期化され、会話はすぐにメッセージタブで利用可能になります。
連絡先を信頼する前に、相手が自分の画面で表示しているものとフィンガープリントが一致することを確認してください。これにより、最初のコンタクト交換中の中間者攻撃を防ぎます。
A3F2:91BC:…)アイデンティティキーが危険にさらされている可能性がある場合:
4 を押すか右に移動)r を押してキーをローテーションしますop4 は前方秘匿性のため、Double Ratchet プロトコル (Signal Protocol に類似) を使用します。つまり、次のことを意味します:
KEM ステップは X25519 と ML-KEM-768 を次のように組み合わせます:
shared_secret = HKDF(X25519_ss || MLKEM_ss)
攻撃者は鍵交換を破るために 両方 のアルゴリズムを破らなければなりません。これにより、量子敵対者 (ML-KEM-768) から保護しつつ、ML-KEM-768 に未知の欠陥がある場合でも古典的な攻撃に対して安全を維持します (X25519 フォールバック)。
メッセージは共有ラチェット状態から導出された鍵を使用して HMAC-SHA256 で認証されます。双方が同じ HMAC 鍵を保持しているため、どちらの当事者も任意の MAC を生成できた可能性があります。これは OTR や Signal でも使われているのと同じ否認可能性の特性です。メッセージは法的手続きにおいて暗号学的に特定の送信者に帰属させることができません。
~/.local/share/op4/vault.op4 のボールトファイルには、すべての連絡先、会話、アイデンティティキーが保存されます。これは 2 つの独立した Argon2id 導出キーで保護されています:
op4 は受信箱用に Tor v3 ヒドゥンサービスを作成します。.onion アドレスはアイデンティティキーから (HKDF 経由で) 決定的に導出されるため、別の鍵を保存する必要なく再起動後も安定しています。送信メッセージは Tor SOCKS5 プロキシを経由して送信されます。実際の IP アドレスは op4 に関連するネットワークパケットに一切現れません。
カバートラフィック (ポアソン分布に従い自分宛に送信されるダミーメッセージ、平均間隔 30 秒) により、ネットワーク観測者はトラフィック量を監視しても、あなたが誰かと活発にメッセージをやり取りしているかどうかを知ることができません。
apparmor/op4.profile) — ファイルシステムへのアクセスを、ボールトディレクトリ、端末デバイス、Tor のみに制限します。┌─────────────────────────────────────────────────────────────┐
│ op4 process │
│ │
│ ┌──────────┐ ┌──────────────────┐ ┌────────────────┐ │
│ │ TUI │ │ Double Ratchet │ │ Tor Transport │ │
│ │ (ratatui)│──▶│ + Hybrid PQ │──▶│ nym_client.rs │ │
│ │ │ │ Crypto │ │ │ │
│ └──────────┘ └──────────────────┘ └───────┬────────┘ │
│ │ │
│ ┌──────────────────────────────┐ │ │
│ │ Encrypted Vault │ SOCKS5 / control port │
│ │ ~/.local/share/op4/vault.op4│ │ │
│ └──────────────────────────────┘ │ │
└────────────────────────────────────────────────┼───────────┘
│
┌────────────▼────────────┐
│ Tor daemon │
│ 127.0.0.1:9050 (SOCKS) │
│ 127.0.0.1:9051 (ctrl) │
└────────────┬────────────┘
│
Tor network
│
┌────────────▼────────────┐
│ Peer's .onion address │
│ (their hidden service) │
└─────────────────────────┘
op4/
├── src/
│ ├── main.rs Entry point, startup sequence
│ ├── error.rs Unified error types
│ ├── crypto/
│ │ ├── keys.rs Hybrid KEM + signature keypairs
│ │ ├── primitives.rs AEAD, HKDF, HMAC, Argon2id
│ │ ├── ratchet.rs Double Ratchet implementation
│ │ ├── hmac_auth.rs Deniable authentication tags
│ │ └── handshake.rs Initial key agreement (X3DH-style)
│ ├── network/
│ │ ├── nym_client.rs Tor hidden-service transport
│ │ └── message.rs Wire message format + padding
│ ├── storage/
│ │ └── vault.rs Encrypted vault (Argon2id + AEAD)
│ ├── identity/
│ │ ├── profile.rs Contact codes, stored contacts
│ │ └── revocation.rs Key revocation records
│ ├── hardening/
│ │ ├── memory.rs mlockall, RLIMIT_CORE, dumpable
│ │ └── seccomp.rs seccomp-bpf syscall filter
│ └── ui/
│ ├── app.rs TUI event loop and state machine
│ ├── contacts.rs Contacts tab rendering
│ ├── conversation.rs Messages tab rendering
│ ├── settings.rs Settings tab rendering
│ ├── duress.rs Duress inbox rendering
│ ├── input.rs Input sanitization (CSI/OSC strip)
│ └── passphrase.rs Secure passphrase prompts
├── apparmor/
│ └── op4.profile AppArmor MAC profile
├── install/
│ └── setup.sh System installation script
├── build.rs Embeds source hash at compile time
├── deny.toml cargo-deny licence + advisory rules
├── rust-toolchain.toml Pins Rust 1.89.0
└── docs/ This documentation
バージョン: 0.2.0-dev (プレリリース)
op4 は活発に開発中です。以下のレイヤーは完成しておりテスト済みです:
すべてのレイヤーがエンドツーエンドで接続されました:
PublicKeyBundle (完全な公開鍵セット + onion アドレス) を生成します。既知の制限はすべて解消されました。アプリケーションは 0.2.0-dev の機能完成ステータスに達しています:
HMAC 否認可能認証 は完全に配線されています。すべての送信データメッセージには、各メッセージのラチェット鍵から (conversation_id || message_counter || ciphertext) に対して計算された HMAC-SHA256 タグが含まれます。受信メッセージは受け入れ前に検証されます。後方互換性のため、古いピアからのゼロ埋めタグは許容されます。
メッセージ履歴は再起動後も保持されます。 完全な会話ログは、会話ごとの HKDF 導出鍵で暗号化され、ボールトの message_log_ct フィールドに保存されます。メッセージは会話を開いたときにボールトから読み込まれ、送受信のたびに書き戻されます。
受信コンタクトリクエスト は、未知の相手からのものでも破棄されずにキューに入れられます。リクエストが待機中の場合、連絡先タブにバッジが表示されます。[p] を押して確認します。送信者のフィンガープリントと最初のメッセージが表示され、名前を入力して Enter を押すと承認されます (Esc で拒否)。承認すると連絡先が追加され、Double Ratchet が初期化され、最初のメッセージがボールトに保存されます。
デュレスボールトは保存後も保持されます。 ボールトファイル形式 (v2) はヘッダーに正確な暗号文長を保存するため、AEAD 復号はゼロパディングされたセクションではなく実際のバイトに対して動作します。暗号化されたデュレスセクションは save() 呼び出しのたびにそのまま保存され、デュレスパスフレーズを無期限に有効に保ちます。
専用の Double Ratchet ブートストラップ鍵。 別の X25519 鍵ペア (identity_ratchet_secret) が初回実行時に生成され、コンタクトコードに ratchet_pub として含まれます。Alice のラチェットは Bob の KEM アイデンティティ鍵ではなく ratchet_pub で初期化され、鍵の役割が分離されます。
設定タブは完全に機能します。 Tor SOCKS5 アドレスと自動削除のしきい値はインラインで編集できます。キーローテーション (新しい鍵ペアの生成、署名付き失効証明書の全連絡先へのブロードキャスト、エクスポートコードの更新) とキー失効のリタイアメントはともに配線済みで動作します。
キー失効はエンドツーエンドで配線されています。 RevocationCertificate 構造体はハイブリッド Ed25519+ML-DSA-65 鍵ペアで署名され、Tor 経由で メッセージとしてすべての連絡先に送信されます。
| バージョン | ソースハッシュ |
|---|
0.3.0 | 80820cb41a63575d2c139dadd425d13d1e87e62a9d60200ae7b894ae2e9ad8ed |
0.3.1 | 48115efb12747fa78b627ddbf7a56c46169f59e777d7d7508941bf89e4fe7521 |
0.2.0-dev | 35740577f6c4a4f19c5a08fe85b1f78a10347f2ba9dd7642d126552266bfa5a5 |
0.1.0 | e1a94761c7d3fa589ba892b47d5295aa417f95aee126809d51a7e7fb7e78982c |
| ディストリビューション | ステータス |
|---|
| Ubuntu 22.04 / 24.04 | サポート |
| Debian 12 | サポート |
| Fedora 39+ | サポート |
| Arch Linux (current) | サポート |
| Tails OS | サポート (セットアップガイド) |
| macOS / Windows / WSL1 | サポート対象外 |
| キー | 操作 |
|---|
1 / ← → | タブを切り替え (連絡先 / メッセージ / 設定) |
↑ ↓ | 選択を移動 |
Enter | 会話を開く / 確定 |
Esc | キャンセル / 戻る |
e | コンタクトコードをエクスポート (連絡先タブ) |
a | 連絡先を追加 (連絡先タブ) |
p | 保留中のリクエストを確認 (連絡先タブ) |
d | 選択中の連絡先を削除 (連絡先タブ) |
r | キーをローテーション (設定タブ) |
q | 終了 |
| 用途 | アルゴリズム |
|---|
| ボールトの鍵導出 | Argon2id (m=64 MiB, t=3, p=1) |
| ボールトの暗号化 | ChaCha20-Poly1305 (256-bit key, 96-bit nonce) |
| メッセージの暗号化 | ChaCha20-Poly1305 (per-message key from ratchet) |
| 鍵導出 (ラチェット) | HKDF-SHA256 |
| 否認可能な認証 | HMAC-SHA256 |
| 古典的な鍵交換 | X25519 |
| ポスト量子鍵交換 | ML-KEM-768 (FIPS 203) |
| 古典的な署名 | Ed25519 |
| ポスト量子署名 | ML-DSA-65 (FIPS 204) |
| トランスポートの匿名性 | Tor v3 hidden services (.onion) |
WireMessageType::Revocation