אלגוריתם פוליג-הלמן

שיטת פוליג הלמן
בתורת החבורות ובקריפטוגרפיה אלגוריתם פוליג-הלמן (באנגלית: Pohlig–Hellman algorithm) הוא אלגוריתם לפתרון בעיית הלוגריתם הבדיד במקרה הפרטי כאשר סדר החבורה הוא מספר חלק (שגורמיו הראשוניים קטנים). האלגוריתם הומצא ב-1978 על ידי סטיבן פוליג ומרטין הלמן. 

==בעיית הלוגריתם הבדיד==

בעיית הלוגריתם הבדיד הכללית היא: בהינתן חבורה ציקלית <math>\mathbb{G}</math> מסדר <math>q</math> ויוצר <math>g</math> ויהי <math>h\in \mathbb{G}</math> איבר כלשהו. מצא <math>x</math> המקיים <math>h=g^x</math>. הוא נקרא הלוגריתם הבדיד של <math>h</math> בבסיס <math>g</math> בקיצור <math>\log_g h</math>. אם <math>q</math> ראשוני, אלגוריתם צעד-קטן צעד-גדול פותר את הבעיה בסיבוכיות זמן של <math>\sqrt{q}</math> צעדים ובסיבוכיות מקום זהה. אלגוריתם רו של פולרד פותר את הבעיה בזמן דומה אך ללא צריכת זיכרון משמעותית.

בעיית הלוגריתם הבדיד נחשבת במקרה הכללי לבעיה קשה. האלגוריתם הטוב ביותר הידוע לפתרון הבעיה כאשר סדר החבורה הוא מספר ראשוני הוא אלגוריתם רו של פולרד המבוסס על אלגוריתם צעד-קטן צעד-גדול.

==רקע מתמטי==
אלגוריתם פוליג הלמן מנסה להאיץ את חישוב הלוגריתם הבדיד במקרה שסדר החבורה <math>q</math> אינו ראשוני וידועים גורמים לא טריוויאליים שלו. ידוע שהסדר של האיבר <math>g</math> הוא השלם <math>i</math> הקטן ביותר המקיים <math>g^i=1</math>. יהי <math>q</math> הסדר של <math>g</math> ונניח שקיים שלם <math>p</math> שהוא מחלק שלו (<math>p|q</math>) אז הסדר של <math>g^p</math> הוא <math>q/p</math>. הכללה של משפט השאריות הסיני אומרת שאם ידוע הפירוק: <math>\textstyle q=\Pi_{i=1}^k q_i</math> כאשר כל <math>q_i</math> זר יחסית לגורמים האחרים (כלומר <math>\text{gcd}(q_i,q_j)=1</math> עבור כל <math>i\ne j</math>) כאשר gcd היא מחלק משותף מקסימלי, אז קיימת התאמה או איזומורפיזם בין החבורות <math>\mathbb{Z}_{q_i}</math> למכפלה הקרטזית שלהם <math>\mathbb{Z}_{q_1}\times\mathbb{Z}_{q_2}\times\cdots\times\mathbb{Z}_{q_k}</math> וקיימת דרך יעילה לעבור בין הייצוגים השונים. 

