סרפנט (צופן)

סרפנט (באנגלית: Serpent) הוא צופן בלוקים סימטרי שפותח ב-1998 על ידי רוס אנדרסון - קיימברידג', אלי ביהם - הטכניון ולארס קנודסן - אוניברסיטת ברגן, במטרה להוות מועמד לתקן ההצפנה המתקדם. זהו צופן בעל תכנון שמרני ושולי ביטחון הגבוהים ביותר מבין כל המועמדים האחרים שהוצעו במהלך התחרות. בסופו של דבר הגיע למקום השני וריינדל נבחר כאלגוריתם הזוכה. סרפנט משתמש בתיבות החלפה (s-box) דומות ל-DES במבנה חדש המאפשר אפקט כדור השלג מהיר, ניתן ליישום יעיל בטכניקת bitslice, קל ופשוט לניתוח, מהיר לפחות כ-DES במחשב אינטל נפוץ ובטוח יותר מ-DES משולש. מימוש ממוטב של הצופן כפי שהוצע לתקן מופץ תחת GPL לשימוש חופשי, למרות שבקוד מצוין אחרת.

==שיקולי פיתוח==
בשל גישה שמרנית, נמנעו המפתחים מלהכניס בצופן טכנולוגיות חדשות ובלתי מוכרות, בשל הכוונה לייעדו להצפנת מידע רב בעל חשיבות כמידע פיננסי, בריאותי או ממשלתי. לכן בתחילה הוחלט על שימוש בתיבות ההחלפה של DES שנחקרו לעומק לאורך שנים על ידי מיטב המומחים, אך במבנה ממוטב המתאים יותר למעבדים מודרניים. ההיגיון היה לרכוש את אמון הציבור ובעיקר להוכיח שלא הוכנסה דלת אחורית. ההצעה המקורית פורסמה בסדנה החמישית של Fast Software Encryption שהתקיימה ב-1998 בפריז (כיום בחסות IACR). לאחר מכן עבר האלגוריתם שיפורים אחדים, תיבות ההחלפה הוחלפו בתיבות אחרות שמציעות עמידות טובה יותר כנגד התקפות בעיקר דיפרנציאליות ושונתה פרוצדורת הרחבת המפתח. בשל כך סומנה הגרסה הראשונה Serpent-0, והגרסה המשודרגת שהייתה מועמדת לתקן Serpent-1. עיקר ההשראה לצופן סרפנט מקורה בטכנולוגיה bitslice - שהיא מעין חישוב מקבילי, שפותחה על ידי אלי ביהם עבור DES במטרה לאפשר הצפנה מקבילית של בלוקים כדי לשפר את מהירותו, מאז התגלתה ככלי שימושי למטרות נוספות. סרפנט משיג ביצועים טובים ביישום מעשי בשל המקביליות של טכניקת bitslice.

==תיאור האלגוריתם==
טרנספורמציית הערבוב הליניארית של סרפנט, הסימן <math>\lll</math> מייצג [[הזזה מעגלית לשמאל במספר פוזיציות לפי הערך שלימינו והסימן <math>\ll</math> מייצג הזזה לשמאל (shift left), הסימן <math>\oplus</math> מייצג XOR]] 
סרפנט (נחש במיתולוגיה) הוא צופן איטרטיבי, הכולל 32 סבבים של רשת החלפה-תמורה על ארבע מילים בגודל 32 סיביות (סך הכול 128 סיביות). כל הערכים בצופן מייצגים מערכי סיביות בסדר בתים קטן (כלומר המילה או הסיבית הנמוכה ביותר - הפחות משמעותית, מאוחסנת בכתובת הראשונה בזיכרון המערך). האלגוריתם מצפין 128 סיביות של טקסט קריא <math>P</math> ל-128 סיביות טקסט מוצפן <math>C</math> באמצעות 33 תת-מפתחות בגודל 128 סיביות כל אחד <math>K_0,...,K_{32}</math> המורחבים ממפתח הצופן המסופק על ידי המשתמש. מפתח הצופן יכול להיות 128, 192 או 256 סיביות. תקציר האלגוריתם פשוט, כדלהלן:

*פרמוטציה ראשונית (Initial Permutation) החלפה בטבלת תמורה קבועה.
*32 סבבים שבכל אחד מהם מערבבים תת-מפתח מתאים עם הקלט באמצעות XOR, את התוצאה מחליפים באמצעות תיבות ההחלפה של סרפנט (להלן) ולמעט בסבב האחרון מוסיפים טרנספורמציה ליניארית (להלן). בסבב האחרון מוחלפת הטרנספורמציה הליניארית בערבוב נוסף עם המפתח באמצעות XOR.
*פרמוטציה מסיימת (Final Permutation) החלפה הופכית שמבטלת את ההחלפה הראשונה.

