সরাসরি পর্বে যান
পর্ব ২৪ · ৮৩-এর মধ্যে · মডিউল ৪

Fermat-এর ছোট উপপাদ্য আর Euler-এর totient

Fermat's Little Theorem and Euler's Totient — Proofs, the φ Formula, Euler's Theorem, Reducing Huge Exponents, Order and Primitive Roots, Wilson's Theorem, Pseudoprimes and Carmichael Numbers

Taught in Bangla, this lesson proves Fermat's little theorem by the permutation argument, derives the totient formula φ(n) = n ∏ (1 − 1/p), and proves Euler's theorem to reduce huge exponents, for example 3^100000 mod 31 = 25. It covers the order of an element, primitive roots, Wilson's theorem, Fermat pseudoprimes and Carmichael numbers such as 561. In-page Python checks the theorems on thousands of cases and lists pseudoprimes below 10,000.

এই পর্বে যা শিখবেন

  • Fermat-এর ছোট উপপাদ্য আর Euler-এর উপপাদ্য, সব শর্তসহ বিবৃতি আর সম্পূর্ণ প্রমাণ
  • φ(n) সংজ্ঞা থেকে আর মৌলিক উৎপাদকের সূত্র থেকে বের করা, আর multiplicative ধর্মের যুক্তি
  • বিশাল ঘাতের ভাগশেষ কয়েক লাইনে বের করা, আর কোথায় এই কৌশল ভুল ফল দেয়
  • Order, primitive root আর Wilson-এর উপপাদ্য, ছোট উদাহরণে হাতে কষে
  • Fermat pseudoprime আর Carmichael সংখ্যা খুঁজে বের করা, আর কেন শুধু Fermat-এর পরীক্ষা যথেষ্ট নয়

১ · ঘাতের ভাগশেষে চক্র — প্রশ্নটা কোথা থেকে আসে

বাজারঘর প্রতিদিন একটি “লাকি কুপন” দেয়। কুপন নম্বর বানানোর নিয়ম সহজ: আগের দিনের নম্বরকে 3 দিয়ে গুণ করে 7 দিয়ে ভাগশেষ নেওয়া হয়, শুরু 1 থেকে। তাহলে দিনগুলোর নম্বর 3, 2, 6, 4, 5, 1, তারপর আবার 3, 2, 6, … ঠিক ছয় দিন পরপর চক্রটি ফিরে আসে। প্রশ্ন জাগে: এটা কি কাকতালীয়? 3-এর জায়গায় 2 নিলে কী হয়? 7-এর জায়গায় 31 বা 100 নিলে? আর এক লক্ষতম দিনের কুপন কত, সেটা কি এক লক্ষবার গুণ না করে বলা যায়?

এই পর্বের সব উপপাদ্য এই এক প্রশ্নের উত্তর: a-এর ঘাতগুলোকে m দিয়ে ভাগ করলে ভাগশেষ কোন চক্রে ঘোরে, আর চক্রের দৈর্ঘ্য কত? উত্তরটি সুন্দর আর কাজের। এর ওপর দাঁড়িয়ে আছে বিশাল ঘাতের দ্রুত হিসাব, মৌলিক সংখ্যা চেনার পরীক্ষা, আর পরের মডিউলের RSA (পর্ব ২৮ “RSA-এর গণিত — key, encryption আর কেন কাজ করে”).

7-এর ঘড়িতে “3 দিয়ে গুণ” — 1 থেকে 6 শুধু জায়গা বদলায়

প্রতিটি তীর k → 3k mod 7. কোনো সংখ্যা হারায় না, কোনোটি দুবার আসে না; 0 কখনো আসে না।

Multiplication by 3 modulo 7 permutes 1 to 6 1 2 3 4 5 6 চক্র: 1 → 3 → 2 → 6 → 4 → 5 → 1 ×3 (mod 7) · লাল তীর: 5 → 1

ছবিটিতে দুটি জিনিস লক্ষ করুন। প্রথমত, “3 দিয়ে গুণ করে mod 7” একটি permutation: {1, …, 6}-এর প্রতিটি সংখ্যা ঠিক একবার তীরের মাথায় আসে, অর্থাৎ পর্ব ১৬ “ফাংশন — one-to-one, onto, inverse আর composition”-এর ভাষায় এটি একটি bijection. দ্বিতীয়ত, 1 থেকে তীর ধরে হাঁটলে কুপনের ক্রমটিই পাওয়া যায়, আর ছয় ধাপে 1-এ ফেরা মানে 36 ≡ 1 (mod 7). Fermat-এর উপপাদ্যের প্রমাণ ঠিক প্রথম পর্যবেক্ষণটিকে কাজে লাগায়।

আগের পর্বগুলো থেকে যা লাগবে, এক জায়গায়: a ≡ b (mod m) মানে m ∣ (a − b), আর যোগ-গুণ এই congruence মেনে চলে (পর্ব ২২ “Modular arithmetic — ঘড়ির গণিত আর modular exponentiation”). gcd(a, m) = 1 হলে a আর m সহমৌলিক (coprime), আর তখন a-এর একটি modular inverse থাকে, অর্থাৎ এমন b যাতে ab ≡ 1 (mod m) (পর্ব ২৩ “Linear congruence আর Chinese Remainder Theorem”). তাই সহমৌলিক সংখ্যাকে congruence-এর দুই পাশ থেকে “কাটা” যায়: ac ≡ bc আর gcd(c, m) = 1 হলে a ≡ b. আর Euclid-এর lemma: মৌলিক p যদি ab-কে ভাগ করে, তবে p ∣ a বা p ∣ b (পর্ব ২১ “GCD আর Euclid-এর algorithm — Bézout আর extended Euclid”). এই তিনটি হাতিয়ারেই পুরো পর্ব চলবে।

২ · Fermat-এর ছোট উপপাদ্য — বিবৃতি আর প্রমাণ

উপপাদ্য ২.১ (Fermat-এর ছোট উপপাদ্য)

p একটি মৌলিক সংখ্যা আর a একটি পূর্ণসংখ্যা, যাতে p ∤ a (p, a-কে ভাগ করে না)। তাহলে

ap−1 ≡ 1 (mod p)