בהינתן היוצר <math>g</math> ואיבר כלשהו נניח <math>h</math> ואנחנו מעוניינים למצוא את <math>x</math> כך שמתקיים <math>g^x=h</math>, נניח שהסדר של <math>g</math> הוא <math>q</math> וידועים לנו הגורמים שלו: <math>\textstyle q=\Pi_{i=1}^k q_i</math> (הגורמים לא חייבים להיות ראשונים כל עוד הם זרים זה לזה), אז ידוע שמתקיים:
:<math>(g^{q/q_i})^x=(g^x)^{q/q_i}=h^{q/q_i}</math> עבור כל <math>i=1,...,k</math>. 
אם <math>g_i=g^{q/q_i}</math> עבור כל <math>i</math> אז מתקבלות <math>k</math> בעיות של לוגריתם בדידי ב-<math>k</math> חבורות, כל אחת מסדר <math>q_i</math> שהסדר שלהן קטן משמעותית מ-<math>q</math>. אם נפתור את <math>k</math> המופעים הללו בעזרת כל אלגוריתם כוח גס לפתרון בעיית לוגריתם בדיד, נוכל לפתור את הבעיה בחבורה הגדולה (נובע ממשפט השאריות הסיני). כלומר הלוגריתמים הבדידיים <math>x_i</math> מ-1 עד <math>k</math> מקיימים: <math>g_i^{x_i}=h^{q/q_i}=g_i^x</math>. היות ש-<math>x</math> שקול ל-<math>x_i</math> מודולו <math>q_i</math> עבור כל <math>i</math> לפי משפט השאריות הסיני למערכת המשוואות הבאה:
{| dir="ltr"
|-
|
:<math>x\equiv x_1\text{ mod }q_1</math>
:<math>\ \ \ \ \ \ \ \ \ \ \ \ \vdots</math>
:<math>x\equiv x_k\text{ mod }q_k</math>
|}
יש פתרון יחיד <math>x</math> מודולו <math>q</math>. כך שאפשר לחשב אותו מתוך <math>x_1,...,x_k</math> עם אלגוריתם כמו אלגוריתם גאוס או אלגוריתם של גרנר (מתואר בהמשך).

==תיאור האלגוריתם==
תיאור אלגוריתם פוליג-הלמן מתוך הספר "מבוא למתמטיקה של ההצפנה". תהי <math>\mathbb{G}</math> חבורה ונניח שיש לנו אלגוריתם לפתרון בעיית הלוגריתם הבדיד ב-<math>\mathbb{G}</math> עבור כל איבר מסדר שהוא חזקה ראשונית (מתואר בהמשך). למשל אם <math>g\in\mathbb{G}</math> הוא מסדר <math>q^e</math> ונניח שיש לנו אלגוריתם שפותר את הבעיה <math>g^x=h</math> בסיבוכיות של <math>q^{e/2}</math>. אם הסדר של <math>g\in\mathbb{G}</math> הוא <math>N</math> שניתן לפירוק מהצורה <math>N=q_1^{e_1}\cdot q_2^{e_2}\cdots q_k^{e_k}</math> אז אפשר לפתור את בעיית הלוגריתם הבדיד <math>g^x=h</math> בסיבוכיות של 
:<math>O(\sum_{i=1}^k q_i^{e_i/2}+\log N)</math> צעדים.

השיטה היא כדלהלן:

#עבור <math>i=1</math> עד <math>k</math> בצעו:
##<math>g_i=g^{N/q_i^{e_i}}</math> וכן <math>h_i=h^{N/q_i^{e_i}}</math>
##היות שכל <math>g_i</math> הוא מסדר חזקה ראשונית, אפשר להשתמש באלגוריתם לפתרון בעיית הלוגריתם הבדיד עם סדר מחזקה ראשונית שמתואר להלן, כתת-שגרה שלו, כדי לפתור את הבעיה <math>g_i^y=h_i</math>.
##יהי <math>y=y_i</math> הפתרון למשוואה זו.
#פותרים את מערכת המשוואות המודולרית בעזרת משפט השאריות הסיני:
{| dir="ltr"
|-
|
::{| dir="ltr"
|-
|
:<math>\ \ \ \ \ \ \ \ \ \ \ \ x\equiv y_1\text{ (mod }q_1^{e_1})</math>,
:<math>\ \ \ \ \ \ \ \ \ \ \ \ x\equiv y_2\text{ (mod }q_2^{e_2})</math>,
:<math>\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \vdots</math>
:<math>\ \ \ \ \ \ \ \ \ \ \ \ x\equiv y_k\text{ (mod }q_k^{e_k})</math>.
|}
|}

