Simon & Speck

בקריפטוגרפיה, **Simon** ו-**Speck** הן משפחות של צופן בלוקים קלי-משקל במבנה פייסטל בסגנון ARX, שפותחו ופורסמו ביוני 2013 על ידי הסוכנות לביטחון לאומי של ארצות הברית במטרה להכשירם כתקן הצפנה על ידי ארגוני התקינה הבינלאומיים. היעד של הצפנים הללו הוא למלא את הצורך בצופן קל משקל, גמיש ונוח לניתוח, המציע תפוקה וביצועים מצוינים, בעיקר לאינטרנט של הדברים - חומרה מוגבלת משאבים וצריכת אנרגיה נמוכה מאוד. Simon מכוון בעיקר לביצועים אופטימליים בחומרה ואילו Speck מכוון לביצועים אופטימליים בתוכנה.

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

תחום חדש יחסית הנקרא צופן בלוקים קל משקל אמור לתת מענה לבעיה זו. קיים כיום היצע רחב וארגוני התקינה שוקדים על הכנסת צפנים כאלה לתקנים הבינלאומיים, עמם נמנים PRESENT, KATAN, KLEIN ו-Picolo. הצפנים Simon ו-Speck אמורים להשתלב בין הצפנים קלי המשקל תוך שהם מפגינים ביטחון הכרחי כנדרש, גמישות וביצועים טובים ביותר ונפח הקטן ביותר האפשרי לעומת הצפנים המתחרים. צופן בלוקים הוא פרימיטיב קריפטוגרפי ורסטילי ולו שימושים רבים כחלק מפרוטוקולים ומערכות הצפנה ולכן חשיבותו רבה. היות שהתחום צעיר, לא קיימת הגדרה ברורה למושג "קל משקל". באופן כללי מתייחסים לשני נושאים, מימוש מינימלי בחומרה במונחים של תואמי שערים לוגיים (GE) או מימוש בתוכנה בכמות זיכרון SRAM או הבזק מינימליים. ניצול שטח קטן בחומרה פירושו פונקציית סבב פנימית פשוטה יותר גם אם המחיר הוא עלייה במספר הסבבים. בחומרה זעירה מסוג זה שלעיתים פועלת ללא מקור אנרגיה עצמאי, אין חשיבות רבה לתפוקה אלא מושם דגש יותר על צריכת אנרגיה נמוכה. למרות שלא הוגדר בתקן, המוסכמה היא תפוקה של 12 קילוביט לשנייה בתדר של 100KHz. כדי שיהיה שמיש, צופן בלוקים קל משקל צריך להיות גמיש מספיק להתאמה למגוון פלטפורמות ולצורכי ביטחון שונים. לדוגמה אם החומרה פחות מוגבלת רצוי שהצופן יוכל לנצל זאת לשיפור התפוקה על חשבון תוספת שערים.

לאור האמור, קיימים מספר היבטים שיש להתחשב בהם כמו: סריאליות, מקביליות ותאימות. סריאליות משפיעה על היכולת למזער את שטח החומרה שהצופן מאכלס למשל אם הצופן עושה שימוש בתיבות החלפה קבועות קשה להתעלם מהשטח שהן תופסות לכן רצוי להימנע מכך. מסיבה זו למבנה ARX יתרון כי הוא אינו עושה שימוש בתיבות החלפה כלל, האי-ליניאריות שלו מושגת משילוב פעולות אריתמטיות בשדות אלגבריים שונים (חיבור מודולרי ו-XOR). מקביליות משפיעה על התפוקה של הצופן ותאימות מתייחסת ליכולת להתאים את האלגוריתם לשימוש ספציפי. לדוגמה בלוק בגודל 64 סיביות ומפתח באורך 128 סיביות בדרך כלל טיפוסיים לתוכנה בעוד שבחומרה לפעמים מעדיפים משיקולי יעילות בלוק באורך 48 סיביות ומפתח באורך 96 סיביות (כאשר מודל הביטחון מאפשר זאת). מסיבה זו Simon ו-Speck עוצבו באופן שיוכלו להשתלב במגוון תצורות (ראו טבלה).

## Simon
300px|ממוזער|שמאל|תיאור מבנה פייסטל של הפונקציה הפנימית בצופן Simon
צופן Simon הוא רשת פייסטל מאוזנת הפועלת על מילים באורך n סיביות ולכן הבלוק באורך 2n סיביות. הצופן מקבל בלוק קריא באורך 2n סיביות ומחזיר בלוק מוצפן באורך 2n סיביות. למען הנוחות הוא מסומן בקיצור SIMON2n כאשר n\in\{16,24,32,48,64\}. אם m\in\{2,3,4\} אז צופן SIMON2n עם מפתח באורך mn מסומן בקיצור SIMON2n/mn. לדוגמה SIMON64/128 מתייחס לגרסה הפועלת על מילים באורך 32 סיביות, בלוק באורך 64 סיביות ומפתח באורך 128 סיביות. הצפנה ופענוח ב-SIMON2n עושה שימוש בשלוש פעולות בסיסיות בלבד בסגנון ARX הידוע בחוסנו וקיים בשימוש צפנים רבים ביניהם Salsa20 והם: XOR, AND והזזה מעגלית S^j כאשר j מציין את מספר הפוזיציות שיש להזיז (אם j שלילי ההזזה היא לימין).

### פונקציית הסבב
עבור מפתח k\in\text{GF}(2)^n (מחרוזת אקראית באורך n סיביות) פונקציית הסבב תלויית המפתח מתבצעת בשני שלבים. מיפוי פייסטל R_k:\text{GF}(2)^n\times\text{GF}(2)^n\rightarrow\text{GF}(2)^n\times\text{GF}(2)^n המוגדר על ידי
:R_k(x,y)=(y\oplus f(x)\oplus k, x)
והפונקציה f(x)=(S^1x\ \ \& \ \ S^8x)\oplus S^2x כאשר k הוא מפתח הסבב.

הביטוי S^ix פירושו הזזה מעגלית של x לשמאל i סיביות והסימן & מייצג את האופרטור AND. הפונקציה ההופכית של פונקציית הסבב הנחוצה לצורך הפענוח היא R_k^{-1}(x,y)=(y,x\oplus f(y)\oplus k). לעיתים קרובות משקולי יעילות מיישמים את הצפנים הללו בתצורה שבה יש צורך רק בפונקציית ההצפנה שהיא טובה גם להצפנה וגם לפענוח (ראו מצב מונה לדוגמה).

תהליך הכנת המפתח מקבל את המפתח שסופק על ידי המשתמש ומייצר ממנו סדרה של T מילים: k_0,k_1,...,k_{T-1}. כאשר T הוא מספר הסבבים. ההצפנה היא בעצם הרכבה של הפונקציות R_{k_{T-1}}\circ\cdots\circ R_{k_1}\circ R_{k_0} (מימין לשמאל).

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

### הכנת המפתח
תהליך הכנת המפתח של Simon כולל שימוש בסדרה של קבועי סבב באורך סיבית אחת. תוספת זו הוכנסה כדי להרוס את הסימטריות של ההזזה המעגלית וכן כדי לסכל התקפת גלישה. למעשה וריאציות של Simon מופרדות באופן קריפטוגרפי על ידי חמש סדרות שונות של קבועים: z_0,z_1,z_2,z_3,z_4. כל אחת מהן היא פונקציה של אחת משלוש הסדרות המחזוריות הקבועות u,v,w עם מחזוריות באורך 31 סיביות שאותן מחשבים לפי מטריצות קבועות המובאות להלן. את חמש הסדרות של הקבועים מחשבים כדלהלן: שתי הראשונות הן למעשה z_0=u וכן z_1=v. שלוש הנותרות z_2,z_3 ו-z_4 הן בעלי מחזוריות באורך 62 סיביות ואותן מחשבים על ידי XOR של הסדרה המחזורית t=t_0t_1t_2,... במחזוריות 2 (שהיא המחרוזת "01010101...") עם הסדרות u,v ו-w בהתאמה. המטריצות להכנת u,v ו-w הן שלוש מטריצות קבועות מסדר 5\times 5 מעל GF(2):
:U=\begin{bmatrix}
0 & 1 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 & 0 \\
1 & 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 0 & 1 \\
1 & 0 & 0 & 0 & 1
\end{bmatrix},V=\begin{bmatrix}
0 & 1 & 1 & 0 & 0 \\
0 & 0 & 1 & 0 & 0 \\
1 & 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 0 & 1 \\
1 & 0 & 0 & 0 & 0
\end{bmatrix}, W =\begin{bmatrix}
0 & 1 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 & 0 \\
1 & 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 0 & 1 \\
1 & 0 & 0 & 0 & 0
\end{bmatrix}
הסיבית ה-i בכל רצף מחושבת על ידי אתחול אוגר זיזה ממושב באורך חמש סיביות בערכים 00001, ואז מפעילים את האוגר i פעמים עם המטריצה המתאימה, וחילוץ הסיבית המשמעותית ביותר. למשל u_i=(0,0,0,0,1)U^i(0,0,0,0,1)^t.

יהי c=2^n-4 שהוא מחרוזת של n-2 אחדים המסתיימת בשני אפסים ("111...11100"). אז עם מילות המפתח הסודי של המשתמש k_{m-1},k_{m-2},...,k_1,k_0 ומחרוזת הקבועים z_j, מחשבים תת-מפתחות נוספים עבור כל הסבבים של הצופן:
:k_{i+m}=\begin{cases}
c \oplus (z_j)_i \oplus k_i \oplus (I \oplus S^{-1})S^{-3}k_{i+1}, & \mbox{if }m=2 \\
c \oplus (z_j)_i \oplus k_i \oplus (I \oplus S^{-1})S^{-3}k_{i+2}, & \mbox{if }m=3 \\
c \oplus (z_j)_i \oplus k_i \oplus (I \oplus S^{-1})(S^{-3}k_{i+3} \oplus k_{i+1}), & \mbox{if }m=4
\end{cases}

עבור 0\le i. שימו לב שהמילים k_0 עד k_{m-1} משמשים ל-m הסבבים הראשונים של הצופן, הם נטענים כמו שהם לאוגר הזיזה כאשר k_0 מצד ימין ו-k_{m-1} מצד שמאל (הצד העליון או הכי משמעותי של הערך). הטבלה הבאה כוללת את כל הקבועים תלויי הגרסה של Simon.

### פסאודו-קוד
הקלט הוא בלוק הטקסט הגלוי כשהוא מחולק לשני חצאים (x,y) והמפתח הסודי באורך m מילים המסומנות ב-k[0] עד k[m-1].

הסמל \oplus מייצג פעולת XOR, הסימן \neg מייצג את אופרטור השלילה, הביטוי S^{-3}k[i-1] פירושו שהערך המצוי בכניסה k[i-1] מסובב בהזזה מעגלית לימין 3 סיביות. שימו לב שהלולאה הראשונה היא הכנת המפתח והלולאה השנייה היא ההצפנה.

## Speck
300px|ממוזער|שמאל|תיאור מבנה פייסטל של הפונקציה הפנימית בצופן Speck
לצופן Speck יש עשר גרסאות שכולן עוצבו כדי להשיג ביצועים אופטימליים במיוחד בתוכנה. בדומה לצופן הקודם את הגרסאות השונות נהוג לסמן ב-SPECK2n/mn, כמו SPECK96/144 כשהכוונה היא לבלוק באורך 96 סיביות ומפתח באורך 144 סיביות. בצופן זה נוספה פעולה בסיסית של חיבור מלא מודולו 2^n. הצמצום המודולרי מתבצע באופן עקיף כי כשהתוצאה נחתכת בגבולות המילה הדבר דומה למודולו 2^n כך שאין צורך בחילוק. הפונקציה הפנימית היא:
:R_k(x,y)=((S^{-\alpha}x+y)\oplus k, S^{\beta}y\oplus (S^{-\alpha}x+y)\oplus k).
כאשר \alpha=7,\beta=2 אם n=16 (בלוק באורך 32) אחרת \alpha=8,\beta=3. קיים דמיון קל בין פונקציית הסבב של Speck לפונקציית הסבב של צופן Threefish. הפונקציה ההופכית של פונקציית הסבב הנחוצה בפענוח משתמשת בחיסור מודולו 2^n במקום חיבור והיא נראית כך:
:R_k^{-1}(x,y)=(S^{\alpha}((x\oplus k)-S^{-\beta}(x\oplus y)),S^{-\beta}(x\oplus y)).
הטבלה הבאה מציגה את כל הפרמטרים של גרסאות צופן Spec בהתאמה:

תהליך הרחבת המפתח מקבל את המפתח הסודי של המשתמש ומפיק ממנו T מפתחות k_0,...,k_{T-1} כאשר T הוא מספר הסבבים. ההצפנה היא הרכבה של הפונקציות R_{k_{T-1}}\circ\cdots\circ R_{k_1},R_{k_0} (מימין לשמאל). במילים אחרות זהו מבנה המתקבל משילוב שתי העתקות דמויות רשת פייסטל ביחס לשני סוגי פעולות חיבור, האחת: (x,y)\mapsto (y,(S^{-\alpha}x+y)\oplus k) והשנייה (x,y)\mapsto(y,S^{\beta}x\oplus y).

### הכנת מפתח
תהליך הכנת המפתח של Speck מנצל את פונקציית הסבב כדי להכין את המפתחות k_i. אם K הוא המפתח אפשר לכתוב אותו בצורה K=(\ell_{m-2},...,\ell_0,k_0), כאשר \ell_i,k_0\in\text{GF}(2)^n עם ערך של m\in\{2,3,4\}. הסדרות k_i ו-\ell_i מוגדרות כך:
:\ell_{i+m-1}=(k_i+S^{-\alpha}\ell_i)\oplus i, וכן
:k_{i+1}=S^{\beta}k_i\oplus\ell_{i+m-1}. המילה k_i היא מפתח הסבב ה-i עבור 0\le i.

### פסאודו-קוד
הקלט הוא בלוק הטקסט הגלוי כשהוא מחולק לשני חצאים (x,y) והמפתח הסודי באורך m מילים המסומנות ב-\ell[m-2],\cdots,\ell[0],k[0].

## ביטחון
היות שהצפנים Simon ו-Speck חדשים קיימת מעט קריפטואנליזה שלהם. השאיפה היא שהביטחון שהם מציעים קרוב ככל האפשר לאורך המפתח בסיביות. אמנם הם עברו קריפטואנליזה על ידי ה-NSA אך לא זכו לביקורת ציבורית מספקת. בשל ההיסטוריה השלילית של ה-NSA קיים חשש ניכר בעולם מפני חולשות נסתרות שאולי קיימות בהם, ה-NSA נאלץ לחזור בו מספר פעמים מההצעה לתקן לאחר שניתקל בספקנות וחשש מצד נציגי ועדת התקן הבינלאומי ולבסוף הסכים לוותר על כל הגרסאות החלשות ולהתמקד בגרסה החזקה ביותר של הצפנים. בכל אופן יש לזכור שהם פותחו בעיקר לסביבת מחשוב מוגבלת משאבים שבה בדרך כלל נאלצים להתפשר. כמו כן צריך לזכור שכמות המידע הזמינה לקריפטואנליזה במשך כל חיי ההתקן היא מזערית. בכל מקרה הצפנים הללו פותחו תוך מתן דגש על עמידות נגד התקפת כוח גס אדפטיבית עם כמות גדולה של מידע, עם חיסרון ברור שתיתכן הרעה קלה בביטחון בפקטור קטן.

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