לטבלאות התמורה IP ו-FP אין חשיבות קריפטוגרפית והן קיימות רק לצורך אופטימיזציה (המרה לפורמט המאפשר יישום bitslice). לצורך תיאור הצופן, ערך הביניים לאחר כל סבב נקרא הווקטור <math>B_i</math>. הקלט לסבב הראשון הוא <math>B_1</math> לשני <math>B_2</math> וכן הלאה (המציין <math>i</math> מתייחס למספר הסבב). הפעולה העיקרית המתרחשת בלב הצופן המסומנת <math>R_i</math> משתמשת בכל סבב בתיבת החלפה אחת משמונה תיבות ההחלפה כשהיא מוכפלת 32 פעמים, כל עותק מחליף ארבע סיביות אחרות של הקלט <math>B_i</math>. בגרסה הממוטבת ההחלפה מתרחשת במקביל. כך יוצא שכל אחת מהתיבות מנוצלת ארבע פעמים במהלך ההצפנה. לאחר ההחלפה מתבצעת הטרנספורמציה הליניארית. 
 ובניסוח פורמלי:
<div class="mw-content-ltr">
# <math>B_0=\mbox{IP}(P)</math>
# <math>\mbox{For }i=0\mbox{ to }30\mbox{ do:}</math>
## <math>B_{i+1}=R_i(B_i)</math>
# <math>C=\mbox{FP}(B_{32})</math>
</div>
למעט בסבב האחרון הטרנספורמציה <math>R_i(X)</math> כוללת שילוב מפתח, החלפה בטבלה והעברה בפונקציה הלניארית <math>L</math> והיא מוגדרת:
<div class="mw-content-ltr">
::<math>R_i(X)=\mbox{L}(S_{i\bmod 8}(X\oplus K_i))</math></div>
ואילו בסבב האחרון מתבצע חיבור נוסף עם חלק המפתח המתאים במקום הפונקציה הליניארית:
<div class="mw-content-ltr">
::<math>R_{31}(X)=S_7(B_{31}\oplus K_{31})\oplus K_{32}</math>.
</div>
הפונקציה <math>S</math> מייצגת את תיבות ההחלפה המתאימות באופן מחזורי לפי המציין התחתי. לפי אסטרטגיה זו בתוך 16 סבבים מתקבל ביטחון מקביל ל-DES משולש ללא פגיעה במהירות ההצפנה. לדעת המפתחים 32 סבבים מניבים שולי ביטחון גבוהים במידה נכרת אף מעבר למספרים המוצהרים.

==תיבות ההחלפה==
תיבות ההחלפה של סרפנט הן תמורה של ארבע סיביות בעלת תכונות דיפרנציאליות וליניאריות המותאמות במיוחד כנגד ההתקפות הידועות. ערכי התיבות המקוריות (בגרסה Serpent-0) חושבו בתהליך הבא; תחילה נבנתה מטריצה בגודל 32 על 16 שבה הועתקו 32 השורות מתיבות ההחלפה של DES ואז בוצעו החלפות בין כניסות בשורה <math>r</math> לפי ערכים משורה <math>r+1</math> ולפי מחרוזת קבועה המייצגת מפתח. אם התוצאה מפגינה תכונות ליניאריות ודיפרנציאליות טובות, נשמרת כתיבת החלפה של סרפנט. על תהליך זה חוזרים מספר פעמים עד שמשלימים את כל התיבות. באופן פורמלי; תחילה מכינים מערך <math>\mbox{serpent}[\cdot]</math> המכיל את ארבע הסיביות הנמוכות של כל האותיות במחרוזת "sboxesforserpent" ומערך דו־ממדי <math>\mbox{S}[\cdot][\cdot]</math> בגודל 32x16 המכיל את 32 השורות של תיבות ההחלפה של DES כאשר <math>\mbox{S}[r][\cdot]</math> מייצג שורה <math>r</math>, המהלך מתואר בפסאודו קוד הבא:
<div class="mw-content-ltr">
#<math>index=0</math>
#<math>\mbox{Repeat:}</math>
:::<math>c = index \ \bmod\ 32</math>
:::<math>\mbox{For }i = 0\mbox{ to }15\mbox{ do:}</math>
::::<math>j = \mbox{S}[(c + 1) \ \bmod\ 32][\mbox{serpent}[i]]</math>
::::<math>\mbox{SwapEntries(S}[c][i],\mbox{S}[c][j])</math>
::::<math>\mbox{If S}[c][\cdot]\mbox{ has the desired properties save it.}</math>
:::<math>index = index + 1</math>
::<math>\mbox{Until 8 S-box have been generated.}</math>
</div>
ביישום מעשי משתמשים בטבלאות ההחלפה שהוכנו מראש באופן שמאפשר יישום החלפה מקבילית. מניתוח ביטחון הצופן עולה כי שינוי בסיבית קלט אחת משפיע על שתי סיביות פלט, כך שבכל סבב מספר הסיביות שהושפעו מקסימלי ותוך שלושה סבבים כל סיביות הפלט מושפעות. תכונה זו נקראת 'אפקט מפולת'. בעת ניתוח תיבות ההחלפה, הגיעו המפתחים למסקנה שקל למצוא תיבות החלפה שישיגו תוצאות טובות יותר והוחלט לשנותם. כמו כן מספרם צומצם מ-32 ל-8, עובדה שמאפשרת ביצועים טובים יותר וצמצום הקוד.

==טרנספורמציה ליניארית==
הווקטור <math>B_i</math> מחולק תחילה לארבע מילים בגודל 32 סיביות <math>X_0,...,X_3</math> ואז מעורבב ליניארית כדלהלן:
<div class="mw-content-ltr">
#<math>X_0=X_0\lll 13</math>
#<math>X_2=X_2\lll 3</math>
#<math>X_1=X_1\oplus X_0\oplus X_2</math>
#<math>X_3=X_3\oplus X_2\oplus (X_0 \ll 3)</math>
#<math>X_1=X_1\lll 1</math>
#<math>X_3=X_3\lll 7</math>
#<math>X_0=X_0\oplus X_1\oplus X_3</math>
#<math>X_2=X_2\oplus X_3\oplus (X_1 \ll 7)</math>
#<math>X_0=X_0\lll 5</math>
#<math>X_2=X_2\lll 22</math>
</div>
התוצאה מומרת לווקטור <math>B_{i+1}</math> שהוא הקלט לסבב הבא. הסמל "<math>\lll</math>" מייצג הזזה מעגלית (Rotate left) לפי מספר פוזיציות המופיע מימין לסימן. הסמל "<math>\ll</math>" מייצג אופרטור הזזה בסיביות (Shift left). והסימן <math>\oplus</math> הוא XOR. אפשר לראות שהטרנספורמציה המתוארת משיגה ערבוב גבוה בתוך מספר קצר של סבבים.  סיבה נוספת לבחירה בטרנספורמציה זו, הפעולות המתוארות פשוטות ברמה כזו שביישום במעבד מודרני לא ייווצרו בועות בצינור עיבוד הנתונים. ביישום מעשי מקודדים את הטרנספורמציה כטבלה קבועה.

==פענוח==
פענוח משיגים על ידי שימוש בתיבות החלפה הופכיות, בטרנספורמציה ליניארית הפוכה ובסדר הפוך של מפתח ההצפנה.

==הרחבת מפתח== 
כאמור הצופן זקוק ל-132 מילים של 'חומר-מפתח' כל אחת בגודל 32 סיביות. אם מפתח הצופן קטן מ-256 סיביות, תחילה מרפדים את המפתח בסיבית '1' ולאחריה אפסים לפי הצורך עד לקבלת מחרוזת של 256 סיביות. ואז מרחיבים אותו ל-33 תת-מפתחות בגודל 128 סיביות כדלהלן: משתמשים במערך עזר של שמונה מילים בגודל 32 סיביות <math>w_{-8},...,w_{-1}</math> אותו מרחיבים לפי הנוסחה:
 
:<math>w_i=(w_{i-8}\oplus w_{i-5}\oplus w_{i-3} \oplus w_{i-1} \oplus \phi \oplus i)\lll 11</math>

כאשר <math>i=0,...,132</math>. הערך <math>\phi=(\sqrt 5 +1)/2</math> מייצג את יחס הזהב או בהקסדצימלית 9E3779B9. שימו לב שהפולינום ברקע <math>x^8+x^7+x^5+x^3+1</math> פרימיטיבי. הפולינום יחד עם הזזה מעגלית לפי אינדקס הסבב, מבטיחים פיזור אחיד של סיביות המפתח כדי לסכל מפתחות הצפנה חלשים. שימו לב שביישום מעשי במרבית שפות התכנות אין אינדקס שלילי במערך, אם מבצעים את הצופן בגרסה הרשמית והלא ממוטבת יש צורך לעקוף בעיה זו בדרך כלשהי. מפתחות הסבב מחושבים מתוך המערך <math>w</math> באופן כזה שכל ארבעה אלמנטים <math>w_i,...,w_{i+4}</math> מועברים בתיבות ההחלפה והתוצאה תהיה הכניסה הבאה של 128 סיביות של מפתח מורחב <math>K_i</math>. כגון:
 
::<math>\{k_0,k_1,k_2,k_3\}=S_3(w_0,w_1,w_2,w_3)</math> 

לאחר מכן הקבוצה 4-7, 8-11 וכן הלאה. כאשר תיבות ההחלפה נבחרות לפי הנוסחה <math>(r + 3 - i)\mbox{ modulo }r</math> ו-<math>i=0,...,r</math>. כאשר הצופן מיושם בשיטה הקונבנציונלית מחשבים בסוף כל סבב את התמורה <math>K_i=\mbox{IP}(K_i)</math>.

==ביטחון הצופן==
בהגדרה המקורית של הצופן בהתחשב בעובדה שהוא מבוסס על התכונות הידועות של תיבות ההחלפה של DES ההתקפה הטובה ביותר האפשרית מוערכת יותר מ-<math>2^{100}</math>. בגרסה המשופרת Serpent-1 שהוצעה במהלך בחירת התקן תיבות ההחלפה החדשות הפגינו תכונות טובות יותר והערכת המפתחים היא שלא קיימת התקפה טובה יותר מחיפוש ממצה (ניסוי פענוח עם כל המפתחות האפשריים) ולכן ההתקפה הטובה ביותר האפשרית גם בניתוח דיפרנציאלי או ליניארי תהיה בסיבוכיות של <math>2^k</math> (k הוא גודל המפתח). במקרה של מפתח 256 סיביות כמות כזו של טקסטים פשוט לא קיימת. לכל מפתח נתון צפויים דיפרנציאלים בהסתברות <math>2^{-120}</math>. נתון זה צפוי בכל המועמדים לתקן החדש. לא ידוע על התקפה יעילה יותר כנגד סרפנט וכן צריך לזכור שללא תלות בצופן שבשימוש, לא מומלץ להצפין עם אותו מפתח <math>2^{64}</math> בלוקים. התקפה ליניארית בגרסת 11 סבבים של הצופן אפשרית בסיבוכיות של <math>2^{118}</math> בזמן של <math>2^{89}</math>.

ב-2011 קריפטואנליזה של סרפנט במספר מצומצם של סבבים הראתה שאפשר לשבור את הצופן עם המפתח 128 ב-11 סבבים עם <math>2^{116}</math> טקסטים ידועים ובזמן <math>2^{107.5}</math> ו-<math>2^{104}</math> זיכרון. ועם מפתח 256 ההתקפה הטובה ביותר על 12 סבבים הייתה של <math>2^{118}</math> טקסטים ידועים <math>2^{228}</math> זיכרון וזמן של <math>2^{228}</math>. כזכור בצופן 32 סבבים.

==יישום יעיל (Bit-slice)==
הרעיון הבסיסי מאחורי טכניקת bitslice הוא לראות במעבד המיישם את הצופן כמכונת SIMD (הוראה בודדת - יחידות מידע מרובות). כלומר לדמות את יישום האלגוריתם בחומרה על ידי פקודות לוגיות בסיסיות ברמה של סיביות, תוך עיבוד מקבילי של בלוקים שלמים בגודל 32 או 64 סיביות. בניגוד לשיטה הקונבנציונלית שבזמן עיבוד כמות קטנה של סיביות המעבד אינו מנוצל די יכולתו. לשם כך יש צורך כמובן לסדר מראש את סיביות הערכים באופן שונה. הטכניקה הזו נוצלה לצורך התקפה כנגד DES בשיטה של כוח גס מקבילי תוך ניצול הזמן הפנוי של אלפי מעבדים. בניגוד ל-DES, צופן סרפנט פותח תוך מתן דגש על מקביליות להשגת יעילות מיטבית.

==ראו גם==
* DES
* AES

==קישורים חיצוניים==
* 
* אלי ביהם, [https://www.cs.technion.ac.il/~biham/Reports/Serpent/ Serpent - A New Block Cipher Proposal for AES]

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

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