<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ECC on kenji.blog</title><link>http://kenji.blog/hi/tags/ecc/</link><description>Recent content in ECC on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 10:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/tags/ecc/index.xml" rel="self" type="application/rss+xml"/><item><title>एलिप्टिक कर्व क्रिप्टोग्राफी (ECC) का गणितीय आधार और C++ में इसका कार्यान्वयन</title><link>http://kenji.blog/hi/p/elliptic-curve-cryptography-math-cpp/</link><pubDate>Fri, 11 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/hi/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> अत्यंत महत्वपूर्ण भूमिका निभाती है। हमारे दैनिक इंटरनेट संचार (HTTPS/TLS) से लेकर, स्मार्टफोन के सुरक्षित एन्क्लेव, SSH के माध्यम से सर्वर प्रमाणीकरण, FIDO जैसे पासवर्ड रहित प्रमाणीकरण, और यहाँ तक कि बिटकॉइन और एथेरियम जैसी क्रिप्टो संपत्तियों तक, यह कहना अतिशयोक्ति नहीं होगी कि आधुनिक डिजिटल समाज का विश्वास आधार ECC द्वारा समर्थित है।&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;एलिप्टिक कर्व पर असतत लघुगणक समस्या (Discrete Logarithm Problem on Elliptic Curves - ECDLP)&amp;rdquo;&lt;/strong> नामक एक अलग गणितीय कठिनाई पर निर्भर करता है। ECDLP को हल करने के लिए आज तक कोई कुशल एल्गोरिदम (जैसे सब-एक्सपोनेंशियल टाइम एल्गोरिदम) नहीं खोजा जा सका है, और यहां तक कि ज्ञात सबसे कुशल हमले के तरीके भी घातांकीय (exponential) समय लेते हैं।&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">एलिप्टिक कर्व क्रिप्टोग्राफी कुंजी की लंबाई (बिट्स)&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-बिट कुंजी की आवश्यकता होती है, लेकिन ECC के साथ केवल 256 बिट्स की आवश्यकता होती है। इससे गणना को कम करना, मेमोरी के उपयोग को कम करना और नेटवर्क बैंडविड्थ को सहेजना संभव हो जाता है, जिससे यह विशेष रूप से सीमित संसाधनों वाले IoT उपकरणों और स्मार्ट कार्ड वातावरण में अत्यधिक फायदेमंद हो जाता है।&lt;/p>
&lt;hr>
&lt;h2 id="2-गणतय-तयर-समह-सदधत-group-theory-और-परमत-कषतर-finite-fields-क-दनय">2. गणितीय तैयारी: समूह सिद्धांत (Group Theory) और परिमित क्षेत्र (Finite Fields) की दुनिया
&lt;/h2>&lt;p>एलिप्टिक कर्व क्रिप्टोग्राफी को वास्तव में समझने के लिए, सार बीजगणित (समूह सिद्धांत और क्षेत्र सिद्धांत) की बुनियादी अवधारणाओं को समझना आवश्यक है। यहाँ हम ECC के निर्माण के लिए आवश्यक पूर्वज्ञान का संक्षेप में सारांश दे रहे हैं।&lt;/p>
&lt;h3 id="21-समह-group-और-एबलयन-समह-abelian-group">2.1. समूह (Group) और एबेलियन समूह (Abelian Group)
&lt;/h3>&lt;p>&lt;strong>समूह (Group)&lt;/strong> एक सेट $G$ और उस सेट पर एक बाइनरी ऑपरेशन (यहाँ हम जोड़ $+$ मानेंगे) का संयोजन $(G, +)$ है, जो निम्नलिखित 4 स्वयंसिद्धों (axioms) को पूरा करता है।&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, c \in G$ के लिए, $(a + b) + c = a + (b + c)$ लागू होता है।&lt;/li>
&lt;li>&lt;strong>तत्समक अवयव का अस्तित्व (Identity element)&lt;/strong>: किसी भी $a \in G$ के लिए, एक ऐसा अवयव $e \in G$ मौजूद होता है कि $a + e = e + a = a$। एक योगात्मक समूह (additive group) के मामले में, इस तत्समक अवयव को आमतौर पर $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 Field)&lt;/strong> या गैलवा क्षेत्र (Galois Field) का उपयोग करते हैं, जिनमें अवयवों की संख्या परिमित होती है।&lt;/p>
&lt;p>सबसे बुनियादी परिमित क्षेत्र अभाज्य संख्या $p$ का उपयोग करने वाला &lt;strong>अभाज्य क्षेत्र (Prime Field) $\mathbb{F}_p$&lt;/strong> है। यह पूर्णांकों के सेट $\{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}$ मॉड्यूलो $p$ के तहत $b$ का गुणनात्मक प्रतिलोम है)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>गुणनात्मक प्रतिलोम (Modular Multiplicative Inverse)&lt;/strong> की गणना क्रिप्टोग्राफ़िक कार्यान्वयन में बहुत महत्वपूर्ण है। $b \times b^{-1} \equiv 1 \pmod p$ को संतुष्ट करने वाले $b^{-1}$ को खोजने के लिए मुख्य रूप से निम्नलिखित दो एल्गोरिदम का उपयोग किया जाता है।&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$ मिलता है। दूसरे शब्दों में, $b$ की घात $p-2$ की गणना करके प्रतिलोम पाया जा सकता है। चूंकि घातांकीकरण (exponentiation) को निरंतर समय (constant time) में लागू करना आसान होता है, इसलिए क्रिप्टोग्राफ़िक कार्यान्वयन में इसे प्राथमिकता दी जाती है।&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="3-एलपटक-करव-क-समकरण-और-जयमत">3. एलिप्टिक कर्व के समीकरण और ज्यामिति
&lt;/h2>&lt;h3 id="31-वयरसटरस-क-समनय-रप-weierstrass-normal-form">3.1. वियरस्ट्रास का सामान्य रूप (Weierstrass Normal Form)
&lt;/h3>&lt;p>&lt;strong>एलिप्टिक कर्व (Elliptic Curve)&lt;/strong> आम तौर पर एक समतलीय वक्र (plane curve) होता है जिसे निम्नलिखित &lt;strong>वियरस्ट्रास के सामान्य रूप (Weierstrass normal form)&lt;/strong> नामक समीकरण द्वारा परिभाषित किया जाता है।&lt;/p>
$$ y^2 = x^3 + ax + b $$
&lt;p>यहाँ, $a$ और $b$ स्थिरांक हैं, और इस शर्त के रूप में कि वक्र में कोई एकवचन बिंदु (singular points जैसे स्व-प्रतिच्छेदन या कस्प) न हो (अर्थात यह एक चिकना वक्र हो), यह आवश्यक है कि निम्नलिखित &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 = (x, y)$ का प्रतिलोम $-P$, x-अक्ष के सममित बिंदु $(x, -y)$ के रूप में परिभाषित किया गया है। इसलिए:
&lt;/p>
$$ P + (-P) = \mathcal{O} $$
&lt;p>
होता है।&lt;/p>
&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>वक्र पर दो अलग-अलग बिंदुओं $P$ और $Q$ को जोड़कर एक नया बिंदु $R$ ($R = P + Q$) खोजने की प्रक्रिया इस प्रकार है।&lt;/p>
&lt;ol>
&lt;li>बिंदु $P$ और बिंदु $Q$ से गुजरने वाली एक रेखा (जीवा/chord) खींचें।&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 + P = 2P$), तो दो बिंदुओं से गुजरने वाली रेखा खींचना संभव नहीं है। इस मामले में, हम &lt;strong>बिंदु $P$ पर वक्र की स्पर्शरेखा (Tangent)&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$ स्पर्शरेखा का ढलान है जिसे अवकलन (differentiation) द्वारा पाया जाता है। (हम $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]
इन सूत्रों में $(x_2 - x_1)^{-1}$ और $(2y_1)^{-1}$ जैसे &lt;strong>विभाजन (मॉड्यूलर प्रतिलोम की गणना)&lt;/strong> शामिल हैं। मॉड्यूलर प्रतिलोम की गणना की कम्प्यूटेशनल लागत बहुत अधिक होती है, इसलिए वास्तविक कार्यान्वयन में, &lt;strong>&amp;ldquo;जैकोबियन कोऑर्डिनेट्स (Jacobian Coordinates)&amp;rdquo;&lt;/strong> जैसी प्रक्षेपीय समन्वय प्रणालियों (projective coordinate systems) का आमतौर पर उपयोग किया जाता है जो विभाजन को विलंबित करते हैं।&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="5-अदश-गणन-scalar-multiplication-और-एलपटक-करव-असतत-लघगणक-समसय-ecdlp">5. अदिश गुणन (Scalar Multiplication) और एलिप्टिक कर्व असतत लघुगणक समस्या (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$ को देखते हुए, अदिश (scalar) $k$ खोजें जो $Q = kP$ को संतुष्ट करता हो।&lt;/p>
&lt;/blockquote>
&lt;p>$k$ और $P$ से $Q$ की गणना करना (आगे की दिशा) बाद में वर्णित एल्गोरिदम का उपयोग करके आसान (बहुपद समय) है, लेकिन $P$ और $Q$ से $k$ की उल्टी गणना (विपरीत दिशा) करना लगभग असंभव है (यह एक वन-वे फ़ंक्शन है), सिवाय ब्रूट-फोर्स खोज के इसके लिए कोई कुशल समाधान नहीं है।
क्रिप्टोग्राफ़िक प्रोटोकॉल में, &lt;strong>$k$ &amp;ldquo;निजी कुंजी (Private Key)&amp;rdquo; से मेल खाता है, और $Q$ &amp;ldquo;सार्वजनिक कुंजी (Public Key)&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>डबल-एंड-ऐड विधि (Double-and-Add method या बाइनरी विधि)&lt;/strong> का उपयोग किया जाता है।&lt;/p>
&lt;p>यह पूर्णांकों के घातांकीकरण को तेज़ी से गणना करने के लिए &amp;ldquo;स्क्वेयर-एंड-मल्टीप्लाई (square-and-multiply)&amp;rdquo; विधि का एलिप्टिक कर्व संस्करण है। यह अदिश $k$ को बाइनरी में दर्शाता है और सबसे महत्वपूर्ण बिट (MSB) से शुरू करके क्रमिक रूप से संसाधित करता है।&lt;/p>
&lt;ol>
&lt;li>परिणाम को संग्रहीत करने के लिए बिंदु $R$ को $\mathcal{O}$ से प्रारंभ करें।&lt;/li>
&lt;li>$k$ के सबसे महत्वपूर्ण बिट (MSB) से सबसे कम महत्वपूर्ण बिट (LSB) तक निम्न को दोहराएं:
&lt;ul>
&lt;li>$R$ को दोगुना करें (Point Doubling: $R = 2R$)&lt;/li>
&lt;li>यदि वर्तमान बिट &lt;code>1&lt;/code> है, तो $R$ में $P$ जोड़ें (Point Addition: $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-कज-वनमय-key-exchange">6. एलिप्टिक कर्व डिफी-हेलमैन (ECDH) कुंजी विनिमय (Key Exchange)
&lt;/h2>&lt;p>यहाँ हम &lt;strong>ECDH (Elliptic Curve Diffie-Hellman) कुंजी विनिमय प्रोटोकॉल&lt;/strong> के तंत्र की व्याख्या करेंगे, जो ECC का सबसे विशिष्ट अनुप्रयोग है। ECDH ऐलिस और बॉब को एक असुरक्षित संचार चैनल पर सुरक्षित रूप से एक सामान्य गुप्त कुंजी (सत्र कुंजी/session key) उत्पन्न करने और साझा करने की अनुमति देता है (यह 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 की कठिनाई के कारण, वह $Q_A = d_A \cdot G$ से ऐलिस की निजी कुंजी $d_A$ का पता नहीं लगा सकता है। इसके अलावा, $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>आइए पहले बताए गए डबल-एंड-ऐड (Double-and-Add) एल्गोरिदम को फिर से देखें।&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">// असुरक्षित डबल-एंड-ऐड का छद्म कोड (pseudocode)
&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>इस कार्यान्वयन में एक घातक खामी है। जब बिट &lt;code>1&lt;/code> होता है, तो पॉइंट एडिशन निष्पादित होता है, इसलिए गणना का समय &lt;strong>थोड़ा लंबा हो जाता है&lt;/strong> तुलना में जब बिट &lt;code>0&lt;/code> होता है। इसके अतिरिक्त, प्रोसेसर की शाखा भविष्यवाणी (branch prediction) और कैश मेमोरी व्यवहार भी बदल जाते हैं।
हमलावर इस गणना समय (या बिजली की खपत) में मिनट के अंतर को हजारों बार सांख्यिकीय रूप से देखकर &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 के लिए (MSB से)"]
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>मोंटगोमेरी लैडर की सुंदरता इस बात में है कि चाहे बिट &lt;code>0&lt;/code> हो या &lt;code>1&lt;/code>, &lt;strong>&amp;ldquo;हमेशा एक पॉइंट एडिशन और एक पॉइंट डबलिंग&amp;rdquo;&lt;/strong> निष्पादित की जाती है। यह गणना समय की डेटा निर्भरता को पूरी तरह से समाप्त कर देता है।&lt;/p>
&lt;p>हालाँकि, यदि कोई शाखा (branch) (&lt;code>if (k_i == 0)&lt;/code>) स्वयं मौजूद है, तो यह जोखिम रहता है कि निष्पादन समय कंपाइलर अनुकूलन और CPU की शाखा भविष्यवाणी के कारण भिन्न हो सकता है। इसलिए, वास्तविक निरंतर-समय के कार्यान्वयन में, सशर्त शाखाओं (&lt;code>if&lt;/code> कथन) को समाप्त कर दिया जाता है और &lt;strong>बिटवाइज़ संचालन (bitwise operations) का उपयोग करके एक सशर्त स्वैप (Conditional Swap)&lt;/strong> का उपयोग किया जाता है।&lt;/p>
&lt;hr>
&lt;h2 id="8-c-क-उपयग-करक-एलपटक-करव-करपटगरफ-क-करयनवयन">8. C++ का उपयोग करके एलिप्टिक कर्व क्रिप्टोग्राफी का कार्यान्वयन
&lt;/h2>&lt;p>यहाँ से, हम सिद्धांत को C++ कोड में बदलेंगे। व्यावहारिक क्रिप्टोग्राफ़िक लाइब्रेरी (जैसे OpenSSL या libsodium) उन्नत असेंबली अनुकूलन और जैकोबियन निर्देशांक का उपयोग करती हैं, लेकिन यहाँ, गणितीय समझ को गहरा करने के लिए, हम &lt;strong>एफाइन निर्देशांक (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>सबसे पहले, हम परिमित क्षेत्र पर संचालन के लिए सहायक कार्यों को परिभाषित करते हैं। हम फ़र्मेट के छोटे प्रमेय (Fermat&amp;rsquo;s Little Theorem) का उपयोग करके प्रतिलोम गणना को लागू करेंगे।&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">// उदाहरण के रूप में secp256k1 की अभाज्य संख्या p और पैरामीटर
&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>हम अनंत पर बिंदु को प्रबंधित करने के लिए एक ध्वज (flag) के साथ एक &lt;code>Point&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;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">// Point Doubling (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">// Point Addition (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>निजी कुंजी के बिट मान के आधार पर चर (variables) की सामग्री की अदला-बदली करते समय, हम &lt;code>if&lt;/code> कथन का उपयोग किए बिना केवल बिटवाइज़ संचालन (मास्क) का उपयोग करके स्वैप करते हैं। यह सुनिश्चित करता है कि निष्पादन पथ (execution path) पूरी तरह से स्थिर रहे।&lt;/p>
&lt;blockquote>
&lt;p>[!TIP]
वास्तविक कार्यान्वयन में, &lt;code>cpp_int&lt;/code> जैसे गतिशील रूप से आवंटित बहु-सटीक (multi-precision) पूर्णांक वर्ग निरंतर-समय प्रसंस्करण के लिए उपयुक्त नहीं हैं। ऐसा इसलिए है क्योंकि मेमोरी आवंटन और सरणी आकार में भिन्नता के कारण टाइमिंग जानकारी लीक होती है। व्यावहारिक पुस्तकालयों में, उन्हें एक निश्चित लंबाई (उदाहरण के लिए, uint64_t का 4-तत्व सरणी) के साथ दर्शाया जाता है, और बिट-स्तरीय मास्किंग लागू की जाती है। निम्नलिखित एक वैचारिक उदाहरण है।&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">// यदि bit 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">// bit 0 या 1 है। यदि bit=1 है तो मास्क सभी 1 (0xFF..) है, और यदि 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">// इसलिए यहाँ तर्क को समझने के लिए हम केवल शाखाओं (branches) द्वारा इसका अनुकरण करते हैं।
&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">// हमेशा समान संक्रिया निष्पादित करें (पॉइंट एडिशन और पॉइंट डबलिंग)
&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>, प्रत्येक लूप पुनरावृत्ति (iteration) के भीतर निष्पादित संक्रियाएँ (&lt;code>cswap&lt;/code> $\to$ &lt;code>pointAdd&lt;/code> $\to$ &lt;code>pointAdd&lt;/code> $\to$ &lt;code>cswap&lt;/code>) बिल्कुल एक ही प्रवाह का पालन करती हैं, जो समय या कैश एक्सेस पैटर्न में अंतर के माध्यम से गुप्त जानकारी के रिसाव को दृढ़ता से रोकता है।&lt;/p>
&lt;hr>
&lt;h2 id="9-नषकरष">9. निष्कर्ष
&lt;/h2>&lt;p>एलिप्टिक कर्व क्रिप्टोग्राफी (ECC), पहली नज़र में अजीब लग सकती है कि &amp;ldquo;क्यों रेखाएँ खींचने और प्रतिच्छेदनों को प्रतिबिंबित करने जैसी ज्यामितीय संक्रियाएँ एन्क्रिप्शन बन जाती हैं?&amp;quot;। हालाँकि, यह गणित और क्रिप्टोग्राफी के एक चमत्कारी संलयन का परिणाम है जो इसे परिमित क्षेत्र के असतत (discrete) दुनिया में मैप करके एक शानदार वन-वे फ़ंक्शन (असतत लघुगणक समस्या) बनाने की अनुमति देता है।&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>: कैसे निजी कुंजी के बिट्स पर निर्भर सशर्त शाखाएं (conditional branches) घातक कमियां पैदा करती हैं।&lt;/li>
&lt;li>&lt;strong>निरंतर-समय (Constant-Time) कार्यान्वयन&lt;/strong>: मोंटगोमेरी लैडर और सशर्त स्वैप (Conditional Swap) का उपयोग करके हार्डवेयर-स्तरीय व्यवहार को सुसंगत बनाने और हमलों को रोकने के लिए C++ कोडिंग तकनीक।&lt;/li>
&lt;/ol>
&lt;p>उत्पादन वातावरण (production environment) में काम करने वाली अपनी खुद की क्रिप्टोग्राफ़िक लाइब्रेरी बनाने को सुरक्षा जोखिमों के कारण अत्यधिक हतोत्साहित किया जाता है (&amp;ldquo;अपना खुद का क्रिप्टो न बनाएं&amp;rdquo;)। हालाँकि, हुड के नीचे काम करने वाले एल्गोरिदम और गणितीय पृष्ठभूमि की गहरी समझ होना, अधिक सुरक्षित और उच्च-प्रदर्शन प्रणाली को डिजाइन और संचालित करने वाले इंजीनियरों के लिए एक अमूल्य और शक्तिशाली हथियार होगा।&lt;/p>
&lt;p>अगले लेख में, हम इस एलिप्टिक कर्व का उपयोग करने वाले डिजिटल हस्ताक्षर एल्गोरिदम &lt;strong>ECDSA (Elliptic Curve Digital Signature Algorithm)&lt;/strong> के तंत्र, और बिटकॉइन में प्रयुक्त &lt;strong>स्क्नोर (Schnorr) हस्ताक्षर&lt;/strong> के बारे में और गहराई से जानेंगे।&lt;/p></description></item></channel></rss>