দুটি শর্তই জরুরি। p ∣ a হলে ap−1 ≡ 0, 1 নয় (যেমন 76 ≡ 0 (mod 7)). আর p মৌলিক না হলে ফলটি সাধারণত ভাঙে: 214 mod 15 = 4, 1 নয়। নামের “ছোট” শব্দটি Fermat-এর বিখ্যাত “শেষ উপপাদ্য” (Fermat's Last Theorem) থেকে আলাদা করার জন্য; এটি গুরুত্বে মোটেই ছোট নয়।

প্রমাণ: S = {1, 2, …, p − 1} নিন, আর প্রতিটি k ∈ S-কে a দিয়ে গুণ করে mod p নিন।

  1. প্রতিটি ak mod p শূন্য নয়। কারণ p ∣ ak হলে Euclid-এর lemma অনুযায়ী p ∣ a বা p ∣ k; প্রথমটি শর্তে নিষিদ্ধ, আর দ্বিতীয়টি অসম্ভব কারণ 1 ≤ k ≤ p − 1. তাই ak mod p ∈ S. — Euclid-এর lemma, p মৌলিক
  2. ভিন্ন k থেকে ভিন্ন ভাগশেষ আসে। ধরুন ai ≡ aj (mod p), যেখানে i, j ∈ S. তাহলে p ∣ a(i − j), আর আবার Euclid-এর lemma-য় p ∣ (i − j). কিন্তু |i − j| < p, তাই i = j. — Euclid-এর lemma
  3. ধাপ ১ আর ২ মিলে k ↦ ak mod p হলো S থেকে S-এ একটি one-to-one ফাংশন। সসীম সেটে one-to-one ফাংশন onto-ও (pigeonhole), তাই {a · 1, a · 2, …, a(p − 1)}-এর ভাগশেষগুলো ঠিক 1, 2, …, p − 1, শুধু অন্য ক্রমে। — সসীম সেটে injection = bijection
  4. দুটি তালিকার সব সংখ্যা গুণ করুন। ক্রম বদলালে গুণফল বদলায় না, তাই (a · 1)(a · 2)⋯(a(p − 1)) ≡ 1 · 2 ⋯ (p − 1), অর্থাৎ ap−1 · (p − 1)! ≡ (p − 1)! (mod p). — গুণ congruence মানে
  5. (p − 1)!-এর প্রতিটি উৎপাদক p-এর চেয়ে ছোট, তাই Euclid-এর lemma-য় p ∤ (p − 1)!, অর্থাৎ gcd((p − 1)!, p) = 1. দুই পাশ থেকে (p − 1)! কেটে দিলে ap−1 ≡ 1 (mod p). ∎ — সহমৌলিক উৎপাদক কাটা যায়

প্রমাণের মূল ধারণাটি একটি পরীক্ষার হলের মতো। ছয়টি বেঞ্চে ছয়জন পরীক্ষার্থী বসেছেন, রোল 1 থেকে 6. পরিদর্শক নিয়ম করলেন: রোল k-এর পরীক্ষার্থী যাবেন বেঞ্চ 3k mod 7-এ। কেউ হল ছাড়েননি, কোনো বেঞ্চে দুজন বসেননি, শুধু আসন বদলেছে। তাই সব বেঞ্চ নম্বরের গুণফল আগে আর পরে একই থাকে। Fermat-এর প্রমাণ ঠিক এই “আসন বদলালেও মোট হিসাব একই” পর্যবেক্ষণ থেকে একটি সমীকরণ বের করে।

নিচের stepper এই পাঁচ ধাপ p = 7, a = 3-এ হুবহু অনুসরণ করে, উপরের ছবির সংখ্যাগুলো দিয়েই।

1p = 7, a = 3, 7 ∤ 32S = {1, 2, 3, 4, 5, 6}33S = {3, 6, 9, 12, 15, 18}4mod 7: {3, 6, 2, 5, 1, 4}53⁶ · 6! ≡ 6! (mod 7)66! = 720 ≡ 6, gcd(6!, 7) = 17⇒ 3⁶ ≡ 1 (mod 7)
এই ধাপে কী হলো
ধাপ
হিসাব
  1. শর্ত। p = 7 মৌলিক, আর 7 ∤ 3. S = {1, …, 6}, অর্থাৎ 7-এর সব শূন্য-নয় ভাগশেষ।
  2. a দিয়ে গুণ। প্রতিটি সদস্যকে 3 দিয়ে গুণ: 3, 6, 9, 12, 15, 18. এদের কোনোটি 7-এর গুণিতক নয়, কারণ 7 ∤ 3 আর 7 ∤ k (প্রমাণের ধাপ ১).
  3. ভাগশেষ। mod 7-এ এরা হয় 3, 6, 2, 5, 1, 4. প্রতিটি সংখ্যা 1–6 ঠিক একবার এসেছে: ছবির তীরগুলোই এই permutation.
  4. গুণফল। দুই তালিকা একই সংখ্যার, তাই গুণফল সমান: (3·1)(3·2)⋯(3·6) = 3⁶ · 6! আর অন্যদিকে 1 · 2 ⋯ 6 = 6! = 720. তাই 3⁶ · 720 ≡ 720 (mod 7).
  5. কেটে দেওয়া। 720 ≡ 6 (mod 7), আর gcd(720, 7) = 1, তাই 720 কাটা যায়: 3⁶ ≡ 1 (mod 7). সরাসরি মিলিয়ে দেখুন: 3⁶ = 729 = 7 · 104 + 1. ∎

উপপাদ্যটি থেকে দুটি কাজের corollary সরাসরি আসে।

Corollary ২.২

(ক) p মৌলিক হলে প্রতিটি পূর্ণসংখ্যা a-তে ap ≡ a (mod p), এখানে p ∤ a শর্ত লাগে না। (খ) p মৌলিক আর p ∤ a হলে a-এর inverse mod p হলো ap−2 mod p.

প্রমাণ:

  1. (ক) p ∤ a হলে উপপাদ্য ২.১-এর দুই পাশকে a দিয়ে গুণ করলেই ap ≡ a. — গুণ congruence মানে
  2. p ∣ a হলে দুই পাশই ≡ 0 (mod p), তাই ap ≡ a এখানেও সত্য। — case-ভিত্তিক প্রমাণ
  3. (খ) a · ap−2 = ap−1 ≡ 1 (mod p), আর inverse-এর সংজ্ঞাই এটি। ∎

(খ) একটি দ্বিতীয় পথ দেয় inverse বের করার: extended Euclid-এর বদলে একটি ঘাত। ঘাতটি দ্রুত বের হয় repeated squaring দিয়ে, যার loop invariant পর্ব ১৩ “Program-এর সঠিকতা — loop invariant আর Hoare logic-এর ধারণা”-এ প্রমাণ করা হয়েছে (binary exponentiation, প্রায় log2 b-টি গুণ). Python-এর pow(a, b, m) ঠিক এই কাজটি করে, আর Python-এর int যত বড় দরকার তত বড় হতে পারে (Python কোর্সের পর্ব ০৭). কনটেস্টে mod 109 + 7-এ এভাবে inverse নেওয়ার কৌশল DSA কোর্সের পর্ব ৬২-এ আছে।

ইতিহাস: Pierre de Fermat ১৬৪০ সালে Frénicle de Bessy-কে লেখা একটি চিঠিতে ফলটি প্রমাণ ছাড়া উল্লেখ করেন বলে সাধারণভাবে বলা হয়। প্রথম প্রকাশিত প্রমাণ Leonhard Euler-এর, ১৭৩৬ সালের দিকে; Gottfried Leibniz-এর অপ্রকাশিত পাণ্ডুলিপিতে এর আগেই (১৬৮০-এর দশকে) প্রায় একই প্রমাণ ছিল বলে ইতিহাসবিদরা উল্লেখ করেন। উপরের permutation-ভিত্তিক প্রমাণটি পরে প্রচলিত হয় এবং এটিই এখন পাঠ্যবইয়ের সাধারণ প্রমাণ।

এবার পরীক্ষা। নিচের ব্লক 200-এর নিচের প্রতিটি মৌলিক p আর প্রতিটি 1 ≤ a ≤ p − 1-এ উপপাদ্যটি যাচাই করে, Corollary ২.২-এর দুই অংশ দেখে, আর একটি যৌগিক modulus-এ কী ভাঙে তা দেখায়। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।

from math import gcd

def is_prime(n):
    return n > 1 and all(n % d for d in range(2, int(n ** 0.5) + 1))

primes = [p for p in range(2, 200) if is_prime(p)]
checks = fails = 0
for p in primes:
    for a in range(1, p):                 # every a with p ∤ a, 1 ≤ a ≤ p-1
        checks += 1
        fails += pow(a, p - 1, p) != 1
print("primes below 200:", len(primes), "  checks:", checks, "  failures:", fails)

# corollary a^p ≡ a (mod p) holds even when p divides a
print("a^7 ≡ a (mod 7) for a = 0..49:", all(pow(a, 7, 7) == a % 7 for a in range(50)))

# inverse by Fermat: a^(p-2) mod p
p = 13
inv = [pow(a, p - 2, p) for a in range(1, p)]
print("inverses mod 13 for a = 1..12:", inv)
print("same as pow(a, -1, 13):", inv == [pow(a, -1, p) for a in range(1, p)])

# a composite modulus: the pattern breaks
n = 15
bad = [a for a in range(1, n) if gcd(a, n) == 1 and pow(a, n - 1, n) != 1]
print("n = 15, coprime a with a^14 mod 15 != 1:", bad)
print("but a^phi(15) = a^8:", [pow(a, 8, 15) for a in (1, 2, 4, 7, 8, 11, 13, 14)])

আসল আউটপুট (ব্রাউজারের Python):

primes below 200: 46   checks: 4181   failures: 0
a^7 ≡ a (mod 7) for a = 0..49: True
inverses mod 13 for a = 1..12: [1, 7, 9, 10, 8, 11, 2, 5, 3, 4, 6, 12]
same as pow(a, -1, 13): True
n = 15, coprime a with a^14 mod 15 != 1: [2, 7, 8, 13]
but a^phi(15) = a^8: [1, 1, 1, 1, 1, 1, 1, 1]

৪৬টি মৌলিক সংখ্যায় মোট ৪,১৮১টি (a, p) জোড়ায় একটিও ব্যর্থতা নেই। দ্বিতীয় লাইন Corollary ২.২(ক): 7-এর গুণিতকসহ ০ থেকে ৪৯ পর্যন্ত প্রতিটি a-তে a7 ≡ a. তৃতীয় লাইনে mod 13-এ inverse-এর তালিকা, যেমন 2-এর inverse 7 (2 · 7 = 14 ≡ 1), আর চতুর্থ লাইন বলে a11 mod 13 আর Python-এর pow(a, -1, 13) হুবহু এক। শেষ দুই লাইন আকর্ষণীয়: 15 মৌলিক নয়, তাই a14 ≡ 1 চারটি সহমৌলিক a-তে ভাঙে। কিন্তু 14-এর বদলে 8 ঘাত নিলে আটটি সহমৌলিক a-এর সবগুলোতেই 1 আসে। এই 8 কোথা থেকে এল? 15-এর সঙ্গে সহমৌলিক সংখ্যা ঠিক আটটি, আর সেটিই পরের অংশের বিষয়।

৩ · Euler-এর totient φ(n) — সহমৌলিক সংখ্যা গোনা

সংজ্ঞা ৩.১

ধনাত্মক পূর্ণসংখ্যা n-এর জন্য Euler-এর totient φ(n) (φ পড়ুন “ফাই”) হলো {1, 2, …, n}-এর সেই সংখ্যাগুলোর সংখ্যা, যারা n-এর সঙ্গে সহমৌলিক:

φ(n) = |{k : 1 ≤ k ≤ n, gcd(k, n) = 1}|

এই সংখ্যাগুলোর ভাগশেষের সেটকে mod n-এর একটি reduced residue system বলে।

কয়েকটি ছোট মান হাতে গুনে দেখুন: φ(1) = 1 (gcd(1, 1) = 1), φ(10) = 4 (1, 3, 7, 9), φ(12) = 4 (1, 5, 7, 11), φ(15) = 8 (1, 2, 4, 7, 8, 11, 13, 14). মৌলিক p-তে 1 থেকে p − 1 সবাই সহমৌলিক, তাই φ(p) = p − 1, আর তখন Fermat-এর ঘাত p − 1 ঠিক φ(p). বড় n-এ এভাবে গোনা ধীর; তার বদলে n-কে মৌলিক উৎপাদকে ভাঙতে হয় (fundamental theorem of arithmetic, পর্ব ২০ “বিভাজ্যতা আর মৌলিক সংখ্যা — division algorithm আর unique factorization”).

উপপাদ্য ৩.২

(ক) p মৌলিক আর k ≥ 1 হলে φ(pk) = pk − pk−1. (খ) gcd(m, n) = 1 হলে φ(mn) = φ(m) φ(n); এমন ফাংশনকে multiplicative বলে। (গ) তাই n = p1e1 ⋯ prer হলে

φ(n) = n (1 − 1/p1)(1 − 1/p2) ⋯ (1 − 1/pr)

প্রমাণ:

  1. (ক) 1 থেকে pk-এর মধ্যে একটি সংখ্যা pk-এর সঙ্গে সহমৌলিক নয় ঠিক তখন, যখন তার আর pk-এর একটি সাধারণ মৌলিক উৎপাদক আছে; pk-এর একমাত্র মৌলিক উৎপাদক p, তাই এরা ঠিক p-এর গুণিতকগুলো: p, 2p, …, pk−1 · p, মোট pk−1টি। বাকি pk − pk−1টি সহমৌলিক। — গণনায় বিয়োগের নিয়ম
  2. (খ) পর্ব ২৩-এর Chinese Remainder Theorem বলে, gcd(m, n) = 1 হলে x mod mn ↦ (x mod m, x mod n) ফাংশনটি {0, …, mn − 1} থেকে সব জোড়ার সেটে একটি bijection. — CRT, পর্ব ২৩
  3. gcd(x, mn) = 1 ⇔ gcd(x, m) = 1 এবং gcd(x, n) = 1, কারণ mn-এর মৌলিক উৎপাদক মানে m বা n-এর মৌলিক উৎপাদক। আর gcd(x, m) শুধু x mod m-এর ওপর নির্ভর করে। — gcd(x, m) = gcd(x mod m, m)
  4. তাই bijection-টি mod mn-এর সহমৌলিক ভাগশেষগুলোকে ঠিক সেই জোড়াগুলোতে পাঠায়, যার প্রথম অংশ mod m-এ সহমৌলিক আর দ্বিতীয় অংশ mod n-এ সহমৌলিক। এমন জোড়া φ(m) · φ(n)টি, তাই φ(mn) = φ(m)φ(n). — গুণের নিয়ম
  5. (গ) বিভিন্ন মৌলিক সংখ্যার ঘাত পরস্পর সহমৌলিক, তাই (খ) বারবার লাগিয়ে φ(n) = ∏ φ(piei) = ∏ piei(1 − 1/pi) = n ∏ (1 − 1/pi). ∎ — (ক), (খ) আর r-এর ওপর induction

এখানে ∏ মানে গুণফল, যেমন ∑ মানে যোগফল। (খ)-এর শর্ত gcd(m, n) = 1 ভুলবেন না: φ(4) · φ(6) = 2 · 2 = 4, অথচ φ(24) = 8. ধাপ ২–৪ পুরো গঠনমূলক প্রমাণের একটি সংক্ষিপ্ত রূপ; CRT-এর bijection প্রমাণসহ পর্ব ২৩-এ আছে। একটি ছোট উদাহরণে ধাপ ২–৪ চোখে দেখুন: m = 3, n = 4, mn = 12. mod 12-এর সহমৌলিক ভাগশেষ 1, 5, 7, 11, আর এদের (mod 3, mod 4) জোড়া যথাক্রমে (1, 1), (2, 1), (1, 3), (2, 3). প্রথম অংশ শুধু 1 বা 2 (φ(3) = 2টি বিকল্প), দ্বিতীয় অংশ শুধু 1 বা 3 (φ(4) = 2টি বিকল্প), আর চারটি সম্ভাব্য জোড়ার প্রতিটি ঠিক একবার এসেছে: φ(12) = 2 · 2 = 4. (ক)-এর সাধারণ যুক্তিটির ভাষায় সূত্রটির একটি সহজ ব্যাখ্যা আছে: 1 থেকে n-এর মধ্যে মোটামুটি 1/p অংশ p দিয়ে বিভাজ্য, তাই প্রতিটি মৌলিক উৎপাদক “(1 − 1/p) অংশ রেখে বাকিটা বাদ দেয়”। নিচের stepper φ(360) এভাবে বের করে।

1360 = 2³ · 3² · 52φ(2³) = 8 − 43φ(3²) = 9 − 34φ(5) = 5 − 15φ(360) = 4 · 6 · 46যাচাই: 360·(1/2)(2/3)(4/5)
মৌলিক ঘাত অনুযায়ী
অংশ
φ
কারণ
  1. উৎপাদকে ভাঙা। 360-কে 2 দিয়ে তিনবার (180, 90, 45), 3 দিয়ে দুবার (15, 5) ভাগ করলে 5 থাকে। তাই 360 = 2³ · 3² · 5, আর তিনটি মৌলিক ঘাত পরস্পর সহমৌলিক।
  2. φ(2³). 1 থেকে 8-এর মধ্যে জোড় সংখ্যা (2, 4, 6, 8) বাদ, অর্থাৎ 2² = 4টি। থাকে 8 − 4 = 4টি: 1, 3, 5, 7.
  3. φ(3²). 1 থেকে 9-এর মধ্যে 3-এর গুণিতক 3, 6, 9 বাদ। থাকে 9 − 3 = 6টি।
  4. φ(5). মৌলিক, তাই শুধু 5 নিজে বাদ: 5 − 1 = 4.
  5. গুণ। Multiplicative ধর্মে φ(360) = 4 · 6 · 4 = 96. সূত্রেও: 360 · (1/2) · (2/3) · (4/5) = 180 · (2/3) · (4/5) = 120 · (4/5) = 96. ∎

সূত্রটি নির্ভুল কি না, সেটি নিজে যাচাই করুন। নিচের ব্লক φ-এর দুটি সংস্করণ লেখে, সংজ্ঞা থেকে গোনা (brute force) আর মৌলিক উৎপাদকের সূত্র, তারপর ১,০০০ পর্যন্ত মেলায়, multiplicative ধর্ম আর তার শর্ত পরীক্ষা করে, আর একটি বিখ্যাত অভেদ দেখায়: n-এর সব ভাজক d-এর জন্য φ(d)-এর যোগফল n.

from math import gcd

def phi_brute(n):                      # count k in 1..n with gcd(k, n) = 1
    return sum(1 for k in range(1, n + 1) if gcd(k, n) == 1)

def phi_formula(n):                    # n times (1 - 1/p) for each prime p | n
    result, m, p = n, n, 2
    while p * p <= m:
        if m % p == 0:
            while m % p == 0:
                m //= p
            result -= result // p
        p += 1
    if m > 1:
        result -= result // m
    return result

print("formula == brute force, n = 1..1000:",
      all(phi_formula(n) == phi_brute(n) for n in range(1, 1001)))
print("phi(360) =", phi_formula(360), "  phi(1001) =", phi_formula(1001),
      "  phi(97) =", phi_formula(97))

mult = all(phi_formula(m * n) == phi_formula(m) * phi_formula(n)
           for m in range(1, 80) for n in range(1, 80) if gcd(m, n) == 1)
print("phi(mn) == phi(m) phi(n) whenever gcd(m, n) = 1:", mult)
print("phi(4) * phi(6) =", phi_formula(4) * phi_formula(6),
      "  but phi(24) =", phi_formula(24))

gauss = all(sum(phi_formula(d) for d in range(1, n + 1) if n % d == 0) == n
            for n in range(1, 500))
print("sum of phi(d) over divisors d of n equals n (n < 500):", gauss)

আসল আউটপুট (ব্রাউজারের Python):

formula == brute force, n = 1..1000: True
phi(360) = 96   phi(1001) = 720   phi(97) = 96
phi(mn) == phi(m) phi(n) whenever gcd(m, n) = 1: True
phi(4) * phi(6) = 4   but phi(24) = 8
sum of phi(d) over divisors d of n equals n (n < 500): True

phi_formula উপপাদ্য ৩.২(গ)-এর সূত্রটিকেই পূর্ণসংখ্যায় লেখে: প্রতিটি নতুন মৌলিক উৎপাদক p পেলে result -= result // p, অর্থাৎ result-কে (1 − 1/p) দিয়ে গুণ। এটি সব ১,০০০টি n-এ brute force-এর সঙ্গে মিলেছে। φ(360) = 96 stepper-এর উত্তর, φ(1001) = φ(7 · 11 · 13) = 6 · 10 · 12 = 720, আর মৌলিক 97-এ φ = 96. চতুর্থ লাইন দেখায়, gcd(4, 6) = 2 বলে multiplicative ধর্ম সেখানে খাটে না। শেষ লাইনের অভেদ ∑d ∣ n φ(d) = n Gauss-এর নামে পরিচিত; এর একটি সুন্দর প্রমাণ হলো 1/n, 2/n, …, n/n ভগ্নাংশগুলোকে লঘিষ্ঠ আকারে লিখে হর অনুযায়ী ভাগ করা। পরীক্ষা ৫০০ পর্যন্ত, প্রমাণ নয়।

৪ · Euler-এর উপপাদ্য আর বিশাল ঘাত ছোট করা

ব্লক ১-এর শেষ লাইন যা ইঙ্গিত দিয়েছিল, Euler সেটিই প্রমাণ করেন: মৌলিক modulus লাগে না, শুধু a আর m সহমৌলিক হলেই চলে, আর ঘাত হবে φ(m).

উপপাদ্য ৪.১ (Euler-এর উপপাদ্য)

m ≥ 1 আর a পূর্ণসংখ্যা, যাতে gcd(a, m) = 1. তাহলে

aφ(m) ≡ 1 (mod m)

m = p মৌলিক হলে φ(p) = p − 1, আর এটি ঠিক Fermat-এর ছোট উপপাদ্য।

প্রমাণ: r1, r2, …, rφ(m) হোক 1 থেকে m-এর মধ্যে m-এর সঙ্গে সহমৌলিক সংখ্যাগুলো। Fermat-এর প্রমাণটিই এখানে চলে, শুধু Euclid-এর lemma-র জায়গায় gcd-এর যুক্তি।

  1. প্রতিটি ari m-এর সঙ্গে সহমৌলিক, কারণ a আর ri দুটিই m-এর সঙ্গে সহমৌলিক, আর দুটি সহমৌলিক সংখ্যার গুণফলের সঙ্গে m-এর কোনো সাধারণ মৌলিক উৎপাদক থাকতে পারে না। তাই ari mod m আবার r-দের একটি। — মৌলিক উৎপাদকের যুক্তি
  2. ari ≡ arj (mod m) হলে a-এর inverse দিয়ে গুণ করে ri ≡ rj, আর দুটিই 1 থেকে m-এর মধ্যে, তাই i = j. — gcd(a, m) = 1 ⇒ a-এর inverse আছে
  3. তাই ar1, …, arφ(m)-এর ভাগশেষগুলো r-দেরই একটি permutation. সব গুণ করলে aφ(m) · R ≡ R (mod m), যেখানে R = r1 ⋯ rφ(m). — ক্রম বদলালে গুণফল একই
  4. R সহমৌলিক সংখ্যার গুণফল, তাই gcd(R, m) = 1, আর R কাটা যায়: aφ(m) ≡ 1 (mod m). ∎ — সহমৌলিক উৎপাদক কাটা যায়

Euler এই সাধারণ রূপটি ১৭৬০-এর দশকে প্রকাশ করেন বলে উল্লেখ করা হয়। φ চিহ্নটি পরে Gauss তাঁর ১৮০১ সালের Disquisitiones Arithmeticae-তে ব্যবহার করেন, আর “totient” নামটি J. J. Sylvester-এর (১৮৭৯-এর দিকে), এমনটাই সাধারণত বলা হয়।

উপপাদ্যটির সবচেয়ে বেশি ব্যবহৃত রূপ হলো ঘাত ছোট করা। b-কে φ(m) দিয়ে ভাগ করুন: b = qφ(m) + r, 0 ≤ r < φ(m). তাহলে ab = (aφ(m))q · ar ≡ 1q · ar.

Corollary ৪.২ (ঘাত ছোট করা)

gcd(a, m) = 1 হলে প্রতিটি b ≥ 0-তে ab ≡ ab mod φ(m) (mod m). বিশেষ করে p মৌলিক আর p ∤ a হলে ab ≡ ab mod (p−1) (mod p).

সাবধান: ঘাত কমে mod φ(m)-এ, mod m-এ নয়; আর শর্ত gcd(a, m) = 1 বাদ দেওয়া যায় না। উদাহরণ: 25 = 32 ≡ 8 (mod 12). কিন্তু φ(12) = 4, আর “নিয়ম” লাগালে 25 mod 4 = 21 = 2, যা ভুল; কারণ gcd(2, 12) = 2. পরীক্ষার খাতায় আর AI-এর উত্তরে এই ভুলটি খুব বেশি দেখা যায়।

131 মৌলিক, 31 ∤ 3 ⇒ 3³⁰ ≡ 12100000 = 30 · 3333 + 1033¹⁰⁰⁰⁰⁰ = (3³⁰)³³³³ · 3¹⁰43⁵ = 243 = 7 · 31 + 2653¹⁰ = (3⁵)² ≡ (−5)² = 25
চলক
বড় ঘাত
কমানো ঘাত
মান mod 31
  1. শর্ত। 31 মৌলিক আর 31 ∤ 3, তাই Fermat (বা Euler, φ(31) = 30) খাটে: 3³⁰ ≡ 1 (mod 31).
  2. ঘাতকে 30 দিয়ে ভাগ। 30 · 3333 = 99990, তাই 100000 = 30 · 3333 + 10. ভাগশেষ 10.
  3. আলাদা করা। 3¹⁰⁰⁰⁰⁰ = (3³⁰)³³³³ · 3¹⁰ ≡ 1³³³³ · 3¹⁰ = 3¹⁰ (mod 31). এক লক্ষ ঘাতের সমস্যা দশ ঘাতে নামল।
  4. 3⁵. 3⁵ = 243, আর 7 · 31 = 217, তাই 243 ≡ 26 (mod 31). 26 ≡ −5 লিখলে বর্গ করা সহজ।
  5. বর্গ। 3¹⁰ = (3⁵)² ≡ (−5)² = 25 (mod 31). উত্তর 25, যা Python-এর pow(3, 100000, 31)-এর সঙ্গে মেলে (পরের ব্লক). ∎

বাজারঘরের কুপনের প্রশ্নে ফিরে যাই: এক লক্ষতম দিনের কুপন 3100000 mod 7. 100000 = 6 · 16666 + 4, তাই উত্তর 34 = 81 ≡ 4. আর যদি modulus 7 না হয়ে 100 হয় (শেষ দুই অঙ্ক), তবে φ(100) = 100 · (1/2) · (4/5) = 40, আর gcd(7, 100) = 1 বলে 72026 ≡ 72026 mod 40 = 726 (mod 100). এটি আরও ছোট করা যায় পরের অংশের ধারণায়।

৫ · Order আর primitive root — চক্রের আসল দৈর্ঘ্য

Euler বলেন aφ(m) ≡ 1, কিন্তু 1-এ প্রথমবার ফেরা আরও আগেও হতে পারে। কুপনের নিয়মে 3-এর বদলে 2 নিলে mod 7-এ ক্রম হয় 2, 4, 1, 2, 4, 1, …, চক্রের দৈর্ঘ্য 3, যদিও φ(7) = 6. চক্রের এই আসল দৈর্ঘ্যের নাম order.

সংজ্ঞা ৫.১

gcd(a, m) = 1 হলে a-এর order mod m, লেখা হয় ordm(a), হলো সবচেয়ে ছোট ধনাত্মক পূর্ণসংখ্যা d, যাতে ad ≡ 1 (mod m). Euler-এর উপপাদ্য বলে এমন অন্তত একটি ধনাত্মক ঘাত (φ(m)) আছে, তাই well-ordering নীতিতে সবচেয়ে ছোটটিও আছে (পর্ব ১১).

যদি ordm(g) = φ(m) হয়, তবে g একটি primitive root mod m: তার ঘাতগুলো mod m-এর সব সহমৌলিক ভাগশেষ ঘুরে আসে।

উপপাদ্য ৫.২

gcd(a, m) = 1 আর d = ordm(a) হলে, যেকোনো k ≥ 0-তে ak ≡ 1 (mod m) ⇔ d ∣ k. বিশেষ করে ordm(a) সবসময় φ(m)-কে ভাগ করে।

প্রমাণ:

  1. (⇐) k = dq হলে ak = (ad)q ≡ 1q = 1. — ঘাতের নিয়ম
  2. (⇒) Division algorithm-এ k = dq + r, 0 ≤ r < d. তাহলে 1 ≡ ak = (ad)q ar ≡ ar. — division algorithm, পর্ব ২০
  3. r > 0 হলে r হতো d-এর চেয়ে ছোট একটি ধনাত্মক ঘাত যেখানে ar ≡ 1, যা d-এর “সবচেয়ে ছোট” হওয়ার বিরোধী। তাই r = 0, অর্থাৎ d ∣ k. — contradiction
  4. Euler-এর উপপাদ্যে aφ(m) ≡ 1, তাই k = φ(m) নিয়ে d ∣ φ(m). ∎

এর একটি কাজের ফল: ax ≡ ay (mod m) ⇔ x ≡ y (mod ordm(a)). তাই ঘাত কমানোর জন্য φ(m)-এর চেয়েও ভালো সংখ্যা হলো order, যদি জানা থাকে। §৪-এর প্রশ্নে 74 = 2401 ≡ 1 (mod 100), অর্থাৎ ord100(7) = 4 (আর 4 ∣ 40, উপপাদ্য মেনে). 2026 = 4 · 506 + 2, তাই 72026 ≡ 72 = 49 (mod 100): শেষ দুই অঙ্ক 49.

উপপাদ্য ৫.২ আসলে একটি বড় নিয়মের বিশেষ রূপ: একটি সসীম group-এর যেকোনো উপাদানের order group-এর আকারকে ভাগ করে (Lagrange-এর উপপাদ্য)। mod m-এর সহমৌলিক ভাগশেষগুলো গুণের অধীনে φ(m) আকারের একটি group, আর এই দৃষ্টিভঙ্গি পর্ব ৭০ “Group — symmetry, cyclic group আর Lagrange-এর উপপাদ্য”-এ আসবে।

উপপাদ্য ৫.৩ (বিবৃতি; প্রমাণ এখানে বাদ)

(ক) প্রতিটি মৌলিক p-তে অন্তত একটি primitive root আছে। (খ) সাধারণভাবে m-এ primitive root আছে ঠিক তখন, যখন m = 1, 2, 4, pk বা 2pk (p বিজোড় মৌলিক, k ≥ 1). (গ) Primitive root থাকলে mod m-এ তাদের সংখ্যা ঠিক φ(φ(m)).

(ক)-এর প্রমাণে polynomial-এর একটি তথ্য লাগে (মৌলিক modulus-এ d ঘাতের polynomial-এর বড়জোর d-টি মূল) আর ∑d ∣ n φ(d) = n অভেদটি, যা ব্লক ২-এ পরীক্ষা করেছেন। পূর্ণ প্রমাণ সংখ্যাতত্ত্বের যেকোনো প্রচলিত পাঠ্যবইয়ে (যেমন Niven–Zuckerman–Montgomery বা Burton-এর বইয়ে primitive root অধ্যায়) পাবেন। এটি একটি অস্তিত্বের উপপাদ্য: কোন সংখ্যাটি primitive root, তা বলার কোনো সহজ সূত্র জানা নেই, তাই বাস্তবে p − 1-এর মৌলিক উৎপাদক জেনে প্রার্থীদের পরীক্ষা করা হয়। ছোট উদাহরণ: mod 7-এ order-গুলো 1 (a = 1), 3 (a = 2, 4), 6 (a = 3, 5), 2 (a = 6). সবগুলো 6-এর ভাজক, আর primitive root 3 ও 5, মোট φ(6) = 2টি। আর m = 8-এ primitive root নেই: 3, 5, 7 সবার বর্গ ≡ 1 (mod 8), অথচ φ(8) = 4.

বাজারঘরের কুপনে এর সরাসরি অর্থ আছে। গুণক 3 হলে mod 7-এ ছয় দিনে ছয়টি আলাদা কুপন আসে, কারণ 3 একটি primitive root. গুণক 2 হলে মাত্র তিনটি কুপন (2, 4, 1) ঘুরে ঘুরে আসে, কারণ ord7(2) = 3; আর গুণক 6 হলে মাত্র দুটি (6, 1). যে নিয়ম যত লম্বা চক্র দেয়, কুপন তত কম পুনরাবৃত্ত হয়। “গুণ করে ভাগশেষ নাও” ধাঁচের pseudorandom সংখ্যা বানানোর পদ্ধতিতে তাই গুণক হিসেবে primitive root বাছা হয়; এই ধরনের generator পর্ব ২৬ “সংখ্যাতত্ত্বের প্রয়োগ — check digit, hashing আর pseudorandom সংখ্যা”-এ আসবে।

Primitive root g থাকলে প্রতিটি সহমৌলিক ভাগশেষ x-কে x ≡ gk হিসেবে লেখা যায়, আর এই k-কে বলে x-এর discrete logarithm. g আর k থেকে x বের করা দ্রুত (repeated squaring), কিন্তু x থেকে k বের করা বড় p-তে কঠিন বলে বিশ্বাস করা হয়। Diffie–Hellman key exchange এই অসমতার ওপর দাঁড়িয়ে, যা পর্ব ২৯ “Discrete logarithm আর Diffie–Hellman key exchange”-এ আসবে।

নিচের ব্লক Euler-এর উপপাদ্য আর উপপাদ্য ৫.২ m < 300-এর সব সহমৌলিক জোড়ায় পরীক্ষা করে, §৪-এর দুটি হিসাব মেলায়, gcd শর্ত ভাঙলে কী হয় দেখায়, আর mod 11-এর order ও primitive root খোঁজে।

from math import gcd

def phi(n):
    return sum(1 for k in range(1, n + 1) if gcd(k, n) == 1)

def order(a, m):                        # smallest k >= 1 with a^k ≡ 1 (mod m)
    k, x = 1, a % m
    while x != 1:
        x, k = x * a % m, k + 1
    return k

PH = {m: phi(m) for m in range(2, 300)}
pairs = [(a, m) for m in range(2, 300) for a in range(1, m) if gcd(a, m) == 1]
print("Euler's theorem on", len(pairs), "pairs (a, m), m < 300:",
      all(pow(a, PH[m], m) == 1 for a, m in pairs))
print("ord_m(a) divides phi(m) on all of them:",
      all(PH[m] % order(a, m) == 0 for a, m in pairs))

e = 100000 % 30                         # phi(31) = 30
print("3^100000 mod 31: exponent ->", e, "  answer", pow(3, e, 31),
      "  direct", pow(3, 100000, 31))
print("7^2026 mod 100: 2026 mod 40 =", 2026 % 40, " answer", pow(7, 26, 100),
      "  ord_100(7) =", order(7, 100))

print("gcd(2, 12) = 2: 2^5 mod 12 =", pow(2, 5, 12),
      " but 2^(5 mod 4) mod 12 =", pow(2, 5 % 4, 12))

print("orders mod 11:", {a: order(a, 11) for a in range(1, 11)})
roots = [a for a in range(1, 11) if order(a, 11) == 10]
print("primitive roots mod 11:", roots, " count =", len(roots), "= phi(10) =", phi(10))
print("powers of 2 mod 11:", [pow(2, k, 11) for k in range(1, 11)])

আসল আউটপুট (ব্রাউজারের Python):

Euler's theorem on 27317 pairs (a, m), m < 300: True
ord_m(a) divides phi(m) on all of them: True
3^100000 mod 31: exponent -> 10   answer 25   direct 25
7^2026 mod 100: 2026 mod 40 = 26  answer 49   ord_100(7) = 4
gcd(2, 12) = 2: 2^5 mod 12 = 8  but 2^(5 mod 4) mod 12 = 2
orders mod 11: {1: 1, 2: 10, 3: 5, 4: 5, 5: 5, 6: 10, 7: 10, 8: 10, 9: 5, 10: 2}
primitive roots mod 11: [2, 6, 7, 8]  count = 4 = phi(10) = 4
powers of 2 mod 11: [2, 4, 8, 5, 10, 9, 7, 3, 6, 1]

২৭,৩১৭টি জোড়ায় দুটি উপপাদ্যই টিকেছে। তৃতীয় লাইন stepper-এর উত্তর 25 মেলায়, আর চতুর্থ লাইন দুই পথেই 49 দেয়: Euler দিয়ে ঘাত 26, order দিয়ে ঘাত 2, ফল একই। পঞ্চম লাইন সাবধানবাণীর counterexample: gcd(2, 12) ≠ 1, তাই ঘাত কমানো ভুল ফল (2) দেয়, আসল উত্তর 8. mod 11-এ সব order 1, 2, 5 বা 10, অর্থাৎ 10-এর ভাজক। Primitive root চারটি, ঠিক φ(10) = 4, উপপাদ্য ৫.৩(গ)-এর মতো। শেষ লাইনে 2-এর ঘাত 1 থেকে 10-এর প্রতিটি ভাগশেষ ঠিক একবার ছুঁয়ে যায়: এটিই primitive root-এর অর্থ।

৬ · Wilson-এর উপপাদ্য — factorial দিয়ে মৌলিকতা

Fermat-এর প্রমাণে (p − 1)! এসেছিল শুধু কেটে দেওয়ার জন্য। কিন্তু (p − 1)! mod p নিজেই একটি সুন্দর মান নেয়। p = 7-এ 6! = 720 = 7 · 102 + 6, অর্থাৎ 6! ≡ 6 ≡ −1 (mod 7).

উপপাদ্য ৬.১ (Wilson-এর উপপাদ্য)

n ≥ 2 হলে, n মৌলিক ⇔ (n − 1)! ≡ −1 (mod n).

প্রমাণ (⇒, p মৌলিক): p = 2-এ 1! = 1 ≡ −1 (mod 2), তাই ধরুন p বিজোড়।

  1. {1, …, p − 1}-এর প্রতিটি a-এর একটি অনন্য inverse a−1 আছে এই সেটের মধ্যেই, কারণ p মৌলিক (Corollary ২.২(খ)). — inverse-এর অস্তিত্ব আর অনন্যতা
  2. কোন a নিজের inverse? a2 ≡ 1 ⇔ p ∣ (a − 1)(a + 1) ⇔ p ∣ a − 1 বা p ∣ a + 1 ⇔ a = 1 বা a = p − 1. — Euclid-এর lemma
  3. বাকি p − 3টি সংখ্যা (2 থেকে p − 2) তাই জোড়ায় জোড়ায় ভাগ হয়, প্রতিটি জোড়া {a, a−1}, আর প্রতিটি জোড়ার গুণফল ≡ 1. — জোড়া বাঁধা
  4. অতএব (p − 1)! ≡ 1 · 1 ⋯ 1 · (p − 1) ≡ −1 (mod p). — গুণ congruence মানে

প্রমাণ (⇐, contrapositive): n যৌগিক হলে n-এর একটি ভাজক d আছে, 1 < d < n. d সংখ্যাটি (n − 1)!-এর একটি উৎপাদক, তাই d ∣ (n − 1)!. যদি (n − 1)! ≡ −1 (mod n) হতো, তবে d ∣ (n − 1)! + 1-ও হতো, ফলে d ∣ 1, যা অসম্ভব। ∎

p = 7-এ জোড়াগুলো চোখে দেখুন: 2 · 4 = 8 ≡ 1, 3 · 5 = 15 ≡ 1, আর 1 ও 6 নিজেরাই নিজেদের inverse. তাই 6! ≡ 1 · (2 · 4) · (3 · 5) · 6 ≡ 6 ≡ −1. ফলটি Edward Waring ১৭৭০ সালে তাঁর ছাত্র John Wilson-এর নামে প্রমাণ ছাড়া প্রকাশ করেন, আর প্রথম প্রমাণ দেন Joseph-Louis Lagrange ১৭৭১ সালে বলে সাধারণত উল্লেখ করা হয়; এর অনেক আগে Ibn al-Haytham (প্রায় ১০০০ খ্রিস্টাব্দ) ফলটি জানতেন বলেও কিছু ইতিহাসবিদ মনে করেন।

যৌগিক n-এ (n − 1)! mod n আসলে আরও সরল: n > 4 হলে এটি সবসময় 0. কারণ n = ab, 1 < a ≤ b < n লিখুন। a < b হলে a আর b দুটিই 1, 2, …, n − 1-এর আলাদা সদস্য, তাই ab = n গুণফলটিকে ভাগ করে। a = b হলে n = a2 (n > 4 বলে a ≥ 3), আর তখন a ও 2a দুটিই n − 1-এর চেয়ে ছোট আলাদা সংখ্যা (2a < a2), তাই a · 2a = 2n গুণফলটিকে ভাগ করে। একমাত্র ব্যতিক্রম n = 4: 3! = 6 ≡ 2 (mod 4).

উপপাদ্যটি মৌলিকতার একটি নিখুঁত পরীক্ষা, শর্ত দুই দিকেই খাটে। তবু কেউ এটি দিয়ে মৌলিকতা যাচাই করেন না: (n − 1)! mod n বের করতে n − 2টি গুণ লাগে, যা trial division-এর √n-টি ভাগের চেয়েও অনেক ধীর। 30 অঙ্কের n-এ এটি অসম্ভব রকম লম্বা। মৌলিকতা পরীক্ষার দ্রুত পথ খুঁজতে আমাদের Fermat-এর দিকেই ফিরতে হবে।

৭ · Fermat-এর পরীক্ষা, pseudoprime আর Carmichael সংখ্যা

Fermat-এর উপপাদ্যকে উল্টো দিক থেকে পড়লে একটি পরীক্ষা পাওয়া যায়: কোনো 1 < a < n নিয়ে an−1 mod n বের করুন (repeated squaring-এ বড়জোর কয়েক হাজার গুণ, এমনকি n কয়েক শ অঙ্কের হলেও)। ফল 1 না হলে n নিশ্চিতভাবে যৌগিক, কারণ মৌলিক হলে ফল 1 হতেই হতো (contrapositive). এই হলো Fermat-এর পরীক্ষা। উদাহরণ: 214 mod 15 = 4 ≠ 1, তাই 15 যৌগিক, একটিও উৎপাদক না খুঁজেই।

কিন্তু ফল 1 হলে? তখন n মৌলিক হতে পারে, প্রমাণ নয়। কারণ “p মৌলিক ⇒ ap−1 ≡ 1” উপপাদ্যের converse সত্য নয়। পর্ব ০৮-এ দেখেছেন, একটি implication প্রমাণ করলে তার converse প্রমাণ হয় না।

সংজ্ঞা ৭.১

যৌগিক n আর gcd(a, n) = 1 হলে, যদি an−1 ≡ 1 (mod n), তবে n একটি base-a Fermat pseudoprime. যে যৌগিক n প্রতিটি সহমৌলিক base a-তে pseudoprime, সে একটি Carmichael সংখ্যা.

সবচেয়ে ছোট base-2 pseudoprime 341 = 11 · 31: 2340 ≡ 1 (mod 341). কেন? 210 = 1024 = 3 · 341 + 1, অর্থাৎ 210 ≡ 1 (mod 341), আর 10 ∣ 340. তবে base 3 নিলে 3340 ≡ 56 (mod 341), তাই দ্বিতীয় base 341-কে ধরে ফেলে। Carmichael সংখ্যায় এই কৌশলও চলে না: সহমৌলিক যে base-ই নিন, ফল 1. সবচেয়ে ছোটটি 561 = 3 · 11 · 17. এটি চেনার একটি সহজ নিয়ম আছে।

উপপাদ্য ৭.২ (Korselt-এর শর্ত)

একটি যৌগিক n Carmichael সংখ্যা ⇔ n squarefree (কোনো মৌলিক সংখ্যার বর্গ n-কে ভাগ করে না) আর n-এর প্রতিটি মৌলিক উৎপাদক p-এর জন্য (p − 1) ∣ (n − 1).

561-এ (⇐) দিকের প্রমাণ: 561 − 1 = 560, আর 2 ∣ 560, 10 ∣ 560, 16 ∣ 560. ধরুন gcd(a, 561) = 1.

  1. 3 ∤ a, তাই Fermat-এ a2 ≡ 1 (mod 3), আর 560 = 2 · 280 বলে a560 ≡ 1 (mod 3). — Fermat, p = 3
  2. একইভাবে a10 ≡ 1 (mod 11) থেকে a560 ≡ 1 (mod 11), আর a16 ≡ 1 (mod 17) থেকে a560 ≡ 1 (mod 17). — Fermat, p = 11, 17
  3. 3, 11, 17 পরস্পর সহমৌলিক, আর প্রত্যেকে a560 − 1-কে ভাগ করে, তাই তাদের গুণফল 561-ও ভাগ করে: a560 ≡ 1 (mod 561). ∎ — সহমৌলিক ভাজকের গুণফলও ভাজক

এই যুক্তি যেকোনো squarefree n-এ (⇐) দিকটি প্রমাণ করে; উল্টো দিকের প্রমাণে primitive root লাগে, তাই এখানে শুধু বিবৃতি। Alwin Korselt শর্তটি ১৮৯৯ সালে দেন, কিন্তু কোনো উদাহরণ দেননি বলে উল্লেখিত; Robert Carmichael ১৯১০ সালে 561 খুঁজে পান। (চেক প্রজাতন্ত্রের গণিতবিদ Václav Šimerka ১৮৮৫ সালেই প্রথম কয়েকটি এমন সংখ্যার তালিকা দিয়েছিলেন বলে পরে জানা যায়।)

Korselt-এর শর্ত থেকে Carmichael সংখ্যার আকার সম্পর্কে দুটি তথ্য সহজেই প্রমাণ হয়। প্রথমত, এরা বিজোড়: n জোড় আর squarefree যৌগিক হলে n-এর একটি বিজোড় মৌলিক উৎপাদক p আছে, তখন p − 1 জোড়, কিন্তু n − 1 বিজোড়, তাই (p − 1) ∣ (n − 1) অসম্ভব। দ্বিতীয়ত, এদের অন্তত তিনটি মৌলিক উৎপাদক থাকে: n = pq (p < q) হলে n − 1 = p(q − 1) + (p − 1), তাই (q − 1) ∣ (n − 1) মানে (q − 1) ∣ (p − 1), যা অসম্ভব কারণ 0 < p − 1 < q − 1. 561, 1105, 1729 সবারই ঠিক তিনটি উৎপাদক।

নিচের ব্লক 104-এর নিচে সব base-2 pseudoprime খোঁজে, Korselt-এর শর্ত দিয়ে 105-এর নিচে সব Carmichael সংখ্যা বের করে (একটি smallest-prime-factor sieve দিয়ে উৎপাদক বের করে), 561-কে সব সহমৌলিক base-এ সরাসরি যাচাই করে, আর ছোট n-এ Wilson-এর উপপাদ্য দেখায়।

from math import gcd, factorial

def is_prime(n):
    return n > 1 and all(n % d for d in range(2, int(n ** 0.5) + 1))

psp = [n for n in range(3, 10**4, 2) if pow(2, n - 1, n) == 1 and not is_prime(n)]
print("base-2 Fermat pseudoprimes below 10^4:", len(psp), psp[:8], "...")
print("341 = 11*31:  2^340 mod 341 =", pow(2, 340, 341),
      "  3^340 mod 341 =", pow(3, 340, 341))

N = 10**5
spf = list(range(N))                    # smallest-prime-factor sieve
for i in range(2, int(N ** 0.5) + 1):
    if spf[i] == i:
        for j in range(i * i, N, i):
            if spf[j] == j:
                spf[j] = i

def factors(n):
    out = []
    while n > 1:
        out.append(spf[n])
        n //= spf[n]
    return out

def korselt(n):     # composite, squarefree, (p - 1) | (n - 1) for each prime p | n
    f = factors(n)
    return len(f) >= 2 and len(set(f)) == len(f) and all((n - 1) % (p - 1) == 0 for p in f)

car = [n for n in range(3, N, 2) if korselt(n)]
print("Carmichael numbers below 10^5:", len(car), car[:6], "...")
print("561 = 3*11*17 passes for every coprime base:",
      all(pow(a, 560, 561) == 1 for a in range(1, 561) if gcd(a, 561) == 1))
print("but 3^560 mod 561 =", pow(3, 560, 561), " because gcd(3, 561) =", gcd(3, 561))
print("n < 40 with (n-1)! mod n == n-1:", [n for n in range(2, 40) if factorial(n - 1) % n == n - 1])

আসল আউটপুট (ব্রাউজারের Python):

base-2 Fermat pseudoprimes below 10^4: 22 [341, 561, 645, 1105, 1387, 1729, 1905, 2047] ...
341 = 11*31:  2^340 mod 341 = 1   3^340 mod 341 = 56
Carmichael numbers below 10^5: 16 [561, 1105, 1729, 2465, 2821, 6601] ...
561 = 3*11*17 passes for every coprime base: True
but 3^560 mod 561 = 375  because gcd(3, 561) = 3
n < 40 with (n-1)! mod n == n-1: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]

