RC6

מתוך המכלול, האנציקלופדיה היהודית
קפיצה לניווט קפיצה לחיפוש

RC6 הוא צופן בלוקים סימטרי שפותח ב-1998, על ידי רונלד ריבסט יחד עם Matt Robshaw ,Ray Sidney ו-Yiqun Lisa Yin, מחברת RSA ו-MIT עבור תקן ההצפנה המתקדם שהחליף את DES. זהו דור ההמשך של צופן RC5 שפותח במיוחד כדי להתאים לדרישות התקן והיה מבין חמשת המועמדים המובילים (מקום רביעי אחרי Twofish). כקודמו RC6 עושה שימוש נרחב בהזזה מעגלית בסיביות (bitwise rotation) תלויית מידע. אולם נוספו בו מאפיינים חדשים; הוא מנצל ארבעה אוגרים במקום שניים וכולל כפל מודולרי בשלמים שמגביר באופן ניכר את רמת הפיזור (diffusion) לסבב. מה שמניב בטחון טוב יותר בפחות סבבים ובתפוקה גבוהה יותר. כיתר המועמדים שעלו לגמר במהלך התחרות הוכרז כי לא נמצאו התקפות יעילות נגדו. RC6 רשום כפטנט, שמו הוא סימן רשום והזכויות עליו שייכות לחברת RSA. ייתכן שהשימוש בו מצריך רישיון (החברה הצהירה כי אם ייבחר על ידי התקן יהיה השימוש בו חופשי אולם לא ניתנה כל הצהרה נוספת לאחר סגירת התחרות).

שיקולי פיתוח

תרשים צופן RC6. הסימן מייצג XOR הסימן מייצג חיבור מודולו הסימן מייצג הזזה מעגלית לשמאל, ו- מתייחס לפונקציה

RC6 נולד בעקבות הרצון להתאים את צופן RC5 שיצא ב-1995 לתקן המתקדם ובעקרון הם דומים בפשטותם הרבה. את השם RC ניתן לפרש כקיצור של Rivest Cipher או Ron's Code. למרות שלא התגלו התקפות מעשיות מוצלחות כנגד RC5, מחקרים גילו אפשרות להתקפה תאורטית שנובעת מהעובדה שמידת ההזזה המעגלית אינה מושפעת מכל סיביות האוגרים. הפתרון היה הוספת כפל שלמים מודולרי. בנוסף, כדי לעמוד בדרישות התקן על הבלוק להיות 128 סיביות לפחות. למרות היותו מהיר RC5 מכיל רק שני אוגרי 32 סיביות לכן לא ניתן היה להרחבה ביעילות כדי להגיע ל-128 סיביות ללא שימוש באוגרים גדולים יותר שהתקן אינו תומך בהם, במקום זאת הוחלט להגדיל את מספר האוגרים. והתוצאה היא RC6 - בטוח ומהיר יותר וכמו קודמו שומר על פשטות וביצועים גבוהים בתוכנה.

תיאור האלגוריתם

RC6 הוא אלגוריתם פרמטרי המוגדר על ידי הסימון RC6-w/r/b. גודל מילה הוא סיביות, מספר הסבבים הוא והמפתח בגודל בתים, לצורך התקן נקבע והמפתח יכול להיות בתים. האלגוריתם פועל על ארבע מילים בגודל תוך שימוש בפעולות הבאות:

או חיבור וחיסור שלמים מודולו
חיבור XOR במילים בגודל 32 סיביות
כפל שלמים מודולו
או הזזה מעגלית של שמאלה או ימינה לפי כיוון החצים במספר פוזיציות לפי הסיביות הראשונות של (כאשר מייצג לוגריתם בבסיס 2, במקרה של לפי התקן, 5 סיביות).

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

הצפנה

פענוח

הרחבת מפתח

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

ביצועים ובטחון

יישום צופן RC6 (על פנטיום 2) בשפת c הגיע למהירות של כ-600 מחזורי שעון לבלוק או כ-5 מגה לשנייה. RC6 עולה בביצועיו על ריינדל במימוש בתוכנה[1] בעיקר על מחשב אינטל 32 סיביות. כמו יתר המועמדים (לפי דרישות התקן) מתאים ליישום גם בחומרה או במעבד כרטיס חכם, אם כי לריינדל ביצועים טובים יותר בשטח זה. היות ש-RC6 אינו משתמש בתיבות החלפה מימוש האלגוריתם מאד קומפקטי ויכול לאכלס פחות מ-256 בתים. הערכת המפתחים היא שההתקפה הטובה ביותר האפשרית כנגד הצופן, היא בסיבוכיות בין ל-.


קוד לדוגמה

להלן קוד C++‎ לא אופטימלי להמחשה. לפי פרמטרים: . המפתח באורך b יכול להיות 16, 24 או 32 בתים. הקלט והפלט הם מערכי 4 מילים בגודל 32 סיביות. S הוא מערך עזר בגודל 44 מילים.

#define ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1)))))
#define ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))


void Setup(byte *key, int b, unsigned int *S)
{
   int i, j, s, v;
   unsigned int L[8], A, B;

   L[((b + 4 - 1) / 4) - 1] = 0;
   for (i = b - 1; i >= 0; i--)
      L[i / 4] = (L[i / 4] << 8) + key[i];

   S[0] = 0xB7E15163;
   for (i = 1; i <= 43; i++)
      S[i] = S[i - 1] + 0x9E3779B9;

   A = B = 0;
   i = j = 0;
   v = 44;
   if (((b + 4 - 1) / 4) > v) v = ((b + 4 - 1) / 4);
   v *= 3;

   for (s = 1; s <= v; s++)
   {
      A = S[i] = ROTL(S[i] + A + B, 3);
      B = L[j] = ROTL(L[j] + A + B, A + B);
      i = (i + 1) % 44;
      j = (j + 1) % ((b + 4 - 1) / 4);
   }
}

void Encrypt(unsigned int *pt, unsigned int *ct, unsigned int *S)
{
   unsigned int A = pt[0], B = pt[1], C = pt[2], D = pt[3];
   B += S[0], D += S[1];
   for (int i = 2; i <= 40; i += 2)
   {
      t = ROTL(B * (2 * B + 1), lgw);
      u = ROTL(D * (2 * D + 1), lgw);
      A = ROTL(A ^ t, u) + S[i];
      C = ROTL(C ^ u, t) + S[i + 1];
      x = A, A = B, B = C, C = D, D = x;
   }
   A += S[42], C += S[43];
   ct[0] = A, ct[1] = B, ct[2] = C, ct[3] = D;
}

void Decrypt(unsigned int *pt, unsigned int *ct, unsigned int *S)
{
   unsigned int A = ct[0], B = ct[1], C = ct[2], D = ct[3];
   C -= S[43], A -= S[42];
   for (int i = 40; i >= 2; i -= 2)
   {
      x = D, D = C, C = B, B = A, A = x;
      u = ROTL(D * (2 * D + 1), lgw);
      t = ROTL(B * (2 * B + 1), lgw);
      C = ROTR(C - S[i + 1], t) ^ u;
      A = ROTR(A - S[i], u) ^ t;
   }
   D -= S[1], B -= S[0];
   pt[0] = A, pt[1] = B, pt[2] = C, pt[3] = D;
}

ראו גם

קישורים חיצוניים

הערות שוליים