Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
RRC_steganography — 回転レンジコーディングを介してLLM生成テキストに秘密メッセージを埋め込む、証明可能な安全な言語ステガノグラフィー。埋め込み、抽出、ラウンドトリップ検証スクリプトが含まれています。 | Kitploit
ツール/GitHubGitHub/ryehr/rrc_steganography
ステガノグラフィー暗号化機械学習論文と研究学習と教育AIセキュリティ
GitHubryehr/rrc_steganography

RRC_steganography

回転レンジコーディングを介してLLM生成テキストに秘密メッセージを埋め込む、証明可能な安全な言語ステガノグラフィー。埋め込み、抽出、ラウンドトリップ検証スクリプトが含まれています。

リポジトリを見る
61801ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

RRC Steganography

Rotation Range-Coding (RRC) Steganography — 大規模言語モデルによって生成された自然言語テキストに秘密メッセージを埋め込む、効率的かつ証明可能に安全な言語的ステガノグラフィ手法。

論文: Efficient Provably Secure Linguistic Steganography via Range Coding (ACL 2026)

仕組み

ステップ説明
埋め込み (アルゴリズム 3)秘密メッセージを10進数値に変換し、LMの確率分布とPRNG生成オフセットに導かれながら、縮小する区間内で反復的に回転させる。各回転ステップが1つのトークンを生成する。
抽出 (アルゴリズム 4)ステゴテキスト上でLMを再実行して区間の境界を復元し、元の10進数値へ逆回転してから二値化する。

回転メカニズムは、バニラなレンジコーディング・ステガノグラフィの2つの問題を解決する:

  1. 確率分布の保持 — 回転された秘密値は各区間内で一様に分布するため、トークン選択は元のLM分布に従う。
  2. 新鮮なランダム性 — 各ステップで新しいPRNGオフセットを用いることで、ランダム性の再利用を防ぐ。

リポジトリ構造

.
├── rrc_core.py        # Algorithms 3 and 4, shared by every entry point
├── RRC_embed.py       # Embedding CLI
├── RRC_extract.py     # Extraction CLI (reports recovery accuracy)
├── test_roundtrip.py  # Round-trip test across several message lengths
├── fastest_embed.py   # Embedding-speed benchmark
├── 0.Prompts.tsv      # 1000 prompts (first ~10 words of C4 sequences)
└── requirements.txt

エンコーダとデコーダは、ループの別々のコピーを保持するのではなく、rrc_core.py を共有する。両者はビット単位で一致しなければならず、独立に保守された2つのコピー間の相違は、ラウンドトリップの失敗としてのみ表面化し、目視では決して現れない。

要件

  • Python >= 3.10
  • PyTorch >= 2.0
  • Transformers >= 4.35 (5.x までテスト済み)
pip install -r requirements.txt

クイックスタート

1. 正しさの検証

python test_roundtrip.py                                  # GPT-2, 32/128/512 bits
python test_roundtrip.py --model meta-llama/Llama-2-7b-hf

2. 埋め込み

python RRC_embed.py \
    --language_model meta-llama/Llama-2-7b-hf \
    --bit_length 128 --key 42 --top_k -1

3. 抽出

python RRC_extract.py \
    --language_model meta-llama/Llama-2-7b-hf \
    --bit_length 128 --key 42 \
    --input_file 1.RC_decimal_Llama-2-7b-hf_bit128.tsv

エンコーダは、埋め込んだ秘密とそれを運んだトークンIDを記録するため、抽出は復元率を報告する。2つの受信側モデルが評価される:

  • ids — 受信側にはトークン列が与えられる。これは符号化方式を分離する。100%未満は数値的または論理的な障害である。
  • text — 受信側にはデトークン化された文字列が与えられ、テキストチャネルが必要とするように再度トークン化される。再トークン化は送信側の分割を常に再現するとは限らないため、これは下限値である。2つの測定値の差は、符号化方式ではなくトークン化の曖昧さを表す。Llama-2-7b の128ビットでは: ids は100%、text は約91%。

重要: 送信側と受信側は、言語モデル、キー、ビット長、top-k設定を共有しなければならず、また同じハードウェアとライブラリのバージョンで実行する必要がある。数値要件を参照。

CLI引数

RRC_embed.py と RRC_extract.py で共有:

引数デフォルト説明
--language_modelmeta-llama/Llama-3.1-8BHuggingFaceモデルID
--bit_length128ビット単位の秘密メッセージ長
--top_k-1Top-k切り捨て; -1 = 全語彙
--key42対称鍵 K (PRNGシード)
--precision_margin402**bit_length が必要とする桁数を超える10進桁数
--max_ctx_len3900KVキャッシュウィンドウ
--deviceautocuda または cpu

RRC_embed.py はさらに --prompts、--output、--limit、--seed、--max_tokens、--resume、--no_verify、およびプロンプトセットをプロセス間でシャーディングするための --part / --part_max を受け取る (--part_max 3 と --part 0,1,2 で、GPUごとに1つ)。

RRC_extract.py はさらに --input_file、--mode {ids,text,both}、--limit、--verbose を受け取る。

数値要件

RRCは幅 2**l の区間を幅 ~1 まで狭めるため、復元値は 2**l 倍の相対誤差に敏感である: 128ビットでは、チェーン内のどこかで1e-16の相対摂動が、0.5の許容範囲に対して結果を ~1e22 変位させる。抽出は緩やかに劣化しない — メッセージを返すか、無関係なビットを返すかのどちらかである。Llama-2-7b での測定:

設定確率の相対摂動抽出
同じバッチ1デコードの繰り返し0 (ビット単位で同一)成功
バッチ2 / 8 / 16 での同じ行~1e-2失敗
プロンプトの左パディング~1e-2失敗
インクリメンタルデコードの代わりに1回のteacher-forcedパス~4e-3失敗

2つの帰結が実装を形作る。バッチ処理は利用できないため、シーケンスは1つずつ処理される。そして受信側は、すべてのトークンを事前に保持していても、ステゴテキストを単一のフォワードパスでスコアリングするのではなく、送信側のインクリメンタルデコードをステップごとに再生する。どちらのショートカットも約9倍高速だが、どちらも確率を保持しない。

ロジット以降はすべてfloat64であり、CPUとGPUでビット単位で同一の境界を生成するため、フォワードパスがステゴテキストをハードウェアに結びつける唯一のステップである。

10進精度

精度はメッセージ長から ceil(bit_length * log10(2)) + margin として導出され、他の何かが実行される前に設定される。これはメッセージに応じてスケールする: 2**256 は78桁、2**8192 は2466桁を必要とする。

その閾値を下回る精度は、きれいに失敗しない。秘密値の下位桁が丸められ、区間は数トークン以内に崩壊し、終了テストが早期に発火するため、実行は完了し、算術的に到達不可能な数値を報告することがある。メッセージ長に関係なく精度を50桁に固定すると:

bits50桁での利用率完了したサンプル導出精度の場合
256157.05%8/20100.17%
512299.67%9/20102.48%
1024660.91%7/10102.58%
20481046.40%1/598.18%
40962483.92%3/3, エラーなし100.87%
81924766.49%1/299.07%

--precision_margin は導出された最小値に対する余裕を調整する; 最小値自体は強制される。

検証済みの終了

アルゴリズム 3 は (L + R) / 2 - d_s が (-0.5, 0.5] に入ったときに停止する。このテストは、区間が1より狭いときに発火することがあり、その場合ウィンドウ [mid - 0.5, mid + 0.5) はそれを運ぶ区間より広くなる。逆回転は区間幅を法とする等長変換であるため、切断部をまたぐウィンドウは受信側を d_s から丸々1区間離れた位置に残す。

したがって送信側は、停止を確定する前に受信側の逆回転を再生し、再生が秘密を返さない場合は別のトークンを出力する。再生は純粋なDecimal演算 (フォワードパスの約20 msに対して約0.05 ms) であるため、ガードは測定可能なコストを要しない。--no_verify はこれを無効にする。

Llama-2-7b での測定:

bitsガードなしで復元ガードあり
128291/300 (97.0%)300/300
51264/65 (98.5%)40/40
102420/2020/20
204810/1010/10

128ビットでは、ガードは追加生成トークンの0.095%のコストであった。1024ビットと2048ビットのサンプルはレートを制限するには少なすぎる — 3%のレートでは0/20がそうでない場合よりも起こりやすい結果である — ため、これらは長いメッセージが異なる挙動をする証拠にはならない。ガードありでは、370/370が復元された。

ガードなしでは、送信側は違いを判別できない: 成功を報告し、無関係なビットにデコードされるステゴテキストを出力する。レートは抽選によって変動する; ある99プロンプトの実行では皆無であり、これは3%のレートで約5%の確率で生じ、再実行すると正確に再現される。同じサンプルは45桁から200桁までのあらゆる実用精度で失敗するため、この挙動は算術ではなく終了テストに起因する。