১০,০০০-এর নিচে ২২টি যৌগিক সংখ্যা base 2-এর Fermat পরীক্ষায় পাস করে; প্রথমটি 341. মৌলিক সংখ্যা এই সীমার নিচে ১,২২৯টি, তাই base 2-এর “পাস” প্রায় সবসময় ঠিক, কিন্তু সবসময় নয়। 105-এর নিচে Carmichael সংখ্যা ১৬টি; 1105 = 5 · 13 · 17 আর 1729 = 7 · 13 · 19 পরের দুটি। 561 সব সহমৌলিক base-এ পাস করে, আর একমাত্র উপায় হলো এমন a নেওয়া যা 561-এর সঙ্গে সহমৌলিক নয়, যেমন 3; কিন্তু এমন a খুঁজে পাওয়া মানে আসলে একটি উৎপাদক খুঁজে পাওয়া, যা বড় সংখ্যায় কঠিন। শেষ লাইন Wilson: ৪০-এর নিচে ঠিক মৌলিক সংখ্যাগুলোই শর্ত পূরণ করে। এই দুর্বলতা সারানোর উপায়, Miller–Rabin পরীক্ষা, পর্ব ২৫ “Primality test আর factoring — Miller–Rabin থেকে কঠিনতার ধারণা”-এর বিষয়।

৮ · পরীক্ষার অঙ্ক আর একটি ভুল প্রমাণ

বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর লিখিত পরীক্ষায় এই বিষয়ের যে ধাঁচের অঙ্ক আসে, তার তিনটি পূর্ণ সমাধান। প্রতিটি সংখ্যা উপরের ব্লক বা scratch-এ Python দিয়ে মেলানো।

অঙ্ক ১: 21000-কে 13 দিয়ে ভাগ করলে ভাগশেষ কত?

  1. শর্ত: 13 মৌলিক, 13 ∤ 2. Fermat-এ 212 ≡ 1 (mod 13).
  2. 1000 = 12 · 83 + 4, তাই 21000 ≡ 24 = 16 ≡ 3 (mod 13). উত্তর 3.

অঙ্ক ২: 72026-এর শেষ দুই অঙ্ক কী?

  1. শেষ দুই অঙ্ক মানে mod 100. gcd(7, 100) = 1, φ(100) = 100 · (1 − 1/2)(1 − 1/5) = 40.
  2. Euler-এ 2026 mod 40 = 26, তাই 72026 ≡ 726 (mod 100). আরও ছোট করতে লক্ষ করুন 72 = 49, 74 = 2401 ≡ 1 (mod 100).
  3. 26 = 4 · 6 + 2, তাই 726 ≡ 72 = 49. উত্তর: শেষ দুই অঙ্ক 49.

