From 9e7616d49ad39c99023475717ecd608fa9b7157d Mon Sep 17 00:00:00 2001 From: Sad Lang Dev Date: Mon, 20 Jul 2026 05:17:33 +0300 Subject: [PATCH] =?UTF-8?q?RFC:=20=D8=AA=D9=88=D8=B3=D9=8A=D8=B9=20=D9=85?= =?UTF-8?q?=D9=83=D8=AA=D8=A8=D8=A9=20=D8=A7=D9=84=D8=AA=D8=B4=D9=81=D9=8A?= =?UTF-8?q?=D8=B1=20=E2=80=94=20=D9=88=D8=AD=D8=AF=D8=A9=20=D8=AA=D8=B4?= =?UTF-8?q?=D9=81=D9=8A=D8=B1=20=D8=AC=D8=AF=D9=8A=D8=AF=D8=A9=20(=D9=87?= =?UTF-8?q?=D8=A7=D8=B4/MAC=20=D8=AD=D8=AF=D9=8A=D8=AB=D8=A7=D9=86=20+=20K?= =?UTF-8?q?DF=20+=20AEAD=20+=20=D8=BA=D9=8A=D8=B1=20=D9=85=D8=AA=D9=85?= =?UTF-8?q?=D8=A7=D8=AB=D9=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit يقترح وحدة `تشفير` ذاتيّة التنفيذ بالكامل (بلا OpenSSL) بجانب `تأكيدات` القائمة: BLAKE3+HMAC، PBKDF2/HKDF، AEAD حقيقيّ عبر ChaCha20-Poly1305، وX25519/Ed25519. يفتح بفحص عاجل مستقلّ: عشوائي_آمن في وقت تشغيل المترجم ليست آمنة فعليًّا (srand(time)+rand())، ويقترح خطّة مرحليّة (٠-٤) تبني كل مرحلة على سابقتها وتُدمَج كـPR مستقلّ. --- ...30\252\330\264\331\201\331\212\330\261.md" | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 "text/0000-\330\252\331\210\330\263\331\212\330\271-\331\205\331\203\330\252\330\250\330\251-\330\247\331\204\330\252\330\264\331\201\331\212\330\261.md" diff --git "a/text/0000-\330\252\331\210\330\263\331\212\330\271-\331\205\331\203\330\252\330\250\330\251-\330\247\331\204\330\252\330\264\331\201\331\212\330\261.md" "b/text/0000-\330\252\331\210\330\263\331\212\330\271-\331\205\331\203\330\252\330\250\330\251-\330\247\331\204\330\252\330\264\331\201\331\212\330\261.md" new file mode 100644 index 0000000..6a67369 --- /dev/null +++ "b/text/0000-\330\252\331\210\330\263\331\212\330\271-\331\205\331\203\330\252\330\250\330\251-\330\247\331\204\330\252\330\264\331\201\331\212\330\261.md" @@ -0,0 +1,266 @@ +- **عنوان المقترح:** توسيع مكتبة التشفير — وحدة `تشفير` جديدة (هاش/MAC حديثان، اشتقاق مفاتيح، AEAD حقيقيّ، تشفير غير متماثل) +- **النطاق:** لغة (`text/`) — يمسّ `language-truth/builtins/`، وقت تشغيل المفسّر والمترجم كليهما +- **تاريخ البدء:** 2026-07-20 +- **رقم الـ RFC:** (يُترك فارغاً حتى الدمج) +- **الحالة:** مقترَح (PR مفتوح) +- **Issue التتبُّع:** (يُترك فارغاً حتى القبول) + +# ملخّص + +إضافة وحدة `تشفير` (Crypto) جديدة — منفصلة عن `تأكيدات` (Assertions) القائمة — +تحوي مجموعة دوال تشفير حديثة ذاتيّة التنفيذ بالكامل (self-rolled، بلا OpenSSL +ولا أيّ اعتماديّة خارجيّة): هاش/MAC حديثان (BLAKE3 + هاش مُفتاح مبنيّ عليه)، +اشتقاق مفاتيح (PBKDF2-HMAC-SHA256 + HKDF)، تشفير متماثل موثَّق حقيقيّ (AEAD عبر +ChaCha20-Poly1305)، وتشفير غير متماثل (X25519 لتبادل المفاتيح + Ed25519 +للتوقيع). **قبل أيّ من ذلك**، يُصلِح هذا المقترح ثغرة حرجة موجودة فعلاً: دالّة +`عشوائي_آمن` في وقت تشغيل المترجم ليست عشوائيّة آمنة إطلاقًا — `srand(time(NULL))` ++ `rand()` قابلة للتنبؤ بالكامل، بينما اسمها يُوحي بضمان أمنيّ لا وجود له. + +# الدافع (Motivation) + +توحيد `هاش`/`شفّر`/`فك_تشفير` بين المفسّر والمترجم +([s-programming-language#212](https://github.com/sadlang/s-programming-language/pull/212)، +[#213](https://github.com/sadlang/s-programming-language/pull/213)) أغلق تباعُدًا +خطيرًا، لكنّه ترك المكتبة عند الحدّ الأدنى: هاش واحد (SHA-256)، وتشفير متماثل +بسيط بلا مصادقة (CTR بلا tag — عرضة للتلاعب دون كشف). أيّ برنامج `.ص` حقيقيّ +يحتاج اليوم: + +- **تخزين كلمات مرور** — لا توجد دالّة اشتقاق مفتاح بطيئة مقاوِمة للتخمين + (PBKDF2/Argon2)؛ استخدام `هاش` مباشرة على كلمة المرور غير آمن (لا ملح، لا + إبطاء). +- **تشفير بيانات حسّاسة مع ضمان عدم العبث** — `شفّر`/`فك_تشفير` الحاليّان بلا + مصادقة (AEAD)؛ تلاعبٌ في النصّ المشفّر يمرّ دون أن يكتشفه فكّ التشفير. +- **تبادل مفاتيح وتوقيع رسائل** — لا يوجد أيّ تشفير غير متماثل؛ أيّ سيناريو + «قناة آمنة بين طرفين» أو «توقيع رسالة» مستحيل اليوم داخل اللغة. +- **عشوائيّة يُعتمَد عليها أمنيًّا** — `عشوائي_آمن` تحمل اسمًا يَعِد بالأمان + ولا تفي به (انظر «الفحص العاجل» أدناه)؛ أيّ nonce أو مفتاح يُشتقّ منها اليوم + في مسار المترجم قابل للتنبّؤ. + +الهدف: مكتبة تشفير تُقارَن معياريًّا (باختصاصاتها الأساسيّة، لا حجمها) بما +تقدّمه لغات ناضجة — `hashlib`/`cryptography` في Python، `crypto/*` في Go، +`ring`/`RustCrypto` في Rust، `libsodium` — دون التخلّي عن قيد الوضع الحرّ +(freestanding) الذي فرض حذف `stdlib/crypto` القائم على OpenSSL أصلًا. + +# فحص عاجل: `عشوائي_آمن` ليست آمنة (يُصلَح أوّلًا، مستقلّ عن باقي المقترح) + +في `tools/compiler/runtime/sad_embedded_runtime.c` (دالّة +`sad_security_secure_random`، والمولِّد الداخليّ للنِّتِرات المستخدَم في +`sad_security_encrypt`/`decrypt`): + +```c +srand((unsigned int)time(NULL)); +r = (r << 16) | ((unsigned long long)rand() & 0xFFFFu); +``` + +هذا مولِّد أرقام عشوائيّ **قابل للتنبّؤ بالكامل** (بذرة = الوقت بالثانية، +`rand()` خطّيّ متطابق). مقابله في المفسّر +(`interpreter/src/builtins/builtin_module_assertions.cpp`) يستعمل +`std::random_device` — أفضل، لكنّه غير مضمون الجودة عبر كل التطبيقات (بعض +تطبيقات MinGW القديمة تُرجعه حتميًّا)، وغير متاح أصلًا في هدف الوضع الحرّ. + +**هذا يُصلَح كخطوة صفريّة مستقلّة عن بقيّة هذا المقترح**، بصرف النظر عمّا +يُقرَّر بشأن باقي RFC، لأنّ كل النِّتِرات (nonces) المُنتَجة بمسار المترجم منذ +توحيد #212 — لا فقط الميزات الجديدة هنا — تعتمد عليها. الإصلاح المقترَح: مصدر +عشوائيّة أساسه نظام التشغيل عبر واجهة موحَّدة +(`BCryptGenRandom` على Windows، `getrandom(2)`/`/dev/urandom` على Linux، +`getentropy`/`arc4random_buf` على macOS/BSD)، مع **سؤال مفتوح صريح** لهدف +الوضع الحرّ البحت (بلا نظام تشغيل مضيف مطلقًا، كنواة sad-os) — انظر «أسئلة +غير محسومة». + +# الشرح التوجيهي (Guide-level explanation) + +وحدة جديدة، منفصلة عن `تأكيدات` (التي تبقى كما هي — `هاش`/`شفّر`/`فك_تشفير` +الحاليّان بلا أيّ تغيير أو كسر توافق): + +```sad +استورد تشفير +``` + +## هاش ومصادقة الرسائل + +```sad +اطبع_سطر(بلايك3("مرحبا")) # BLAKE3-256، أسرع من SHA-256 +اطبع_سطر(هاش_مفتاح("رسالة", "مفتاح_سرّي")) # HMAC-BLAKE3 (مصادقة رسالة) +``` + +## اشتقاق المفاتيح + +```sad +متغير مفتاح_كلمة_مرور = اشتق_مفتاح_مرور("كلمة_سرّ_ضعيفة", "ملح_عشوائي", 100000) +متغير مفتاح_فرعي = اشتق_مفتاح("سرّ_مشترك", "ملح", "سياق_الاستخدام", 32) # HKDF +``` + +## تشفير متماثل موثَّق (AEAD) + +```sad +متغير مغلّف = شفّر_موثّق("سرّ حسّاس", مفتاح_كلمة_مرور) +اطبع_سطر(فك_تشفير_موثّق(مغلّف, مفتاح_كلمة_مرور)) # يرمي استثناءً إن عُبِث بالنصّ المشفّر +``` + +بخلاف `شفّر`/`فك_تشفير` الحاليّين، `فك_تشفير_موثّق` **يكتشف** أيّ تلاعب في +النصّ المشفّر ويرمي استثناءً بدل إرجاع بيانات فاسدة صامتًا. + +## تشفير غير متماثل + +```sad +متغير زوج_مفاتيح = ولّد_مفتاحين_توقيع() # Ed25519: {عام، خاص} +متغير توقيع = وقّع("رسالة مهمّة", زوج_مفاتيح.خاص) +اطبع_سطر(تحقق_توقيع("رسالة مهمّة", توقيع, زوج_مفاتيح.عام)) # صحيح/خطأ + +متغير زوج_تبادل = ولّد_مفتاحين_x25519() # X25519: {عام، خاص} +متغير سرّ_مشترك = تبادل_مفتاح(زوج_تبادل.خاص, مفتاح_عام_الطرف_الآخر) +``` + +# الشرح المرجعي (Reference-level explanation) + +## البنية المعماريّة: ذاتيّة التنفيذ بالكامل، لا استثناء + +كل خوارزميّة self-rolled (C خالص، بلا OpenSSL/libsodium/أيّ اعتماديّة)، +لتبقى وحدة `تشفير` عاملة على هدف الوضع الحرّ تمامًا كوحدة `تأكيدات` الحاليّة. +هذا يعني عبء تحقّق أعلى من الاستعانة بمكتبة مُدقَّقة، ويُعالَج عبر: + +1. **اختيار خوارزميّات تقاوم أخطاء التنفيذ الذاتيّ ببساطتها البنيويّة.** + تحديدًا **ChaCha20-Poly1305 لا AES-GCM**: تنفيذ AES بلا تسريع عتاديّ + (AES-NI) يعتمد جداول بحث (S-box lookup tables) عرضة لتسريب زمنيّ + (timing side-channel) على عتاد بلا تعليمات AES مخصَّصة — بالضبط الوضع + المفترَض لهدف حرّ محمول. ChaCha20 بنية ARX (Add-Rotate-XOR) بلا فروع ولا + جداول بحث تعتمد على البيانات — زمن تنفيذ ثابت طبيعيًّا في C خالص. هذا نفس + الخيار الذي تفضّله TLS 1.3 وlibsodium على عتاد بلا AES-NI. +2. **كل خوارزميّة تُختبَر بشعاعات اختبار رسميّة (test vectors) قبل أيّ دمج** + — RFC 8439 لـChaCha20-Poly1305، RFC 8032 لـEd25519/X25519، RFC 7693 + لـBLAKE2 أو مواصفة BLAKE3 الرسميّة، RFC 2898/8018 لـPBKDF2، RFC 5869 + لـHKDF. لا خوارزميّة تُعتبَر «منجَزة» بدون مطابقة شعاعاتها الرسميّة حرفيًّا + على المحرّكين معًا — نفس منهجيّة اختبار SHA-256 القائمة + (`tests/behavior/sections/09_المكتبة_القياسية/04_تشفير/150_stdlib_security_hash.ص`). +3. **الدرس المستفاد من #212:** التوحيد بين المحرّكين ليس اختياريًّا لاحقًا — + كل دالّة جديدة تُنفَّذ في المفسّر **والمترجم معًا** ضمن نفس PR، لا بالتتابع؛ + PR #212 كشف نسخة ثالثة منسيّة في مُصدِّر Android + (`tools/compiler/compiler_driver_android_linker.cpp`) لم تُكتشَف إلا + بمراجعة مستقلّة قبل الدفع — أيّ دالّة تشفير جديدة تُضاف إلى وقت التشغيل + المشترك (`sad_embedded_runtime.c`) يجب فحص كل نقاط الربط الأخرى (Android + وغيره) صراحةً، لا افتراض أنّ الملفّ المشترك هو الوحيد. + +## مصدر الحقيقة + +وحدة جديدة `language-truth/builtins/crypto.yaml` (بجانب `assertions.yaml` +القائم، لا داخله — فصل الاهتمامات: `تأكيدات` دوال اختبار/سلامة عامّة، +`تشفير` تشفير حصرًا)، تُضاف إلى `language-truth/builtins/_index.yaml`. كل +دالّة: `cpp_id`, `canonical` (الاسم العربيّ)، `namespace: Crypto`, +`module: CRYPTO`, `compiler_strategy: RUNTIME_CALL`, `description_ar/en` +كاملان، `params`, `examples` قابلة للتشغيل — بنفس معايير إثراء `assertions.yaml` +في #213. + +## خطّة مرحليّة (كل مرحلة PR مستقلّ قابل للدمج بمفرده) + +| المرحلة | المحتوى | يعتمد على | +|---|---|---| +| **٠** | إصلاح `عشوائي_آمن`/توليد النِّتِرات — CSPRNG حقيقيّ عبر نظام التشغيل في المفسّر والمترجم | — (عاجل، مستقلّ) | +| **١** | `بلايك3` + `هاش_مفتاح` (HMAC-BLAKE3) | المرحلة ٠ (البذرة/الاختبارات لا تحتاجها فعليًّا، لكن الترتيب المنطقيّ يضعها أوّلًا) | +| **٢** | `اشتق_مفتاح_مرور` (PBKDF2-HMAC-SHA256) + `اشتق_مفتاح` (HKDF) | المرحلة ١ (تُبنى فوق HMAC) | +| **٣** | `شفّر_موثّق`/`فك_تشفير_موثّق` (ChaCha20-Poly1305 AEAD) | المرحلة ٠ (نِتر آمن إلزاميّ لكل استدعاء) | +| **٤** | `ولّد_مفتاحين_x25519`/`تبادل_مفتاح` (X25519) + `ولّد_مفتاحين_توقيع`/`وقّع`/`تحقق_توقيع` (Ed25519) | المرحلة ٠ (توليد مفاتيح يحتاج عشوائيّة آمنة) | + +**Argon2 (اشتقاق مفتاح مقاوم للذاكرة/GPU) مؤجَّل عمدًا خارج هذا المقترح** — +انظر «السلبيات» و«أسئلة غير محسومة». + +## التنفيذ (كل مرحلة: طبقتان متطابقتان) + +| الطبقة | المكان | +|---|---| +| المفسّر | `interpreter/src/builtins/builtin_module_crypto.cpp` (ملفّ جديد، بنمط `builtin_module_assertions.cpp`) | +| المترجم | امتداد `tools/compiler/runtime/sad_embedded_runtime.c` (دوال C جديدة) + `compiler/src/frontend/builders/builtins_crypto.cpp` (SIR) + مولِّد LLVM مطابق لنمط `security_builtins_ops.cpp` | +| مُصدِّر Android | فحص `tools/compiler/compiler_driver_android_linker.cpp` صراحة لكل دالّة جديدة — إمّا تُضاف مطابقة، أو يُوثَّق لماذا الهدف لا يدعمها (كما `شفّر`/`فك_تشفير` غير موجودتين له أصلًا اليوم) | + +## نظام الأخطاء + +`فك_تشفير_موثّق` على تلاعب/فشل مصادقة: خطأ لغويّ قابل للالتقاط بـ`حاول`/ +`امسك` في **كلا** المحرّكين من اليوم الأوّل — لا يتكرّر تباعُد `فك_تشفير` +الحاليّ (مفسّر يرمي، مترجم يطبع على `stderr` بصمت) الموثَّق في +`language-truth/builtins/assertions.yaml` كتباعُد مقبول تاريخيًّا؛ AEAD جديد +فلا عذر تاريخيّ لتكراره. + +## الأدوات + +لا تأثير على LSP/المنسّق مباشرة (دوال مضمنة عاديّة، كـ`تأكيدات`). سطر أوامر +`sad-run`/`sadc` بلا تغيير. + +## التوافق الخلفيّ + +لا كسر إطلاقًا — وحدة جديدة بالكامل، `تأكيدات` وثلاثيّتها (`هاش`/`شفّر`/ +`فك_تشفير`) دون أيّ تعديل. + +# السلبيات (Drawbacks) + +- **عبء تدقيق أمنيّ ضخم.** تنفيذ ذاتيّ لـChaCha20-Poly1305/X25519/Ed25519 + بلا مكتبة مُدقَّقة يعني أنّ أيّ خطأ دقيق (side-channel زمنيّ، خطأ ثابت + مجال منحنى إهليلجيّ، إلخ) عيبٌ أمنيّ حقيقيّ في الإنتاج — لا مجرّد باغ وظيفيّ. + هذا أثقل بكثير من عبء SHA-256/CTR البسيط الذي وُحِّد في #212. +- **Argon2 مؤجَّل** يعني أنّ اشتقاق كلمات المرور في هذا المقترح (PBKDF2) + أضعف من المعيار الحاليّ الأفضل صناعيًّا (Argon2id) أمام هجمات GPU/ASIC — + مقايضة واعية بين الأمان الأقصى وقابليّة التنفيذ الذاتيّ الآمنة عمليًّا. +- **مساحة سطح هجوم أكبر**: أربع خوارزميّات جديدة × محرّكان = ثمانية مسارات + تنفيذ تحتاج صيانة أمنيّة مستمرّة (لا مرّة واحدة). +- **لا اعتماد على تسريع عتاديّ** (AES-NI مثلاً) يعني أداءً أبطأ من مكتبات + تستغلّ تعليمات المعالج المخصَّصة — مقبول لهدف حرّ محمول، لكنّه تنازل أداء + صريح أمام «المكتبات العالميّة المتصدّرة». + +# المبرّرات والبدائل (Rationale and alternatives) + +- **البديل المرفوض: إعادة `stdlib/crypto` (OpenSSL) للمترجم على الأهداف + المضيفة فقط.** أسرع وأضمن أمنيًّا (مكتبة مُدقَّقة عالميًّا)، لكنّه يُبقي + انقسامًا دائمًا بين هدف حرّ (self-rolled) وهدف مضيف (OpenSSL) — بالضبط ما + استُبعِد في قرار #212 لتوحيد المسارين على تنفيذ واحد. المستخدم اختار صراحةً + رفض هذا الخيار لهذا المقترح. +- **البديل المرفوض: تأجيل الكلّ حتى وجود فريق تدقيق أمنيّ مخصَّص.** يُبقي + اللغة بلا أيّ AEAD حقيقيّ أو تشفير غير متماثل أجلًا غير مسمّى؛ الخطّة + المرحليّة هنا تسمح بمراجعة/قبول تدريجيّ (كل مرحلة PR مستقلّ) بدل التزام + ضخم دفعة واحدة. +- **لماذا BLAKE3 لا SHA-3/Keccak؟** BLAKE3 أبسط بنيويًّا للتنفيذ الذاتيّ + الصحيح (دالّة ضغط واحدة قابلة للتوازي، لا خطوات إسفنجيّة معقّدة)، وأسرع + في الممارسة — نفس السبب الذي يجعله خيار مكتبات حديثة (`libgit2`، `rustls` + الفرعيّة). + +# أعمال سابقة (Prior art) + +- **Go `crypto/*`**: كل خوارزميّة في حزمة فرعيّة منفصلة (`crypto/chacha20poly1305`، + `crypto/ed25519`)، بلا اعتماديّة C خارجيّة — أقرب سابقة لنهج «ذاتيّ التنفيذ + بالكامل» المُقترَح هنا. +- **Rust `RustCrypto`/`ring`**: `ring` يستعمل BoringSSL مُجمَّعًا داخليًّا (ليس + self-rolled بالكامل)؛ `RustCrypto` (`chacha20poly1305`, `ed25519-dalek`) + Rust خالص — النموذج الأقرب لروح هذا المقترح. +- **libsodium**: يفضّل ChaCha20-Poly1305 وX25519/Ed25519 كخيارات افتراضيّة + تحديدًا لمقاومتها لتسريب التوقيت بلا عتاد مخصَّص — نفس المبرّر المُستشهَد + به أعلاه لاختيار ChaCha20 على AES-GCM. +- **Python `hashlib`/`cryptography`**: يعتمد OpenSSL مباشرة — غير قابل للمقارنة + معماريًّا بسبب غياب قيد الوضع الحرّ في Python. + +# أسئلة غير محسومة (Unresolved questions) + +- **الأسماء العربيّة الكانونيّة النهائيّة** لكل دالّة (`بلايك3`، `هاش_مفتاح`، + `اشتق_مفتاح_مرور`، `شفّر_موثّق`، إلخ) مقترَحات أوّليّة — تحتاج مراجعة + لغويّة قبل تجميدها في `crypto.yaml` (بلايك اسم علم أجنبيّ؛ هل يُترجَم + مفهوميًّا أم يُنقَل صوتيًّا؟). +- **مصدر عشوائيّة لهدف الوضع الحرّ البحت** (بلا نظام تشغيل مضيف، كنواة + sad-os): لا `/dev/urandom` ولا `BCryptGenRandom` هناك. هل يُشترَط توفّر + مصدر عشوائيّة عتاديّ (RDRAND/RDSEED على x86، أو مولِّد هاردوير آخر) كشرط + مسبق لتفعيل وحدة `تشفير` على هذا الهدف، أم تُعطَّل الوحدة كليًّا عليه حتى + توفّر مصدر إنتروبيا موثوق؟ هذا يحدّد نطاق المرحلة ٠ الفعليّ على sad-os. +- **موقع Argon2** — يُعاد طرحه كمقترح منفصل لاحقًا بعد إثبات جدوى المرحلة ٢ + (PBKDF2/HKDF)، أم يبقى خارج النطاق كليًّا لصالح توصية المستخدم دومًا + بمعامل تكرار PBKDF2 مرتفع؟ +- **من يراجع أمنيًّا؟** هل يكفي تدقيق أميليا (مراجعة الوكيل الإلزاميّة + قبل الدفع، القائمة حاليًّا) لخوارزميّات بهذه الحساسيّة، أم يحتاج المشروع + مسارًا إضافيًّا (مراجعة بشريّة متخصّصة/أداة تحليل ثابت أمنيّة) قبل دمج + المرحلتين ٣ و٤ تحديدًا؟ + +# إمكانات مستقبلية (Future possibilities) + +- **Argon2id** كاشتقاق مفتاح مقاوم للذاكرة (بعد حسم «أسئلة غير محسومة» أعلاه). +- **تسريع عتاديّ اختياريّ** (AES-NI/ARM crypto extensions) خلف `#ifdef` على + الأهداف المضيفة فقط، مع بقاء المسار الذاتيّ التنفيذ fallback إلزاميًّا — + دون كسر مبدأ «لا اعتماديّة خارجيّة». +- **تواقيع ما بعد الكمّ (Post-quantum)** — Kyber/Dilithium أو ما يعادلهما، + إذا نضج الطلب العمليّ. +- **واجهة تشفير قنوات كاملة (TLS-like)** فوق X25519/ChaCha20-Poly1305 لدعم + `شبكة_عالية`/`مقابس` بقناة آمنة أصيلة دون اعتماد OpenSSL — امتداد طبيعيّ + بعد اكتمال المراحل ٠-٤.