אלגוריתם פוליג-הלמן בעצם מצמצם את בעיית הלוגריתם הבדיד של איבר מסדר כלשהו לבעיית הלוגריתם הבדיד של איבר מסדר שהוא חזקה של ראשוני. לכן בעיית הלוגריתם הבדיד בחבורה <math>\mathbb{G}</math> קלה לפתרון אם הסדר של החבורה הוא כפולה של ראשוניים קטנים. למשל במקרה של השדה <math>\mathbb{F}_p</math> אם <math>p-1</math> מתפרק לגורמים קטנים אז לא מומלץ להשתמש בשדה הזה אם רוצים חבורה שבה הבעיה נחשבת קשה. מה שאפשר לעשות זה למצוא שדה כזה כך שהראשוני <math>p</math> שווה <math>2q+1</math> כאשר <math>q</math> ראשוני וכן לבחור יוצר מסדר <math>q</math> ואז עובדים בתת-חבורה מסדר <math>q</math> של <math>\mathbb{F}_p</math> וסיבוכיות פתרון בעיית הלוגריתם הבדיד בתת-חבורה זו יהיה מסדר <math>O(\sqrt{q})</math>. בגלל שאלגוריתם תחשיב אינדקסים הוא תת-מעריכי <math>q</math> צריך להיות גדול.

יתרה מזו אפשר לצמצם את בעיית הלוגריתם הבדיד של איבר מסדר חזקה ראשונית לסדר ראשוני בסיבוכיות <math>O(e\sqrt{q})</math> (להיפטר מהחזקה). בגלל הטריק הבא: אם <math>g</math> הוא מסדר <math>q^e</math> אז <math>g^{q^{e-1}}</math> הוא מסדר <math>q</math>. אם חוזרים על פעולה זו מספר פעמים אפשר להגיע לפתרון הלוגריתם הבדיד. הרעיון הוא לכתוב את המעריך <math>x</math> בצורה:
:<math>x=x_0+x_1q+x_2q^2+\cdots x_{e-1}q^{e-1}</math> כאשר <math>0\le x_i<q</math>.
ואז לחשב רקורסיבית את <math>x_0,x_1,x_2,...</math>. היות ש-<math>g^{q^{e-1}}</math> הוא מסדר <math>q</math> מזה נובע ש:

{| dir="ltr"
|-
|
:<math>h^{q^{e-1}}=\left(g^x\right)^{q^{e-1}}</math>
:<math>\ \ \ \ \ \ \ \ =\left(g^\right)^{q^{e-1}}</math>
:<math>\ \ \ \ \ \ \ \ =g^{x_0q^{e-1}}\cdot\left(g^{q^e}\right)^{x_1+x_2q+\cdots +x_{e-1}q^{e-2}}</math>
:<math>\ \ \ \ \ \ \ \ =\left(g^{q^{e-1}}\right)^{x_0}</math>
|}

הראשון נובע מהעלאת שני האגפים של <math>g^x=h</math> בחזקת <math>q^{e-1}</math>. השני נובע מההצגה המורחבת של <math>x</math> השלישי נובע מהעובדה ש-<math>g^{q^e}=1</math>. לכן המשוואה: 
:<math>\left(g^{q^{e-1}}\right)^{x_0}=h^{q^{e-1}}</math>
הוא לוגריתם בדיד שהבסיס שלו הוא איבר מסדר <math>q</math>. ההנחה היא שאפשר לפתור בעיה זו ב-<math>\sqrt{q}</math> צעדים. אם פתרנו את המשווה הזו נוכל למצוא את <math>x_0</math> עם המאפיין:
:<math>g^{x_0q^{e-1}}=h^{q^{e-1}}</math> בחבורה <math>\mathbb{G}</math>.

בשלב הבא מבצעים חישוב דומה והפעם מעלים את שני האגפים של <math>g^x=h</math> בחזקת <math>q^{e-2}</math> ומקבלים את:
{| dir="ltr"
|-
|
:<math>h^{q^{e-2}}=\left(g^x\right)^{q^{e-2}}</math>
:<math>=\left(g^\right)^{q^{e-2}}</math>
:<math>=g^{x_0q^{e-2}}\cdot g^{x_1q^{e-1}}\cdot(g^{q^e})^{x_2+x_3q+\cdots+x_{e-1}q^{e-3}}</math>
:<math>=g^{x_0q^{e-2}}\cdot g^{x_1q^{e-1}}</math>.
|}
היות שאנחנו כבר יודעים את ערכו של <math>x_0</math>, כדי למצוא את <math>x_1</math> אנחנו צריכים לחשב את הלוגריתם הבדיד
:<math>\left(g^{q^{e-1}}\right)^{x_1}=\left(h\cdot g^{-x_0}\right)^{q^{e-2}}</math>.
עבור הנעלם <math>x_1</math>. שוב אפשר עם האלגוריתם לפתרון לוגריתם בדיד מסדר ראשוני ב-<math>\sqrt{q}</math> צעדים למצוא את <math>x_1</math> ואז קיבלנו את <math>x_0</math> ו-<math>x_1</math> המקיימים:
:<math>g^{(x_0+x_1q)q^{e-2}}=h^{q^{e-2}}</math> ב-<math>\mathbb{G}</math>.
באותה דרך אפשר למצוא את <math>x_2</math>, באופן כללי אחרי שאנחנו יודעים מהם הערכים של <math>x_0,...,x_{i-1}</math> אז אפשר לחשב את <math>x_i</math> על ידי פתרון:
:<math>(g^{q^{e-1}})^{x_i}=(h\cdot g^{-x_0-x_1q-\cdots -x_{i-1}q^{i-1}})^{q^{e-i-1}}</math> בחבורה <math>\mathbb{G}</math>. כל לוגריתם כזה ניתן לפתרון בזמן שורש <math>q</math> צעדים. לכן אחרי <math>e\sqrt{q}</math> צעדים אפשר לקבל את המעריך <math>x=x_0+x_1q+\cdots + x_{e-1}q^{e-1}</math> המקיים <math>g^x=h</math>.

===דוגמאות להמחשה===
נתונים הערכים: 
:<math>p=11251, g=23, h=9689</math>. 
:<math>N=(p-1)=q_1^{e_1}q_2^{e_2}q_3^{e_3}=2\cdot 3^2\cdot 5^4</math>
והבעיה היא לפתור את המשוואה <math>g^x=9689</math> בשדה <math>\mathbb{F}_{11251}^*</math> שהוא מסדר 11250. במקרה זה פותרים את הלוגריתם הבדיד של תת-בעיות מסדר נמוך לפי הגורמים הראשוניים של <math>N</math>. שני הגורמים הראשונים קטנים לכן הפתרון שלהם טריוויאלי. להלן דוגמה לפתרון בעיית הלוגריתם הבדיד בסדר של הגורם השלישי. אנחנו מנסים לפתור את המשוואה <math>5448^x=6909</math> בשדה <math>\mathbb{F}_{11251}^*</math>. היות שהראשוני <math>p=11251</math> נבחר בצורה כזו ש-<math>p-1</math> מתחלק ב-<math>5^4</math> ולכן <math>5448</math> הוא מסדר <math>5^4</math> בשדה <math>\mathbb{F}_{11251}^*</math>. פותרים אותו בהדרגה כדי לקבל את <math>x</math> כדלהלן:

1. הצעד הראשון הוא לפתור את המשוואה <math>(5448^{5^3})^{x_0}=6909^{5^3}</math>, שמצטמצמת למשוואה <math>11089^{x_0}=11089</math> זה קל כי <math>x_0=1</math> הוא הפתרון היחיד ובשלב זה ערכו של <math>x</math> הוא <math>x=x_0=1</math>.

2. בצעד השני מנסים לפתור את: 
:<math>\left(5448^{5^3}\right)^{x_1}=\left(6909\cdot 5448^{-x_0}\right)^{5^2}=\left(6909\cdot 5448^{-1}\right)^{5^2}</math>,
שמצטמצמת למשוואה <math>11089^{x_1}=3742</math>.
כל מה שצריך לבדוק עבור <math>x_1</math> זה ערכים בטווח 1 עד 4. כך שאפשר לפתור את זה בכוח גס די בקלות. במקרה זה הפתרון הוא <math>x_1=2</math>, לכן בשלב זה ערכו של <math>x</math> הוא <math>x=11=1+2\cdot 5</math>.

3. ממשיכים לצעד הבא ומנסים לפתור את: 
:<math>\left(5448^{5^3}\right)^{x_2}=\left(6909\cdot 5448^{-x_0-x_1\cdot 5}\right)^5=\left(6909 \cdot 5448^{-11}\right)^5</math>,
שמצטמצמת למשוואה <math>11089^{x_2}=1</math> לכן <math>x_2=0</math> והמשמעות במקרה זה היא שערכו של <math>x</math> נשאר 11 בשלב זה.

4. הצעד הבא והאחרון הוא לפתור את:
:<math>\left(5448^{5^3}\right)^{x_3}=6909\cdot 5448^{-x_0-x_1\cdot 5-x_2\cdot 5^2}=6909\cdot 5448^{-11}</math>.

5. התוצאה האחרונה היא <math>11089^{x_3}=6320</math>, שהפתרון שלה הוא <math>x_3=4</math> לכן התשובה הסופית היא:
:<math>x=511=1+2\cdot 5+4\cdot 5^3</math>.
:אפשר לראות שמתקיים <math>5448^{511}=6909</math> בשדה <math>\mathbb{F}_{11251}^*</math>.

להלן דוגמה לאלגוריתם פוליג הלמן המשתמש במשפט השאריות הסיני כדי לחבר ביחד את כל הפתרונות לפתרון השלם. בטבלה הבאה מוצגים פתרונות שלוש תת-הבעיות:
{| class="wikitable" dir="ltr"
|-
! <math>q</math> !! <math>e</math> !! <math>g^{N/q^e}</math> !! <math>h^{N/q^e}</math> !! <math>(g^{N/q^e})^x = h^{N/q^e}</math>
|- align="center"
| 2 || 1 || 11250 || 11250 || 1
|- align="center"
| 3 || 2 || 5029 || 10724 || 4
|- align="center"
| 5 || 4 || 5448 || 6909 || 511
|}

הבעיה המופיעה בשורה השלישית היא הבעיה מהדוגמה הקודמת.

בשלב זה מנצלים את משפט השאריות הסיני כדי לפתור את מערכת המשוואות המודולרית:
{| dir="ltr"
|-
| 
:<math>x\equiv 1\text{ (mod }2)</math>
:<math>x\equiv 4\text{ (mod }3^2)</math>
:<math>x\equiv 511\text{ (mod }5^4)</math>
|}

והפתרון הוא <math>23^{4261}=9689</math> מודולו <math>11251</math>.

===אלגוריתם גרנר לפתרון CRT===
אלגוריתם גרנר לפתרון מערכת משוואות מודלרית לפי משפט השאריות הסיני. 

קלט: שלם חיובי <math>m</math> שהוא כפולה של <math>t</math> שלמים חיוביים זרים זה לזה <math>m_1\cdot m_2\cdots m_t</math> וייצוג מודולרי <math>v(x)=(v_1,v_2,...,v_t)</math> (השאריות) של <math>x</math> מודולו <math>m_i</math> בהתאמה.

פלט: שלם <math>x</math> המקיים את משוואת CRT.
# עבור <math>i=2</math> עד <math>t</math> מצבעים:
##<math>C_i=1</math>
##עבור <math>j=1</math> עד <math>(i-1)</math> מבצעים:
###<math>u=m_j^{-1}\text{ mod }m_i</math>
###<math>C_i=u\cdot C_i\text{ mod }m_i</math>
#<math>u=v_1,x=u</math>
#עבור <math>i=2</math> עד <math>t</math> מחשבים את: <math>u=(v_i-x)C_i\text{ mod }m_i,x=x+u\Pi_{j=1}^{i-1}m_j</math>.
#מחזירים את <math>x</math>.

==הערות שוליים==

קטגוריה:תורת המספרים
קטגוריה:קריפטוגרפיה
קטגוריה:אלגוריתמים