ガードは、それを無効にして埋め込み、実際の抽出器を実行することでグラウンドトゥルースと照合された: それがフラグを立てるサンプルは、受信側が失敗するサンプルと正確に一致し、偽陽性も見逃しもなかった。

パフォーマンスに関する注記

LMのフォワードパスは、Llama-2-7b での生成ステップの95–97%を占め、7B fp16モデルのバッチ1デコードはメモリ帯域幅のルーフライン上にある (測定値約18.7 ms/トークンに対して約13.5 ms/トークン)。したがって埋め込み速度はモデルのデコード速度に追随し、符号化自体はそれにほとんど影響しない。

より小さなモデルではフォワードパスがもはや支配的ではなくなり、ステップごとのCPU作業が可視化される。GPT-2 の128ビット、共有マシン上でセルあたり100メッセージのエンドツーエンド測定:

torch CPUスレッドbits/s
11320, 1205
161232, 756
20 (torchデフォルト)352

スループットは、符号化パス内の何かではなく、CPUスレッドの競合によって左右され、マルチスレッドの数値は実行ごとに再現しない。したがってすべてのエントリポイントは torch.set_num_threads(1) を呼び出す: ここでの各CPU演算は単一の語彙サイズのパスであり、スレッドプールから利益を得るには小さすぎ、プールが他の作業と競合すると大きく損をするほど大きい。これは予測可能性をもたらすのであって、アイドルマシンでの高速化ではない。

残りのステップごとの選択は、単独では安価であり、1スレッドでのエンドツーエンドスループットを測定可能なほど変えない; コストがかからないために採用されている:

  • エントロピーは、別のGPUカーネルと同期ではなく、ステップがすでに必要とする確率のホストコピー上で削減される。これは報告される統計であり、符号化にフィードバックされない。
  • 候補選択は単調な境界述語を二分探索し、スキャンされる候補ごとに1つではなく、ステップごとに約15のDecimal積を評価する。これは最悪ケースを制限する; 線形スキャンはプロファイリングでインデックス2923に達した。
  • 境界は、トークンごとに語彙サイズのテンソルを割り当てるのではなく、事前に割り当てられたバッファに書き込まれる。
  • 生成がトークン予算を超えるプロンプトは、新しい秘密で再試行するのではなくスキップされる: 予算はプロンプトのエントロピーに依存するため、メッセージを引き直しても結果は変わらない。
  • ロジットは min(config.vocab_size, len(tokenizer.vocab)) にスライスされ、トークナイザと整合される。これにより埋め込み行列の再割り当てを避け、モデルオブジェクトをそのままに保つ。これは同じモデルが実行間で共有される場合に重要である。

測定されたスループット

128ビットメッセージ、全語彙、temperature 1.0、RTX 6000 Ada、1 CPUスレッド、それ以外はアイドル状態のGPU。モデルあたり100メッセージ (Llama-2-7b は60)、すべてがラウンドトリップされチェックされた:

modelembedextracttokens/msgutilisation
GPT-21386 bits/s1385 bits/s22.399.4%
OPT-1.3b754 bits/s753 bits/s30.498.7%
Llama-2-7b183 bits/s183 bits/s45.498.9%

抽出は埋め込みと同じ速度で実行される。どちらもトークンごとに1回のフォワードパスを実行し、逆回転チェーンはそれらに比べて無視できるからである。

スループットはGPU上の他のジョブに影響されない — 完全に負荷のかかったカードでも同じ数値が数%以内で返る — なぜならワークロードはデバイスを飽和させるものではなく、レイテンシに縛られた単一トークンのフォワードパスの連鎖だからである。実行間の約6%の変動は、抽選されたプロンプトに由来する: bits/s は bit_length / time であり、時間はメッセージが必要とするトークン数に比例するため、低エントロピーのプロンプトのサンプルはより遅く読める。

技術的な注記: Decimalの剰余

Pythonの Decimal の % は切り捨て除算を使用し、負の剰余を返すことがある (Decimal('-19672') % Decimal('65536') は 45864 ではなく -19672 を返す)。逆回転は真の剰余を必要とするため、decimal_mod は床除算のセマンティクスを使用する:

def decimal_mod(a, m):
    return a - m * (a / m).to_integral_value(rounding=ROUND_FLOOR)

引用

ツールをダウンロード