Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
- [توليد LLVM (المترجم sadc)](backend/llvm.md)
- [الآلة الافتراضية (VM)](backend/vm.md)
- [دراسة حالة: توحيد هاش/شفّر/فك_تشفير](backend/crypto-unification.md)
- [دراسة حالة: توسيع مكتبة التشفير (٥ مراحل + Argon2id)](backend/crypto-library-expansion.md)

# الجزء السادس · أنظمة اللغة

Expand Down
134 changes: 134 additions & 0 deletions src/backend/crypto-library-expansion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# دراسة حالة: توسيع مكتبة التشفير (٥ مراحل + Argon2id)

بعد [توحيد هاش/شفّر](crypto-unification.md) (`هاش`/`شفّر`/`فك_تشفير` في وحدة `تأكيدات`)، وُسِّعت
اللغة بمكتبة تشفير حديثة كاملة في وحدة منفصلة `تشفير` — عبر RFC كامل
(`sadlang-rfcs/text/0000-توسيع-مكتبة-التشفير.md`) نُفِّذ على ٥ مراحل + مرحلة
إضافيّة (Argon2id) بطلب صريح من المالك رغم تأجيلها في نصّ RFC الأصليّ. المرجع
اللغويّ للمستخدم في
[sadlang-docs](https://github.com/sadlang/sadlang-docs/blob/main/src/language/security.md#وحدة-تشفير--المكتبة-الموسَّعة)؛
هذه الصفحة للمساهم في **التنفيذ والمنهجيّة**. (نصّ RFC نفسه موجود على فرع
`rfc/expand-crypto-library` في `sadlang-rfcs` — لم يُدمَج إلى `main` بعد.)

## المراحل

| المرحلة | الدوال | المعيار | PR |
|---|---|---|---|
| ٠ | `عشوائي_آمن` | CSPRNG النظام | مدموج |
| ١ | `بلايك3` / `هاش_مفتاح` | BLAKE3 (keyed mode) | مدموج |
| ٢ | `اشتق_مفتاح_مرور` / `اشتق_مفتاح` | PBKDF2-HMAC-SHA256 (RFC 2898/8018) / HKDF-SHA256 (RFC 5869) | #217 |
| — | `أرجون2` | Argon2id (RFC 9106) — مؤجَّلة أصلًا، أُدرِجت بطلب صريح | #219 |
| ٣ | `شفر_موثق` / `فك_تشفير_موثق` | ChaCha20-Poly1305 AEAD (RFC 8439) | #220 |
| ٤ | `ولّد_مفتاح_خاص_x25519` وعائلتها (7 دوال) | X25519 (RFC 7748) + Ed25519 (RFC 8032) + SHA-512 ذاتيّ | #221 |

كل الدوال ذاتيّة التنفيذ (self-rolled، بلا OpenSSL/libsodium) حفاظًا على قابليّة
العمل على هدف الوضع الحرّ (نفس قيد [[crypto-unification|توحيد هاش/شفّر]])، وسطح
اللغة لكل دالّة **سلسلة تدخل ⇒ سلسلة تخرج** حصرًا على كلا المحرِّكين — لا كائنات
مركَّبة عابرة للحدود.

## المنهجيّة: كل مرحلة عبر worktree معزول

```mermaid
flowchart LR
RFC["sadlang-rfcs: نصّ المرحلة"] --> WT["worktree معزول<br/>wt-crypto-phaseN"]
WT --> REF["مرجع C مستقلّ (scratchpad)<br/>يُختبَر مقابل شعاعات RFC الرسميّة"]
REF -->|"تطابق تامّ"| IMPL["نقل الكود لثلاث نسخ إنتاج:<br/>مفسّر C++ / وقت تشغيل C / رابط أندرويد C"]
IMPL --> AMELIA["مراجعة أميليا مستقلّة<br/>(متزامنة لا خلفيّة)"]
AMELIA -->|"إجازة"| PR["PR ضدّ dev<br/>«لا دمج بلا إذن صريح»"]
AMELIA -->|"عِلَّة"| WT
```

كل مرحلة استُنسِخت بنفس القالب: (1) مرجع C مستقلّ في scratchpad يُختبَر بايتًا
بايت مقابل شعاعات الاختبار **الرسميّة** للمعيار (لا بيانات اختبار مؤلَّفة يدويًّا)؛
(2) بعد التطابق التامّ فقط، نقل نفس المنطق إلى **ثلاث** نسخ إنتاج متطابقة —
المفسّر (`interpreter/src/builtins/builtin_module_crypto.cpp`)، وقت تشغيل
المترجم (`tools/compiler/runtime/sad_embedded_runtime.c`)، ورابط أندرويد
(`tools/compiler/compiler_driver_android_linker.cpp` — نسخة ثالثة منفصلة لأنّ
هذا الهدف [لا يشارك رابط سطح المكتب](crypto-unification.md)؛ يصطدم عادةً بحدّ
سلاسل MSVC الخام، انظر أدناه)؛ (3) مراجعة أميليا مستقلّة **متزامنة إلزاميّة** قبل
أيّ `git push` (لا خلفيّة — راجع فخّ التوقّف الموثَّق في الذاكرة الداخليّة)؛ (4)
PR ضدّ `dev` بلا دمج تلقائيّ، وسطر «لا دمج بلا إذن صريح» حرفيًّا في كل PR.

## الدرس الأهمّ: تحيّز اختيار شعاعات الاختبار (Argon2id)

أثناء Argon2id، طابق المرجع المستقلّ `libargon2` الرسميّة (عبر `argon2-cffi`)
تطابقًا تامًّا عبر 12 حالة اختبار اخترتُها بنفسي. رغم ذلك كشفت مراجعة أميليا
المستقلّة عِلَّة حقيقيّة: التجزئة الأوّليّة H0 (RFC 9106 §3.2) كانت تُطعَم بقيمة
تكلفة الذاكرة **المقرَّبة داخليًّا** لمضاعِف 4 (`m'`) بدل القيمة **الخام** —
والسبب أنّ **كل الحالات الاثنتَي عشرة صدفةً استعملت تكلفة ذاكرة مضاعِفة لـ4**
(8/1024/2048/4096)، فكان `m'==m` دومًا وأخفى العلّة رغم "التطابق التامّ" المُعلَن.

> **الدرس:** اختيار حالات الاختبار بنفسك — حتى مع تنويع البارامترات — قد يحمل
> تحيّزًا غير واعٍ ينبع من نفس سوء الفهم الذي قد يكون وقع فيه التنفيذ نفسه.
> "طابق تنفيذًا مرجعيًّا مستقلًّا" ليس كافيًا وحده لكود تشفيريّ حسّاس — لازم أيضًا
> مراجعة تقرأ الخوارزميّة سطرًا سطرًا مقابل نصّ المعيار مباشرة، لا تكتفِ بالثقة
> بنتائج الاختبار. لخوارزميّة فيها تقريب/تقليم داخليّ، اختبر **عمدًا** حالة لا
> تقع على حدود التقريب.

## فخّ الدمج المتسلسل: دالّة مشتركة الجسم مختلفة الاسم

تفرّعت PR #219 (Argon2id) وPR #220 (AEAD) وPR #221 (X25519/Ed25519) من نفس
القاعدة (قبل #219) وتمسّ نفس الملفّات المشتركة (SIR opcode enum، مولّدات LLVM،
المفسّر، وقت تشغيل C، رابط أندرويد، YAML SoT). دمج كلّ فرع لاحق كشف جولة تعارض
جديدة، والقاعدة المتّبعة دومًا: **أبقِ إضافات الجانبين معًا، لا تُسقِط أيًّا
منهما**. الفخّ: كل فرع أضاف دالّة توليد عشوائيّة مساعدة باسم مختلف
(`sadx_random_bytes` مقابل `sad_crypto_random_bytes`) لكن جسمها شبه متطابق —
والنصّ "المشترك" الظاهر بعد علامة `>>>>>>>` في تعارض git ثلاثيّ ينتمي في
الحقيقة لدالّة واحدة فقط. محاولة حلّ هذا بتحرير واحد ضخم يفترض إعادة استخدام
هذا النصّ لكلتا الدالّتين تنتج **فسادًا صامتًا**: دالّة مكرَّرة، تعليق مبتور،
جسم دالّة ناقص — دون أيّ خطأ بناء فوريّ يكشفه.

**الاكتشاف:** فحص توازن الأقواس (`python -c "text.count('{')==text.count('}')"`)
ثمّ إعادة الملفّ لحالته المتعارضة (`git checkout --conflict=merge -- <path>`)
والبدء من جديد بتحريرات صغيرة متسلسلة على حدود كل علامة تعارض على حدة، مع كتابة
جسم كل دالّة كاملًا صراحة (تكرار المنطق بدل محاولة مشاركته نصّيًّا). طُبِّق هذا
الدرس بنجاح من المحاولة الأولى على الملفّ التالي المصاب بنفس النمط.

## فخّ ما بعد الدمج: حدّ MSVC C2026 لسلاسل C الخام

رابط أندرويد يُصدِر runtime التشفير كسلسلة C++ خام (`R"( ... )"`) مقسَّمة
استباقيًّا لتفادي حدّ MSVC (٦٥٥٣٥ بايت لكل حرفيّ سلسلة). كل فرع (PR #220 وPR
#221) قسَّم محتواه الخاصّ تحت الحدّ بمعزل عن الآخر — لكن دمج X25519/Ed25519 مع
AEAD في **نفس** القطعة بعد حلّ التعارض أعاد تجاوز الحدّ، وهذا **لا يكشفه أيّ
حارس ساكن أو مولِّد** — يظهر فقط كخطأ بناء `C2026: string too big` وقت الترجمة
الفعليّة على MSVC.

> **القاعدة العامّة:** أيّ دمج لسلاسل C/C++ خام مقسَّمة مسبقًا بسبب حدّ حجم
> يحتاج تحقّقًا من الحدّ **من جديد بعد الدمج** — لا تفترض بقاء التقسيم الأصليّ
> كافيًا لمجرّد أنّ كل فرع وحده كان تحته. الحلّ: إغلاق `)";` بعد حدّ دالّة نظيف
> وفتح `R"(` جديدة، فيتحوّل تقسيم كل فرع (قطعتان) إلى ثلاث/أربع قطع بعد الدمج.

## قرار تصميميّ: X25519/Ed25519 بدوال مقسَّمة لا كائن {عام، خاص}

نصّ RFC اقترح دالّة توليد زوج مفاتيح تُرجع كائنًا بحقلين (عامّ وخاصّ). التصميم
الفعليّ استعمل **دالّتين منفصلتين** بدلًا من ذلك (`ولّد_مفتاح_خاص_x25519` +
`اشتق_مفتاح_عام_x25519`) — تجنّبًا لبناء آليّة تمرير كائنات مركَّبة جديدة عابرة
للمحرِّكين حين يكفي عقد "سلسلة ⇒ سلسلة" الموجود أصلًا لكل دالّة أخرى في
المكتبة. لا خسارة أمنيّة: المفتاح العامّ دومًا دالّة حتميّة للخاصّ (تقييد سلميّ +
ضرب بالنقطة الأساس)، فالفصل بلا أثر جانبيّ.

## قرار تصميميّ: تباعُد فشل مقصود بين AEAD ونظيراتها

`فك_تشفير_موثق` (AEAD) يفشل **مُغلَقًا** (fail-closed) دومًا على فشل مصادقة —
بخلاف `فك_تشفير` (وحدة `تأكيدات`، تشفير بلا مصادقة) الذي [يُرجع مدخله كما هو
صامتًا](crypto-unification.md#نقطة-الحسم-هل-يُذكَر-خطأ-فكّ_تشفير-على-مدخل-غير-صالح)
على خطأ تنسيق. لكن آليّة **الإبلاغ** عن هذا الفشل المُغلَق تتباعد بين
المحرِّكين، بنفس السبب الجذريّ الموثَّق سلفًا: المفسّر يرمي استثناءً قابلًا
للالتقاط بـ`حاول`/`امسك`؛ المترجم يطبع رسالة عامّة على `stderr` (لا تُسرّب
الوسم/المفتاح) ثمّ `exit(1)`، لأنّه لا يوجد اليوم مسار استثناء C-callable من
وقت تشغيل المترجم إلى LLVM. بناء هذا المسار العامّ **عمل لاحق موثَّق، خارج
نطاق هذه الحملة** — لكن الفشل نفسه مُغلَق على الحالتين، فلا يُرجع أيّ محرّك نصًّا
مُحرَّفًا صامتًا أبدًا (أأمن من تباعُد `فك_تشفير` غير الموثَّق فيه فشل مفتوح).

## الاختبار

كل مرحلة أضافت ملفّات إلى
`tests/behavior/sections/09_المكتبة_القياسية/04_تشفير/` (14 ملفًّا إجمالًا)،
كلّ واحد يُشغَّل عبر `sad-run.exe` **و**`sadc.exe` ويُقارَن الناتج حرفيًّا —
شعاعات RFC/مسابقة رسميّة لكل معيار (BLAKE3-team، RFC 2898/5869/7748/8032/8439/
9106)، إضافة إلى حالات رفض صريحة (سرّ مشترك كلّه أصفار في X25519، توقيع/مفتاح
مُعبَث بهما في Ed25519، بارامترات خارج الحدود الآمنة في KDFs).

---
**اقرأ بعده:** [توحيد هاش/شفّر/فك_تشفير](crypto-unification.md) ·
[دوال مضمنة ووحدات](../systems/builtins.md) ·
[نظام معالجة الأخطاء](../systems/errors.md).
4 changes: 4 additions & 0 deletions sync/sources.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
"interpreter/include/core/interpreter_core.h": "031ec8bc4b77e628b67615c7680897387fe821cc",
"interpreter/include/visitors/expression_evaluator.h": "a6e90c03cb75de00525fd7888bb61c91d57aa2fc",
"interpreter/src/builtins": "a6699522fd97b4053bc4b6d39c8ad3ca7ba2e17c",
"interpreter/src/builtins/builtin_module_crypto.cpp": "8b91ba562ce32776810bb508f0130087ea0fb1af",
"language-truth": "13c2e41986f2a5d7b2e4897efd593d295d14e909",
"language-truth/_schemas": "bca3eaef4997d6318feeeb4c80dafa44c454024c",
"language-truth/builtins": "870a0daee27d07cac40aee70659b2afeb4884c80",
"language-truth/builtins/crypto.yaml": "543ee1ecc79c6d42f791a8aeb77ad6f7df609d8e",
"language-truth/errors": "1225323dae85f68a5b4658012b80ae6e58a61583",
"language-truth/grammar": "efd940df914c0cb125e13f4ee9590fb5c7e677ec",
"language-truth/keywords.yaml": "64bb3292e235b268228792c5e1fc49d1e220e56e",
Expand All @@ -37,6 +39,8 @@
"shared/types/include/sad_type_system.h": "4e792e5b8ddb605fbb1c33200c019e9ded39f656",
"shared/types/include/type_bridge.h": "0bf37baafc415409082a284c9b2de84d3837e4e1",
"shared/types/include/value.h": "9b40909fd452fac4e27e41aed85852020f2af1e6",
"tools/compiler/compiler_driver_android_linker.cpp": "e0c69cb8859b4d6b65bde3e4a4d37980c108dbd9",
"tools/compiler/runtime/sad_embedded_runtime.c": "6fa885fb7277c79674aaab298ee5cadd6ff162b3",
"vm/include/sad_vm_executor.h": "2a9c74f182c5d76643b58dfd036877ad03ad97c1",
"vm/include/sad_vm_opcodes.h": "8b92d998a5a26d3b9716d25bd6dee8a61a5fca4d",
"vm/src/sad_vm_executor.cpp": "76a1d059b635ebc6a3d55f0fb9b75c95fa2984a7"
Expand Down
7 changes: 7 additions & 0 deletions sync/sources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ chapters:
- interpreter/src/builtins/builtin_module_assertions.cpp
- language-truth/builtins/assertions.yaml

- file: src/backend/crypto-library-expansion.md
sources:
- interpreter/src/builtins/builtin_module_crypto.cpp
- tools/compiler/runtime/sad_embedded_runtime.c
- tools/compiler/compiler_driver_android_linker.cpp
- language-truth/builtins/crypto.yaml

- file: src/sot/philosophy.md
sources:
- language-truth/_schemas
Expand Down
Loading