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

בתורת החבורות ובקריפטוגרפיה אלגוריתם פוליג-הלמן (באנגלית: Pohlig–Hellman algorithm) הוא אלגוריתם לפתרון בעיית הלוגריתם הבדיד במקרה הפרטי כאשר סדר החבורה הוא מספר חלק (שגורמיו הראשוניים קטנים). האלגוריתם הומצא ב-1978 על ידי סטיבן פוליג ומרטין הלמן. ערך מורחב – בעיית הלוגריתם הבדיד בעיית הלוגריתם הבדיד הכללית היא: בהינתן חבורה ציקלית G {\displaystyle \mathbb {G} } מסדר q {\displaystyle q} ויוצר g {\displaystyle g} ויהי h ∈ G {\displaystyle h\in \mathbb {G} } איבר כלשהו. מצא x {\displaystyle x} המקיים h = g x {\displaystyle h=g^{x}} . הוא נקרא הלוגריתם הבדיד של h {\displaystyle h} בבסיס g {\displaystyle g} בקיצור log g ⁡ h {\displaystyle \log _{g}h} . אם q {\displaystyle q} ראשוני, אלגוריתם צעד-קטן צעד-גדול פותר את הבעיה בסיבוכיות זמן של q {\displaystyle {\sqrt {q}}} צעדים ובסיבוכיות מקום זהה. אלגוריתם רו של פולרד פותר את הבעיה בזמן דומה אך ללא צריכת זיכרון משמעותית. בעיית הלוגריתם הבדיד נחשבת במקרה הכללי לבעיה קשה. האלגוריתם הטוב ביותר הידוע לפתרון הבעיה כאשר סדר החבורה הוא מספר ראשוני הוא אלגוריתם רו של פולרד המבוסס על אלגוריתם צעד-קטן צעד-גדול. אלגוריתם פוליג הלמן מנסה להאיץ את חישוב הלוגריתם הבדיד במקרה שסדר החבורה q {\displaystyle q} אינו ראשוני וידועים גורמים לא טריוויאליים שלו. ידוע שהסדר של האיבר g {\displaystyle g} הוא השלם i {\displaystyle i} הקטן ביותר המקיים g i = 1 {\displaystyle g^{i}=1} . יהי q {\displaystyle q} הסדר של g {\displaystyle g} ונניח שקיים שלם p {\displaystyle p} שהוא מחלק שלו ( p | q {\displaystyle p|q} ) אז הסדר של g p {\displaystyle g^{p}} הוא q / p {\displaystyle q/p} . הכללה של משפט השאריות הסיני אומרת שאם ידוע הפירוק: q = Π i = 1 k q i {\displaystyle \textstyle q=\Pi _{i=1}^{k}q_{i}} כאשר כל q i {\displaystyle q_{i}} זר יחסית לגורמים האחרים (כלומר gcd ( q i , q j ) = 1 {\displaystyle {\text{gcd}}(q_{i},q_{j})=1} עבור כל i ≠ j {\displaystyle i\neq j} ) כאשר gcd היא מחלק משותף מקסימלי, אז קיימת התאמה או איזומורפיזם בין החבורות Z q i {\displaystyle \mathbb {Z} _{q_{i}}} למכפלה הקרטזית שלהם Z q 1 × Z q 2 × ⋯ × Z q k {\displaystyle \mathbb {Z} _{q_{1}}\times \mathbb {Z} _{q_{2}}\times \cdots \times \mathbb {Z} _{q_{k}}} וקיימת דרך יעילה לעבור בין הייצוגים השונים. בהינתן היוצר g {\displaystyle g} ואיבר כלשהו נניח h {\displaystyle h} ואנחנו מעוניינים למצוא את x {\displaystyle x} כך שמתקיים g x = h {\displaystyle g^{x}=h} , נניח שהסדר של g {\displaystyle g} הוא q {\displaystyle q} וידועים לנו הגורמים שלו: q = Π i = 1 k q i {\displaystyle \textstyle q=\Pi _{i=1}^{k}q_{i}} (הגורמים לא חייבים להיות ראשונים כל עוד הם זרים זה לזה), אז ידוע שמתקיים: ( g q / q i ) x = ( g x ) q / q i = h q / q i {\displaystyle (g^{q/q_{i}})^{x}=(g^{x})^{q/q_{i}}=h^{q/q_{i}}} עבור כל i = 1 , . . . , k {\displaystyle i=1,...,k} . אם g i = g q / q i {\displaystyle g_{i}=g^{q/q_{i}}} עבור כל i {\displaystyle i} אז מתקבלות k {\displaystyle k} בעיות של לוגריתם בדידי ב- k {\displaystyle k} חבורות, כל אחת מסדר q i {\displaystyle q_{i}} שהסדר שלהן קטן משמעותית מ- q {\displaystyle q} . אם נפתור את k {\displaystyle k} המופעים הללו בעזרת כל אלגוריתם כוח גס לפתרון בעיית לוגריתם בדיד, נוכל לפתור את הבעיה בחבורה הגדולה (נובע ממשפט השאריות הסיני). כלומר הלוגריתמים הבדידיים x i {\displaystyle x_{i}} מ-1 עד k {\displaystyle k} מקיימים: g i x i = h q / q i = g i x {\displaystyle g_{i}^{x_{i}}=h^{q/q_{i}}=g_{i}^{x}} . היות ש- x {\displaystyle x} שקול ל- x i {\displaystyle x_{i}} מודולו q i {\displaystyle q_{i}} עבור כל i {\displaystyle i} לפי משפט השאריות הסיני למערכת המשוואות הבאה: יש פתרון יחיד x {\displaystyle x} מודולו q {\displaystyle q} . כך שאפשר לחשב אותו מתוך x 1 , . . . , x k {\displaystyle x_{1},...,x_{k}} עם אלגוריתם כמו אלגוריתם גאוס או אלגוריתם של גרנר (מתואר בהמשך). תיאור אלגוריתם פוליג-הלמן מתוך הספר "מבוא למתמטיקה של ההצפנה". תהי G {\displaystyle \mathbb {G} } חבורה ונניח שיש לנו אלגוריתם לפתרון בעיית הלוגריתם הבדיד ב- G {\displaystyle \mathbb {G} } עבור כל איבר מסדר שהוא חזקה ראשונית (מתואר בהמשך). למשל אם g ∈ G {\displaystyle g\in \mathbb {G} } הוא מסדר q e {\displaystyle q^{e}} ונניח שיש לנו אלגוריתם שפותר את הבעיה g x = h {\displaystyle g^{x}=h} בסיבוכיות של q e / 2 {\displaystyle q^{e/2}} . אם הסדר של g ∈ G {\displaystyle g\in \mathbb {G} } הוא N {\displaystyle N} שניתן לפירוק מהצורה N = q 1 e 1 ⋅ q 2 e 2 ⋯ q k e k {\displaystyle N=q_{1}^{e_{1}}\cdot q_{2}^{e_{2}}\cdots q_{k}^{e_{k}}} אז אפשר לפתור את בעיית הלוגריתם הבדיד g x = h {\displaystyle g^{x}=h} בסיבוכיות של O ( ∑ i = 1 k q i e i / 2 + log ⁡ N ) {\displaystyle O(\sum _{i=1}^{k}q_{i}^{e_{i}/2}+\log N)} צעדים. השיטה היא כדלהלן: עבור i = 1 {\displaystyle i=1} עד k {\displaystyle k} בצעו: g i = g N / q i e i {\displaystyle g_{i}=g^{N/q_{i}^{e_{i}}}} וכן h i = h N / q i e i {\displaystyle h_{i}=h^{N/q_{i}^{e_{i}}}} היות שכל g i {\displaystyle g_{i}} הוא מסדר חזקה ראשונית, אפשר להשתמש באלגוריתם לפתרון בעיית הלוגריתם הבדיד עם סדר מחזקה ראשונית שמתואר להלן, כתת-שגרה שלו, כדי לפתור את הבעיה g i y = h i {\displaystyle g_{i}^{y}=h_{i}} . יהי y = y i {\displaystyle y=y_{i}} הפתרון למשוואה זו. פותרים את מערכת המשוואות המודולרית בעזרת משפט השאריות הסיני: אלגוריתם פוליג-הלמן בעצם מצמצם את בעיית הלוגריתם הבדיד של איבר מסדר כלשהו לבעיית הלוגריתם הבדיד של איבר מסדר שהוא חזקה של ראשוני. לכן בעיית הלוגריתם הבדיד בחבורה G {\displaystyle \mathbb {G} } קלה לפתרון אם הסדר של החבורה הוא כפולה של ראשוניים קטנים. למשל במקרה של השדה F p {\displaystyle \mathbb {F} _{p}} אם p − 1 {\displaystyle p-1} מתפרק לגורמים קטנים אז לא מומלץ להשתמש בשדה הזה אם רוצים חבורה שבה הבעיה נחשבת קשה. מה שאפשר לעשות זה למצוא שדה כזה כך שהראשוני p {\displaystyle p} שווה 2 q + 1 {\displaystyle 2q+1} כאשר q {\displaystyle q} ראשוני וכן לבחור יוצר מסדר q {\displaystyle q} ואז עובדים בתת-חבורה מסדר q {\displaystyle q} של F p {\displaystyle \mathbb {F} _{p}} וסיבוכיות פתרון בעיית הלוגריתם הבדיד בתת-חבורה זו יהיה מסדר O ( q ) {\displaystyle O({\sqrt {q}})} . בגלל שאלגוריתם תחשיב אינדקסים הוא תת-מעריכי q {\displaystyle q} צריך להיות גדול. יתרה מזו אפשר לצמצם את בעיית הלוגריתם הבדיד של איבר מסדר חזקה ראשונית לסדר ראשוני בסיבוכיות O ( e q ) {\displaystyle O(e{\sqrt {q}})} (להיפטר מהחזקה). בגלל הטריק הבא: אם g {\displaystyle g} הוא מסדר q e {\displaystyle q^{e}} אז g q e − 1 {\displaystyle g^{q^{e-1}}} הוא מסדר q {\displaystyle q} . אם חוזרים על פעולה זו מספר פעמים אפשר להגיע לפתרון הלוגריתם הבדיד. הרעיון הוא לכתוב את המעריך x {\displaystyle x} בצורה: x = x 0 + x 1 q + x 2 q 2 + ⋯ x e − 1 q e − 1 {\displaystyle x=x_{0}+x_{1}q+x_{2}q^{2}+\cdots x_{e-1}q^{e-1}} כאשר 0 ≤ x i < q {\displaystyle 0\leq x_{i}<q} . ואז לחשב רקורסיבית את x 0 , x 1 , x 2 , . . . {\displaystyle x_{0},x_{1},x_{2},...} . היות ש- g q e − 1 {\displaystyle g^{q^{e-1}}} הוא מסדר q {\displaystyle q} מזה נובע ש: הראשון נובע מהעלאת שני האגפים של g x = h {\displaystyle g^{x}=h} בחזקת q e − 1 {\displaystyle q^{e-1}} . השני נובע מההצגה המורחבת של x {\displaystyle x} השלישי נובע מהעובדה ש- g q e = 1 {\displaystyle g^{q^{e}}=1} . לכן המשוואה: ( g q e − 1 ) x 0 = h q e − 1 {\displaystyle \left(g^{q^{e-1}}\right)^{x_{0}}=h^{q^{e-1}}} הוא לוגריתם בדיד שהבסיס שלו הוא איבר מסדר q {\displaystyle q} . ההנחה היא שאפשר לפתור בעיה זו ב- q {\displaystyle {\sqrt {q}}} צעדים. אם פתרנו את המשווה הזו נוכל למצוא את x 0 {\displaystyle x_{0}} עם המאפיין: g x 0 q e − 1 = h q e − 1 {\displaystyle g^{x_{0}q^{e-1}}=h^{q^{e-1}}} בחבורה G {\displaystyle \mathbb {G} } . בשלב הבא מבצעים חישוב דומה והפעם מעלים את שני האגפים של g x = h {\displaystyle g^{x}=h} בחזקת q e − 2 {\displaystyle q^{e-2}} ומקבלים את: היות שאנחנו כבר יודעים את ערכו של x 0 {\displaystyle x_{0}} , כדי למצוא את x 1 {\displaystyle x_{1}} אנחנו צריכים לחשב את הלוגריתם הבדיד ( g q e − 1 ) x 1 = ( h ⋅ g − x 0 ) q e − 2 {\displaystyle \left(g^{q^{e-1}}\right)^{x_{1}}=\left(h\cdot g^{-x_{0}}\right)^{q^{e-2}}} . עבור הנעלם x 1 {\displaystyle x_{1}} . שוב אפשר עם האלגוריתם לפתרון לוגריתם בדיד מסדר ראשוני ב- q {\displaystyle {\sqrt {q}}} צעדים למצוא את x 1 {\displaystyle x_{1}} ואז קיבלנו את x 0 {\displaystyle x_{0}} ו- x 1 {\displaystyle x_{1}} המקיימים: g ( x 0 + x 1 q ) q e − 2 = h q e − 2 {\displaystyle g^{(x_{0}+x_{1}q)q^{e-2}}=h^{q^{e-2}}} ב- G {\displaystyle \mathbb {G} } . באותה דרך אפשר למצוא את x 2 {\displaystyle x_{2}} , באופן כללי אחרי שאנחנו יודעים מהם הערכים של x 0 , . . . , x i − 1 {\displaystyle x_{0},...,x_{i-1}} אז אפשר לחשב את x i {\displaystyle x_{i}} על ידי פתרון: ( g q e − 1 ) x i = ( h ⋅ g − x 0 − x 1 q − ⋯ − x i − 1 q i − 1 ) q e − i − 1 {\displaystyle (g^{q^{e-1}})^{x_{i}}=(h\cdot g^{-x_{0}-x_{1}q-\cdots -x_{i-1}q^{i-1}})^{q^{e-i-1}}} בחבורה G {\displaystyle \mathbb {G} } . כל לוגריתם כזה ניתן לפתרון בזמן שורש q {\displaystyle q} צעדים. לכן אחרי e q {\displaystyle e{\sqrt {q}}} צעדים אפשר לקבל את המעריך x = x 0 + x 1 q + ⋯ + x e − 1 q e − 1 {\displaystyle x=x_{0}+x_{1}q+\cdots +x_{e-1}q^{e-1}} המקיים g x = h {\displaystyle g^{x}=h} . נתונים הערכים: p = 11251 , g = 23 , h = 9689 {\displaystyle p=11251,g=23,h=9689} . N = ( p − 1 ) = q 1 e 1 q 2 e 2 q 3 e 3 = 2 ⋅ 3 2 ⋅ 5 4 {\displaystyle N=(p-1)=q_{1}^{e_{1}}q_{2}^{e_{2}}q_{3}^{e_{3}}=2\cdot 3^{2}\cdot 5^{4}} והבעיה היא לפתור את המשוואה g x = 9689 {\displaystyle g^{x}=9689} בשדה F 11251 ∗ {\displaystyle \mathbb {F} _{11251}^{*}} שהוא מסדר 11250. במקרה זה פותרים את הלוגריתם הבדיד של תת-בעיות מסדר נמוך לפי הגורמים הראשוניים של N {\displaystyle N} . שני הגורמים הראשונים קטנים לכן הפתרון שלהם טריוויאלי. להלן דוגמה לפתרון בעיית הלוגריתם הבדיד בסדר של הגורם השלישי. אנחנו מנסים לפתור את המשוואה 5448 x = 6909 {\displaystyle 5448^{x}=6909} בשדה F 11251 ∗ {\displaystyle \mathbb {F} _{11251}^{*}} . היות שהראשוני p = 11251 {\displaystyle p=11251} נבחר בצורה כזו ש- p − 1 {\displaystyle p-1} מתחלק ב- 5 4 {\displaystyle 5^{4}} ולכן 5448 {\displaystyle 5448} הוא מסדר 5 4 {\displaystyle 5^{4}} בשדה F 11251 ∗ {\displaystyle \mathbb {F} _{11251}^{*}} . פותרים אותו בהדרגה כדי לקבל את x {\displaystyle x} כדלהלן: 1. הצעד הראשון הוא לפתור את המשוואה ( 5448 5 3 ) x 0 = 6909 5 3 {\displaystyle (5448^{5^{3}})^{x_{0}}=6909^{5^{3}}} , שמצטמצמת למשוואה 11089 x 0 = 11089 {\displaystyle 11089^{x_{0}}=11089} זה קל כי x 0 = 1 {\displaystyle x_{0}=1} הוא הפתרון היחיד ובשלב זה ערכו של x {\displaystyle x} הוא x = x 0 = 1 {\displaystyle x=x_{0}=1} . 2. בצעד השני מנסים לפתור את: ( 5448 5 3 ) x 1 = ( 6909 ⋅ 5448 − x 0 ) 5 2 = ( 6909 ⋅ 5448 − 1 ) 5 2 {\displaystyle \left(5448^{5^{3}}\right)^{x_{1}}=\left(6909\cdot 5448^{-x_{0}}\right)^{5^{2}}=\left(6909\cdot 5448^{-1}\right)^{5^{2}}} , שמצטמצמת למשוואה 11089 x 1 = 3742 {\displaystyle 11089^{x_{1}}=3742} . כל מה שצריך לבדוק עבור x 1 {\displaystyle x_{1}} זה ערכים בטווח 1 עד 4. כך שאפשר לפתור את זה בכוח גס די בקלות. במקרה זה הפתרון הוא x 1 = 2 {\displaystyle x_{1}=2} , לכן בשלב זה ערכו של x {\displaystyle x} הוא x = 11 = 1 + 2 ⋅ 5 {\displaystyle x=11=1+2\cdot 5} . 3. ממשיכים לצעד הבא ומנסים לפתור את: ( 5448 5 3 ) x 2 = ( 6909 ⋅ 5448 − x 0 − x 1 ⋅ 5 ) 5 = ( 6909 ⋅ 5448 − 11 ) 5 {\displaystyle \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}} , שמצטמצמת למשוואה 11089 x 2 = 1 {\displaystyle 11089^{x_{2}}=1} לכן x 2 = 0 {\displaystyle x_{2}=0} והמשמעות במקרה זה היא שערכו של x {\displaystyle x} נשאר 11 בשלב זה. 4. הצעד הבא והאחרון הוא לפתור את: ( 5448 5 3 ) x 3 = 6909 ⋅ 5448 − x 0 − x 1 ⋅ 5 − x 2 ⋅ 5 2 = 6909 ⋅ 5448 − 11 {\displaystyle \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}} . 5. התוצאה האחרונה היא 11089 x 3 = 6320 {\displaystyle 11089^{x_{3}}=6320} , שהפתרון שלה הוא x 3 = 4 {\displaystyle x_{3}=4} לכן התשובה הסופית היא: x = 511 = 1 + 2 ⋅ 5 + 4 ⋅ 5 3 {\displaystyle x=511=1+2\cdot 5+4\cdot 5^{3}} . אפשר לראות שמתקיים 5448 511 = 6909 {\displaystyle 5448^{511}=6909} בשדה F 11251 ∗ {\displaystyle \mathbb {F} _{11251}^{*}} . להלן דוגמה לאלגוריתם פוליג הלמן המשתמש במשפט השאריות הסיני כדי לחבר ביחד את כל הפתרונות לפתרון השלם. בטבלה הבאה מוצגים פתרונות שלוש תת-הבעיות: הבעיה המופיעה בשורה השלישית היא הבעיה מהדוגמה הקודמת. בשלב זה מנצלים את משפט השאריות הסיני כדי לפתור את מערכת המשוואות המודולרית: והפתרון הוא 23 4261 = 9689 {\displaystyle 23^{4261}=9689} מודולו 11251 {\displaystyle 11251} . אלגוריתם גרנר לפתרון מערכת משוואות מודלרית לפי משפט השאריות הסיני. קלט: שלם חיובי m {\displaystyle m} שהוא כפולה של t {\displaystyle t} שלמים חיוביים זרים זה לזה m 1 ⋅ m 2 ⋯ m t {\displaystyle m_{1}\cdot m_{2}\cdots m_{t}} וייצוג מודולרי v ( x ) = ( v 1 , v 2 , . . . , v t ) {\displaystyle v(x)=(v_{1},v_{2},...,v_{t})} (השאריות) של x {\displaystyle x} מודולו m i {\displaystyle m_{i}} בהתאמה. פלט: שלם x {\displaystyle x} המקיים את משוואת CRT. עבור i = 2 {\displaystyle i=2} עד t {\displaystyle t} מצבעים: C i = 1 {\displaystyle C_{i}=1} עבור j = 1 {\displaystyle j=1} עד ( i − 1 ) {\displaystyle (i-1)} מבצעים: u = m j − 1  mod  m i {\displaystyle u=m_{j}^{-1}{\text{ mod }}m_{i}} C i = u ⋅ C i  mod  m i {\displaystyle C_{i}=u\cdot C_{i}{\text{ mod }}m_{i}} u = v 1 , x = u {\displaystyle u=v_{1},x=u} עבור i = 2 {\displaystyle i=2} עד t {\displaystyle t} מחשבים את: u = ( v i − x ) C i  mod  m i , x = x + u Π j = 1 i − 1 m j {\displaystyle u=(v_{i}-x)C_{i}{\text{ mod }}m_{i},x=x+u\Pi _{j=1}^{i-1}m_{j}} . מחזירים את x {\displaystyle x} . S. Pohlig and M. Hellman, "An improved algorithm for computing logarithms over GF(p) and its cryptographic significance (Corresp.)," Information Theory, IEEE Transactions on 24, no. 1 (1978): 106-110. An Introduction to Mathematical Cryptography Hoffstein, Jeffrey, Pipher, Jill, Silverman, J.H. Springer 2014, Chapter 2: The Pohlig-Hellman algorithm, Page 86 Handbook of Applied Cryptography Number-Theoretic Reference Problems, Paul van Oorschot, Alfred J. Menezes, Scott A. Vanstone, CRC Press 1997