
إخفاء معلومات لغوي آمن إثباتيًا يدمج الرسائل السرية في النص المُولَّد بواسطة نماذج اللغات الكبيرة عبر ترميز نطاق التدوير. يتضمن نصوصًا لدمج البيانات، واستخراجها، والتحقق من الرحلة الكاملة.
إخفاء المعلومات بتشفير مدى التدوير (RRC) — طريقة إخفاء معلومات لغوية فعّالة وقابلة للإثبات آمنة، تُضمّن رسائل سرية في نص باللغة الطبيعية يُولّده نماذج اللغة الكبيرة.
الورقة البحثية: Efficient Provably Secure Linguistic Steganography via Range Coding (ACL 2026)
| الخطوة | الوصف |
|---|---|
| التضمين (الخوارزمية 3) | تحويل الرسالة السرية إلى قيمة عشرية ثم تدويرها تكرارياً ضمن فترة متقلّصة موجّهة بتوزيع احتمالي من نموذج اللغة وإزاحة مولّدة بواسطة PRNG. كل خطوة تدوير تنتج رمزاً واحداً. |
| الاستخراج (الخوارزمية 4) | إعادة تشغيل نموذج اللغة على النص المُخفى لاستعادة حدود الفترة، ثم التدوير العكسي للعودة إلى القيمة العشرية الأصلية وتحويلها إلى ثنائي. |
آلية التدوير تحل مشكلتين في إخفاء المعلومات بتشفير المدى التقليدي:
.
├── 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 بدلاً من الاحتفاظ بنسختين منفصلتين من الحلقة. يجب أن يتوافق الجانبان بتاً ببت، وأي تباين بين نسختين مُصانتين بشكل مستقل لا يظهر إلا كفشل في الرحلة الكاملة، ولا يظهر أبداً عند الفحص.
pip install -r requirements.txt
python test_roundtrip.py # GPT-2, 32/128/512 bits
python test_roundtrip.py --model meta-llama/Llama-2-7b-hf
python RRC_embed.py \
--language_model meta-llama/Llama-2-7b-hf \
--bit_length 128 --key 42 --top_k -1
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
يسجّل المُرمِّز السر الذي ضمّنه ومعرّفات الرموز التي حملته، لذا يُبلّغ الاستخراج عن معدل استرداد. يتم تقييم نموذجَي مستقبِل:
ids — يُعطى المستقبِل تسلسل الرموز. هذا يعزل مخطط الترميز؛ أي نتيجة أقل من 100% هي خطأ رقمي أو منطقي.text — يُعطى المستقبِل السلسلة المُفكَّكة من الرموز ويُعيد ترميزها، كما تتطلب قناة نصية. إعادة الترميز لا تعيد إنتاج تقسيم المُرسِل دائماً، لذا هذا حد أدنى؛ والفجوة بين المقياسين تقيس غموض الترميز وليس مخطط الترميز. على Llama-2-7b عند 128 بت: 100% لـ ids، و~91% لـ text.مهم: يجب أن يتشارك المُرسِل والمستقبِل نموذج اللغة والمفتاح وطول البت وإعداد top-k، ويجب أيضاً تشغيل نفس الأجهزة وإصدارات المكتبات. انظر المتطلبات الرقمية.
مشتركة بين RRC_embed.py و RRC_extract.py:
| الوسيط | الافتراضي | الوصف |
|---|---|---|
--language_model | meta-llama/Llama-3.1-8B | معرّف نموذج HuggingFace |
--bit_length | 128 | طول الرسالة السرية بالبت |
--top_k | -1 | اقتطاع top-k؛ -1 = المفردات الكاملة |
--key | 42 | المفتاح المتماثل K (بذرة PRNG) |
--precision_margin | 40 | أرقام عشرية تتجاوز ما يحتاجه 2**bit_length |
--max_ctx_len | 3900 | نافذة ذاكرة KV المؤقتة |
--device | تلقائي | cuda أو cpu |
يأخذ RRC_embed.py أيضاً --prompts و --output و --limit و --seed و --max_tokens و --resume و --no_verify و --part / --part_max لتقسيم مجموعة مطالبات عبر العمليات (--part_max 3 مع --part 0,1,2، واحد لكل GPU).
يأخذ RRC_extract.py أيضاً --input_file و --mode {ids,text,both} و --limit و --verbose.
يضيّق RRC فترة عرضها 2**l إلى عرض ~1، لذا تكون القيمة المُستردّة حساسة للخطأ النسبي بمعامل 2**l: عند 128 بت، اضطراب نسبي بمقدار 1e-16 في أي مكان في السلسلة يُزيح النتيجة بمقدار ~1e22 مقابل تفاوت قدره 0.5. الاستخراج لا يتدهور بسلاسة — إما يُعيد الرسالة أو يُعيد بتات غير ذات صلة. مقيس على Llama-2-7b:
| الإعداد | الاضطراب النسبي للاحتمالات | الاستخراج |
|---|---|---|
| تكرار نفس فك الترميز بدفعة 1 | 0 (متطابق بتاً ببت) | يعمل |
| نفس الصف عند دفعة 2 / 8 / 16 | ~1e-2 | يفشل |
| حشو المطالبة من اليسار | ~1e-2 | يفشل |
| تمريرة واحدة بإجبار المعلم بدلاً من فك الترميز التدريجي | ~4e-3 | يفشل |
نتيجتان تشكّلان التنفيذ. التجميع في دفعات غير متاح، لذا تُعالَج التسلسلات واحداً تلو الآخر. والمستقبِل يُعيد تشغيل فك الترميز التدريجي للمُرسِل خطوة بخطوة بدلاً من تقييم النص المُخفى في تمريرة أمامية واحدة، رغم أنه يحمل كل الرموز مسبقاً. كلا الاختصارين يقيس ~9x أسرع ولا يحافظ أي منهما على الاحتمالات.
كل شيء بعد logits هو float64 ويُنتج حدوداً متطابقة بتاً ببت على CPU و GPU، لذا التمريرة الأمامية هي الخطوة الوحيدة التي تربط النص المُخفى بعتاده.
تُشتق الدقة من طول الرسالة كـ ceil(bit_length * log10(2)) + margin وتُضبط قبل تشغيل أي شيء آخر. تتدرّج مع الرسالة: 2**256 يحتاج 78 رقماً و 2**8192 يحتاج 2466.
الدقة دون هذا الحد لا تفشل بشكل نظيف. تُقرَّب الأرقام ذات الرتبة المنخفضة من القيمة السرية، وتنهار الفترة خلال بضعة رموز ويُفعَّل اختبار الإنهاء مبكراً، لذا يمكن أن تكتمل الجولة وتُبلّغ عن أرقام غير قابلة للوصول حسابياً. إبقاء الدقة عند 50 رقماً بغض النظر عن طول الرسالة يعطي:
| bits | الاستخدام عند 50 رقماً | العينات المكتملة | مع الدقة المشتقة |
|---|---|---|---|
| 256 | 157.05% | 8/20 | 100.17% |
| 512 | 299.67% | 9/20 | 102.48% |
| 1024 | 660.91% | 7/10 | 102.58% |
| 2048 | 1046.40% | 1/5 | 98.18% |
| 4096 | 2483.92% | 3/3، لم يُرفع خطأ | 100.87% |
| 8192 | 4766.49% | 1/2 | 99.07% |
يضبط --precision_margin الهامش فوق الحد الأدنى المشتق؛ والحد الأدنى نفسه مفروض.
تتوقف الخوارزمية 3 عندما يقع (L + R) / 2 - d_s في (-0.5, 0.5]. يمكن أن يُفعَّل هذا الاختبار بينما تكون الفترة أضيق من 1، وتكون النافذة [mid - 0.5, mid + 0.5) حينها أوسع من الفترة التي تحملها. التدوير العكسي هو تماثل قياسي بمعامل عرض الفترة، لذا نافذة تعبر القطع تترك المستقبِل على مسافة فترة كاملة من d_s.
لذلك يُعيد المُرسِل تشغيل التدوير العكسي للمستقبِل قبل الالتزام بالتوقف ويُصدر رمزاً آخر إذا لم يُعِد التشغيل السر. إعادة التشغيل هي عمل Decimal خالص (~0.05 ms مقابل ~20 ms لتمريرة أمامية)، لذا لا يكلّف الحارس شيئاً ملموساً. --no_verify يعطّله.
مقيس على Llama-2-7b:
| bits | مُستردّ بدون الحارس | معه |
|---|---|---|
| 128 | 291/300 (97.0%) | 300/300 |
| 512 | 64/65 (98.5%) | 40/40 |
| 1024 | 20/20 | 20/20 |
| 2048 | 10/10 | 10/10 |
عند 128 بت كلّف الحارس 0.095% رموزاً مولّدة إضافية. العينات عند 1024 و 2048 بت قليلة جداً لتحديد المعدل — 0/20 هي النتيجة الأرجح عند معدل 3% — لذا ليست دليلاً على أن الرسائل الأطول تتصرف بشكل مختلف. مع الحارس، استُردّت 370/370.
بدون الحارس لا يستطيع المُرسِل تمييز الفرق: يُبلّغ عن النجاح ويُصدر نصاً مُخفى يفكّ ترميزه إلى بتات غير ذات صلة. يتفاوت المعدل مع السحب؛ جولة واحدة من 99 مطالبة لم تشهد أي فشل، وهو ما يُنتجه معدل 3% حوالي 5% من الوقت، ويتكرر بالضبط عند إعادة التشغيل. تفشل نفس العينات عند كل دقة عاملة من 45 إلى 200 رقماً، لذا ينتج السلوك من اختبار الإنهاء وليس من الحساب.
تم التحقق من الحارس مقابل الحقيقة الأرضية بالتضمين مع تعطيله وتشغيل المستخرِج الحقيقي: العينات التي يُعلّمها هي بالضبط العينات التي يفشل فيها المستقبِل، دون إيجابيات كاذبة ودون أي تفويت.
التمريرة الأمامية لنموذج اللغة هي 95–97% من خطوة توليدية على Llama-2-7b، وفك ترميز بدفعة 1 لنموذج 7B fp16 يقع عند سقف عرض نطاق الذاكرة (~13.5 ms لكل رمز مقابل ~18.7 ms مقيسة). لذا تتبع سرعة التضمين سرعة فك ترميز النموذج، والترميز نفسه له تأثير ضئيل عليه.
على النماذج الأصغر لم تعد التمريرة الأمامية مهيمنة ويصبح عمل CPU لكل خطوة مرئياً. مقيس من البداية إلى النهاية على GPT-2 عند 128 بت، 100 رسالة لكل خلية على جهاز مشترك: