התקפת איזון זמן/זיכרון

בקריפטואנליזה, התקפת איזון זמן/זיכרון (באנגלית: Time/Memory Tradeoff) היא סוג של התקפת כוח גס גנרית הסתברותית שבה המתקיף (או הקריפטאנליסט) מנסה לקצר את זמן החישוב על חשבון שימוש בזיכרון או להפך. שני המשאבים, דרישות זיכרון מצד אחד וזמן עיבוד מהצד השני משלימים זה את זה והתוקף מנסה להגיע לאיזון אופטימלי כך שההתקפה תצליח בזמן הקצר ביותר תוך שימוש בכמות המינימלית של זיכרון. ניצול זיכרון לצורך האצת ביצועים אטרקטיבי לאור העובדה ששטח אחסון נעשה זמין וזול בקצב מהיר. השיטה יכולה לשמש להיפוך כל פונקציה חד-כיוונית ומסיבה זו ישימה במיוחד כנגד פונקציית גיבוב או צופן בלוקים וכן לניחוש מפתחות הצפנה וסיסמאות. מקרה פרטי של התקפה זו נקרא איזון זמן/זיכרון/דטה (באנגלית: Time/Memory/Data Tradeoff), שבו נוסף פרמטר דאטה המתייחס לכמות המידע שהתוקף משיג בזמן ריצה (און ליין). היא מבוססת על איזון בין שלושת הפרמטרים הללו והיא טובה במיוחד כנגד צופן זרם.

==הגדרה כללית==
התקפת איזון זמן/זיכרון היא התקפת כוח גס המורכבת משני שלבים: שלב "קדם חישוב" שיכול לקחת הרבה זמן. בשלב זה המתקיף מנסה לנצל חולשות במערכת ההצפנה ומנסה לסכם את הממצאים שלו בטבלה ענקית. ושלב "און ליין" שבו המתקיף מקבל נתונים אמיתיים שהופקו באמצעות האלגוריתם אותו הוא מתקיף עם מפתח שאינו ידוע לו, והמטרה שלו היא כמובן לגלות את המפתח מהר ככל האפשר. שלב זה מוגבל בזמן. בהתקפת איזון זמן/זיכרון ישנם חמישה פרמטרים עיקריים: 
:N מייצג את גודל מרחב החיפוש (למשל מספר המפתחות האפשריים).
:P מייצג את הזמן הדרוש לעבודת ההכנה בשלב הלא מקוון.
:M מייצג את כמות מילות הזיכרון הזמינה למתקיף (במונחים של שטח אחסון בדיסק הקשיח).
:T מייצג את הזמן הדרוש לביצוע ההתקפה המקוונת (במונחים של מספר פעולות בסיסיות).
:D מייצג את כמות המידע הנגיש למתקיף בזמן ההתקפה המקוונת (מספר בלוקים או סיביות).

במקרה של צופן בלוקים <math>N=2^n</math> הוא מרחב כל המפתחות האפשריים כאשר <math>n</math> הוא אורך המפתח בסיביות (למשל בצופן AES עם מפתח באורך 128 סיביות <math>N=2^{128}</math>). למען הפשטות ההנחה היא שגם מרחב המסרים האפשריים הוא <math>N</math>. בדרך כלל לצורך ההתקפה המתקיף רשאי לבחור בלוק מוצפן יחיד והבלוק המקורי שהוצפן. במונח "לבחור" מתכוונים שהמתקיף הצליח להשיג לכל הפחות בלוק טקסט קריא אחד לפי בחירתו ואת תוצאת ההצפנה שלו עם מפתח לא ידוע. מודל זה נקרא התקפת גלוי-נבחר. התקפת איזון זמן/זיכרון שהוצגה לראשונה על ידי מרטין הלמן נחשבת להתקפה הטובה ביותר מסוג זה נגד פונקציה אקראית, היא מאזנת בין הערכים <math>TM^2=N^2, P=N, D=1</math>, הערכים האופטימליים תלויים בעלות היחסית של המשאבים החישוביים שברשות המתקיף. למשל אם <math>T=M</math>, לפי הלמן אפשר להגיע לאיזון של <math>T=N^{2/3}</math> וכן <math>M=N^{2/3}</math> כלומר שיפור בפקטור של שליש לעומת התקפת כוח גס.

==רקע==
התקפת איזון זמן/זיכרון הועלתה לראשונה ב-1980 על ידי מרטין הלמן. 
בעיות חיפוש רבות כמו בעיית תרמיל הגב או בעיית הלוגריתם הבדיד ניתנות לפתרון מהיר יותר מכוח גס באמצעות שימוש מושכל בזמן וזיכרון. כלומר אם קיימים <math>N</math> פתרונות אפשריים לבעיה נתונה, איזון זמן זיכרון מאפשר למצוא את הפתרון הנכון בזמן של <math>T</math> פעולות חישוב עם <math>M</math> מילות זיכרון בתנאי שהמשוואה <math>TM=N</math> מתקיימת. ליתר דיוק האגף הימני של המשוואה צריך להיות <math>cN\log_2N</math> אולם אפשר להתעלם מהלוגריתם והקבוע <math>c</math>.

ניחוש מפתח הצפנה שהוא בעצם קריפטואנליזה בסיסית של כל צופן סימטרי, אינו אלא בעיית חיפוש שיש לה שני מקרי קצה. המקרה <math>T=N,M=1</math> שבו לא נעשה שימוש בזיכרון כלל אך מצריך זמן ביצוע מלא, כלומר המתקיף צריך לנסות כמעט את כל <math>N</math> המפתחות האפשריים במקרה הממוצע עד שימצא המפתח הנכון ומהצד השני <math>T=1,M=N</math> שמסתמך על טבלת איחזור ענקית, כך שהזמן הדרוש לאיחזור המפתח הנכון מתקרב ל-<math>O(1)</math> (אם לא מביאים בחשבון את זמן ההכנה). מציאת התאמה בטבלה ממויינת באמצעות חיפוש בינארי וטבלאות גיבוב היא פעולה קלה במונחי מחשוב, אך מאידך המחיר הוא שימוש מופרז בזיכרון. שני מקרי הקצה אינם מעשיים מצד אחד הזמן הדרוש גבוה מדי ומהצד השני כמות הזיכרון בלתי מעשית.

יהיו <math>t</math> ו-<math>m</math> שני פרמטרים שחשיבותם תובהר בהמשך, אם מתעלמים לרגע מזמן הביצוע של ההכנה המוקדמת, חיפוש פתרון של כל פונקציה חד-כיוונית באמצעות טכניקת איזון זמן זיכרון יכול להתבצע בסיבוכיות מקום ממוצעת של <math>M=tm</math> וזמן בסדר גודל של <math>T=t^2</math> פעולות בקירוב, בתנאי שמתקיים <math>mt^2=N</math>. אם <math>m=t=N^{1/3}</math> מתקבל <math>M=T=N^{2/3}</math> שזהו שיפור משמעותי לעומת חיפוש ממצה של כל הפתרונות האפשריים בשיטה הישירה וזאת עם זיכרון בגודל <math>tm</math>. אם סיבוכיות החיפוש נמדדת במונחים של <math>M+T</math> (זמן פלוס זיכרון) אף על פי שזיכרון וזמן אינם מושגים זהים אפשר להתעלם מפרט זה, בכללות מושג שיפור בפקטור של שליש בסיבוכיות. ההשלכה היא שחיפוש מפתח DES באורך 56 סיביות מתקצר לחיפוש בסדר גודל של 38 סיביות. יתרה מזו, בבעיות מסוימות כמו פרמוטציה פסאודו אקראית או בעיית הלוגריתם הבדיד, אפשר להשיג שיפור גדול יותר עד פקטור של חצי, קרי <math>M=T=N^{1/2}</math> על חשבון עליה קלה בסיבוכיות עבודת ההכנה.

===חיפוש ממצה===

חיפוש ממצה של מפתח ההצפנה או התקפת כוח גס ישירה נגד צופן סימטרי יכולה להתבצע לפי מודל התקפת גלוי-ידוע כך שברשות המתקיף לפחות בלוק טקסט גלוי אחד ובלוק מוצפן שמתאים לו (כלומר שהוצפן עם מפתח סודי כלשהו אותו המתקיף מעוניין לחשוף), אותו הוא השיג בדרך כלשהי אך אין לו שליטה על התוכן. ואילו התקפה שעושה שימוש בטבלת חיפוש דורשת מודל התקפת גלוי-נבחר, כלומר המתקיף שהכין את הטבלה מראש עם בלוק נתון (למשל בלוק המכיל רק אפסים), צריך שתהיה לו היכולת לבחור בזמן ריצה לפחות בלוק גלוי אחד המכיל את הנתונים שהוא מעוניין והבלוק המוצפן המתאים לפני שהוא מתחיל בהתקפה. זה אפשרי בעולם האמיתי, אפשר למשל לחשוב על מקרה שבו המתקיף יודע שהוצפן בלוק המכיל נתונים קבועים הידועים לכל. הרעיון של התקפת כוח גס ישירה פשוט, אם נתון בלוק טקסט מוצפן <math>C_0</math> שהוצפן עם המפתח <math>K</math> וההנחה היא שהמתקיף יודע בדרך כלשהי מהו הבלוק שהוצפן <math>P_0</math> והוא מעוניין לגלות את <math>K</math>, בניסוח פורמלי:
:<math>C_0=F_K(P_0)</math>
כאשר <math>F</math> היא פונקציית הצפנה כמו DES והנעלם היחיד במשוואה האמורה הוא <math>K</math>. המתקיף תחילה בונה טבלה שמכילה <math>N</math> הצפנות של <math>P_0</math> עם מפתחות הצפנה שונים כאשר <math>N</math> מתייחס למרחב כל המפתחות האפשריים של הצופן (לדוגמה ב-DES <math>N=2^{56}</math>), בכל שורה בטבלה הוא מאחסן מפתח אחר וטקסט מוצפן מתאים, ממיין את הטבלה לפי הטקסט המוצפן ואז מחפש התאמה עם <math>C_0</math>, היות שהטבלה ממוינת אפשר למצוא התאמה אם קיימת באמצעות חיפוש בינארי בזמן של <math>\log_2N</math>, אם מאיצים את החיפוש עם טבלאות גיבוב אפשר להתעלם מהלוגריתם לצורך הדיון ולהחשיב את פעולת החיפוש כקרובה ל-<math>O(1)</math>.

בטכניקת איזון זמן/זיכרון מתעלמים מפעולת ההכנה המוקדמת כי היא אינה משפיעה ישירות על סיבוכיות ההתקפה משני טעמים. ראשית, פעולת ההכנה יכולה להתבצע באופן לא מקוון בזמנו החופשי של המתקיף ושנית במקרים מסוימים פעולת ההכנה יכולה להיות שימושית לכמה התקפות ולכן אפשר להניח לצורך הדיון שהיא כבר נעשתה.


==תיאור כללי של שיטת הלמן==
בהינתן פונקציה אקראית <math>f</math> הממפה את המפתח <math>x</math> לבלוק טקסט מוצפן <math>y</math> עבור טקסט קריא קבוע כלשהו. אפשר לראות שקל לחשב את <math>f</math> אבל קשה להפוך אותה, כי חישוב הפונקציה ההופכית <math>x=f^{-1}(y)</math> היא בדיוק הבעיה הקריפטואנליטית של חילוץ מפתח ההצפנה <math>x</math> בהינתן טקסט מוצפן <math>y</math>. כדי לבצע את הפעולה ההפוכה מהר יותר מכוח גס הציע הלמן לנצל את פרדוקס יום ההולדת על ידי הוספת שלב "קדם עיבוד" שמנסה "לכסות" במידה רבה ככל האפשר את <math>N</math> הנקודות של מרחב המפתח. כלומר להגביר ככל האפשר את הסיכויים שהמפתח אותו מחפשים יפול במקרה באחת מנקודות הכיסוי. הוא הציע להשתמש במטריצה מסדר <math>m\times t </math> שהשורות בה הם "מסלולים" באורך <math>t</math> הנוצרים מהפעלה רקורסיבית של הפונקציה <math>f</math> על <math>m</math> נקודות התחלה אקראיות שונות. היות שכל נקודה ניתנת לחישוב על ידי הנקודה הקודמת לה במסלול, אפשר למעשה לאחסן בזיכרון רק את נקודת ההתחלה ונקודת הסיום של כל מסלול כזה. תוצאת שלב ההכנה היא הטבלה המכילה אוסף ערכים המייצגים נקודות התחלה ונקודות סיום של המסלולים, הממוינים לפי נקודת הסיום. בשלב ההתקפה המקוונת המתקיף מנסה לגלות אם <math>x</math> מכוסה על ידי אחת הנקודות בטבלה. האלגוריתם מחשב את <math>f</math> על <math>y</math> באופן איטרטיבי, סורק את עמודוצת הטבלה ומנסה למצוא התאמה של התוצאה שבידו עם נקודת סיום כלשהי. אם נמצאה התאמה הוא יודע שהפתרון <math>x</math> נמצא בשורה זו ולכן כל שעליו לעשות הוא לקפוץ לנקודת ההתחלה של אותה שורה ולחשב את <math>f</math> על <math>y</math> במספר הפעמים הדרוש עד שהוא מגיע ל-<math>x</math> והערך שבו ביקר צעד אחד לפניו הוא הפתרון הנכון בסבירות גבוהה.

===התמזגות===
מטריצה אחת לא יכולה לכסות את כל הנקודות כי ככל שמוסיפים שורות, לפי פרדוקס יום ההולדת כל עוד <math>t\cdot mt\le N</math> בהכרח שייוצרו התנגשויות. התנגשות פירושה שהתקבל ערך זהה בשתי נקודות בשורות שונות לא בהכרח באותה עמודה. הבעיה היא שכל התנגשות גורמת להתמזגות, אם נקודה מסוימת הופיעה שוב בשורה אחרת מנקודה זו ואילך עד סוף המסלול הנקודות בשתי השורות הללו תהיינה זהות. התמזגויות קשות להבחנה כיוון שאם ההתנגשות חלה בעמודות שונות נקודת הסיום לא תהיה זהה. מבחינה סטטיסטית התמזגויות פוגעות באופן משמעותי ברמת הכיסוי ולכן בסיכויים לנחש מפתח, זאת למרות עבודת ההכנה הזהה. החסם העליון לכיסוי מקסימלי עבור טבלה אחת הוא במקרה שהפרמטרים מקיימים <math>mt^2=N</math>. במקרה כזה הטבלה מכסה רק שטח של <math>1/t</math> מהמרחב לכן יש צורך ב-<math>t</math> טבלאות בלתי תלויות כאלו כדי לכסות את המרחב כולו. אולם הלמן הבחין בעובדה מעניינת שאם משנים מעט את הפונקציה <math>f</math> עבור כל טבלה, למשל <math>f_i(x)=h_i(f(x))</math> כאשר <math>h_i</math> היא פונקציה פשוטה של הפלט כמו סידור מחדש של סיביות, אפשר למנוע התנגשויות ולשפר את רמת הכיסוי מאוד. התכונות של הפונקציות המותאמות הן:
#כל זוג נקודות <math>f_i</math> ו-<math>f_j</math> כאשר <math>i\ne j</math> בעיקרון בלתי תלויות. גם אם תימצא נקודה זהה אין זה מעיד בהכרח על התמזגות, כלומר הנקודות שלאחריה לא תהיינה בהכרח זהות. כתוצאה מכך האיחוד של <math>t</math> המטריצות (כשכל אחת מכסה <math>mt</math> נקודות) מכסה חלק קבוע פחות או יותר של טווח הכיסוי המלא.
#הבעיה של חישוב <math>x</math> מתוך <math>y=f(x)</math> ניתנת לפתרון על ידי היפוך כל אחת מהווריאציות <math>f_i</math> של הפונקציה <math>f</math> מעל הנקודה המתאימה <math>y_i=f_i(x)=h_i(f(x))</math>.
#הערך <math>y_i=f_i(x)</math> ניתן לחישוב אפילו אם <math>x</math> לא ידוע על ידי חישוב <math>h_i</math> לערך כלשהו <math>y=f(x)</math>.

שלב ההכנה דורש רק <math>P\approx N</math> פעולות, כל מטריצה מכסה <math>mt</math> נקודות אך דורשת רק <math>m</math> מילים בזיכרון, כל פעולת חיפוש בטבלה דורשת <math>t</math> ניסיונות שכל אחד מהם דורש <math>t</math> הפעלות של פונקציה <math>f_i</math> כלשהי של אחת הטבלאות, זמן ההתקפה הכולל הוא <math>T=t^2</math>, כדי למצוא את עקומת האיזון בין <math>T</math> ל-<math>M</math> שמביאה לביצועים אופטימליים משתמשים בחסם האמור <math>mt^2=N</math> ומקבלים <math>TM^2=t^2\cdot m^2t^2=N^2</math>. בעוד שהזמן <math>T</math> יכול להיות כל ערך בטווח <math>1\le T\le N</math>, המקום <math>M</math> מוגבל ל-<math>N^{1/2}\le M\le N</math> שאם לא כן יוצא ש-<math>T>N</math> ואז ההתקפה תהיה איטית מכוח גס.

===פירוט האלגוריתם===
יהי <math>E_K(X):2^n\times 2^k\rightarrow 2^n</math> פונקציה המייצגת הצפנה של בלוק <math>n</math>-סיביות טקסט קריא <math>X</math> עם מפתח סודי <math>K</math> בגודל <math>k</math> סיביות. כחלק מההתקפה בלוק טקסט מוצפן בגודל <math>n</math> משמש בעצמו כמפתח הצפנה בגודל <math>k</math> כך שיש צורך בפונקציה כלשהי שממירה בלוק מוצפן של <math>n</math> סיביות למפתח הצפנה <math>g:2^n\rightarrow 2^k</math>. במקרה של DES המפתח קטן מהבלוק, לכן הציע הלמן למשל פונקציית כיווץ פשוטה שחותכת את התוצאה לגודל הרצוי ומתעלמת משמונה הסיביות האחרונות. במקרה ש-<math>n<k</math> – מצב אפשרי בצופן AES עם מפתח הגדול מ-128, הפונקציה יכולה להוסיף מספר סיביות קבועות (למשל אפסים) כדי להרחיב את הבלוק <math>n</math> לגודל המתאים כמפתח.

לסיכום לצורך ההתקפה מגדירים פונקציה <math>f</math> שהיא תוצאת הצפנה של הבלוק <math>P</math> לאחר המרה למפתח הצפנה עם הפונקציה <math>g</math> (הפונקציה <math>g</math> אינה הכרחית אם הבלוק המוצפן יכול לשמש ישירות כמפתח הצפנה): 
:<math>f(K)=g(E_K(P))</math>. 
חישוב <math>f(K)</math> הוא פעולה קלה כפעולת הצפנה. לעומת זאת חישוב <math>K</math> מתוך <math>f(K)</math> שקול לקריפטואנליזה של הצופן. התקפת איזון זמן/זיכרון מורכבת משני שלבים, שלב הכנה שמתבצע אוף ליין ושלב ההתקפה און ליין המתוארים להלן.

===שלב ההכנה הלא מקוון===
תחילה <math>N=2^n</math> הוא מרחב המפתחות האפשריים. התוקף בוחר מתוך המרחב <math>N</math>, <math>m</math> נקודות התחלה start point אקראיות שונות שיהיו מפתחות הצפנה, אותן מסמנים: <math>\text{SP}_1,\text{SP}_2,...,\text{SP}_m</math>. ואז עבור כל נקודת התחלה מחשב את 'שרשרת ההצפנה' כדלהלן: (א) מציב בכניסה הראשונה בשורה <math>i</math> את נקודת ההתחלה <math>X_{i,0}=\text{SP}_i</math> ואז (ב) כל כניסה הבאה אחריה מכילה את <math>X_{i,j+1}=f(X_{i,j})</math> עבור <math>1\le j\le t</math>, כלומר כל כניסה היא הצפנה של <math>P</math> עם מפתח שהוא תוצאת ההצפנה של כניסה קודמת. הטקסט המוצפן עצמו משמש כמפתח הצפנה לאחר שעבר המרה מתאימה עם הפונקציה <math>g</math>. למעשה שורה אחת היא שרשרת של <math>t</math> הצפנות חוזרות של <math>P</math> על ידי <math>f</math>, עם סדרה של מפתחות שהאחד נוצר מהשני, עד שמגיעים לנקודת הסיום <math>X_{i,t}=\text{EP}_i</math>. לסיכום הטבלה היא:

:::<math>\text{SP}_1=X_{1,0}\ \ \ \xrightarrow{f}\ \ \ X_{1,1}\ \ \ \xrightarrow{f} \ \ \ X_{1,2}\ \ \ \xrightarrow{f} \ \ \ \cdots\cdots \ \ \ \xrightarrow{f} \ \ \ X_{1,t}=\text{EP}_1</math>
:::<math>\text{SP}_2=X_{2,0}\ \ \ \xrightarrow{f} \ \ \ X_{2,1}\ \ \ \xrightarrow{f} \ \ \ X_{2,2}\ \ \ \xrightarrow{f} \ \ \ \cdots\cdots \ \ \ \xrightarrow{f} \ \ \ X_{2,t}=\text{EP}_2</math>
:::<math>\text{SP}_3=X_{3,0}\ \ \ \xrightarrow{f} \ \ \ X_{3,1}\ \ \ \xrightarrow{f} \ \ \ X_{3,2}\ \ \ \xrightarrow{f} \ \ \ \cdots\cdots \ \ \ \xrightarrow{f} \ \ \ X_{3,t}=\text{EP}_3</math>
:::::::::::<math>\vdots</math>
:::<math>\text{SP}_m=X_{m,0}\; \; \; \xrightarrow{f} \; \; \ X_{m,1}\; \; \xrightarrow{f} \; \; \ X_{m,2}\; \; \; \xrightarrow{f} \; \; \; \cdots\cdots \; \; \; \xrightarrow{f} \; \; \ X_{m,t}=\text{EP}_m</math>

כדי לצמצם דרישות זיכרון לא מאחסנים את ערכי הביניים אלא את נקודות ההתחלה והסיום <math>\text{SP}_i,\text{EP}_i</math> בלבד וממיינים אותן בסדר נומרי לפי נקודות הסיום <math>\text{EP}_i</math>.

===שלב ההתקפה המקוונת===
לצורך הפשטות (כאמור לעיל) משתמש מסוים בחר במפתח סודי <math>K</math> כלשהו, הצפין את הבלוק הקריא <math>P</math> (שידוע לתוקף, למשל הבלוק יכול להיות מחרוזת אפסים או כל טקסט קבוע ומוסכם) ובדרך מסוימת התוצאה <math>C=E_K(P)</math> נפלה לידי התוקף ועליו לגלות את <math>K</math>. התוקף מיישם את הפונקציה <math>g</math> כדי לקבל את <math>Y_1=g(C)=f(K)</math> ואז מבצע את המהלכים הבאים:
#בודק בטבלה אם <math>Y_1=\text{EP}_i</math>, עבור כל <math>i</math> מ-<math>1</math> עד <math>m</math>. במקרה שכן, התוקף יודע שהמפתח הנכון הוא הערך האחד לפני אחרון בשורה <math>i</math> כי כאמור הערך האחרון הוא תוצאה של הצפנת המקור עם מפתח אחד לפניו. היות שתוצאות הביניים לא שמורות, עליו לחשב את כל השורה מנקודת ההתחלה לפי הסדר עד הגיעו לנקודה הרצויה במקרה זה <math>X_{i,t-1}</math> וזהו בדיוק המפתח אותו הוא מחפש. כעת עליו רק לוודא שפענוח <math>C</math> אכן מוביל ל-<math>P</math> וההתקפה הסתיימה בהצלחה. ייתכן מצב שבו ל-<math>\text{EP}_i</math> יש יותר ממקור אחד ואז השוויון האחרון אינו נכון, כלומר אף על פי שקיימת התאמה עם <math>\text{EP}_i</math>, בפענוח <math>C</math> התגלה שהתוצאה אינה תואמת את <math>P</math>. זהו מצב אפשרי והוא מכונה כאן 'אזעקת שווא'. מתייחסים אליו כאילו לא הייתה התאמה. הוכח שמספר אזעקות השווא הצפוי חסום על ידי <math>mt(t+1)/2N</math>.
#אם <math>Y_1\ne \text{EP}_i</math>. כלומר אף אחת מנקודות הסיום אינה מתאימה, או שהייתה אזעקת שווא מסעיף 1, התוקף מחשב את <math>Y_2=f(Y_1)</math> וחוזר לשלב 1. בשלב זה הבדיקה תוכיח אם המפתח הוא בעמודה השנייה מימין (<math>X_{i,t-2}</math>), בסבב השלישי ייבדק אם המפתח הוא אחד מ-<math>X_{i,t-3}</math> וכן הלאה עד לבדיקת כל הערכים בטבלה, שאז במידה שלא נמצאה התאמה ההתקפה נכשלה.

יש לשים לב שהתוקף צריך לגשת לטבלה בכל פעם שמחושב <math>Y</math> חדש. אם כל <math>m\times t</math> האלמנטים שבטבלה שונים, ההסתברות להצלחה היא <math>\textstyle P(S)=\frac{m\times t}{2^k}</math>. בפועל סיכויי ההצלחה נמוכים יותר כי הם תלויים באופן שבו השרשראות מתפרסות על פני מרחב המפתח. קיימת גם אפשרות ששרשרת הצפנה שהתחילה עם מפתח אחד תתנגש ותתמזג עם שרשרת אחרת שהתחילה עם מפתח אחר (מנקודה זו ועד לנקודת הסיום כל החוליות בשתי השרשראות תהיינה זהות). ככל שהטבלה גדולה יותר כך גדלים הסיכויים להתנגשות. כל התמזגות מצמצמת למעשה את מספר האפשרויות שהטבלה מכסה. אם <math>f</math> היא פונקציה ראנדומלית, ההסתברות להצלחה חסומה ב:
:<math>P(S)\ge \frac{1}{N}\sum_{i=1}^m\sum_{j=0}^{t-1}\left(\frac{N-it}{N}\right)^{j+1}</math>
מהמשוואה עולה כי הערכים האופטימליים של <math>t</math> ו-<math>m</math> הם כאלו שמקיימים <math>mt^2=N</math> שאז הסיכויים הם בערך <math>1/0.80=1.25</math>. שזהו לא שיפור משמעותי כפי שהיינו מצפים. כדי לקבל סיכויי הצלחה גבוהים יותר משתמשים בטבלאות מרובות, כל אחת עם פונקציה <math>f</math> שונה, בכך מבטיחים פריסה טובה יותר של אלמנטים והימנעות מהתמזגויות ובכך מגבירים את הסיכויים בפקטור שהוא ביחס לכמות הטבלאות (או סך כל האלמנטים). אי אפשר למנוע התנגשות לגמרי אך גם אם ערך כלשהו מתנגש בנקודה כלשהי היות שהפונקציה שונה לא תתרחש התמזגות. בכללות עבור <math>r</math> טבלאות הסיכויים הם:
:<math>P(S)_{\text{total}}\ge 1-(1-P(S)_{\text{table}})^r</math>
כאשר <math>P(S)_{\text{table}}</math> מתייחס לסיכויים עם טבלה אחת. אם מציבים <math>m=t=N^{1/3}</math> ההסתברות לטבלה אחת היא בערך <math>P(S)=N^{1/3}</math>, לכן עם <math>N^{1/3}</math> טבלאות אפשר להשיג סיכויים של <math>N^{2/3}</math>. כמות הזיכרון תהיה במקרה זה <math>M=N^{2/3}</math> מילים וסך כל הפעולות הוא <math>T=N^{2/3}</math>. החיפוש בטבלאות יכול להתבצע באופן סדרתי או מקבילי להאצה נוספת וכמובן שאפשר להשתמש ביותר טבלאות לפי הצורך כדי להגביר סיכויים. 

==נקודות מובחנות==
חיסרון מעשי אחד בשיטת הלמן הוא מספר הקריאות בדיסק הקשיח. באופן כללי גישה לדיסק צורכת כשמונה מילישניות לעומת פעולה בתוך זיכרון המעבד שהיא בערך שתי ננושניות. בגלל ההבדל העצום במהירות הגישה מומלץ לצמצם את מספר הקריאות בדיסק ככל האפשר. רון ריבסט הציע רעיון במקום לקבוע את אורך המסלולים בכל שורה בטבלה לאורך קבוע, המסלול יכול להמשיך עד שמגיעים לנקודה כלשהי שיש לה מאפיין מיוחד כלשהו כמו ערך המכיל רצף מסוים של אפסים. נקודה כזו נקראת "נקודה מובחנת" (באנגלית Distinguished point). במהלך שלב ההכנה מתחילים מנקודות התחלה מובחנות אקראיות ומחשבים את המסלולים באותה דרך, אך עוצרים רק כאשר מגיעים לנקודה מובחנת נוספת. כך נוצרים מסלולים באורכים שונים המכילים נקודות מובחנות בלבד. אם <math>k=\log(t)</math> האורך הצפוי של כל מסלול יהיה בערך <math>t</math>. קבוצת כל נקודות הסיום בכל <math>t</math> הטבלאות בסך הכול <math>t^2m</math> נקודות מכסה כמות ניכרת של בערך <math>N/t</math> מהנקודות המובחנות האפשריות. נקודות מובחנות קלות להכנה וקלות לזיהוי.

היתרון העיקרי של גישה זו הוא שבמהלך ההתקפה יש צורך לבצע רק קריאה אחת בדיסק הקשיח עבור כל מסלול (כאשר ניתקלים לראשונה בנקודה מובחנת), מספר ההפעלות של הפונקציה <math>f_i</math> נשאר <math>t^2</math> אבל מספר הקריאות בדיסק יורד מ-<math>t^2</math> ל-<math>t</math> שזה יתרון משמעותי.

==Rainbow Table==

טבלת ריינבו היא שיטת כוח גס גנרית המבוססת על שיטת הלמן לשבירת פונקציית גיבוב, יעילה בעיקר לניחוש סיסמאות או מספרי כרטיס אשראי וכדומה המכילים מחרוזת אלפנומרית קצרה. הוצעה לראשונה על ידי Philippe Oechslin ב-2003 ומהווה שיפור ניכר של שיטת הלמן המתוארת לעיל. המגבלה העיקרית בשיטת הלמן היא שכאשר שני מסלולים מתנגשים באותה טבלה הם מתמזגים (מאותה נקודה ואילך הנקודות בשני המסלולים תהיינה זהות) מה שמגביל את רמת הכיסוי של הטבלאות ופוגע בסיכויי ההצלחה למצוא סיסמה (או מפתח הצפנה). טבלת ריינבו היא גישה אחרת המאפשרת התנגשות ללא התמזגות אפילו באותה טבלה. כזכור הלמן הציע להשתמש בטבלאות שונות שההבדל ביניהן הוא שהפונקציה <math>g</math> שמכינה את פלט הפונקציה כמפתח הצפנה לפונקציה הבאה תהיה שונה במעט מטבלה לטבלה. הרעיון שנקרא מסלול ריינבו (rainbow chain) הוא להשתמש בפונקציית הכנה <math>R_i</math> המשתנה לא רק מטבלה לטבלה אלא גם מנקודה לנקודה. אם נתונה הפונקציה החד-כיוונית <math>f</math> מתחילים מהנקודה <math>R_1(f_0(X_0))</math> ומחשבים את המסלול: <math>X_{i+1}=R_i(f_{i-1}(X_i))</math> עד שמגיעים ל-<math>R_{t},f_{t-1}(X)</math>. כל פונקציה שונה מקודמתה באופן מינורי (כמו היפוך מספר מועט של סיביות). בשיטה זו קיימת רק טבלה אחת ואורך המסלולים קבוע. אין צורך בטבלאות מרובות כפי שהציע הלמן וכן אין צורך בנקודות מובחנות כפי שהציע ריבסט. היות שהפונקציות משתנות בתדירות גבוהה, כדי שתהיה התמזגות ההתנגשות חייבת להופיע בדיוק באותה פוזיציה (עמודה). עבור טבלה עם מסלולים באורך <math>t</math> הסיכויים שיופיע ערך זהה בשתי שורות באותה עמודה הם <math>1/t</math>. ההסתברות להצלחה בהינתן טבלה בגודל <math>m\times t</math> חסומה על ידי:
:<math>P_{table}=1-\prod_{i-1}^t \left(1-\frac{m_i}{N}\right)</math>.
כאשר <math>m_1=m</math> ו-<math>m_{n+1}=N\left(1-e^{-\frac{m_n}{N}}\right)</math>.

בדומה לטבלאות של הלמן כדי לחפש מפתח, תחילה מחשבים את <math>R_{n-1}</math> על טקסט המוצפן ומחפשים נקודת סיום תואמת לפלט שהתקבל, אם נמצאה התאמה אפשר לשחזר את המסלול מנקודת ההתחלה של אותה שורה. אם לא נמצאה התאמה, מפעילים את הפונקציות <math>R_{n-2},f_{n-1}</math> על הפלט ומנסים לראות אם המפתח נמצא בעמודה לפני האחרונה, אם לא נמצאה התאמה ממשיכים עם <math>R_{n-3},f_{n-2},f_{n-1}</math> וכן הלאה. סך כל הפעולות הן <math>\textstyle \frac{t(t-1)}{2}</math>. זהו שיפור בפקטור של חצי לעומת הטבלאות של הלמן שבהן נדרשים <math>t^2</math> הפעלות של הפונקציה <math>f</math> כדי לחפש ב-<math>t</math> טבלאות בגודל <math>m\times t</math>.

בהשוואה לטבלאות של הלמן, עם טבלת ריינבו בגודל <math>mt\times t</math>, סיכויי ההצלחה בשניהם שווים. בשני המקרים הטבלאות מכסות <math>mt^2</math> מפתחות עם <math>t</math> פונקציות הכנה שונות. בשניהם עלולה להיווצר התמזגות אם נמצאה התנגשות באותה טבלה או באותה עמודה במקרה של ריינבו, אך הדבר אינו משפיע על התנגשויות בנקודות אחרות. מעבר לעובדה שהושג שיפור בחצי בסיכויי ההצלחה, לטבלת ריינבו מספר יתרונות:
*מספר הטבלאות מצטמצם בפקטור של <math>t</math>. 
*התמזגות של מסלול ריינבו גורמת לכך שנקודת הסיום תהיה זהה ולכן ניתן להבחין בכך. בדרך זו אפשר לייצר טבלאות נטולות התמזגויות (אך לא נטולות התנגשויות).
*טבלת ריינבו נטולת לולאות. לולאה היא מצב שבו הפונקציה <math>f</math> מייצרת מסלול קצר מ-<math>t</math> שחוזר על עצמו באופן מעגלי. אפשר לאתר לולאות גם בשיטת הלמן אך הדבר דורש פעולות נוספות. 
*שיטת הנקודות המובחנות של ריבסט יוצרת בעיה בגלל האורך המשתנה של המסלולים. לעובדה זו חשיבות רבה, כי זה עוזר לצמצם את מספר אזעקות השווא כזכור אילו מקרים בהם אף על פי שפלט הפונקציה תואם המפתח שונה.

בניסוי מעשי הראו מפתחי האלגוריתם איך הצליחו לנחש סיסמאות מגובבות של מערכת ההפעלה חלונות, כחלק ממערכת שנקראה LanManager. במערכת זו שעדיין נתמכת בשל תאימות לאחור, השיטה הייתה לחתוך סיסמה באורך מקסימלי של 14 אותיות לשתי מחרוזות באורך 7 בתים כל אחת, אחרי המרת האותיות לאותיות רישיות. כל מחרוזת שימשה כמפתח הצפנה לצופן DES. עם מפתחות אילו מצפינים פעמיים מחרוזת טקסט קבועה (שאינה סודית) ומתקבלים שני פלטים באורך 8 בתים כל אחד, אותם משרשרים יחד למחרוזת אחת באורך 16 בתים המשמשת כגיבוב של הסיסמה.

בגלל התכנון הגרוע, אפשר לתקוף את המערכת בשיטת הפרד ומשול, מנסים לנחש כל חצי של מחרוזת הגיבוב בנפרד. היות שהסיסמה היא לכל היותר 14 אותיות או ספרות למעשה סיבוכיות ההתקפה היא רק <math>2^{37}</math> פעולות גיבוב של 8 בתים לעומת <math>2^{83}</math> של 16 בתים. לצורך הדגמה הם השתמשו בטבלת ריינבו אחת בגודל <math>t=4666, m=38223872</math>. כמו כן השוו ביצועים לעומת 4666 טבלאות הלמן בגודל <math>4666\times 8192</math>. עם טבלאות אילו הם ניסו לנחש 500 סיסמאות אקראיות על מחשב שולחני מסוג פנטיום 4 1.5GHz עם זיכרון בגודל 500MB. רמת הכיסוי הגיעה ל-75.8% בטבלאות הלמן ו-78.8% בטבלת ריינבו והביצועים שהתקבלו הראו שטבלת ריינבו הייתה מהירה פי שבעה מטבלאות הלמן באותו גודל. עם שטח אחסון שאינו עולה על 1.4GB אפשר היה לפצח 99.9 אחוז מכל הגיבובים של סיסמאות אלפנומריות בטווח <math>2^{37}</math> בזמן של 13.6 שניות. תוצאה זו היא המהירה ביותר בהשוואה לשיטות אחרות.

הדרך הטובה ביותר לסכל התקפה כזו היא להוסיף גיוון לתהליך גיבוב הסיסמאות. השיטה המומלצת כיום היא פונקציית גזירת מפתח קריפטוגרפית שמשלבת salt (מלח) שהיא מחרוזת אקראית חד-פעמית שאינה סודית. גישה אחרת היא להגביר את כמות העבודה הדרושה בהכנת סיסמה אחת, למשל להפעיל את פונקציית הגיבוב אלף פעמים במקום פעם אחת עבור כל סיסמה. ההאטה בזמן עבור משתמש בודד אינה מורגשת, אך היא מאטה מאוד את הזמן הכולל הדרוש לשלב ההכנה המקודם של התקפת איזון/זמן זיכרון והופכת אותה ללא כדאית.

==התקפת איזון זמן/זיכרון/דטה==
בשל ההתנהגות השונה של צופן זרם לעומת צופן בלוקים, התקפת איזון זמן/זיכרון נגד צופן זרם שונה בהתאם. היא נקראת התקפת איזון זמן/זיכרון/דטה (time/memory/data tradeoff), כי נוסף אלמנט שלא קיים בהתקפה הבסיסית המתייחס לכמות המידע המושג און ליין הדרוש לצורך ההתקפה. בצופן זרם, המרחב <math>N</math> מייצג את מספר המצבים הפנימיים של המחולל שיכול להיות שונה ממרחב המפתחות. "מצב פנימי" של המחולל הפסאודו אקראי המובנה בצופן זרם הוא בעצם תכולת הזיכרון הפנימי ברגע נתון בזמן הפעלת הצופן. כזכור צופן זרם הוא סוג של מכונת מצבים שמכילה זיכרון. הנתונים שהמתקיף מקבל בזמן ההתקפה הם <math>D</math> הסיביות הראשונות של פלט המחולל שהן בעצם תחילתו של זרם המפתח איתו הוצפן הטקסט הקריא. ההנחה היא שהמתקיף הצליח להשיג אותן למשל על ידי XOR עם קטע טקסט קריא ידוע כמו כותר (במקרה זה אין הבדל בין מודל התקפת גלוי-ידוע לבין גלוי-נבחר). מטרת המתקיף או הקריפטואנליסט היא לגלות לפחות אחד מהמצבים הפנימיים של המחולל. משום שברגע שנמצא מצב פנימי אחד, ניתן לשחזר את כל הסיביות שהופקו מנקודת זמן זו ואילך על ידי הפעלת המחולל קדימה במספר הפעימות הדרוש עד לפענוח כל הטקסט המוצפן. כמובן שהמתקיף יכול להפעיל את המחולל לאחור ובכך להגיע למצב הפנימי הראשון או במילים אחרות לגלות את מפתח ההצפנה, אבל בצופן זרם פעולה זו לא נחוצה כלל כי בידי המתקיף מספיק מידע לפענח את כל הטקסט המוצפן מנקודה זו.

כדי להבין את ההבדל בין צופן זרם לצופן בלוקים בהקשר זה. אפשר לראות שבצופן בלוקים קיים בידי המתקיף בלוק אחד שאיתו הוא מבצע את ההתקפה, כלומר ישנם שני קלטים (מפתח ובלוק קריא) ופלט אחד (בלוק מוצפן). לא ניתן להפיק תועלת ממספר מרובה של בלוקים ידועים כי בלוקים שונים מצריכים טבלאות שונות. לעומת זאת בצופן זרם קיים רק קלט אחד (מצב פנימי) ופלט אחד (קטע מזרם המחולל), כאשר מנסים להפוך את הפונקציה במקרה זה אפשר לעשות שימוש באותן טבלאות כדי להפוך מספר פלטים שונים. למעשה בצופן בלוקים לא ברור איך אפשר בשיטת הלמן לשפר את ההתקפה אם בידי המתקיף יותר מבלוק אחד, לעומת זאת בצופן זרם מספר רב של סיביות פלט יכול לשפר את הסיכויים משמעותית.

התקפת איזון זמן זיכרון על צופן זרם תוארה לראשונה על ידי Steve Babbage ו-Jovan Dj. Golić. בהתקפה זו ממפים את <math>N</math> המצבים הפנימיים האפשריים ל-<math>\log(N)</math> הסיביות הראשונות שנוצרו על ידי המחולל. במילים אחרות המיפוי <math>f(x)=y</math> מהמצב הפנימי <math>x</math> לפלט המחולל <math>y</math> נחשב כפונקציה אקראית חד-כיוונית מעל <math>N</math> נקודות שקל לחשב בכיוון אחד אך קשה להפוך. אם המתקיף מצליח להפוך את הפונקציה עבור מצב פנימי אחד כלומר למצוא את מצב פנימי כלשהו לפי פלט המחולל הרי שהוא הצליח לשבור את הצופן. שלב ההכנה המקודמת של ההתקפה מתחיל ב-<math>M</math> מצבים פנימיים אקראיים כלשהם וחישוב פלט המחולל לפי מצבים אילו עד טווח מסוים, אחסונם בטבלה ענקית לפי סדר עולה של הפלט. שורות הטבלה מכילות <math>(x_i,y_i)</math> כאשר <math>x_i</math> הוא מצב פנימי כלשהו ו-<math>y_i</math> הוא פלט המחולל. בשלב ההתקפה המקוונת ניתנים למתקיף <math>D+\log(N)-1</math> סיביות מהם המתקיף מכין את כל החלונות (או רצפים) האפשריים <math>y_1,y_2,...,y_D</math> של <math>\log(N)</math> סיביות עוקבות (עם חפיפות). היות שהטבלה ממויינת אפשר למצוא בזמן לוגריתמי שורה בטבלה המכילה מצב פנימי ופלט שמתאימים לרצף הקיים <math>D</math> אם קיימת. בשל פרדוקס יום ההולדת אפשר להעריך את האיזון בין זמן וזיכרון ולהגיע לסיבוכיות אופטימלית. כיוון שידוע שהתנגשות (התאמה) בין שתי תת-קבוצות מתוך <math>N</math> נקודות תקרה בהסתברות גבוהה אם המכפלה שלהן גבוהה מ-<math>N</math>. אם מתעלמים מהלוגריתם מתקבל <math>DM=N</math> כאשר זמן ההכנה הוא <math>P=M</math> וזמן ההתקפה הוא <math>T=D</math>. אפשר לצמצם את <math>T</math> מ-<math>D</math> ל-1 ולהכליל את האיזון ל-<math>TM=N</math> כמו האיזון של הלמן לתמורה אקראית בניגוד לאיזון <math>TM^2=N^2</math> לפונקציה אקראית (לכן כאשר <math>T=M</math> מתקבל <math>T=M=N^{1/2}</math> שזה פקטור של חצי במקום שליש). אף על פי שבאמת ההשוואה אינה מדויקת בגלל שצופן זרם מתנהג אחרת.

אלכס ביריוקוב ועדי שמיר הרחיבו ושיפרו את ההתקפה בסגנון איזון זמן/זיכרון/דאטה באופן כזה שניצול <math>D</math> משפר את סיבוכיות ההתקפה על ידי שילוב שני הסוגים המתוארים. כלומר <math>P=N/D</math> וכן <math>TM^2D^2=N^2</math> עבור כל<math> D^2\le T\le N</math>. עם זה אפשר להשיג איזון של זמן עיבוד מוקדם <math>P=N^{2/3}</math> וכן זמן התקפה <math>T=N^{2/3}</math> וזיכרון <math>M=N^{1/3}</math> עם דטה זמינה און ליין בסדר גודל <math>D=N^{1/3}</math>. למשל עבור <math>N=2^{100}</math> הפרמטרים <math>P=T=2^{66}</math> וכן <math>M=D=2^{33}</math> הם כמעט פרקטיים.

==ראו גם==
* כוח גס
* התקפת ניפגש באמצע
* קריפטואנליזה

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

קטגוריה:קריפטוגרפיה
קטגוריה:תקיפות קריפטוגרפיות