## סירוב ארגון התקינה הבינלאומי לתקנן את הצפנים
נציגים ממדינות רבות, בהן ישראל, בלגיה, יפן וגרמניה בארגון התקינה הבינלאומי ISO התנגדו לניסיון של ה-NSA להוסיף את הצפנים שלהם לתקן הבינלאומי בקטגוריית צופן בלוקים קל משקל לחומרה זעירה. הם הביעו דאגה שה-NSA מקדם את הצפנים שלו תוך ידיעה של חולשות נסתרות שכנראה הוכנסו בהם במכוון. ל-NSA היסטוריה עשירה של ניסיונות להחדיר לשוק האזרחי טכנולוגיות הצפנה פרי פיתוחם שידוע לפחות על חלקם שהכילו דלתות סתר וחולשות, חלקם הוחדרו במכוון וחלקם היו ידועים להם ונשמרו בסוד. לטענתם, ה-NSA לא סיפקו קריפטואנליזה, הסברים ושיקולים תאורטיים שהנחו אותם בפיתוח הצפנים ובעיקר בקביעת מספר הסבבים עבור כל וריאציה של הצפנים וכן השיקולים שהנחו אותם לבחירת המטריצות U,V ו-W בתהליך הכנת המפתח. ב-NSA הביעו תרעומת על כך שארגון התקינה בחר שלא לקבל את הצפנים שלהם שלטענתם טובים מאוד, למרות שלא הייתה כל בעיה לקבל צפנים שפותחו על ידי הרוסים או הסינים. ד"ר תומר אשור המייצג את בלגיה בוועדת התקינה הגיב: "ארגון ה-NSA התנהג בבריונות וסירב לבקשות הוועדה לקבלת הסברים וכמעט שהצליח בכך", לדעתו "לארגוני מודיעין אין מקום בתקינה אזרחית". אור דונקלמן המייצג את ישראל בארגון התקינה אמר "קיימים אנשים רבים ב-NSA שחושבים שהעבודה שלהם היא להחליש את התקן, תפקידנו הוא לחזק אותו". הצפנים היחידים הנתמכים על ידי התקן נכון ל-2018 הם CLEFIA ו-PRESENT.

ברוס שנייר התבטא בבלוג שלו כי הוא אינו מאמין שהצפנים Simon ו-Speck מכילים חולשות נסתרות או דלתות סתר כלשהן. "זה מסקרן לדעת מדוע בכלל הצפנים האלו פורסמו ולמה דווקא בעיתוי זה" הוא אמר. "זה תמיד מרתק לנתח צפנים שפותחו על ידי ה-NSA, בעיקר משך את תשומת ליבי הדמיון של חלקים של Speck ל-Threefish (ששנייר הוא אחד ממפתחיו). התרשמתי ביותר מתהליך הכנת המפתח שלהם, זה תמיד מרתק לראות צופן של ה-NSA, זה כמו להתבונן בטכנולוגיה חייזרית...".

## קוד לדוגמה
להלן קוד ייחוס של האלגוריתם בגרסה החזקה ביותר שלו Speck128/256 בשפת C++ ללא אופטימיזציות.

```cpp
typedef unsigned __int64 uint64;

#define ROR(x, r) ((x >> r) | (x << (64 - r)))
#define ROL(x, r) ((x << r) | (x >> (64 - r)))
#define R(x, y, k) (x = ROR(x, 8), x += y, x ^= k, y = ROL(y, 3), y ^= x)

void speck_encrypt(uint64 const pt[2], uint64 ct[2], uint64 const K[4])
{
	uint64 i, b = K[0], a[3];
	ct[0] = pt[0]; ct[1] = pt[1];

	for (i = 0; i < 3; i++){
		a[i] = K[i + 1];
	}

	R(ct[1], ct[0], b);
	for (i = 0; i < 33; i++) {
		R(a[i % 3], b, i);
		R(ct[1], ct[0], b);
	}
}

#define RR(x, y, k) (y ^= x, y = ROR(y, 3), x ^= k, x -= y, x = ROL(x, 8))

void speck_decrypt(uint64 const ct[2], uint64 pt[2], uint64 const K[4])
{
	uint64 i, b = K[0], a[3];
	pt[0] = ct[0]; pt[1] = ct[1];

	for (i = 0; i < 3; i++){
		a[i] = K[i + 1];
	}

	for (i = 0; i < 33; i++){
		R(a[i % 3], b, i);
	}

	for (i = 0; i < 34; i++) {
		RR(pt[1], pt[0], b);
		RR(a[((32) - i) % 3], b, (32 - i));
	}
}
```


## ראו גם
* צופן בלוקים
* AES
* Threefish

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

קטגוריה:צפני בלוקים