অঙ্ক ৩: mod 13-এ কয়টি primitive root, আর 2 কি তাদের একটি?

  1. 13 মৌলিক, তাই primitive root আছে, আর তাদের সংখ্যা φ(φ(13)) = φ(12) = 4.
  2. ord13(2) হতে হবে 12-এর একটি ভাজক: 1, 2, 3, 4, 6 বা 12. 12-এর মৌলিক উৎপাদক 2 আর 3, তাই শুধু 12/2 = 6 আর 12/3 = 4 পরীক্ষা করলেই চলে: 24 = 16 ≡ 3 আর 26 = 64 ≡ 12 (mod 13), কোনোটি 1 নয়।
  3. তাই ord13(2) = 12, আর 2 একটি primitive root. (চারটি primitive root হলো 2, 6, 7, 11.)

ধাপ ২-এর কৌশলটি মনে রাখুন: g primitive root mod p ⇔ p − 1-এর প্রতিটি মৌলিক উৎপাদক q-তে g(p−1)/q ≢ 1. কারণ order যদি p − 1-এর একটি ছোট ভাজক হয়, তবে সেটি অন্তত একটি (p − 1)/q-কে ভাগ করে।

প্রমাণের ভুল ধরুন: “Fermat-এর পরীক্ষায় পাস মানেই মৌলিক”

