
Intégrer plusieurs messages secrets dans les choix de jetons de chat LLM à l'aide de codeurs stéganographiques arithmétiques/Discop, avec décodage bit-exact et évaluation de la stéganalyse.
Code de recherche pour la stéganographie linguistique dans les dialogues de chat par LLM, avec une baseline mono-flux et un protocole multi-flux (HiTMS) par lots qui dissimule plusieurs messages secrets indépendants à la fois et exploite le traitement par lots sur GPU pour un débit bien plus élevé.
Un modèle Bob pose des questions ; un modèle Alice répond, encodant secrètement la charge utile dans ses choix de jetons via un codeur stéganographique ; Bob réexécute le modèle sur la réponse d'Alice pour récupérer les bits. L'encodage et le décodage sont exacts au bit près, de sorte que le secret est récupéré sans perte.
arithmetic*.py)discop*.py)single_stream.py) : aucun surcoût de trame — chaque
bit de canal est de la charge utile (~100 % d'utilisation).protocol.py) : flux secrets fragmentés
sur plusieurs tours, un mappage flux→emplacement piloté par PRF, des emplacements leurres, des en-têtes de longueur
16 bits et un flux de remplissage. Plusieurs réponses par tour sont générées en
, donc le débit évolue avec la taille du lot.Modèles utilisés dans les expériences : meta-llama/Llama-3.2-3B-Instruct et
google/gemma-3-4b-it. Jeux de données : sous-ensembles créatifs/à réponse libre de
databricks/databricks-dolly-15k et HuggingFaceH4/no_robots.
| Chemin | Description |
|---|---|
arithmetic.py, arithmetic_batch.py | Stégo par codage arithmétique (codeur/décodeur mono-flux + par lots). |
discop.py, discop_batch.py | Codeur stégo Discop + PRG partagé (mono-flux + par lots). |
utils.py | Utilitaires partagés (conversion bits/entiers, entropie, top-k, vérifications de fin de phrase). |
protocol.py | Protocole multi-flux HiTMS (mappage de flux, leurres, en-têtes, remplissage). |
single_stream.py | Protocole mono-flux (sans trame ; troncature au L-ième bit). |
round_trip.py, batch_round_trip.py | Démonstrations/tests minimalistes d'aller-retour en un coup. |
multi_round_demo.py | Exécuteur d'essais multi-flux (run_trial) + démo verbose d'un seul essai. |
single_stream_demo.py | Exécuteur d'essais mono-flux (run_single_trial) + démo. |
run_sweep.py | Balayage multi-flux sur {modèle}×{pool}×{codeur}, reprenable. |
run_single_sweep.py | Balayage équivalent mono-flux. |
run_scaling_sweep.py | Balayage de montée en charge du nombre de flux (x ∈ {1,2,4,8,16,32,64}), tout modèle/pool/codeur. |
run_x1_shards.py, run_x1_finish.sh, merge_x1_shards.py | Ablation x=1 : fragmenter une cellule sur plusieurs GPU, puis fusionner avec vérifications de couverture. |
judge_quality.py | Scoreur d'imperceptibilité par LLM-juge (un QA par appel, reprenable). |
gen_cover.py | Génération de texte « cover » sans charge utile (référence pour la stéganalyse). |
steganalysis_bert.py | Détecteur cover-vs-stégo (BERT / RoBERTa / DeBERTa-v3 / ELECTRA). |
export_data.py | Construit le miroir publiable limité aux résumés dans . |
data/ contient les résultats de chaque expérience de l'article — capacité,
débit, utilisation, scores du juge et AUROC du détecteur — sous forme d'un objet JSON
par essai. Voir data/README.md pour le schéma complet.
Le stégotexte généré lui-même n'est pas inclus : les journaux bruts intègrent la
question et la réponse pour chaque fragment, ce qui les rend d'environ 1 Go ; aussi
export_data.py supprime ces champs et conserve toutes les mesures (~24 Mo). Tous
les pilotes sont ensemencés, donc relancer un balayage régénère le texte à l'identique.
Les répertoires de sortie bruts (
sweep_logs/,single_sweep_logs/,scaling_logs/,judge_logs/,cover_logs/,run_logs/,steganalysis_logs/) sont gitignorés — ils sont volumineux (le dernier contient des points de contrôle de détecteurs entraînés de plusieurs Go) et entièrement régénérables.
conda create -n ems python=3.10 -y && conda activate ems
pip install torch transformers datasets numpy
pip install openai # only needed for judge_quality.py
Une GPU CUDA est requise pour exécuter les LLM. Les points de contrôle Llama et Gemma sont
soumis à un contrôle d'accès sur le Hugging Face Hub ; exécutez donc huggingface-cli login (avec un accès
accordé à ces modèles) avant la première utilisation.
Construisez les pools de questions (une fois) :
python build_question_pool.py # -> dolly15k_creative_questions.json
python build_norobots_pool.py # -> norobots_creative_questions.json
Essai unique verbeux (vérification de cohérence) :
# multi-stream
CUDA_VISIBLE_DEVICES=0 python multi_round_demo.py
# single-stream
CUDA_VISIBLE_DEVICES=0 python single_stream_demo.py
# override model / coder / pool via env
ROUND_TRIP_MODEL=google/gemma-3-4b-it STEGO_ALGORITHM=discop \
STEGO_QUESTION_POOL=norobots_creative_questions.json \
CUDA_VISIBLE_DEVICES=0 python multi_round_demo.py
Expériences complètes (reprenables — relancez la même commande pour continuer) :
# multi-stream (8 streams x 1024 bits), all model/pool/coder combos, 500 trials
CUDA_VISIBLE_DEVICES=0 python run_sweep.py --trials 500
# single-stream baseline
CUDA_VISIBLE_DEVICES=0 python run_single_sweep.py --trials 500
# stream-count scaling (dolly + Llama + Discop)
CUDA_VISIBLE_DEVICES=0 python run_scaling_sweep.py --x-values 4 8 16 32 64
Évaluation de l'imperceptibilité (nécessite une clé OpenAI dans OPENAI_API_KEY ou un
fichier local OPENAI_API_key.txt, tous deux gitignorés) :
python judge_quality.py --dry-run # plan only, no API calls
python judge_quality.py --limit 2 # tiny live smoke test
python judge_quality.py # full run (resumable)
python judge_quality.py --aggregate-only # recompute the score table
Chaque pilote fixe ses graines (mélange des prompts, échantillonnage de la charge utile, RNG d'échantillonnage,
torch.manual_seed) et consomme les prompts depuis un flux de prompts déterministe et
sensible à la passe, de sorte qu'un balayage complet est reproductible de bout en bout et reprend exactement
depuis son point de contrôle après une interruption.
OPENAI_API_key.txt, *.key et .env sont ignorés.data/build_question_pool.py, build_norobots_pool.py | Construisent les pools de questions à partir des jeux de données HF. |
*_creative_questions.json | Pools de questions pré-construits. |
legacy/ | Scripts / pools antérieurs, conservés pour référence. |