<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>الرياضيات on kenji.blog</title><link>http://kenji.blog/ar/categories/%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%B6%D9%8A%D8%A7%D8%AA/</link><description>Recent content in الرياضيات on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ar</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 10:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ar/categories/%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%B6%D9%8A%D8%A7%D8%AA/index.xml" rel="self" type="application/rss+xml"/><item><title>الأسس الرياضية لتشفير المنحنيات الإهليلجية (ECC) وتنفيذه بلغة C++</title><link>http://kenji.blog/ar/p/elliptic-curve-cryptography-math-cpp/</link><pubDate>Fri, 11 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/elliptic-curve-cryptography-math-cpp/</guid><description>&lt;img src="http://kenji.blog/p/elliptic-curve-cryptography-math-cpp/img/eyecatch.jpg" alt="Featured image of post الأسس الرياضية لتشفير المنحنيات الإهليلجية (ECC) وتنفيذه بلغة C++" />&lt;h1 id="الأسس-الرياضية-لتشفير-المنحنيات-الإهليلجية-ecc-وتنفيذه-بلغة-c">الأسس الرياضية لتشفير المنحنيات الإهليلجية (ECC) وتنفيذه بلغة C++
&lt;/h1>&lt;p>في تقنيات التشفير الحديثة، يلعب &lt;strong>تشفير المنحنيات الإهليلجية (Elliptic Curve Cryptography: ECC)&lt;/strong> دورًا بالغ الأهمية. ليس من المبالغة القول إن أساس الثقة في مجتمعنا الرقمي الحديث يعتمد على ECC، بدءًا من اتصالات الإنترنت اليومية (HTTPS/TLS)، والجيوب الآمنة (Secure Enclaves) في الهواتف الذكية، ومصادقة الخوادم عبر SSH، والمصادقة بدون كلمات مرور مثل FIDO، وصولاً إلى الأصول المشفرة مثل بيتكوين وإيثريوم.&lt;/p>
&lt;p>في هذا المقال، سنشرح بشكل شامل وكثيف كيف يعمل تشفير المنحنيات الإهليلجية، بدءًا من النظرية الرياضية الجميلة والمعقدة التي تكمن وراءه (الهندسة الجبرية على الحقول المنتهية)، مرورًا بطريقة تنفيذه الفعلي باستخدام لغة C++، وصولاً إلى تقنيات البرمجة الآمنة لمنع هجمات القنوات الجانبية (مثل هجمات التوقيت).&lt;/p>
&lt;hr>
&lt;h2 id="1-لماذا-تشفير-المنحنيات-الإهليلجية-مقارنة-مع-rsa">1. لماذا تشفير المنحنيات الإهليلجية؟ (مقارنة مع RSA)
&lt;/h2>&lt;p>لطالما كان &lt;strong>تشفير RSA&lt;/strong> هو المرادف لتشفير المفتاح العام. يعتمد تشفير RSA في أمانه على &amp;ldquo;صعوبة تحليل الأعداد المركبة الضخمة إلى عواملها الأولية&amp;rdquo;. ومع ذلك، مع تحسن القوة الحسابية لأجهزة الكمبيوتر، أصبح من الضروري زيادة طول مفتاح RSA (عدد بتات المعامل) باستمرار للحفاظ على الأمان. حاليًا، يُوصى باستخدام مفاتيح بطول 2048 بت كحد أدنى، ولأمان أكبر يُفضل استخدام 3072 بت أو 4096 بت.&lt;/p>
&lt;p>في المقابل، يعتمد تشفير المنحنيات الإهليلجية (ECC) على صعوبة رياضية مختلفة وهي &lt;strong>&amp;ldquo;مشكلة اللوغاريتم المتقطع على المنحنيات الإهليلجية (ECDLP)&amp;rdquo;&lt;/strong>. حتى الآن، لم يتم اكتشاف خوارزمية فعالة (مثل خوارزميات الوقت شبه الأسّي) لحل ECDLP، وحتى أكثر طرق الهجوم الفعالة المعروفة تتطلب وقتًا أسّيًا.&lt;/p>
&lt;p>بسبب هذه الخاصية، يتمتع ECC بميزة حاسمة وهي &lt;strong>القدرة على تحقيق مستوى أمان مكافئ لـ RSA باستخدام مفاتيح أقصر بكثير&lt;/strong>.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:center">قوة الأمان (بت)&lt;/th>
&lt;th style="text-align:center">طول مفتاح RSA (بت)&lt;/th>
&lt;th style="text-align:center">طول مفتاح ECC (بت)&lt;/th>
&lt;th style="text-align:center">نسبة طول المفتاح&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:center">80&lt;/td>
&lt;td style="text-align:center">1024&lt;/td>
&lt;td style="text-align:center">160&lt;/td>
&lt;td style="text-align:center">1:6&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">112&lt;/td>
&lt;td style="text-align:center">2048&lt;/td>
&lt;td style="text-align:center">224&lt;/td>
&lt;td style="text-align:center">1:9&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">128&lt;/td>
&lt;td style="text-align:center">3072&lt;/td>
&lt;td style="text-align:center">256&lt;/td>
&lt;td style="text-align:center">1:12&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">192&lt;/td>
&lt;td style="text-align:center">7680&lt;/td>
&lt;td style="text-align:center">384&lt;/td>
&lt;td style="text-align:center">1:20&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">256&lt;/td>
&lt;td style="text-align:center">15360&lt;/td>
&lt;td style="text-align:center">512&lt;/td>
&lt;td style="text-align:center">1:30&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>كما يوضح الجدول أعلاه، للحصول على قوة أمان تبلغ 128 بت (القوة القياسية الحالية)، يتطلب RSA مفتاحًا بطول 3072 بت، بينما يكفي 256 بت فقط في حالة ECC. هذا يتيح تقليل العمليات الحسابية، وخفض استهلاك الذاكرة، وتوفير النطاق الترددي للشبكة، مما يمنحه تفوقًا ساحقًا خاصة في بيئات إنترنت الأشياء (IoT) والبطاقات الذكية ذات الموارد المحدودة.&lt;/p>
&lt;hr>
&lt;h2 id="2-التحضير-الرياضي-نظرية-الزمر-وعالم-الحقول-المنتهية">2. التحضير الرياضي: نظرية الزمر وعالم الحقول المنتهية
&lt;/h2>&lt;p>لفهم تشفير المنحنيات الإهليلجية حقًا، من الضروري استيعاب المفاهيم الأساسية في الجبر المجرد (نظرية الزمر ونظرية الحقول). نلخص هنا المعرفة الأساسية اللازمة لبناء ECC.&lt;/p>
&lt;h3 id="21-الزمرة-group-والزمرة-الأبيلية">2.1. الزمرة (Group) والزمرة الأبيلية
&lt;/h3>&lt;p>&lt;strong>الزمرة (Group)&lt;/strong> هي مجموعة $G$ مقترنة بعملية ثنائية (سنفترض هنا أنها الجمع $+$) يُرمز لها بـ $(G, +)$، والتي تحقق البديهيات الأربع التالية:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>الانغلاق (Closure)&lt;/strong>: لأي $a, b \in G$، يكون $a + b \in G$.&lt;/li>
&lt;li>&lt;strong>الدمج (Associativity)&lt;/strong>: لأي $a, b \in G$، يتحقق $(a + b) + c = a + (b + c)$.&lt;/li>
&lt;li>&lt;strong>وجود العنصر المحايد (Identity element)&lt;/strong>: يوجد عنصر $e \in G$ بحيث لأي $a \in G$ يكون $a + e = e + a = a$. في حالة زمرة الجمع، يُشار إلى هذا العنصر المحايد عادةً بـ $0$ أو $\mathcal{O}$.&lt;/li>
&lt;li>&lt;strong>وجود المعكوس (Inverse element)&lt;/strong>: لأي $a \in G$، يوجد عنصر $b \in G$ بحيث يكون $a + b = b + a = e$. يُشار إلى هذا الـ $b$ بـ $-a$.&lt;/li>
&lt;/ol>
&lt;p>بالإضافة إلى ذلك، إذا كانت الزمرة تحقق الشرط التالي (أي أن تغيير ترتيب العملية لا يغير النتيجة)، فإنها تُسمى &lt;strong>زمرة أبيلية (Abelian Group)&lt;/strong> أو زمرة إبدالية.&lt;/p>
&lt;ol start="5">
&lt;li>&lt;strong>الإبدال (Commutativity)&lt;/strong>: لأي $a, b \in G$، يتحقق $a + b = b + a$.&lt;/li>
&lt;/ol>
&lt;p>تشكل مجموعة النقاط على المنحنى الإهليلجي هذه &lt;strong>الزمرة الأبيلية&lt;/strong> من خلال تعريف قاعدة جمع محددة.&lt;/p>
&lt;h3 id="22-الحقل-المنتهي-finite-field">2.2. الحقل المنتهي (Finite Field)
&lt;/h3>&lt;p>في نظرية التشفير، لا نستخدم حقولاً مستمرة ذات عناصر لا نهائية مثل الأعداد الحقيقية أو المركبة، بل نستخدم &lt;strong>الحقول المنتهية (Finite Fields)&lt;/strong> أو حقول غالوا (Galois Fields) التي تحتوي على عدد محدود من العناصر.&lt;/p>
&lt;p>الحقل المنتهي الأساسي هو &lt;strong>الحقل الأولي $\mathbb{F}_p$&lt;/strong> باستخدام عدد أولي $p$. وهو عبارة عن مجموعة الأعداد الصحيحة $\{0, 1, 2, \dots, p-1\}$ مع تعريف العمليات الحسابية الأربع (الجمع، الطرح، الضرب، القسمة) باستخدام المعامل $p$ (الباقي من القسمة على $p$).&lt;/p>
&lt;ul>
&lt;li>&lt;strong>الجمع&lt;/strong>: $(a + b) \pmod p$&lt;/li>
&lt;li>&lt;strong>الطرح&lt;/strong>: $(a - b) \pmod p$&lt;/li>
&lt;li>&lt;strong>الضرب&lt;/strong>: $(a \times b) \pmod p$&lt;/li>
&lt;li>&lt;strong>القسمة&lt;/strong>: $a \times b^{-1} \pmod p$ (حيث $b^{-1}$ هو المعكوس الضربي لـ $b$ في المعامل $p$)&lt;/li>
&lt;/ul>
&lt;p>يعتبر حساب &lt;strong>المعكوس الضربي (Modular Multiplicative Inverse)&lt;/strong> بالغ الأهمية في تنفيذ التشفير. لإيجاد $b^{-1}$ الذي يحقق $b \times b^{-1} \equiv 1 \pmod p$، تُستخدم أساسًا الخوارزميتان التاليتان:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>خوارزمية إقليدس الممتدة (Extended Euclidean Algorithm)&lt;/strong>: سريعة، لكن في بعض التنفيذات يعتمد وقت المعالجة على قيم الإدخال، مما يشكل خطر التعرض لهجمات التوقيت.&lt;/li>
&lt;li>&lt;strong>مبرهنة فيرما الصغرى (Fermat&amp;rsquo;s Little Theorem)&lt;/strong>: عندما يكون $p$ عددًا أوليًا و $b \neq 0$، يتحقق $b^{p-1} \equiv 1 \pmod p$. بقسمة الطرفين على $b$، نحصل على $b^{p-2} \equiv b^{-1} \pmod p$. أي أن حساب القوة $p-2$ لـ $b$ يعطينا المعكوس. نظرًا لسهولة تنفيذ عمليات الرفع للأس في وقت ثابت (Constant-Time)، يُفضل استخدام هذه الطريقة في تنفيذ التشفير.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="3-معادلة-المنحنى-الإهليلجي-والهندسة">3. معادلة المنحنى الإهليلجي والهندسة
&lt;/h2>&lt;h3 id="31-شكل-فايرشتراس-القياسي">3.1. شكل فايرشتراس القياسي
&lt;/h3>&lt;p>&lt;strong>المنحنى الإهليلجي (Elliptic Curve)&lt;/strong> هو بشكل عام منحنى مستوٍ يُعرّف بالمعادلة التالية التي تُعرف بـ &lt;strong>شكل فايرشتراس القياسي (Weierstrass normal form)&lt;/strong>:&lt;/p>
$$ y^2 = x^3 + ax + b $$
&lt;p>حيث $a$ و $b$ ثوابت، ولضمان عدم احتواء المنحنى على نقاط شاذة (مثل التقاطعات الذاتية أو النقاط المدببة) أي ليكون منحنى أملس (smooth)، يُشترط ألا يكون &lt;strong>المميز (Discriminant) $\Delta$&lt;/strong> التالي مساويًا للصفر:&lt;/p>
$$ \Delta = -16(4a^3 + 27b^2) \neq 0 $$
&lt;p>نظرًا لأن المنحنيات ذات النقاط الشاذة تُضعف الأمان التشفيري، يتم دائمًا اختيار معاملات $a, b$ تحقق هذا الشرط.&lt;/p>
&lt;h3 id="32-نقطة-في-اللانهاية-point-at-infinity">3.2. نقطة في اللانهاية (Point at Infinity)
&lt;/h3>&lt;p>لجعل المنحنى الإهليلجي زمرة رياضية مكتملة، نُدخل نقطة افتراضية تُسمى &lt;strong>&amp;ldquo;نقطة في اللانهاية (Point at Infinity)&amp;rdquo;&lt;/strong> بالإضافة إلى النقاط على المستوى. يُرمز لها بـ $\mathcal{O}$.&lt;/p>
&lt;p>تُعرّف النقطة في اللانهاية $\mathcal{O}$ على أنها النقطة التي تتقاطع عندها جميع الخطوط الرأسية في اللانهاية. في نظرية الزمر، تعمل هذه النقطة $\mathcal{O}$ كـ &lt;strong>عنصر محايد في الجمع&lt;/strong> (صفر).&lt;/p>
&lt;p>أي أنه لأي نقطة $P$ على المنحنى، يتحقق ما يلي:
&lt;/p>
$$ P + \mathcal{O} = \mathcal{O} + P = P $$
&lt;p>كما أن المعكوس $-P$ للنقطة $P = (x, y)$ يُعرّف على أنه النقطة المتناظرة بالنسبة لمحور x وهي $(x, -y)$. وبالتالي:
&lt;/p>
$$ P + (-P) = \mathcal{O} $$
&lt;hr>
&lt;h2 id="4-عمليات-الزمرة-على-المنحنى-الإهليلجي-جمع-النقاط-والمضاعفة">4. عمليات الزمرة على المنحنى الإهليلجي (جمع النقاط والمضاعفة)
&lt;/h2>&lt;p>العملية الأساسية في تشفير المنحنيات الإهليلجية هي &lt;strong>&amp;ldquo;الجمع (Addition)&amp;rdquo;&lt;/strong> بين النقاط على المنحنى. وهذا يختلف عن الجمع العادي للأعداد الصحيحة، حيث يتم تعريفه بناءً على عمليات هندسية.&lt;/p>
&lt;h3 id="41-الجمع-الهندسي-tangent-and-chord-method">4.1. الجمع الهندسي (Tangent and Chord Method)
&lt;/h3>&lt;p>لإيجاد نقطة جديدة $R$ ($R = P + Q$) بجمع نقطتين مختلفتين $P$ و $Q$ على المنحنى، نتبع الخطوات التالية:&lt;/p>
&lt;ol>
&lt;li>نرسم خطًا مستقيمًا (وترًا) يمر بالنقطتين $P$ و $Q$.&lt;/li>
&lt;li>سيتقاطع هذا الخط دائمًا مع المنحنى الإهليلجي في نقطة ثالثة (سنسميها $-R$). (※بناءً على نظرية في الهندسة الجبرية)&lt;/li>
&lt;li>النقطة الناتجة عن عكس $-R$ بشكل متناظر حول محور x (بعكس إشارة الإحداثي y) هي النقطة المطلوبة $R$.&lt;/li>
&lt;/ol>
&lt;div class="mermaid">graph TD
Step1["رسم خط يمر بـ P(x1, y1) و Q(x2, y2)"] --> Step2["إيجاد نقطة التقاطع الثالثة -R مع المنحنى"]
Step2 --> Step3["عكس -R حول محور x للحصول على R(x3, y3)"]
Step3 -.-> Result["هذه هي R = P + Q"]&lt;/div>
&lt;h3 id="42-مضاعفة-النقطة-point-doubling">4.2. مضاعفة النقطة (Point Doubling)
&lt;/h3>&lt;p>عند جمع النقطة $P$ مع نفسها ($P + P = 2P$)، لا يمكننا رسم خط يمر بنقطتين. في هذه الحالة، نرسم &lt;strong>مماس المنحنى (Tangent) عند النقطة $P$&lt;/strong>.&lt;/p>
&lt;ol>
&lt;li>نرسم المماس للمنحنى عند النقطة $P$.&lt;/li>
&lt;li>يتقاطع هذا المماس مع المنحنى في نقطة أخرى $-R$.&lt;/li>
&lt;li>النقطة المعكوسة متناظرًا حول محور x لنقطة التقاطع هي النقطة المطلوبة $R = 2P$.&lt;/li>
&lt;/ol>
&lt;h3 id="43-المعادلات-الجبرية-للحساب">4.3. المعادلات الجبرية للحساب
&lt;/h3>&lt;p>يتم تحويل العمليات الهندسية إلى معادلات جبرية يمكن للكمبيوتر حسابها.
تتم جميع العمليات &lt;strong>فوق الحقل المنتهي $\mathbb{F}_p$ (بالمعامل $p$)&lt;/strong>.&lt;/p>
&lt;p>لنفترض أن النقطة $P = (x_1, y_1)$ والنقطة $Q = (x_2, y_2)$.
ونقطة النتيجة هي $R = P + Q = (x_3, y_3)$.&lt;/p>
&lt;p>ليكن ميل الخط $\lambda$ (لامدا).&lt;/p>
&lt;p>&lt;strong>【الحالة 1: عندما $P \neq Q$ (جمع النقاط)】&lt;/strong>
الميل $\lambda$ هو معدل التغير بين النقطتين.
&lt;/p>
$$ \lambda \equiv \frac{y_2 - y_1}{x_2 - x_1} \pmod p $$
$$ \lambda \equiv (y_2 - y_1) \cdot (x_2 - x_1)^{-1} \pmod p $$
&lt;p>باستخدام هذا $\lambda$، يمكن حساب $x_3, y_3$ كما يلي:
&lt;/p>
$$ x_3 \equiv \lambda^2 - x_1 - x_2 \pmod p $$
$$ y_3 \equiv \lambda(x_1 - x_3) - y_1 \pmod p $$
&lt;p>&lt;strong>【الحالة 2: عندما $P = Q$ (مضاعفة النقطة)】&lt;/strong>
الميل $\lambda$ سيكون ميل المماس المحسوب بواسطة الاشتقاق. (نشتق المعادلة $y^2 = x^3 + ax + b$ ضمنيًا)
&lt;/p>
$$ 2y \cdot y' = 3x^2 + a \implies y' = \frac{3x^2 + a}{2y} $$
&lt;p>
لذلك،
&lt;/p>
$$ \lambda \equiv (3x_1^2 + a) \cdot (2y_1)^{-1} \pmod p $$
&lt;p>صيغتا $x_3, y_3$ هما نفس صيغتي الجمع، ولكن بما أن $x_2 = x_1$ تصبحان كالتالي:
&lt;/p>
$$ x_3 \equiv \lambda^2 - 2x_1 \pmod p $$
$$ y_3 \equiv \lambda(x_1 - x_3) - y_1 \pmod p $$
&lt;blockquote>
&lt;p>[!IMPORTANT]
تتضمن هذه المعادلات &lt;strong>عمليات قسمة (حساب المعكوس النمطي)&lt;/strong> مثل $(x_2 - x_1)^{-1}$ و $(2y_1)^{-1}$. نظرًا لأن تكلفة حساب المعكوس النمطي عالية جدًا، تُستخدم في التنفيذ الفعلي عادةً أنظمة الإحداثيات الإسقاطية مثل &lt;strong>&amp;ldquo;إحداثيات جاكوبي (Jacobian Coordinates)&amp;rdquo;&lt;/strong> لتأخير عملية القسمة.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="5-الضرب-القياسي-ومشكلة-اللوغاريتم-المتقطع-على-المنحنيات-الإهليلجية-ecdlp">5. الضرب القياسي ومشكلة اللوغاريتم المتقطع على المنحنيات الإهليلجية (ECDLP)
&lt;/h2>&lt;p>العملية التي تتطلب أكبر قدر من الحسابات وتُشكل جوهر الأمان في تشفير المنحنيات الإهليلجية هي &lt;strong>الضرب القياسي (Scalar Multiplication)&lt;/strong>.&lt;/p>
&lt;h3 id="51-ما-هو-الضرب-القياسي">5.1. ما هو الضرب القياسي
&lt;/h3>&lt;p>يُسمى جمع النقطة $P$ مع نفسها عدد $k$ من المرات بالضرب القياسي، ويُكتب $kP$.
&lt;/p>
$$ kP = \underbrace{P + P + \dots + P}_{k \text{ من المرات}} $$
&lt;p>حيث $k$ هو عدد صحيح كبير جدًا (مثلاً عدد صحيح من 256 بت).&lt;/p>
&lt;h3 id="52-مشكلة-اللوغاريتم-المتقطع-على-المنحنيات-الإهليلجية-ecdlp">5.2. مشكلة اللوغاريتم المتقطع على المنحنيات الإهليلجية (ECDLP)
&lt;/h3>&lt;p>يعتمد أمان تشفير المنحنيات الإهليلجية على صعوبة المشكلة التالية.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>مشكلة اللوغاريتم المتقطع على المنحنيات الإهليلجية (Elliptic Curve Discrete Logarithm Problem: ECDLP)&lt;/strong>
عند إعطاء النقطة المعروفة $P$ (النقطة الأساسية) والنقطة المحسوبة $Q$، أوجد المُعامل القياسي $k$ الذي يحقق $Q = kP$.&lt;/p>
&lt;/blockquote>
&lt;p>حساب $Q$ من $k$ و $P$ (الاتجاه الأمامي) أمر سهل (وقت متعدد الحدود) باستخدام الخوارزمية الموضحة أدناه، لكن العكس (الاتجاه المعكس) لاستنتاج $k$ من $P$ و $Q$ أمر مستحيل عمليًا، حيث لا توجد طريقة فعالة لحله سوى البحث الشامل (دالة وحيدة الاتجاه).
في بروتوكولات التشفير، يتوافق &lt;strong>$k$ مع &amp;ldquo;المفتاح الخاص&amp;rdquo; و $Q$ مع &amp;ldquo;المفتاح العام&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="53-خوارزمية-المضاعفة-والجمع-double-and-add">5.3. خوارزمية المضاعفة والجمع (Double-and-Add)
&lt;/h3>&lt;p>عندما يكون $k$ رقمًا ضخمًا (مثال: $2^{256}$)، فإن جمع $P$ بشكل مباشر $k$ مرة لن ينتهي حتى لو انتهى عمر الكون. لذلك، لإجراء الضرب القياسي بسرعة، تُستخدم &lt;strong>طريقة المضاعفة والجمع (الطريقة الثنائية)&lt;/strong>.&lt;/p>
&lt;p>هذه هي النسخة الخاصة بالمنحنيات الإهليلجية من &amp;ldquo;طريقة التربيع المتكرر&amp;rdquo; المُستخدمة لحساب قوى الأعداد الصحيحة بسرعة. يتم تمثيل المُعامل $k$ بالنظام الثنائي، وتتم معالجته بدءًا من البت الأكثر أهمية (MSB).&lt;/p>
&lt;ol>
&lt;li>تهيئة النقطة $R$ التي ستحتفظ بالنتيجة بـ $\mathcal{O}$.&lt;/li>
&lt;li>من البت الأكثر أهمية في $k$ إلى البت الأقل أهمية، كرر ما يلي:
&lt;ul>
&lt;li>ضاعف $R$ (مضاعفة النقطة: $R = 2R$)&lt;/li>
&lt;li>إذا كان البت الحالي &lt;code>1&lt;/code>، أضف $P$ إلى $R$ (جمع النقاط: $R = R + P$)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>بفضل هذه الخوارزمية، ينخفض التعقيد الحسابي بشكل كبير من $O(k)$ إلى $O(\log_2 k)$، مما يجعل الحساب ممكنًا في وقت واقعي (بأجزاء من الثانية).&lt;/p>
&lt;hr>
&lt;h2 id="6-تبادل-مفاتيح-ديفي-هيلمان-على-المنحنيات-الإهليلجية-ecdh">6. تبادل مفاتيح ديفي-هيلمان على المنحنيات الإهليلجية (ECDH)
&lt;/h2>&lt;p>نشرح هنا آلية بروتوكول &lt;strong>تبادل مفاتيح ECDH (Elliptic Curve Diffie-Hellman)&lt;/strong>، وهو التطبيق الأكثر تمثيلاً لـ ECC. ECDH هي آلية تتيح لأليس وبوب إنشاء ومشاركة مفتاح سري مشترك (مفتاح الجلسة) بأمان عبر قناة اتصال عرضة للتنصت (وهي جوهر عملية مصافحة TLS).&lt;/p>
&lt;p>&lt;strong>【المعلمات المسبقة (معلمات المجال)】&lt;/strong>
يتشارك الطرفان مسبقًا في المنحنى الإهليلجي المُستخدم $E$، العدد الأولي $p$، والنقطة الأساسية $G$. (على سبيل المثال، NIST P-256 أو secp256k1)&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant Alice as "أليس (Alice)"
participant Bob as "بوب (Bob)"
Note over Alice,Bob: "المعلمات العامة: المنحنى E، النقطة الأساسية G، العدد الأولي p"
Alice->>Alice: "توليد المفتاح الخاص d_A (عدد صحيح عشوائي)"
Alice->>Alice: "حساب المفتاح العام Q_A = d_A * G"
Bob->>Bob: "توليد المفتاح الخاص d_B (عدد صحيح عشوائي)"
Bob->>Bob: "حساب المفتاح العام Q_B = d_B * G"
Alice->>Bob: "إرسال المفتاح العام Q_A (نص صريح)"
Bob->>Alice: "إرسال المفتاح العام Q_B (نص صريح)"
Alice->>Alice: "حساب السر المشترك S = d_A * Q_B"
Bob->>Bob: "حساب السر المشترك S = d_B * Q_A"
Note over Alice,Bob: "S = d_A * (d_B * G) = d_B * (d_A * G) = (d_A * d_B) * G"
Note over Alice,Bob: "النتيجة الحسابية S لكلا الطرفين متطابقة تمامًا!"&lt;/div>
&lt;p>يمكن للمتنصت (إيف) اعتراض $G$ و $Q_A$ و $Q_B$ أثناء انتقالها عبر قناة الاتصال، ولكن نظرًا لصعوبة ECDLP، لا يمكن استنتاج المفتاح الخاص لأليس $d_A$ من $Q_A = d_A \cdot G$. علاوة على ذلك، فإن ضرب $Q_A$ في $Q_B$ لا ينتج المفتاح المشترك $S$، لذلك لا يستطيع المتنصت حساب $S$.&lt;/p>
&lt;hr>
&lt;h2 id="7-فخاخ-التنفيذ-هجمات-القنوات-الجانبية-وطرق-الوقاية-منها">7. فخاخ التنفيذ: هجمات القنوات الجانبية وطرق الوقاية منها
&lt;/h2>&lt;p>حتى لو كانت خوارزمية التشفير مثالية نظريًا، فقد تنشأ نقاط ضعف أثناء عملية تحويلها إلى برنامج. هذا ما يُعرف بـ &lt;strong>&amp;ldquo;هجوم القناة الجانبية (Side-Channel Attack)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h3 id="71-هجوم-التوقيت-timing-attack">7.1. هجوم التوقيت (Timing Attack)
&lt;/h3>&lt;p>دعونا نراجع خوارزمية المضاعفة والجمع المذكورة أعلاه.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// الكود الزائف لـ Double-and-Add الضعيف
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">Point&lt;/span> &lt;span class="n">R&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Infinity&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">255&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">R&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PointDoubling&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// يتم تنفيذه دائمًا
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">bit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">R&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PointAddition&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// يتم تنفيذه فقط عندما يكون البت 1!
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>هذا التنفيذ يحتوي على خلل قاتل. نظرًا لأن Point Addition يتم تنفيذه عندما يكون البت &lt;code>1&lt;/code>، فإن &lt;strong>وقت الحساب سيكون أطول قليلاً&lt;/strong> مما لو كان البت &lt;code>0&lt;/code>. كما يتغير سلوك التنبؤ بالتفرعات في المعالج (Branch Prediction) وذاكرة التخزين المؤقت (Cache).
من خلال مراقبة هذه الفروق الدقيقة في وقت الحساب (أو استهلاك الطاقة) إحصائيًا لآلاف المرات، يمكن للمهاجم &lt;strong>استعادة سلسلة بتات المفتاح الخاص $k$ بتًا بتًا بالكامل&lt;/strong>. هذا هو هجوم التوقيت.&lt;/p>
&lt;h3 id="72-تنفيذ-الوقت-الثابت-constant-time-سلم-مونتغمري-montgomery-ladder">7.2. تنفيذ الوقت الثابت (Constant-Time): سُلَّم مونتغمري (Montgomery Ladder)
&lt;/h3>&lt;p>لمنع هجمات التوقيت، من الضروري اعتماد خوارزمية تكون فيها &lt;strong>سلسلة الأوامر المنفذة ووقت الحساب ثابتين دائمًا (Constant-Time) بغض النظر عن قيمة بتات المفتاح الخاص&lt;/strong>.&lt;/p>
&lt;p>المثال الأبرز على ذلك هو &lt;strong>سُلَّم مونتغمري (Montgomery Ladder)&lt;/strong>.&lt;/p>
&lt;div class="mermaid">graph TD
Start["التهيئة: R0 = O, R1 = P"] --> LoopStart["لكل بت i (من البت الأعلى)"]
LoopStart --> Cond{"ما هي قيمة k_i ؟"}
Cond -->|0| Branch0["R1 = R0 + R1&lt;br>R0 = 2 * R0"]
Cond -->|1| Branch1["R0 = R0 + R1&lt;br>R1 = 2 * R1"]
Branch0 --> LoopEnd["إلى البت التالي"]
Branch1 --> LoopEnd
LoopEnd --> LoopStart
LoopStart -.->|"اكتملت جميع البتات"| End["النهاية: R0 هو النتيجة (kP)"]&lt;/div>
&lt;p>يكمن جمال Montgomery Ladder في أنه، سواء كان البت &lt;code>0&lt;/code> أو &lt;code>1&lt;/code>، يتم &lt;strong>&amp;ldquo;دائمًا تنفيذ عملية Point Addition واحدة وعملية Point Doubling واحدة&amp;rdquo;&lt;/strong>. هذا يقضي تمامًا على اعتماد وقت الحساب على البيانات.&lt;/p>
&lt;p>ومع ذلك، إذا كان هناك تفرع (Branch) نفسه (&lt;code>if (k_i == 0)&lt;/code>)، يظل هناك خطر تغير وقت التنفيذ بسبب تحسينات المترجم (Compiler Optimizations) أو التنبؤ بالتفرعات في وحدة المعالجة المركزية. لذلك، في تنفيذ الوقت الثابت الفعلي، يتم استبعاد الشروط (جملة &lt;code>if&lt;/code>)، ويُستخدم &lt;strong>التبديل الشرطي (Conditional Swap) باستخدام العمليات على مستوى البتات (Bitwise Operations)&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h2 id="8-تنفيذ-تشفير-المنحنيات-الإهليلجية-بلغة-c">8. تنفيذ تشفير المنحنيات الإهليلجية بلغة C++
&lt;/h2>&lt;p>من هنا، سنقوم بتطبيق النظرية في كود C++. على الرغم من أن مكتبات التشفير العملية (مثل OpenSSL أو libsodium) تستخدم تحسينات تجميع (Assembly) متقدمة وأنظمة إحداثيات جاكوبي، إلا أننا سنعرض هنا الهيكل الأساسي لـ &lt;strong>تنفيذ واضح بوقت ثابت (Constant-Time) باستخدام نظام الإحداثيات الأفينية (Affine Coordinates)&lt;/strong> لتعميق الفهم الرياضي.&lt;/p>
&lt;p>سنفترض استخدام &lt;code>boost::multiprecision::cpp_int&lt;/code> للعمليات على الأعداد الصحيحة الضخمة.&lt;/p>
&lt;h3 id="81-العمليات-النمطية-والمعكوس">8.1. العمليات النمطية والمعكوس
&lt;/h3>&lt;p>أولاً، سنعرّف دوال مساعدة للعمليات على الحقول المنتهية. سننفذ حساب المعكوس باستخدام مبرهنة فيرما الصغرى.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;stdexcept&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;boost/multiprecision/cpp_int.hpp&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">boost&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">multiprecision&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// مثال: العدد الأولي p ومعلمات secp256k1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="nf">p&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">const&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// عملية المعامل للحصول على باقي موجب
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">cpp_int&lt;/span> &lt;span class="nf">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">cpp_int&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nl">m&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// حساب قوة المعامل (x^y mod m)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">cpp_int&lt;/span> &lt;span class="nf">powerMod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">cpp_int&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">exp&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">base&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">exp&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">exp&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">res&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">base&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">base&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">base&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">exp&lt;/span> &lt;span class="o">/=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">res&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// المعكوس النمطي باستخدام مبرهنة فيرما الصغرى
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">cpp_int&lt;/span> &lt;span class="nf">modInverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">cpp_int&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// بافتراض أن m عدد أولي: n^(m-2) ≡ n^(-1) mod m
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">powerMod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="82-تمثيل-النقاط-وعمليات-الزمرة-الجمع-والمضاعفة">8.2. تمثيل النقاط وعمليات الزمرة (الجمع والمضاعفة)
&lt;/h3>&lt;p>سننفذ بنية &lt;code>Point&lt;/code> التي تدير النقطة في اللانهاية بواسطة علامة (Flag)، بالإضافة إلى معادلات الجمع.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Point&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">bool&lt;/span> &lt;span class="n">isInfinity&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// إنشاء نقطة في اللانهاية
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">isInfinity&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">true&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// إنشاء نقطة عادية
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">cpp_int&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">isInfinity&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">false&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// جمع النقاط على المنحنى الإهليلجي (R = P + Q)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">Point&lt;/span> &lt;span class="nf">pointAdd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">Q&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">isInfinity&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">Q&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">isInfinity&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="c1">// P + (-P) = النقطة في اللانهاية
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">lambda&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// مضاعفة النقطة (عندما P = Q)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// lambda = (3x^2 + a) / 2y
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">num&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">den&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">modInverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lambda&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">num&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">den&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// جمع النقاط (عندما P != Q)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// lambda = (y2 - y1) / (x2 - x1)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">num&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">den&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">modInverse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lambda&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">num&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">den&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">x3&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lambda&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">lambda&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">Q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">y3&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">mod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lambda&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">x3&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y3&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="83-تنفيذ-التبديل-الشرطي-بوقت-ثابت-constant-time-conditional-swap">8.3. تنفيذ التبديل الشرطي بوقت ثابت (Constant-Time Conditional Swap)
&lt;/h3>&lt;p>عند تبديل محتويات المتغيرات بناءً على قيمة بت المفتاح الخاص، سنقوم بالتبديل باستخدام العمليات على البتات (Mask) فقط بدون استخدام جمل &lt;code>if&lt;/code>. هذا يضمن أن يكون مسار التنفيذ ثابتًا تمامًا.&lt;/p>
&lt;blockquote>
&lt;p>[!TIP]
في التنفيذ الفعلي، لا تعد فئات الأعداد الصحيحة الكبيرة ذات التخصيص الديناميكي مثل &lt;code>cpp_int&lt;/code> مناسبة لمعالجة الوقت الثابت (Constant-Time). يرجع ذلك إلى تسريب معلومات التوقيت عبر تخصيص الذاكرة وتغييرات حجم المصفوفة. في المكتبات العملية، يتم تمثيل الأعداد بحجم ثابت (مثلاً مصفوفة من 4 عناصر من نوع uint64_t)، وتُنفذ عمليات التقنيع (Masking) على مستوى البتات. فيما يلي مثال مفاهيمي.&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// التبديل الشرطي بوقت ثابت (بافتراض استخدام أعداد صحيحة ثابتة الطول)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// إذا كان البت 1 بَدِّل بين P1 و P2، وإذا كان 0 لا تبدل
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">void&lt;/span> &lt;span class="nf">cswap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Point&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">P1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">P2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">uint8_t&lt;/span> &lt;span class="n">bit&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// البت إما 0 أو 1. القناع (Mask) يكون كله 1 (0xFF..) إذا كان البت 1، وكله 0 إذا كان البت 0.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// (نفترض هنا للتوضيح أن كل كلمة في فئة BigInt ثابتة الطول هي w)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="cm">/*
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> uint64_t mask = 0 - (uint64_t)bit;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> for (int i = 0; i &amp;lt; NUM_WORDS; i++) {
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> uint64_t dummy = mask &amp;amp; (P1.x.words[i] ^ P2.x.words[i]);
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> P1.x.words[i] ^= dummy;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> P2.x.words[i] ^= dummy;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> // يتم معالجة الإحداثي y وعلامة isInfinity بنفس الطريقة
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> }
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ※ من الصعب تنفيذ تبديل وقت ثابت مثالي باستخدام boost::multiprecision،
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// لكننا نقتصر هنا على محاكاته باستخدام التفرع لفهم المنطق.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">bit&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">P1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">P2&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="84-الضرب-القياسي-باستخدام-سلم-مونتغمري-montgomery-ladder">8.4. الضرب القياسي باستخدام سُلَّم مونتغمري (Montgomery Ladder)
&lt;/h3>&lt;p>سنجمع بين &lt;code>pointAdd&lt;/code> و &lt;code>cswap&lt;/code> المذكورتين أعلاه لتنفيذ ضرب قياسي آمن.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// الضرب القياسي k * P (باستخدام طريقة سُلَّم مونتغمري)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">Point&lt;/span> &lt;span class="nf">scalarMultiply&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cpp_int&lt;/span> &lt;span class="n">k&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Point&lt;/span> &lt;span class="n">R0&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Point&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="c1">// نقطة في اللانهاية
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Point&lt;/span> &lt;span class="n">R1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">P&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// الحصول على طول بتات k (في secp256k1 هو 256 بت)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">numBits&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">256&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">numBits&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// الحصول على قيمة البت i (0 أو 1)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">uint8_t&lt;/span> &lt;span class="n">bit&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">static_cast&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">uint8_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bit_test&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// إذا كان bit == 1، يتم التبديل بين R0 و R1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cswap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">bit&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// تنفيذ نفس العمليات دائمًا (Point Addition و Point Doubling)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">R1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pointAdd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">R0&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pointAdd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// إذا كان bit == 1، يتم التبديل مرة أخرى لإعادة الحالة
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">cswap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">bit&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">R0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>بفضل منطق التنفيذ هذا، سواء كان كل بت من المُعامل $k$ هو &lt;code>0&lt;/code> أو &lt;code>1&lt;/code>، فإن العمليات المُنفذة داخل كل تكرار للحلقة (&lt;code>cswap&lt;/code> $\to$ &lt;code>pointAdd&lt;/code> $\to$ &lt;code>pointAdd&lt;/code> $\to$ &lt;code>cswap&lt;/code>) ستكون لها نفس المسار تمامًا، مما يوفر حماية قوية ضد تسريب المعلومات السرية من خلال فروق التوقيت أو أنماط الوصول إلى الذاكرة المخبئية (Cache).&lt;/p>
&lt;hr>
&lt;h2 id="9-الخاتمة">9. الخاتمة
&lt;/h2>&lt;p>قد يبدو تشفير المنحنيات الإهليلجية (ECC) للوهلة الأولى غريبًا متسائلاً &amp;ldquo;لماذا تشكل عملية هندسية مثل رسم خط وعكس نقطة التقاطع نظام تشفير؟&amp;rdquo;. لكنه نتاج دمج مذهل بين الرياضيات وعلم التشفير، حيث يمكن بناء دالة وحيدة الاتجاه ممتازة (مشكلة اللوغاريتم المتقطع) من خلال التعيين إلى عالم منفصل وهو الحقول المنتهية.&lt;/p>
&lt;p>في هذا المقال، شرحنا النقاط الهامة التالية:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>التفوق على RSA&lt;/strong>: يوفر أمانًا قويًا بمفاتيح قصيرة جدًا، مما يجعله مثاليًا لعصر الأجهزة المحمولة وإنترنت الأشياء (IoT) الحديث.&lt;/li>
&lt;li>&lt;strong>أساسيات نظرية الزمر والحقول المنتهية&lt;/strong>: البنية الرياضية التي تشكل أساس ECC.&lt;/li>
&lt;li>&lt;strong>صيغ الجمع والمضاعفة&lt;/strong>: طريقة تنفيذ عمليات الزمرة الجبرية باستخدام معادلة فايرشتراس.&lt;/li>
&lt;li>&lt;strong>تهديدات هجمات القنوات الجانبية&lt;/strong>: كيف أن التفرعات الشرطية المعتمدة على بتات المفتاح الخاص تخلق ثغرات قاتلة.&lt;/li>
&lt;li>&lt;strong>تنفيذ الوقت الثابت (Constant-Time)&lt;/strong>: تقنيات برمجة C++ لمنع الهجمات عن طريق توحيد السلوك على مستوى العتاد باستخدام Montgomery Ladder و Conditional Swap.&lt;/li>
&lt;/ol>
&lt;p>في الواقع، يُعتبر بناء مكتبة تشفير مخصصة للعمل في بيئة إنتاجية أمرًا غير مستحسن بسبب المخاطر الأمنية العالية جدًا (قاعدة &amp;ldquo;لا تصنع تشفيرك الخاص&amp;rdquo; أو &amp;ldquo;Don&amp;rsquo;t roll your own crypto&amp;rdquo;). ومع ذلك، فإن الفهم العميق للخوارزمية والخلفية الرياضية التي تعمل بداخلها، سيكون بمثابة سلاح قوي لا يقدر بثمن للمهندسين الذين يصممون ويديرون أنظمة أكثر أمانًا وعالية الأداء.&lt;/p>
&lt;p>في المقال القادم، نود التعمق أكثر في آلية &lt;strong>ECDSA (خوارزمية التوقيع الرقمي للمنحنيات الإهليلجية)&lt;/strong> التي تستخدم هذه المنحنيات، وكذلك &lt;strong>توقيع شنور (Schnorr Signature)&lt;/strong> المُستخدم في بيتكوين.&lt;/p></description></item><item><title>محاكاة خوارزمية شور باستخدام بايثون</title><link>http://kenji.blog/ar/p/shors-algorithm-simulation-python/</link><pubDate>Fri, 11 Sep 2026 08:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/shors-algorithm-simulation-python/</guid><description>&lt;img src="http://kenji.blog/p/shors-algorithm-simulation-python/img/eyecatch.jpg" alt="Featured image of post محاكاة خوارزمية شور باستخدام بايثون" />&lt;h1 id="1-مقدمة-أزمة-التشفير-التي-تجلبها-الحواسيب-الكمومية">1. مقدمة: أزمة التشفير التي تجلبها الحواسيب الكمومية
&lt;/h1>&lt;p>تعتمد معظم معايير الأمان في مجتمع الإنترنت الحديث على &lt;strong>تشفير المفتاح العام&lt;/strong> (خاصة تشفير RSA). عندما نرسل معلومات بطاقة الائتمان الخاصة بنا للتسوق عبر الإنترنت أو نتبادل البيانات شديدة السرية، فإن محتوى هذه الاتصالات محمي بقوة بواسطة تشفير RSA.&lt;/p>
&lt;p>يعتمد أساس أمان تشفير RSA على حقيقة رياضية مفادها أن &amp;ldquo;&lt;strong>تحليل الأعداد الصحيحة الضخمة إلى عواملها الأولية يعد أمرًا بالغ الصعوبة بالنسبة للحواسيب الكلاسيكية (مثل أجهزة الكمبيوتر الشخصية والحواسيب الخارقة التي نستخدمها عادةً)&lt;/strong>&amp;rdquo;. ومع ذلك، فإن &amp;ldquo;&lt;strong>خوارزمية شور (Shor&amp;rsquo;s Algorithm)&lt;/strong>&amp;rdquo; التي أعلن عنها بيتر شور (Peter Shor) في عام 1994، قلبت هذا الافتراض رأسًا على عقب. لقد تم إثبات رياضيًا أنه إذا تم تشغيل خوارزمية شور على حاسوب كمومي واسع النطاق، فيمكنها حل مشاكل تحليل العوامل الأولية التي قد تستغرق من الحواسيب الكلاسيكية وقتًا أطول من عمر الكون، في غضون بضع دقائق إلى بضع ساعات.&lt;/p>
&lt;p>في هذا المقال، سنشرح بالتفصيل الدقيق كيف تقوم خوارزمية شور بتحليل العوامل الأولية بسرعة، بدءًا من آليتها الرياضية وحتى التنفيذ العملي للمحاكاة باستخدام بايثون وإطار عمل الحوسبة الكمومية &lt;strong>Qiskit&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="2-تغيير-جذري-في-التعقيد-الحسابي-من-الوقت-الأسي-إلى-الوقت-متعدد-الحدود">2. تغيير جذري في التعقيد الحسابي: من الوقت الأسي إلى الوقت متعدد الحدود
&lt;/h1>&lt;p>لماذا يعد تحليل العوامل الأولية صعبًا؟ حتى لو استخدمنا &amp;ldquo;طريقة غربال حقل الأعداد العام (General Number Field Sieve, GNFS)&amp;quot;، والتي تُعرف بأنها أفضل خوارزمية لتحليل العوامل الأولية في الحواسيب الكلاسيكية، فإن تعقيدها الحسابي سيكون شبه أسي.&lt;/p>
&lt;p>يُعطى الوقت اللازم لتحليل عدد مؤلف من $N$ خانة إلى عوامله الأولية باستخدام الطرق الكلاسيكية على النحو التالي:&lt;/p>
$$ O\left(\exp\left( c (\log N)^{1/3} (\log \log N)^{2/3} \right)\right) $$
&lt;p>لهذا السبب، بمجرد زيادة طول المفتاح (على سبيل المثال، إلى 2048 بت أو 4096 بت)، فإن فك التشفير باستخدام الحواسيب الكلاسيكية سيستغرق وقتًا غير واقعي، مثل آلاف أو عشرات الآلاف من السنين.&lt;/p>
&lt;p>ومع ذلك، عند استخدام &lt;strong>خوارزمية شور&lt;/strong> على حاسوب كمومي، يتم تقليل التعقيد الحسابي بشكل كبير إلى وقت متعدد الحدود بالنسبة لعدد البتات المدخلة $\log N$.&lt;/p>
$$ O((\log N)^3) $$
&lt;p>هذا يعني أنه إذا قمنا بمضاعفة عدد البتات، فإن وقت الحساب سيزداد بشكل فلكي على الحاسوب الكلاسيكي، بينما سيزداد على الأكثر بحوالي 8 أضعاف على الحاسوب الكمومي. هذا &lt;strong>التقليل في فئة التعقيد الحسابي من الوقت الأسي إلى الوقت متعدد الحدود (الشمول في فئة BQP)&lt;/strong> هو العظمة الحقيقية لخوارزمية شور.&lt;/p>
&lt;div class="mermaid">graph TD
A["زيادة حجم الإدخال (عدد البتات) N"] --> B{"اختيار الخوارزمية"}
B -->|كلاسيكية: غربال حقل الأعداد العام| C["زيادة شبه أسية O(exp(...))"]
B -->|كمومية: خوارزمية شور| D["وقت متعدد الحدود O((log N)^3)"]
C --> E["آلاف إلى مليارات السنين (غير قابل للفك)"]
D --> F["بضع دقائق إلى ساعات (وقت واقعي للفك)"]&lt;/div>
&lt;hr>
&lt;h1 id="3-النظرة-العامة-للخوارزمية-والخلفية-الرياضية">3. النظرة العامة للخوارزمية والخلفية الرياضية
&lt;/h1>&lt;p>في الواقع، لا تقوم خوارزمية شور بتنفيذ كل شيء على الحاسوب الكمومي. إنها تعتمد على التعاون بين المعالجة المسبقة واللاحقة التي يقوم بها الحاسوب الكلاسيكي، والجزء الأساسي (خوارزمية إيجاد الدورة) الذي يقوم به الحاسوب الكمومي.&lt;/p>
&lt;p>التدفق العام للخوارزمية هو كما يلي.&lt;/p>
&lt;div class="mermaid">graph TD
A["المدخل: العدد المؤلف المراد تحليله N"] --> B["اختيار رقم عشوائي a بحيث a &lt; N"]
B --> C{"gcd(a, N) > 1 ?"}
C -- "نعم" --> D["إخراج العامل البديهي gcd(a, N) والإنهاء"]
C -- "لا" --> E["استخدام الخوارزمية الكمومية لإيجاد الدورة r للدالة f(x) = a^x mod N"]
E --> F{"r زوجي و a^(r/2) ≢ -1 mod N ؟"}
F -- "لا" --> B
F -- "نعم" --> G["حساب العوامل p = gcd(a^(r/2) - 1, N), q = gcd(a^(r/2) + 1, N)"]
G --> H["الإخراج: p, q"]&lt;/div>
&lt;h2 id="اختزال-تحليل-العوامل-الأولية-إلى-مشكلة-إيجاد-الدورة">اختزال تحليل العوامل الأولية إلى مشكلة إيجاد الدورة
&lt;/h2>&lt;p>تكمن عبقرية شور في تحويله لـ &amp;ldquo;&lt;strong>مشكلة تحليل العوامل الأولية&lt;/strong>&amp;rdquo; إلى &amp;ldquo;&lt;strong>مشكلة إيجاد الدورة (Order Finding Problem)&lt;/strong>&amp;rdquo;.&lt;/p>
&lt;p>نعتبر عددًا صحيحًا $N$ (الرقم المراد تحليله)، وعددًا صحيحًا أوليًا نسبيًا معه $a$ ($1 &lt; a &lt; N$). نُعرّف دالة الأس النمطية التالية:&lt;/p>
$$ f(x) = a^x \bmod N $$
&lt;p>هذه الدالة لها دورة معينة $r$. أي أنه لأي $x$، يتحقق $f(x+r) = f(x)$. بشكل خاص، عندما يكون $x=0$:&lt;/p>
$$ a^r \equiv 1 \pmod N $$
&lt;p>أصغر عدد صحيح موجب $r$ يحقق هذا يسمى &amp;ldquo;رتبة (Order) العدد $a$ قياسًا لـ $N$&amp;rdquo;. إذا تمكنا من إيجاد هذه الدورة $r$، فيمكننا استنتاج العوامل الأولية بالطريقة التالية.&lt;/p>
&lt;p>بتعديل المعادلة:
&lt;/p>
$$ a^r - 1 \equiv 0 \pmod N $$
&lt;p>
إذا كان $r$ عددًا زوجيًا، يمكننا تحليله باستخدام صيغة الفرق بين مربعين:
&lt;/p>
$$ (a^{r/2} - 1)(a^{r/2} + 1) \equiv 0 \pmod N $$
&lt;p>هذا يعني أن $N$ يشترك في قاسم مشترك إما مع $(a^{r/2} - 1)$ أو $(a^{r/2} + 1)$ (بشرط أن يحقق الشرط $a^{r/2} \not\equiv -1 \pmod N$). وبالتالي، باستخدام خوارزمية إقليدس:&lt;/p>
$$ p = \gcd(a^{r/2} - 1, N) $$
$$ q = \gcd(a^{r/2} + 1, N) $$
&lt;p>بحساب ما سبق، يمكننا العثور على العوامل الأولية غير البديهية $p, q$ للعدد $N$. يمكن إجراء هذا الحساب (حساب القاسم المشترك الأكبر وتوليد الأرقام العشوائية) بسرعة كبيرة على الحواسيب الكلاسيكية. المشكلة تقتصر على &lt;strong>كيفية إيجاد الدورة $r$ بسرعة&lt;/strong>. في الحواسيب الكلاسيكية، يستغرق إيجاد هذه الدورة $r$ نفسها وقتًا أسيًا. وهنا يأتي دور الحواسيب الكمومية.&lt;/p>
&lt;hr>
&lt;h1 id="4-جزء-الخوارزمية-الكمومية-آلية-إيجاد-الدورة">4. جزء الخوارزمية الكمومية: آلية إيجاد الدورة
&lt;/h1>&lt;p>يتكون الروتين الفرعي لإيجاد الدورة $r$ باستخدام الحاسوب الكمومي من الخطوات الأربع التالية:&lt;/p>
&lt;div class="mermaid">graph LR
subgraph "انتقال الحالة الكمومية"
S1["|0⟩|0⟩ (التهيئة)"] --> S2["بوابة H: التراكب Σ|x⟩|0⟩"]
S2 --> S3["الأوراكل U: Σ|x⟩|a^x mod N⟩"]
S3 --> S4["QFT: استخراج الدورة عبر التداخل"]
S4 --> S5["القياس: الحصول على القيمة التقريبية y"]
end&lt;/div>
&lt;h2 id="الخطوة-1-تهيئة-السجل-الكمومي-والتراكب">الخطوة 1: تهيئة السجل الكمومي والتراكب
&lt;/h2>&lt;p>أولاً، نُعد سجلين كموميين. السجل الأول يُستخدم لإدخال الحالة، والسجل الثاني لتخزين نتيجة حساب الدالة.
الحالة الأولية هي كلها $|0\rangle$.&lt;/p>
$$ |\psi_0\rangle = |0\rangle_1 |0\rangle_2 $$
&lt;p>نطبق بوابة هادامارد (Hadamard Gate) على جميع البتات الكمومية في السجل الأول، لإنشاء حالة تراكب متساوية الاحتمال لجميع المدخلات الممكنة $x$ (من $0$ إلى $Q-1$، حيث $Q=2^n$).&lt;/p>
$$ |\psi_1\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle_1 |0\rangle_2 $$
&lt;p>وبهذا، يحتفظ الحاسوب الكمومي بحالة لجميع المدخلات الـ $Q$ في نفس الوقت بعملية واحدة. هذا هو المصدر القوي لـ &lt;strong>التوازي الكمومي&lt;/strong>.&lt;/p>
&lt;h2 id="الخطوة-2-تطبيق-دالة-الأوراكل-الأسية-النمطية">الخطوة 2: تطبيق دالة الأوراكل (الأسية النمطية)
&lt;/h2>&lt;p>بعد ذلك، باستخدام الدائرة المنطقية الكمومية $U_f$، نحسب الدالة $f(x) = a^x \bmod N$ ونخزن النتيجة في السجل الثاني.&lt;/p>
$$ |\psi_2\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle_1 |a^x \bmod N\rangle_2 $$
&lt;p>في هذه المرحلة، يكون السجلان الأول والثاني في حالة &lt;strong>تشابك كمومي (Entanglement)&lt;/strong>. إذا قمنا (افتراضيًا) برصد السجل الثاني وحصلنا على قيمة معينة $k = a^{x_0} \bmod N$، فإن حالة السجل الأول ستنهار إلى تراكب لقيم $x$ التي تعطي تلك القيمة $k$. نظرًا لأن دورة الدالة هي $r$، ستكون الحالات المتبقية هي قيم تبعد بمسافة $r$، أي $x_0, x_0+r, x_0+2r, \dots$.&lt;/p>
$$ |\psi_3\rangle = \sqrt{\frac{r}{Q}} \sum_{j=0}^{M-1} |x_0 + j r\rangle_1 |k\rangle_2 $$
&lt;p>ولكن، نحن لا نريد معرفة $x_0$، بل نريد معرفة الدورة $r$ نفسها. من المستحيل ملاحظة $r$ مباشرة من هذه الحالة. لذلك، نستخدم تحويل فورييه الكمومي.&lt;/p>
&lt;h2 id="الخطوة-3-التداخل-الطوري-بواسطة-تحويل-فورييه-الكمومي-qft">الخطوة 3: التداخل الطوري بواسطة تحويل فورييه الكمومي (QFT)
&lt;/h2>&lt;p>نُطبق &lt;strong>تحويل فورييه الكمومي (Quantum Fourier Transform, QFT)&lt;/strong> على السجل الأول. QFT هو النسخة الكمومية من تحويل فورييه المتقطع الكلاسيكي، ويقوم بتحويل سعات متجه الحالة. يُعرّف تأثير QFT على حالة الأساس $|x\rangle$ على النحو التالي:&lt;/p>
$$ QFT |x\rangle = \frac{1}{\sqrt{Q}} \sum_{y=0}^{Q-1} \omega^{xy} |y\rangle $$
&lt;p>حيث $\omega = e^{2\pi i / Q}$.&lt;/p>
&lt;p>عند تطبيق QFT، تتداخل سعات الحالة. دون الدخول في التفاصيل الرياضية المعقدة، عند تطبيق QFT على حالة ذات دورة $r$، فإن الموجة تُحدث &lt;strong>تداخلاً بناءً (Constructive Interference)&lt;/strong> فقط عندما تكون $y$ قريبة جدًا من مضاعف صحيح للرقم $Q/r$. أما الحالات الأخرى فتُلغى فيها سعات الاحتمال بسبب &lt;strong>التداخل الهدام (Destructive Interference)&lt;/strong> وتقترب من الصفر.&lt;/p>
&lt;h2 id="الخطوة-4-القياس-والتوسع-في-الكسور-المستمرة">الخطوة 4: القياس والتوسع في الكسور المستمرة
&lt;/h2>&lt;p>أخيرًا، نقيس السجل الأول. القيمة $y$ التي يتم الحصول عليها بالقياس ستحقق الشرط التالي باحتمال كبير:&lt;/p>
$$ y \approx c \frac{Q}{r} \implies \frac{y}{Q} \approx \frac{c}{r} $$
&lt;p>(حيث $c$ هو عدد صحيح مجهول يحقق $0 \le c &lt; r$)&lt;/p>
&lt;p>من خلال تطبيق الخوارزمية الكلاسيكية لـ &lt;strong>الكسور المستمرة (Continued Fraction Expansion)&lt;/strong> على العدد الكسري الناتج $y/Q$، يمكننا حساب الكسر التقريبي $c/r$ واستخراج الدورة $r$ من المقام.&lt;/p>
&lt;hr>
&lt;h1 id="5-محاكاة-التنفيذ-باستخدام-بايثون-و-qiskit">5. محاكاة التنفيذ باستخدام بايثون و Qiskit
&lt;/h1>&lt;p>لأن النظرية وحدها قد لا تعطي إحساسًا ملموسًا، دعونا نقوم بمحاكاة خوارزمية شور فعليًا باستخدام بايثون وإطار عمل الحوسبة الكمومية من IBM &lt;strong>Qiskit&lt;/strong>.&lt;/p>
&lt;p>هنا، سننفذ السيناريو الكلاسيكي والأكثر شهرة وهو &amp;ldquo;&lt;strong>تحليل $N=15$ باستخدام $a=7$&lt;/strong>&amp;rdquo;.&lt;/p>
&lt;h2 id="إعداد-بيئة-التشغيل">إعداد بيئة التشغيل
&lt;/h2>&lt;p>يرجى تثبيت Qiskit مسبقًا.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install qiskit qiskit-aer numpy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="النظرة-العامة-على-كود-بايثون">النظرة العامة على كود بايثون
&lt;/h2>&lt;p>الكود التالي هو مثال تنفيذي لخوارزمية شور مخصص لـ $N=15, a=7$. نظرًا لأن بناء دائرة أسية نمطية عامة مكلف جدًا في المحاكيات الحالية، فقد قمنا بترميز سلوك البوابات المنطقية للحالة الخاصة $a=7$.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt"> 10
&lt;/span>&lt;span class="lnt"> 11
&lt;/span>&lt;span class="lnt"> 12
&lt;/span>&lt;span class="lnt"> 13
&lt;/span>&lt;span class="lnt"> 14
&lt;/span>&lt;span class="lnt"> 15
&lt;/span>&lt;span class="lnt"> 16
&lt;/span>&lt;span class="lnt"> 17
&lt;/span>&lt;span class="lnt"> 18
&lt;/span>&lt;span class="lnt"> 19
&lt;/span>&lt;span class="lnt"> 20
&lt;/span>&lt;span class="lnt"> 21
&lt;/span>&lt;span class="lnt"> 22
&lt;/span>&lt;span class="lnt"> 23
&lt;/span>&lt;span class="lnt"> 24
&lt;/span>&lt;span class="lnt"> 25
&lt;/span>&lt;span class="lnt"> 26
&lt;/span>&lt;span class="lnt"> 27
&lt;/span>&lt;span class="lnt"> 28
&lt;/span>&lt;span class="lnt"> 29
&lt;/span>&lt;span class="lnt"> 30
&lt;/span>&lt;span class="lnt"> 31
&lt;/span>&lt;span class="lnt"> 32
&lt;/span>&lt;span class="lnt"> 33
&lt;/span>&lt;span class="lnt"> 34
&lt;/span>&lt;span class="lnt"> 35
&lt;/span>&lt;span class="lnt"> 36
&lt;/span>&lt;span class="lnt"> 37
&lt;/span>&lt;span class="lnt"> 38
&lt;/span>&lt;span class="lnt"> 39
&lt;/span>&lt;span class="lnt"> 40
&lt;/span>&lt;span class="lnt"> 41
&lt;/span>&lt;span class="lnt"> 42
&lt;/span>&lt;span class="lnt"> 43
&lt;/span>&lt;span class="lnt"> 44
&lt;/span>&lt;span class="lnt"> 45
&lt;/span>&lt;span class="lnt"> 46
&lt;/span>&lt;span class="lnt"> 47
&lt;/span>&lt;span class="lnt"> 48
&lt;/span>&lt;span class="lnt"> 49
&lt;/span>&lt;span class="lnt"> 50
&lt;/span>&lt;span class="lnt"> 51
&lt;/span>&lt;span class="lnt"> 52
&lt;/span>&lt;span class="lnt"> 53
&lt;/span>&lt;span class="lnt"> 54
&lt;/span>&lt;span class="lnt"> 55
&lt;/span>&lt;span class="lnt"> 56
&lt;/span>&lt;span class="lnt"> 57
&lt;/span>&lt;span class="lnt"> 58
&lt;/span>&lt;span class="lnt"> 59
&lt;/span>&lt;span class="lnt"> 60
&lt;/span>&lt;span class="lnt"> 61
&lt;/span>&lt;span class="lnt"> 62
&lt;/span>&lt;span class="lnt"> 63
&lt;/span>&lt;span class="lnt"> 64
&lt;/span>&lt;span class="lnt"> 65
&lt;/span>&lt;span class="lnt"> 66
&lt;/span>&lt;span class="lnt"> 67
&lt;/span>&lt;span class="lnt"> 68
&lt;/span>&lt;span class="lnt"> 69
&lt;/span>&lt;span class="lnt"> 70
&lt;/span>&lt;span class="lnt"> 71
&lt;/span>&lt;span class="lnt"> 72
&lt;/span>&lt;span class="lnt"> 73
&lt;/span>&lt;span class="lnt"> 74
&lt;/span>&lt;span class="lnt"> 75
&lt;/span>&lt;span class="lnt"> 76
&lt;/span>&lt;span class="lnt"> 77
&lt;/span>&lt;span class="lnt"> 78
&lt;/span>&lt;span class="lnt"> 79
&lt;/span>&lt;span class="lnt"> 80
&lt;/span>&lt;span class="lnt"> 81
&lt;/span>&lt;span class="lnt"> 82
&lt;/span>&lt;span class="lnt"> 83
&lt;/span>&lt;span class="lnt"> 84
&lt;/span>&lt;span class="lnt"> 85
&lt;/span>&lt;span class="lnt"> 86
&lt;/span>&lt;span class="lnt"> 87
&lt;/span>&lt;span class="lnt"> 88
&lt;/span>&lt;span class="lnt"> 89
&lt;/span>&lt;span class="lnt"> 90
&lt;/span>&lt;span class="lnt"> 91
&lt;/span>&lt;span class="lnt"> 92
&lt;/span>&lt;span class="lnt"> 93
&lt;/span>&lt;span class="lnt"> 94
&lt;/span>&lt;span class="lnt"> 95
&lt;/span>&lt;span class="lnt"> 96
&lt;/span>&lt;span class="lnt"> 97
&lt;/span>&lt;span class="lnt"> 98
&lt;/span>&lt;span class="lnt"> 99
&lt;/span>&lt;span class="lnt">100
&lt;/span>&lt;span class="lnt">101
&lt;/span>&lt;span class="lnt">102
&lt;/span>&lt;span class="lnt">103
&lt;/span>&lt;span class="lnt">104
&lt;/span>&lt;span class="lnt">105
&lt;/span>&lt;span class="lnt">106
&lt;/span>&lt;span class="lnt">107
&lt;/span>&lt;span class="lnt">108
&lt;/span>&lt;span class="lnt">109
&lt;/span>&lt;span class="lnt">110
&lt;/span>&lt;span class="lnt">111
&lt;/span>&lt;span class="lnt">112
&lt;/span>&lt;span class="lnt">113
&lt;/span>&lt;span class="lnt">114
&lt;/span>&lt;span class="lnt">115
&lt;/span>&lt;span class="lnt">116
&lt;/span>&lt;span class="lnt">117
&lt;/span>&lt;span class="lnt">118
&lt;/span>&lt;span class="lnt">119
&lt;/span>&lt;span class="lnt">120
&lt;/span>&lt;span class="lnt">121
&lt;/span>&lt;span class="lnt">122
&lt;/span>&lt;span class="lnt">123
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit_aer&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AerSimulator&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit.visualization&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">plot_histogram&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">fractions&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Fraction&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. دالة لإنشاء تحويل فورييه الكمومي العكسي (QFT†)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">qft_dagger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;إنشاء دائرة تحويل فورييه الكمومي العكسي لـ n بت كمومي&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># بوابة SWAP لعكس الترتيب&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">qubit&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qubit&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">qubit&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تطبيق بوابة الطور المتحكم فيها وبوابة H&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">j&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">cp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pi&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nb">float&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">)),&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">j&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;QFT_dagger&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">qc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. دالة لإنشاء عملية الأس النمطية المتحكم فيها 7^x mod 15&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">c_amod15&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">power&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;إنشاء بوابة U للتحكم لـ a وأس معينين (مخصص لـ N=15)&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">_&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">power&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># منطق مرمز لحالة 7^x mod 15 عندما a=7&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">13&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">11&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">11&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">13&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">to_gate&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">^&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">power&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> mod 15&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">c_U&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">control&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">c_U&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. تكوين الدائرة الكمومية الرئيسية&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">shor_circuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># n_count: عدد بتات سجل التحكم&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># سجل الهدف يحتاج 4 بتات لتمثيل 0 إلى 15&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تهيئة السجل الأول (سجل التحكم) (إنشاء تراكب)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تهيئة السجل الثاني (سجل الهدف) إلى |1&amp;gt; (0001)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تطبيق عملية الأس النمطية المتحكم فيها (الأوراكل)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تطبيق عملية 2^q&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c_amod15&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="n">n_count&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">)])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تطبيق تحويل فورييه الكمومي العكسي على السجل الأول&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qft_dagger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># قياس السجل الأول&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">measure&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">qc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># --- قسم التنفيذ ---&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">N&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">15&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">7&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">n_count&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">8&lt;/span> &lt;span class="c1"># استخدام 8 بتات كمومية في سجل التحكم (Q=256)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;إعدادات البحث: N=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, a=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, عدد بتات التحكم=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># إنشاء الدائرة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">shor_circuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># التنفيذ على المحاكي&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sim&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AerSimulator&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># يوصى باستخدام transpile في الإصدارات الأحدث من Qiskit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">transpile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">compiled_circuit&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">transpile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sim&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">job&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sim&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">compiled_circuit&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">shots&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">job&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">counts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_counts&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">نتائج القياس (سلسلة البتات: عدد مرات الرصد):&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">bitstring&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">count&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">counts&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">items&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">bitstring&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> مرات&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># المعالجة البعدية الكلاسيكية: تحديد الدورة r بواسطة الكسور المستمرة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">--- حساب الدورة وتحليل العوامل الأولية ---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">output&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">counts&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تحويل سلسلة البتات إلى عدد عشري&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">decimal&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">int&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">output&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># الطور = القيمة المقاسة / 2^n_count&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phase&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">decimal&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phases&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">phase&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># الحصول على كسر تقريبي عبر الكسور المستمرة. أقصى مقام هو N=15&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">frac&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Fraction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">phase&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">limit_denominator&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">15&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">frac&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">denominator&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;القيمة المرصودة: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">decimal&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">3d&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> | الطور: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">phase&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.4f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> | الكسر المستمر: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">frac&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> | الدورة المقدرة r = &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># التأكد مما إذا كانت الدورة r زوجية وتعطي نتائج صالحة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">guess1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">guess2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">guess1&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="ow">or&lt;/span> &lt;span class="n">guess2&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; =&amp;gt; نجاح！ عوامل &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> الأولية هي &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">guess1&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> و &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">guess2&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; =&amp;gt; عوامل بديهية فقط. يرجى إعادة المحاولة.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; =&amp;gt; فشل لأن الدورة فردية.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="شرح-الكود-وتحليل-نتائج-التنفيذ">شرح الكود وتحليل نتائج التنفيذ
&lt;/h2>&lt;p>عند تشغيل الكود أعلاه، سنحصل باحتمال كبير على ذروات معينة (قيم مرصودة) كنتيجة لقياس سجل التحكم. في حالة &lt;code>n_count=8&lt;/code> ($Q=256$)، إذا استخدمنا حاسوبًا كموميًا مثاليًا (أو محاكيًا)، فإن القيم مثل &lt;code>0&lt;/code>, &lt;code>64&lt;/code>, &lt;code>128&lt;/code>, &lt;code>192&lt;/code> ستظهر باحتمال هائل.&lt;/p>
&lt;p>عند تقسيم هذه القيم على $Q=256$، سنجد أن الطور $y/Q$ يصبح $0.0$, $0.25$, $0.5$, $0.75$ على التوالي.
عند توسيع هذه الأطوار إلى كسور مستمرة، نحصل على:&lt;/p>
&lt;ul>
&lt;li>$0.25 \to 1/4$ (الدورة المقدرة $r=4$)&lt;/li>
&lt;li>$0.50 \to 1/2$ (الدورة المقدرة $r=2$)&lt;/li>
&lt;li>$0.75 \to 3/4$ (الدورة المقدرة $r=4$)&lt;/li>
&lt;/ul>
&lt;p>باستخدام الدورة $r=4$ التي حصلنا عليها هنا، نحسب العوامل الأولية.
بما أن $a=7, r=4$:
$p = \gcd(7^2 - 1, 15) = \gcd(48, 15) = 3$
$q = \gcd(7^2 + 1, 15) = \gcd(50, 15) = 5$&lt;/p>
&lt;p>لقد نجحنا بنجاح كبير في تحليل $15 = 3 \times 5$ إلى عوامله الأولية.&lt;/p>
&lt;blockquote>
&lt;p>[!TIP]
إذا تم الحصول على القيمة المقاسة $y=128$ (الطور $0.5$)، فإن المقام يصبح $2$، ونحصل على قاسم للدورة الحقيقية بدلاً من الدورة $r=4$. في مثل هذه الحالات، يمكننا الوصول إلى الدورة الحقيقية بتنفيذ الخوارزمية عدة مرات أو عن طريق التحقق من مضاعفات الـ $r$ التي حصلنا عليها.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h1 id="6-تحديات-التطبيق-العملي-وحدود-عصر-nisq">6. تحديات التطبيق العملي وحدود عصر NISQ
&lt;/h1>&lt;p>على الرغم من سهولة تحليل $N=15$ على المحاكي، إلا أنه لا تزال هناك عقبات عديدة أمام الحواسيب الكمومية الفعلية لتحليل تشفير RSA-2048 المستخدم في العالم الحقيقي (والذي يتكون من 617 رقمًا عشريًا).&lt;/p>
&lt;p>يُطلق على العصر الذي نعيش فيه الآن اسم &lt;strong>عصر NISQ (Noisy Intermediate-Scale Quantum: الحواسيب الكمومية متوسطة الحجم والمصحوبة بالضوضاء)&lt;/strong>. البتات الكمومية حساسة للغاية لضوضاء البيئة الخارجية، وتتسبب في حدوث &amp;ldquo;فقدان الترابط (Decoherence)&amp;rdquo; أثناء العمليات الحسابية، مما يؤدي إلى تدمير حالتها.&lt;/p>
&lt;p>لتنفيذ دائرة عميقة (تحتوي على عدد كبير من البوابات) مثل خوارزمية شور بدقة، فإن &lt;strong>تصحيح الأخطاء الكمومية (Quantum Error Correction)&lt;/strong> أمر لا غنى عنه. لإنشاء &amp;ldquo;بت كمومي منطقي&amp;rdquo; واحد خالٍ من الضوضاء، يلزم تشفير آلاف &amp;ldquo;البتات الكمومية المادية&amp;rdquo; باستخدام رمز السطح (Surface Code) أو طرق مشابهة.&lt;/p>
&lt;p>لكسر تشفير RSA ذي الـ 2048 بت، يُقدر أننا نحتاج إلى آلاف البتات الكمومية المنطقية المثالية، ولتحقيق ذلك نحتاج إلى حاسوب كمومي متسامح مع الأخطاء يحتوي على &lt;strong>ملايين إلى عشرات الملايين من البتات الكمومية المادية&lt;/strong>. نظرًا لأن أحدث المعالجات الكمومية الحالية تحتوي فقط على مئات إلى آلاف البتات الكمومية المادية، فلن يتم كسر أنظمة التشفير في العالم على الفور.&lt;/p>
&lt;blockquote>
&lt;p>[!WARNING]
ومع ذلك، هناك نموذج تهديد يُعرف باسم &amp;ldquo;خزّن الآن، وفك التشفير لاحقًا (Store Now, Decrypt Later)&amp;rdquo;. يمكن للمهاجمين تخزين كميات هائلة من الاتصالات السرية المشفرة حاليًا كما هي، واعتماد استراتيجية لفك تشفيرها بالكامل في اللحظة التي يتم فيها إنجاز حاسوب كمومي قوي بعد 10 إلى 20 عامًا.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h1 id="7-الانتقال-إلى-التشفير-ما-بعد-الكمومي-pqc">7. الانتقال إلى التشفير ما بعد الكمومي (PQC)
&lt;/h1>&lt;p>استعدادًا لمجيء &amp;ldquo;Q-Day (اليوم الذي تكسر فيه الحواسيب الكمومية التشفير)&amp;quot;، يعكف علماء التشفير حول العالم، بقيادة المعهد الوطني للمعايير والتقنية (NIST) في الولايات المتحدة، على تطوير معايير &lt;strong>التشفير ما بعد الكمومي (Post-Quantum Cryptography, PQC)&lt;/strong>.&lt;/p>
&lt;p>يعتمد PQC على مسائل رياضية جديدة (مثل مشاكل الشبكات، ومسائل كثيرات الحدود متعددة المتغيرات، والطرق المعتمدة على دوال التجزئة) والتي يُعتقد رياضيًا أنه لا يمكن حلها بكفاءة حتى باستخدام خوارزمية شور (أو حتى خوارزمية جروفر). لقد تم بالفعل اختيار خوارزميات مثل &amp;ldquo;CRYSTALS-Kyber&amp;rdquo; و &amp;ldquo;CRYSTALS-Dilithium&amp;rdquo; كمعايير قياسية، وبدأ دمجها تدريجيًا في بروتوكولات الاتصال الخاصة بـ iMessage من Apple ومختلف متصفحات الويب.&lt;/p>
&lt;p>بالنسبة للمهندسين الذين يديرون البنية التحتية لتكنولوجيا المعلومات، فإن دمج &amp;ldquo;المرونة التشفيرية (Crypto-Agility: التصميم الذي يسمح بالتبديل السريع لأساليب التشفير)&amp;rdquo; في الأنظمة للانتقال من تشفير RSA ومنحنيات إهليلجية الحالي إلى PQC سيكون مهمة حاسمة في المستقبل.&lt;/p>
&lt;hr>
&lt;h1 id="8-خاتمة">8. خاتمة
&lt;/h1>&lt;p>في هذا المقال، قمنا بشرح مفصل ومكثف بخلفية نظرية واسعة، بدءًا من الأساس الرياضي النظري لخوارزمية شور، مرورًا بآلية استخراج الدورة باستخدام تحويل فورييه الكمومي، وصولاً إلى كود المحاكاة العملي باستخدام بايثون و Qiskit.&lt;/p>
&lt;p>حقيقة أن القوانين الفيزيائية للعالم المجهري (ميكانيكا الكم) يمكن أن تقلب المفاهيم الأساسية لعلم المعلومات الماكروسكوبي مثل نظرية التعقيد الحسابي ونظرية التشفير رأسًا على عقب، هي واحدة من أكثر التحولات النموذجية إثارة في تاريخ العلم. لن نرفع أعيننا عن تقنية الحوسبة الكمومية التي تستمر في التطور حاليًا، والمعركة التي تخوضها ضد تقنيات التشفير الجديدة.&lt;/p>
&lt;p>ندعوك لتشغيل كود بايثون المقدم هنا في بيئتك الخاصة لتجربة &amp;ldquo;سحر الحوسبة&amp;rdquo; الذي يولده التراكب والتداخل في الحالات الكمومية.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>المراجع&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Shor, P. W. (1994). &amp;ldquo;Algorithms for quantum computation: discrete logarithms and factoring&amp;rdquo;. Proceedings 35th Annual Symposium on Foundations of Computer Science.&lt;/li>
&lt;li>Nielsen, M. A., &amp;amp; Chuang, I. L. (2010). &amp;ldquo;Quantum Computation and Quantum Information&amp;rdquo;. Cambridge University Press.&lt;/li>
&lt;li>Qiskit Documentation: &lt;a class="link" href="https://qiskit.org/documentation/" target="_blank" rel="noopener"
>https://qiskit.org/documentation/&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>