একজন লিখলেন: “দাবি: n > 2 বিজোড় আর 2n−1 ≡ 1 (mod n) হলে n মৌলিক। প্রমাণ: Fermat-এর ছোট উপপাদ্য বলে মৌলিক p-তে 2p−1 ≡ 1. এখানে n-এ ঠিক এই সম্পর্কটি সত্য, তাই n মৌলিক। ∎” পড়ে ভুলটি নিজে খুঁজুন।

ভুল কোথায়: প্রমাণটি “P ⇒ Q” থেকে “Q ⇒ P” টেনেছে, অর্থাৎ converse-কে সত্য ধরেছে (affirming the consequent, পর্ব ০৬-এর একটি পরিচিত ভুল যুক্তি)। একটি counterexample-ই দাবিটি বাতিল করে: n = 341 = 11 · 31 বিজোড় ও যৌগিক, তবু 2340 ≡ 1 (mod 341). সঠিক বক্তব্য শুধু এক দিকে: 2n−1 ≢ 1 (mod n) হলে n যৌগিক।

আরও গভীরে: W. R. Alford, Andrew Granville আর Carl Pomerance ১৯৯৪ সালে প্রমাণ করেন যে Carmichael সংখ্যা অসীম সংখ্যক, তাই Fermat-এর পরীক্ষার ফাঁক কখনো “শেষ” হয় না। Emil Artin ১৯২৭ সালে অনুমান করেন যে বর্গ নয় এমন প্রতিটি পূর্ণসংখ্যা a ≠ −1 (যেমন 2) অসীম সংখ্যক মৌলিক p-এর primitive root; এটি আজও খোলা প্রশ্ন, যদিও Christopher Hooley ১৯৬৭ সালে একটি অপ্রমাণিত অনুমানের (generalized Riemann hypothesis) ওপর ভর করে এটি প্রমাণ করেন। আর এই পর্বের উপপাদ্যগুলোর group-তত্ত্বের রূপ, যেখানে mod m-এর সহমৌলিক ভাগশেষ একটি group আর primitive root মানে group-টি cyclic, পর্ব ৭০-এ আসবে।

পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় এই ধরনের প্রশ্ন প্রায়ই আসে:

  • 3100 mod 7? 100 mod 6 = 4, তাই 34 = 81 ≡ 4.
  • φ(36)? 36 = 22 · 32, φ = 36 · (1/2) · (2/3) = 12.
  • p মৌলিক হলে a-এর inverse mod p কোন ঘাতে? ap−2 mod p, যদি p ∤ a.
  • 12! mod 13? Wilson-এ −1 ≡ 12.
  • Carmichael সংখ্যার উদাহরণ আর তাৎপর্য? 561 = 3 · 11 · 17; যৌগিক, তবু সব সহমৌলিক base-এ Fermat-এর পরীক্ষায় পাস করে।

৯ · AI-এর যুগে — ঘাত, φ আর প্রমাণের হিসাব যাচাই

AI সহকারী এই বিষয়ের প্রশ্নে খুব আত্মবিশ্বাসী উত্তর দেয়, কিন্তু বড় সংখ্যার মাথায় হিসাবে আর উপপাদ্যের শর্তে নিয়মিত ভুল করে। কয়েকটি ধরন, আর কীভাবে ধরবেন:

AI-এর ভুলকীভাবে ধরবেন
শর্ত ছাড়া উপপাদ্য: gcd(a, m) ≠ 1 হলেও ঘাত mod φ(m) কমানো, বা যৌগিক modulus-এ Fermat লাগানোপ্রতিটি উপপাদ্যের শর্ত জিজ্ঞেস করুন; 25 mod 12-এর মতো ছোট counterexample চালান
ঘাত mod m কমানো (mod φ(m) বা mod order-এর বদলে)Python-এর pow(a, b, m) দিয়ে সরাসরি উত্তরের সঙ্গে মেলান
বড় সংখ্যার ভাগশেষে মাথার হিসাবের ভুল, বা φ-এর সূত্রে একটি মৌলিক উৎপাদক বাদ পড়াφ brute force-এ গুনে সূত্রের সঙ্গে মেলান (ব্লক ২); উৎপাদকে ভাঙা গুণ করে মূল সংখ্যা ফিরে আসে কি না দেখুন
Converse-কে সত্য ধরা: “Fermat-এ পাস তাই মৌলিক”, বা “order φ(m)-কে ভাগ করে তাই order = φ(m)”341, 561-এর মতো পরিচিত counterexample দিয়ে দাবি পরীক্ষা করুন
প্রমাণে শূন্য বা অ-সহমৌলিক সংখ্যা কেটে দেওয়া (যেমন mod 12-এ দুই পাশ থেকে 2 কেটে দেওয়া)প্রতিটি “কেটে দিলাম” ধাপে gcd = 1 কি না নিজে দেখুন
বানানো ইতিহাস বা সূত্র: ভুল সাল, ভুল আবিষ্কারক, “প্রাচীন চীনা পরীক্ষা”-র মতো প্রচলিত গল্পবিশ্বস্ত পাঠ্যবই বা গণিত-ইতিহাসের উৎসে মিলিয়ে নিন; নিশ্চিত না হলে দাবিটি বাদ দিন

AI-এর কাছে সংখ্যাতত্ত্বের হিসাব বা প্রমাণ চাইলে এমন কাঠামো দিন, যাতে প্রতিটি ধাপ আলাদা করে যাচাই করা যায়:

নিচের সংখ্যাতত্ত্বের প্রশ্নটি ধাপে ধাপে সমাধান করো: প্রশ্ন: [যেমন a^b mod m, বা φ(n), বা একটি প্রমাণ] ১. কোন উপপাদ্য (Fermat, Euler, Wilson, CRT) ব্যবহার করছ, তার পূর্ণ বিবৃতি আর সব শর্ত লেখো। ২. প্রতিটি শর্ত এই সংখ্যাগুলোতে সত্য কি না আলাদা করে দেখাও (যেমন p মৌলিক কি না, gcd(a, m) = 1 কি না)। ৩. ঘাত কমালে কোন সংখ্যা দিয়ে কমাচ্ছ (φ(m) নাকি order) আর কেন, তা লেখো। ৪. প্রতিটি মধ্যবর্তী ভাগশেষ আলাদা লাইনে দাও, যাতে আমি মেলাতে পারি। ৫. প্রমাণে কোথাও কিছু "কেটে দিলে" সেখানে gcd = 1 কেন, তা বলো। ৬. শেষে উত্তর যাচাইয়ের একটি ছোট Python কোড দাও (শুধু standard library, pow(a, b, m) ব্যবহার করে)।

AI-এর উত্তর হাতে পেলে — যাচাইয়ের চেকলিস্ট

সবচেয়ে সস্তা প্রথম পরীক্ষা: AI যে সংখ্যাটি দিল, সেটি এক লাইনের Python-এ মিলিয়ে নিন। এই পর্বের প্রায় প্রতিটি দাবি ছোট সংখ্যায় এক সেকেন্ডে পরীক্ষা করা যায়, আর একটি অমিলই পুরো উত্তরকে সন্দেহজনক করে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।

প্র ০১Fermat প্রমাণ ছাড়াই ফলটি জানিয়েছিলেন। এত সহজ প্রমাণের উপপাদ্য নিয়ে ইতিহাসে এত দেরি কেন, আর “ছোট” উপপাদ্যটি পরে এত বড় হলো কীভাবে?

সতেরো শতকে গণিতবিদরা প্রায়ই চিঠিতে ফল জানাতেন, প্রমাণ নয়; প্রমাণকে অনেকে নিজের কৌশল হিসেবে গোপন রাখতেন। Fermat ১৬৪০ সালে Frénicle de Bessy-কে লেখা চিঠিতে ফলটি জানান এবং বলেন যে প্রমাণ পাঠাতেন যদি তা খুব দীর্ঘ না হতো, এমনটাই প্রচলিত বর্ণনা। Fermat-এর অনেক দাবিই এভাবে প্রমাণহীন ছিল, তার একটি পরে “শেষ উপপাদ্য” নামে সাড়ে তিন শ বছর অপ্রমাণিত থাকে, যতক্ষণ না Andrew Wiles ১৯৯০-এর দশকে তা প্রমাণ করেন।

ছোট উপপাদ্যের প্রথম প্রকাশিত প্রমাণ Euler-এর, ১৭৩৬ সালের দিকে, আর সেটি ছিল a-এর ওপর induction ও binomial theorem-ভিত্তিক: (a + 1)p ≡ ap + 1 (mod p), কারণ মাঝের সব binomial coefficient p দিয়ে বিভাজ্য। Leibniz প্রায় একই যুক্তি আগেই লিখে রেখেছিলেন কিন্তু প্রকাশ করেননি বলে পাণ্ডুলিপি থেকে জানা যায়। পরে Euler ফলটিকে যৌগিক modulus-এ সাধারণ করেন, আর এই পর্বের permutation-ভিত্তিক প্রমাণটি James Ivory ১৮০৬ সালের দিকে দেন বলে প্রায়ই উল্লেখ করা হয়। এটি গুরুত্বপূর্ণ, কারণ এই প্রমাণটিই পরে group তত্ত্বের Lagrange-এর উপপাদ্যের বিশেষ রূপ হিসেবে চেনা গেল।

“ছোট” উপপাদ্যটি বিশ শতকে বিশাল হয়ে ওঠে দুটি কারণে। প্রথমত, কম্পিউটারে বড় সংখ্যার মৌলিকতা পরীক্ষা: Fermat-এর পরীক্ষা আর তার উন্নত রূপ Miller–Rabin (পর্ব ২৫) অনেক cryptographic লাইব্রেরিতে মৌলিক সংখ্যা বানাতে ব্যবহৃত হয়। দ্বিতীয়ত, ১৯৭৭ সালের RSA, যার decryption কেন কাজ করে তার যুক্তিই Euler-এর উপপাদ্য। যে ফল তিন শ বছর আগে চিঠির এক লাইন ছিল, আজ তা নিরাপদ ইন্টারনেট সংযোগের গণিতের একটি অংশ।

মূল উপলব্ধি: একটি উপপাদ্যের মূল্য তার প্রমাণের দৈর্ঘ্যে নয়; সঠিক দৃষ্টিভঙ্গি (permutation, group) একটি সহজ প্রমাণকে বহু বড় তত্ত্বের দরজা বানায়।

প্র ০২RSA কেন Euler-এর উপপাদ্যের ওপর দাঁড়িয়ে, আর n = pq-এর φ(n) জানা কেন n-কে factor করার সমান কঠিন?

RSA-র পূর্ণ গণিত পর্ব ২৮-এ আসবে; এখানে শুধু মূল যুক্তি। দুটি বড় মৌলিক p, q নিয়ে n = pq, আর φ(n) = (p − 1)(q − 1). একটি e বাছা হয় যাতে gcd(e, φ(n)) = 1, আর d হয় e-এর inverse mod φ(n), অর্থাৎ ed = 1 + kφ(n). বার্তা M (gcd(M, n) = 1 ধরে) থেকে C = Me mod n, আর ফেরত আনতে Cd = Med = M · (Mφ(n))k ≡ M (mod n). শেষ ধাপটি ঠিক Euler-এর উপপাদ্য। (gcd(M, n) ≠ 1-এর ক্ষেত্রও CRT দিয়ে আলাদা করে প্রমাণ করা যায়।)

নিরাপত্তার যুক্তি হলো: e আর n সবাই জানে, কিন্তু d বের করতে φ(n) লাগে। আর φ(n) জানা মানে কার্যত p, q জানা। কারণ n − φ(n) + 1 = pq − (pq − p − q + 1) + 1 = p + q. যোগফল p + q আর গুণফল pq জানা থাকলে p আর q হলো x2 − (p + q)x + pq = 0 সমীকরণের দুটি মূল, যা স্কুলের সূত্রে বের হয়। অর্থাৎ φ(n) বের করা n-কে factor করার চেয়ে সহজ নয়। আর বড় n-কে factor করার দ্রুত কোনো পদ্ধতি সাধারণ কম্পিউটারে জানা নেই (পর্ব ২৫).

একটি জরুরি সাবধানবাণী: এখানে বর্ণিত “textbook RSA” শুধু গণিত বোঝার জন্য। একই বার্তা সবসময় একই ciphertext দেয়, ছোট বার্তা আর ছোট e-তে আক্রমণ সম্ভব, আর আরও অনেক ফাঁক আছে। বাস্তব সিস্টেমে padding, বড় key আর যাচাই-করা লাইব্রেরি লাগে; নিজে RSA লিখে ব্যবহার করবেন না। বাস্তব ব্যবহারের দিকটি Cybersecurity কোর্সের পর্ব ১০-এ আছে।

মূল উপলব্ধি: Euler-এর উপপাদ্য RSA-কে সঠিক করে, আর φ(n) বের করার কঠিনতা (যা factoring-এর সমান) একে নিরাপদ রাখে; কিন্তু গণিত সঠিক হলেই সিস্টেম নিরাপদ হয় না।

প্র ০৩Carmichael সংখ্যা কত বিরল, আর তারা থাকা সত্ত্বেও বাস্তবে Fermat-ধাঁচের পরীক্ষা কেন এত ব্যবহৃত হয়?

ব্লক ৪ দেখিয়েছে, 105-এর নিচে মাত্র ১৬টি Carmichael সংখ্যা, অথচ মৌলিক সংখ্যা ৯ হাজারের বেশি। বড় সীমায় অনুপাত আরও ছোট হয়, যদিও Alford, Granville আর Pomerance ১৯৯৪ সালে প্রমাণ করেন যে এরা অসীম সংখ্যক, আর যথেষ্ট বড় x-এর নিচে অন্তত x2/7টি আছে। অর্থাৎ বিরল, কিন্তু কখনো শেষ হয় না।

এলোমেলোভাবে বাছা একটি বড় বিজোড় সংখ্যা Carmichael হওয়ার সম্ভাবনা খুবই কম, তাই অনেক পুরোনো সফটওয়্যার base 2-এর Fermat পরীক্ষাকেই যথেষ্ট মনে করত, আর সংখ্যাগুলোকে কখনো কখনো “industrial-grade prime” বলা হতো। সমস্যা হয় যখন সংখ্যাটি এলোমেলো নয়, বরং কেউ ইচ্ছা করে বানিয়েছে। একটি প্রতিপক্ষ জেনেশুনে একটি Carmichael সংখ্যা বা একটি নির্দিষ্ট base-এর pseudoprime পাঠাতে পারে, আর পরীক্ষাটি তাকে মৌলিক বলে মেনে নেবে। নিরাপত্তার কাজে তাই “গড়ে ঠিক” যথেষ্ট নয়, “প্রতিপক্ষের বাছা ইনপুটেও ঠিক” হতে হয়।

সমাধান Miller–Rabin (পর্ব ২৫), যা Fermat-এর পরীক্ষার সঙ্গে আরও একটি তথ্য যোগ করে: মৌলিক p-তে x2 ≡ 1-এর সমাধান শুধু ±1 (Wilson-এর প্রমাণের ধাপ ২)। এই বাড়তি শর্ত Carmichael সংখ্যাকেও ধরে ফেলে, আর প্রতিটি যৌগিক n-এর জন্য বেশিরভাগ base সাক্ষী হয়। এই উন্নত পরীক্ষাগুলো আজ cryptographic লাইব্রেরিতে মৌলিক সংখ্যা বানানোর আদর্শ উপায়। অর্থাৎ Fermat-এর ধারণা বাদ যায়নি, শুধু পরিশুদ্ধ হয়েছে। DSA কোর্সের পর্ব ৬২-এ 561-এ Miller–Rabin কীভাবে কাজ করে, তার একটি stepper আছে।

মূল উপলব্ধি: একটি পরীক্ষা “প্রায় সবসময়” ঠিক হলেই যথেষ্ট নয়, যদি কেউ ইচ্ছা করে ব্যতিক্রমটি বেছে নিতে পারে; Carmichael সংখ্যা এই শিক্ষার সবচেয়ে পরিষ্কার উদাহরণ।

প্র ০৪Primitive root আছে বলে জানা, কিন্তু খুঁজতে সূত্র নেই। এই “অস্তিত্ব আছে, সূত্র নেই” অবস্থা কম্পিউটার বিজ্ঞানে কী অর্থ বহন করে?

মৌলিক p-তে primitive root-এর অস্তিত্ব Gauss ১৮০১ সালের Disquisitiones Arithmeticae-তে প্রমাণ করেন বলে উল্লেখ করা হয়; Euler এর আগে ফলটি নিয়ে কাজ করেছিলেন, কিন্তু তাঁর যুক্তি সম্পূর্ণ ছিল না বলে মনে করা হয়। প্রমাণটি গণনা দিয়ে চলে: প্রতিটি ভাজক d ∣ p − 1-এ order d-এর উপাদান বড়জোর φ(d)টি, আর ∑ φ(d) = p − 1 বলে প্রতিটি d-তে ঠিক φ(d)টিই থাকতে বাধ্য, তাই d = p − 1-এও। এটি একটি nonconstructive প্রমাণ (পর্ব ০৯): সংখ্যা আছে বলে, কোনটি তা বলে না।

বাস্তবে primitive root খোঁজা হয় পরীক্ষা করে: g = 2, 3, 5, … নিয়ে দেখা হয় p − 1-এর প্রতিটি মৌলিক উৎপাদক q-তে g(p−1)/q ≢ 1 কি না (§৮-এর অঙ্ক ৩). কাজটি দ্রুত, যদি p − 1-এর উৎপাদক জানা থাকে। আর সেই উৎপাদক না জানলে কাজটি কঠিন হতে পারে, কারণ বড় সংখ্যা factor করা কঠিন। তাই cryptography-তে প্রায়ই এমন p বাছা হয়, যেখানে p − 1 = 2q আর q-ও মৌলিক (“safe prime”), যাতে উৎপাদক আগেই জানা।

সবচেয়ে ছোট primitive root সাধারণত খুব ছোট হয় বলে পরীক্ষায় দেখা যায়, কিন্তু এর ভালো ওপরের সীমা প্রমাণ করা কঠিন। আর Artin-এর ১৯২৭ সালের অনুমান, যে 2 অসীম সংখ্যক মৌলিকের primitive root, আজও প্রমাণিত নয়। একই primitive root-এর ওপর discrete logarithm সমস্যা দাঁড়িয়ে আছে, যার কঠিনতা Diffie–Hellman (পর্ব ২৯) ব্যবহার করে।

মূল উপলব্ধি: গণিতে অস্তিত্বের প্রমাণ আর কম্পিউটারে খুঁজে বের করার পদ্ধতি আলাদা জিনিস; কম্পিউটার বিজ্ঞানে প্রায়ই প্রশ্ন “আছে কি” নয়, “কত দ্রুত পাওয়া যায়”।

প্র ০৫Wilson-এর উপপাদ্য মৌলিকতার একটি নিখুঁত শর্ত, তবু অকেজো। একটি “সুন্দর” চরিত্রায়ন আর একটি “দ্রুত” পরীক্ষার পার্থক্য কী?

Wilson-এর উপপাদ্য “n মৌলিক ⇔ (n − 1)! ≡ −1 (mod n)” একটি if-and-only-if, অর্থাৎ মৌলিকতার পূর্ণ চরিত্রায়ন: কোনো ব্যতিক্রম নেই, Carmichael-এর মতো কোনো ফাঁক নেই। ইতিহাসেও এটি পুরোনো: Ibn al-Haytham প্রায় এক হাজার বছর আগে এ ধরনের ফল জানতেন বলে মনে করা হয়, Waring ১৭৭০ সালে Wilson-এর নামে এটি প্রকাশ করেন, আর Lagrange ১৭৭১ সালে প্রমাণ করেন বলে উল্লেখিত।

সমস্যা খরচে। (n − 1)! mod n বের করার সরাসরি পথে n − 2টি গুণ, প্রতিটি গুণের পর mod নিয়ে। n যদি 20 অঙ্কের হয়, গুণ লাগে প্রায় 1020টি, যা আধুনিক কম্পিউটারেও হাজার বছরের কাজ। তুলনায় Fermat-এর পরীক্ষায় repeated squaring-এ প্রায় log2 n, অর্থাৎ 20 অঙ্কে প্রায় ৬৭টি বর্গ। Factorial দ্রুত বের করার চতুর পদ্ধতি আছে, কিন্তু কোনোটিই n-এর অঙ্কসংখ্যায় polynomial সময়ে চলে বলে জানা নেই।

এই পার্থক্যটি কম্পিউটার বিজ্ঞানের একটি মৌলিক শিক্ষা। একটি সমস্যার গাণিতিক বর্ণনা যত সুন্দরই হোক, algorithm হিসেবে তার খরচ আলাদা প্রশ্ন। মৌলিকতা polynomial সময়ে নির্ধারণ করা যায় কি না, এই প্রশ্নের উত্তর এল ২০০২ সালে Agrawal, Kayal আর Saxena-র AKS পরীক্ষায়, যা কানপুরের IIT-এর তিন গবেষকের কাজ (পর্ব ২৫). তবু বাস্তবে দ্রুততার জন্য Miller–Rabin-ই বেশি ব্যবহৃত। আর Wilson-এর উপপাদ্যের নিজস্ব গবেষণা-দিকও আছে: যে মৌলিক p-তে (p − 1)! ≡ −1 শুধু mod p নয়, mod p2-এও সত্য, তাদের Wilson prime বলে; জানা উদাহরণ মাত্র তিনটি (5, 13, 563), আর আরও আছে কি না তা খোলা প্রশ্ন।

মূল উপলব্ধি: “সঠিক চরিত্রায়ন” আর “দক্ষ algorithm” আলাদা লক্ষ্য; প্রথমটি বোঝায় কী সত্য, দ্বিতীয়টি বলে কত দ্রুত তা যাচাই করা যায়।

অনুশীলন

আগে খাতায় করুন, তারপর উত্তর খুলে মেলান।

  1. প্রমাণ: প্রমাণ করুন, n ≥ 3 হলে φ(n) একটি জোড় সংখ্যা।
    1. R = {k : 1 ≤ k ≤ n, gcd(k, n) = 1}, তাই |R| = φ(n). k ↦ n − k ফাংশনটি নিন। gcd(n − k, n) = gcd(k, n), কারণ n − k আর k-এর পার্থক্য n-এর গুণিতক; তাই k ∈ R হলে n − k ∈ R (k = n বাদে, যা n ≥ 2-এ R-এ নেই)। — gcd-এর ধর্ম
    2. ফাংশনটি নিজের inverse, তাই R-এর সদস্যরা {k, n − k} জোড়ায় ভাগ হয়, যদি কোনো k নিজের জোড়া না হয়।
    3. k = n − k হলে n = 2k, আর তখন gcd(k, n) = k. k ∈ R হতে হলে k = 1, অর্থাৎ n = 2. n ≥ 3-এ তাই এমন k নেই। — case বিশ্লেষণ
    4. সব সদস্য আলাদা আলাদা দুজনের জোড়ায়, তাই φ(n) = |R| জোড়। ∎

    যাচাই: φ(3) = 2, φ(10) = 4, φ(15) = 8, φ(36) = 12, সব জোড়; আর φ(1) = φ(2) = 1, ঠিক যেখানে শর্ত n ≥ 3 খাটে না।

  2. হিসাব: (ক) φ(1001) আর φ(210) বের করুন। (খ) 32026-এর শেষ দুই অঙ্ক কী? (গ) Fermat দিয়ে 8-এর inverse mod 17 বের করুন। (ঘ) 52026 mod 13 কত?

    (ক) 1001 = 7 · 11 · 13, তাই φ = 6 · 10 · 12 = 720. φ(210) = 1024 − 512 = 512.

    (খ) gcd(3, 100) = 1, φ(100) = 40, আর 2026 mod 40 = 26, তাই 32026 ≡ 326 (mod 100). আসলে ord100(3) = 20 (320 ≡ 1), তাই আরও ছোট: 2026 mod 20 = 6, 36 = 729 ≡ 29. শেষ দুই অঙ্ক 29.

    (গ) 17 মৌলিক, 17 ∤ 8, তাই inverse = 815 mod 17. 82 = 64 ≡ 13 ≡ −4, 84 ≡ 16 ≡ −1, 88 ≡ 1. তাই 815 = 88 · 84 · 82 · 8 ≡ 1 · (−1) · (−4) · 8 = 32 ≡ 15. যাচাই: 8 · 15 = 120 = 7 · 17 + 1 ✓.

    (ঘ) 52 = 25 ≡ −1 (mod 13), তাই 54 ≡ 1, ord13(5) = 4. 2026 = 4 · 506 + 2, তাই 52026 ≡ 52 ≡ −1 ≡ 12. সব সংখ্যা scratch-এ Python দিয়ে যাচাই করা।

  3. আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে। তারপর যেকোনো Python-এ চালিয়ে মেলান।
    from math import gcd
    print(pow(5, 16, 17), pow(5, 15, 17) * 5 % 17)
    print([pow(a, 4, 10) for a in range(1, 10) if gcd(a, 10) == 1])
    print(pow(2, 10**6, 7))
    1 1
    [1, 1, 1, 1]
    2

    প্রথম লাইন: Fermat-এ 516 ≡ 1 (mod 17), আর 515 হলো 5-এর inverse, তাই 5 দিয়ে গুণ করলেও 1. দ্বিতীয় লাইন: 10-এর সঙ্গে সহমৌলিক a = 1, 3, 7, 9, আর φ(10) = 4, তাই Euler-এ প্রতিটির চতুর্থ ঘাত ≡ 1. তৃতীয় লাইন: 23 = 8 ≡ 1 (mod 7), অর্থাৎ ord7(2) = 3, আর 106 mod 3 = 1, তাই উত্তর 21 = 2.

  4. প্রমাণের ভুল ধরুন: একজন লিখলেন: “দাবি: যেকোনো m ≥ 2 আর যেকোনো a-তে aφ(m) ≡ 1 (mod m). প্রমাণ: r1, …, rφ(m) হোক m-এর সঙ্গে সহমৌলিক ভাগশেষগুলো। ar1, …, arφ(m) তাদেরই permutation, তাই গুণ করে aφ(m)R ≡ R, আর R কেটে দিলে ফল আসে। ∎” ভুল কোথায়, আর সঠিক দাবি কী?
    • ভুল: “ari-গুলো r-দেরই permutation” ধাপটি gcd(a, m) = 1 ছাড়া সত্য নয়। gcd(a, m) = d > 1 হলে ari-এর সঙ্গে m-এর সাধারণ উৎপাদক d থাকে, তাই ari সহমৌলিক ভাগশেষই নয়। দাবিটির উপসংহারও মিথ্যা।
    • Counterexample: m = 12, a = 2: φ(12) = 4, আর 24 = 16 ≡ 4 (mod 12), 1 নয়। আরও সরল: a ≡ 0 হলে aφ(m) ≡ 0.
    • সঠিক দাবি: Euler-এর উপপাদ্য, শর্তসহ: gcd(a, m) = 1 হলে aφ(m) ≡ 1 (mod m). আর gcd(a, m) > 1 হলে ak ≡ 1 কোনো k ≥ 1-এ সম্ভবই নয়, কারণ তাহলে a · ak−1 ≡ 1 মানে a-এর inverse থাকত।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমমৌলিক p আর বড় b-এর জন্য ab mod p বের করার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. p মৌলিক আর p ∤ a, এই দুই শর্ত মেলানো
  2. b-কে p − 1 দিয়ে ভাগ করে ভাগশেষ r বের করা
  3. ab = (ap−1)q · ar লিখে প্রথম অংশকে 1 ধরা
  4. ar mod p বারবার বর্গ করে বের করা
  5. pow(a, b, p) দিয়ে উত্তর মিলিয়ে নেওয়া

3100-কে 7 দিয়ে ভাগ করলে ভাগশেষ কত?

  • 4
  • 3
  • 1
  • 6

φ(36)-এর মান কত?

  • 12
  • 24
  • 18
  • 6

Euler-এর উপপাদ্য aφ(m) ≡ 1 (mod m) সত্য হওয়ার জন্য কোন শর্তটি জরুরি?

  • m মৌলিক
  • a < m
  • gcd(a, m) = 1
  • a বিজোড়

561 = 3 · 11 · 17 সংখ্যাটি সম্পর্কে কোনটি সঠিক?

  • এটি মৌলিক, কারণ 2560 ≡ 1 (mod 561)
  • এটি যৌগিক, তবু প্রতিটি সহমৌলিক a-তে a560 ≡ 1 (mod 561)
  • এটি শুধু base 2-এ pseudoprime, base 3-এ ধরা পড়ে
  • এটি Wilson-এর শর্ত (n − 1)! ≡ −1 (mod n) পূরণ করে

mod 7-এ 2-এর order ord7(2) কত?

  • 3
  • 6
  • 2
  • 7

12!-কে 13 দিয়ে ভাগ করলে ভাগশেষ কত?

  • 1
  • 0
  • 6
  • 12

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. Fermat: p মৌলিক, p ∤ a ⇒ ap−1 ≡ 1 (mod p); সব a-তে ap ≡ a; inverse = ap−2. প্রমাণ: a দিয়ে গুণ {1, …, p − 1}-এর permutation.
  2. φ(n): 1 থেকে n-এর মধ্যে সহমৌলিক সংখ্যার সংখ্যা; φ(pk) = pk − pk−1; সহমৌলিক m, n-এ φ(mn) = φ(m)φ(n); φ(n) = n ∏ (1 − 1/p).
  3. Euler: gcd(a, m) = 1 ⇒ aφ(m) ≡ 1 (mod m). ঘাত কমে mod φ(m)-এ (বা mod order-এ), mod m-এ নয়, আর শর্ত gcd = 1 ছাড়া নয়।
  4. Order: ak ≡ 1 ⇔ ordm(a) ∣ k; তাই order ∣ φ(m). Primitive root-এর order φ(m); প্রতিটি মৌলিক p-তে φ(p − 1)টি।
  5. Wilson আর Carmichael: n মৌলিক ⇔ (n − 1)! ≡ −1 (mod n), কিন্তু ধীর। Fermat-এর পরীক্ষা যৌগিক সংখ্যা প্রমাণ করে, মৌলিক নয়: 341 base 2-এ ঠকায়, 561 সব সহমৌলিক base-এ।

পরের পর্বে: পর্ব ২৫ “Primality test আর factoring — Miller–Rabin থেকে কঠিনতার ধারণা”: Carmichael সংখ্যাকেও ধরে ফেলা Miller–Rabin পরীক্ষা, Pollard-এর rho দিয়ে factoring, আর কেন বড় সংখ্যা ভাঙা কঠিন বলে বিশ্বাস করা হয়।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান