קמליה (צופן)

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

קמליה - Camellia[1] הוא צופן בלוקים סימטרי שפותח בשנת 2000 בשיתוף פעולה של מיצובישי ו-NTT על ידי צוות קריפטוגרפים בראשות מיצורו מצואי (Mitsuru Matsui). הוצע לגופי תקינה רבים, נכלל ברשימת הצפנים המומלצים של פרויקט NESSIE האירופאי משנת 2003 ופרויקט CRYPTREC של ממשלת יפן, הוצע במזכר RFC 3713 של IETF כתוספת ל-IPSec, אושר על ידי ארגון התקינה הבינלאומי בתקן ISO/IEC 18033-3 ונכלל בפרוטוקולי אבטחה פופולריים רבים, ביניהם SSL, OpenPGP ו-S/MIME. ספריות אבטחה רבות מספקות תמיכה לקמליה, ביניהן Crypto++, GPG, OpenSSL. קמליה מוגן בפטנט והותר על ידי NTT לשימוש ברישיון חופשי.

הצופן מקבל בלוק מידע בגודל 128 סיביות ומפתח הצפנה בשלושה גדלים אפשריים 128, 192 או 256 סיביות והפלט הוא בלוק מוצפן בגודל 128 סיביות. הצופן בעל סגנון ייחודי - מעין רשת פייסטל רקורסיבית, בשמונה-עשר או עשרים וארבעה סבבים בהתאם לאורך המפתח ופועל ברמה של בתים. הפונקציה הפנימית מתנהגת כרשת החלפה-תמורה על שמונה בתים, שכבת ההחלפה מתבצעת במקביל באמצעות שמונה תיבות החלפה (S-box) בגודל 8x8 סיביות ושכבת התמורה היא קומבינציה של XOR בין בתי הקלט. בנוסף, בדומה לMISTY ו-KASUMI כולל גם שכבת טרנספורמציה ליניארית תלוית מפתח שמופעלת אחת לשישה סבבים.


ביטחון

צופן קמליה קיבל הכרה כצופן מודרני בטוח ואינו נופל ברמתו מ-AES. הוא זוכה לפופולריות רבה גם עקב פשטותו ויעילותו הרבה הן בחומרה והן בתוכנה. ההתקפות הטובות ביותר הידועות נגד הצופן הן התקפה שנקראת Square Attack[2] על גרסה מצומצמת (תשעה סבבים) בסיבוכיות של 2202 הצפנות ועם 261 טקסטים מוצפנים. התקפה אחרת שנקראת Rectangle Attack[3] של Shirai מצליחה לשבור את הצופן בעשרה סבבים בסיבוכיות של 2241 קריאות זיכרון עם 2127 טקסטים נבחרים. התקפה נוספת שהיא סוג של התקפה דיפרנציאלית[4] אינה טובה משמעותית מכוח גס. בכללות אילו התקפות תאורטיות שאינן מסכנות את ביטחון הצופן. יש לציין שהטרנספורמציה הליניארית הנוספת (להלן), אחראית בין היתר על חוזקו.

תיאור הצופן

תיאור פעולת ההצפנה של צופן קמליה עם מפתח 192 או 256 סיביות

צופן קמליה (על שם צמח התה) הוא ממשיכו של E2 שהיה מהמועמדים ל-AES והסגנון הייחודי שלו מבוסס עליו במידה רבה. הפעולות בצופן הן בעיקר פעולות החלפה ופעולות לוגיות OR, XOR ו-AND על מילים או בתים. כאשר המרות ממילים לבתים וההפך הן לפי סדר בתים גדול (למשל אם המילה מכילה את הערך 0x01234567 (בבסיס הקסדצימלי) בהמרה לבתים הבית הראשון יכיל 0x01, השני 0x23, השלישי 0x45 והרביעי 0x67). בגרסת מפתח 128 סיביות, בלוק המידע עובר 18 סבבים של טרנספורמציה במבנה פייסטל בנוסף לשכבות הטרנספורמציה הליניארית FL והטרנספורמציה ההופכית FL1 לאחר הסבב השישי והסבב השנים-עשר (כמתואר בתרשים משמאל). פונקציית הרחבת המפתח מקבלת את המפתח הסודי המסופק על ידי המשתמש ומייצרת ממנו תת-מפתחות מורחבים לכל הסבבים שהם ארבעה מפתחות הלבנה המסומנים kwt כאשר t=1,2,3,4, שמונה עשר מפתחות סבבים ku כאשר u=1,2,...,18 וכן ארבעה מפתחות klv (עבור הפונקציות הליניאריות) כאשר v=1,2,3,4, כולם מילים באורך 64 סיביות. תחילה בלוק הטקסט M מחובר ב-XOR (המסומן כאן ב-) עם שני המפתחות הראשונים kw1,kw2 בהתאמה, פעולה זו נקראת הלבנה. התוצאה מחולקת לשני חצאים L ו-R ואז הפעולות הבאות מבוצעות r פעמים כאשר r=1,...,18 למעט הסבבים 6 ו-12:

Lr=Rr1F(Lr1,kr),
Rr=Lr1.

עבור הסבבים 6 ו-12 מבצעים כדלהלן:

Lr'=Rr1F(Lr1,kr),
Rr'=Lr1,
Lr=FL(Lr',kl2r/61),
Rr=FL1(Rr',kl2r/6).

לבסוף התוצאות האחרונות R18 ו-L18 עוברים שוב הלבנה עם המפתחות kw3,kw4 בהתאמה. במילים אחרות פלט הצופן הוא C=(R18kw3  L18kw4).


מפתחות 192 ו-256 סיביות

כאשר נבחר מפתח באורך 192 או 256 סיביות יחולו השינויים הבאים. יהיו ששה מפתחות עבור הפונקציות הליניאריות כלומר נוספו שני מפתחות kl5,kl6. יהיו 24 מפתחות ku במקום 18 וכן קוראים לטרנספורמציה הליניארית והטרנספורמציה ההופכית שלה שלוש פעמים; בסבבים 6, 12 ו-18. כל היתר זהה.

פענוח

הפענוח בקמליה זהה להצפנה למעט היפוך סדר תת-המפתחות. אם המפתח הוא באורך 128 סיביות, תחילה מבטלים את ההלבנה על ידי חיבור ב-XOR עם המפתחות kw3,kw4 בהתאמה ומתקבלים החצאים L18,R18 מהסבב האחרון של ההצפנה ואז מבצעים עבור r=18 עד r=1 בסדר יורד למעט הסבבים 13 ו-7 כדלהלן:

Rr1=LrF(Rr,kr),
Lr1=Rr.

בסבבים 13 ו-7 מבצעים:

Rr1'=LrF(Rr,kr),
Lr1'=Rr,
Rr1=FL(Rr1,kl2(r1)/6),
Lr1=FL1(Lr1',kl2(r1)/61).

הטקסט הקריא יהיה M=(L0kw1  R0kw2).

אם המפתח הנבחר הוא באורך 192 או 256 סיביות, ההבדלים הם שמתבצעים בסך הכול 24 סבבים בסדר יורד והטרנספורמציה הליניארית מתבצעת בסבבים 19, 13 ו-7.

הכנת מפתח

סכמת הכנת המפתח של צופן קמליה

הכנת המפתח נעשית באמצעות גרסה מצומצמת של רשת פייסטל כמתואר בתרשים משמאל. תחילה מגדירים שני משתנים מקומיים KL,KR באורך 128 סיביות כל אחד בהם מציבים את המפתח המסופק על ידי המשתמש. לכל משתנה אפשר להתייחס כאל מילה אחת באורך 128 סיביות או שתי מילים באורך 64 סיביות המייצגים את שני החצאים של משתנה האב, צד ימין של KL ייקרא KLR וצד שמאל KLL וכן לגבי KR, בסך הכול ארבעה רבעים KLL,KLR,KRL ו-KRR באורך 64 סיביות כל אחד. כאשר המפתח המסופק על ידי המשתמש הוא באורך 128 סיביות מציבים אותו ב-KL ואילו המילה KR=0. את המפתח המסופק על ידי המשתמש טוענים למשתנים הפנימיים כך שהכללים הבאים מתקיימים:

  • עבור מפתח 128 סיביות; המפתח בחצי השמאלי KL ואילו החצי הימני KR=0. שים לב ש- KLL ו-KLR מכילים את שני חצאי KL בהתאמה.
  • עבור מפתח 192 סיביות; המפתח מחולק כך ש-K=KL  KRL,KRR=KRL. הסמל x הוא המשלים ל-1 של x (אותו אפשר לקבל על ידי חיבור XOR עם וקטור של 64 אחדים). המפתח מתפרס על פני KL ומחצית מ-KR - כלומר KRL ואילו החלק האחרון KRR מכיל את המשלים של KRL.
  • עבור מפתח 256 סיביות; המפתח מחולק כך ש-K=KL  KR.
  • עבור כל המפתחות; KL=KLL  KLR וכן KR=KRL  KRR.

בנוסף מגדירים שני משתנים KA ו-KB באורך 128 סיביות כל אחד, אותם מאתחלים כדלהלן. תחילה מבצעים KLKR, את התוצאה מצפינים בהצפנה מקוצרת ברשת פייסטל בשני סבבים עם הפונקציה F המתוארת להלן כאשר הערכים Σ1,Σ2 מתוך הטבלה להלן משמשים כמפתחות הצפנה. את התוצאה מחברים ב-XOR עם KL ושוב מצפינים עם Σ3 ו-Σ4 והתוצאה האחרונה תהיה KA. את KA מחברים שוב ב-XOR עם KR ומצפינים עם Σ5,Σ6 והתוצאה האחרונה היא KB. התהליך מומחש בתרשים משמאל.

ערכי הקבועים הם 16 ספרות החל מהספרה השנייה ועד הספרה ה-17 של הייצוג ההקסדצימלי של חלק השבר של השורש הריבועי של ששת המספרים הראשוניים הראשונים.

משתנה ערך
Σ1 0xa09e667f3bcc908b
Σ2 0xb67ae8584caa73b2
Σ3 0xc6ef372fe94f82be
Σ4 0x54ff53a5f1d36f1c
Σ5 0x10e527fade682d1d
Σ6 0xb05688c2b3e6c1fd

מתוך המשתנים KL,KR,KA,KB גוזרים תת-מפתחות (kwt,ku,klv) כל אחד באורך 64 סיביות. כל מפתח נגזר מהחלק השמאלי או הימני של הזזה מעגלית של אחד מהמשתנים האמורים לפי הטבלה הבאה. למשל אם המפתח הנבחר הוא 192 או 256 סיביות אזי לפי הטבלה הימנית, ערכו של תת-המפתח k8 עבור הסבב השמיני הוא החצי הימני של KB המסומן בטבלה KBR לאחר הזזה מעגלית 30 פוזיציות לשמאל.

192/256 סיביות
סבב תת-מפתח ערך
הלבנה kw1 KLL
הלבנה kw2 KLR
סבב 1 k1 KBL
סבב 2 k2 KBR
סבב 3 k3 KRL15
סבב 4 k4 KRR15
סבב 5 k5 KAL15
סבב 6 k6 KAR15
FL kl1 KRL30
FL1 kl2 KRR30
סבב 7 k7 KBL30
סבב 8 k8 KBR30
סבב 9 k9 KLL45
סבב 10 k10 KLR45
סבב 11 k11 KAL45
סבב 12 k12 KAR45
FL kl3 KLL60
FL1 kl4 KLR60
סבב 13 k13 KRL60
סבב 14 k14 KRR60
סבב 15 k15 KBL60
סבב 16 k16 KBR60
סבב 17 k17 KLL77
סבב 18 k18 KLR77
FL kl5 KAL77
FL1 kl6 KAR77
סבב 19 k19 KRL94
סבב 20 k20 KRR94
סבב 21 k21 KAL94
סבב 22 k22 KAR94
סבב 23 k23 KLL111
סבב 24 k24 KLR111
הלבנה kw3 KBL111
הלבנה kw4 KBR111
128 סיביות
סבב תת-מפתח ערך
הלבנה kw1 KLL
הלבנה kw2 KLR
סבב 1 k1 KAL
סבב 2 k2 KAR
סבב 3 k3 KLL15
סבב 4 k4 KLR15
סבב 5 k5 KAL15
סבב 6 k6 KAR15
FL kl1 KAL30
FL1 kl2 KAR30
סבב 7 k7 KLL45
סבב 8 k8 KLR45
סבב 9 k9 KAL45
סבב 10 k10 KLR60
סבב 11 k11 KAL60
סבב 12 k12 KAR60
FL kl3 KLL77
FL1 kl4 KLR77
סבב 13 k13 KLL94
סבב 14 k14 KLR94
סבב 15 k15 KAL94
סבב 16 k16 KAR94
סבב 17 k17 KLL111
סבב 18 k18 KLR111
הלבנה kw3 KAL111
הלבנה kw4 KAR111

הביטוי xy פירושו כאן הזזה מעגלית של x במספר סיביות המצוין על ידי y בגבולות מילה באורך 64 סיביות. לדוגמה אם המשתנה באורך 8 סיביות (בית), והוא מכיל את הערך 169 או 'A9' (בבסיס בינארי "10101001") לאחר הזה מעגלית לשמאל שלוש סיביות יתקבל 53 או '35' ("110101").

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

פונקציות עזר

תיאור הפונקציה F

להלן תיאור הפונקציות המרכיבות את הצופן מהגדול לקטן. הפונקציה F המופיעה בתרשים משמאל מוגדרת כדלהלן:

F(X,k)Y=P(S(Xk)

הפונקציה מקבלת שני פרמטרים, ערך X וקטע מתאים מהמפתח המורחב k באורך 64 סיביות כל אחד ומחזירה את Y גם הוא באורך 64 סיביות תוך שימוש בפונקציות S ו-P המייצגות החלפה ותמורה בהתאמה בנוסף לחיבור עם k.

הפונקציה FL

הפונקציות הליניאריות של קמליה

הפונקציה הליניארית FL מקבלת שני פרמטרים; X באורך 64 סיביות המחולק לצד ימין וצד שמאל XK ו-XR בהתאמה ואת kl המחולק גם הוא לשני חצאים klL,klR ומחזירה את Y באורך 64 סיביות כדלהלן:

FL(XL  XR,klL  klR)YL  YR

כאשר

YR=((XLklL)1)XR,
YL=(YRklR)XL.

הסימן מייצג את האופרטור הלוגי AND והסימן מייצג את האופרטור הלוגי OR.

הפונקציה הליניארית ההופכית

הפונקציה ההופכית מוגדרת כך:

FL1(YL  YR,klL  klR)XL  XR

כאשר

XL=(YRklR)YL,
XR=((XLklL)1)YR.

התרשים משמאל מתאר את שתי הפונקציות הליניאריות.

הפונקציה S

פונקציית ההחלפה מקבלת קלט l באורך 8 בתים ונעזרת בארבע טבלאות החלפה s1,s2,s3 ו-s4 להלן כדי להחליף את ערכי הבתים בבתים שבטבלה לפי אינדקסים - בכל טבלה בסך הכול 256 ערכים אפשריים. כדלהלן:

l1=s1(l1),l2=s2(l2),l3=s3(l3),l4=s4(l4)
l5=s2(l5),l6=s3(l6),l7=s4(l7),l8=s1(l8)

לדוגמה אם ערכו של הבית l1=12, התוצאה לפי הטבלה הראשונה היא l1=s1(12)=234.

תיבות ההחלפה

תיבות ההחלפה של קמליה (s-box) הן ערכי שקילות אפינית של פונקציות הופכיות מעל השדה GF(28). בהצגה אלגברית:

s1(x)𝐡(𝐠(𝐟(0xc5x)))0x6a
s2(x)s1(x)1
s3(x)s1(x)1
s4(x)s1(x1)

הפונקציה 𝐟 היא צירוף ליניארי של סיביות הקלט לפי הנוסחה:

b1=a6a2,b2=a7a1,b3=a8a5a3,b4=a8a3,
b5=a7a4,b6=a5a2,b7=a8a1,b8=a6a4.

הפונקציה 𝐠 מוגדרת כך:

(b8+b7α+b6α2+b5α3)+(b4+b3α+b2α2+b1α3)β
=1/((a8+a7α+a6α2+a5α3)+(a1+a3α+a2α2+a1α3)β)

כאשר β מקיים β8+β6+β5+β3+1=0 וכן α=β238=β6+β5+β3+β2 הוא אלמנט בשדה GF(24) המקיים α4+α+1=0.

הפונקציה 𝐡 מוגדרת בסיביות עבור הקלט a=a1a2a3a4a5a6a7a8 כך:

b1=a5a6a2,b2=a6a2,b3=a7a4,b4=a8a2
b5=a7a3,b6=a8a1,b7=a5a1,b8=a6a3

אפשר לראות שערכי התיבות s2,s3 ו-s4 למעשה נגזרות מהתיבה הראשונה. לכן אם הזיכרון מוגבל כמו בכרטיס חכם, אפשר לאחסן בזיכרון רק את הטבלה הראשונה ולחשב את ההחלפה במקום על ידי הנוסחאות המתוארות. למשל אם x=20 החלפה של x לפי טבלה 3 היא: s1(20)1=691=162.


להלן ערכי תיבות ההחלפה:

s𝟏

 112, 130,  44, 236, 179,  39, 192, 229, 228, 133,  87,  53, 234,  12, 174,  65,
  35, 239, 107, 147,  69,  25, 165,  33, 237,  14,  79,  78,  29, 101, 146, 189,
 134, 184, 175, 143, 124, 235,  31, 206,  62,  48, 220,  95,  94, 197,  11,  26,
 166, 225,  57, 202, 213,  71,  93,  61, 217,   1,  90, 214,  81,  86, 108,  77,
 139,  13, 154, 102, 251, 204, 176,  45, 116,  18,  43,  32, 240, 177, 132, 153,
 223,  76, 203, 194,  52, 126, 118,   5, 109, 183, 169,  49, 209,  23,   4, 215,
  20,  88,  58,  97, 222,  27,  17,  28,  50,  15, 156,  22,  83,  24, 242,  34,
 254,  68, 207, 178, 195, 181, 122, 145,  36,   8, 232, 168,  96, 252, 105,  80,
 170, 208, 160, 125, 161, 137,  98, 151,  84,  91,  30, 149, 224, 255, 100, 210,
  16, 196,   0,  72, 163, 247, 117, 219, 138,   3, 230, 218,   9,  63, 221, 148,
 135,  92, 131,   2, 205,  74, 144,  51, 115, 103, 246, 243, 157, 127, 191, 226,
  82, 155, 216,  38, 200,  55, 198,  59, 129, 150, 111,  75,  19, 190,  99,  46,
 233, 121, 167, 140, 159, 110, 188, 142,  41, 245, 249, 182,  47, 253, 180,  89,
 120, 152,   6, 106, 231,  70, 113, 186, 212,  37, 171,  66, 136, 162, 141, 250,
 114,   7, 185,  85, 248, 238, 172,  10,  54,  73,  42, 104,  60,  56, 241, 164,
  64,  40, 211, 123, 187, 201,  67, 193,  21, 227, 173, 244, 119, 199, 128, 158

s𝟐

 224,   5,  88, 217, 103,  78, 129, 203, 201,  11, 174, 106, 213,  24,  93, 130,
  70, 223, 214,  39, 138,  50,  75,  66, 219,  28, 158, 156,  58, 202,  37, 123,
  13, 113,  95,  31, 248, 215,  62, 157, 124,  96, 185, 190, 188, 139,  22,  52,
  77, 195, 114, 149, 171, 142, 186, 122, 179,   2, 180, 173, 162, 172, 216, 154,
  23,  26,  53, 204, 247, 153,  97,  90, 232,  36,  86,  64, 225,  99,   9,  51,
 191, 152, 151, 133, 104, 252, 236,  10, 218, 111,  83,  98, 163,  46,   8, 175,
  40, 176, 116, 194, 189,  54,  34,  56, 100,  30,  57,  44, 166,  48, 229,  68,
 253, 136, 159, 101, 135, 107, 244,  35,  72,  16, 209,  81, 192, 249, 210, 160,
  85, 161,  65, 250,  67,  19, 196,  47, 168, 182,  60,  43, 193, 255, 200, 165,
  32, 137,   0, 144,  71, 239, 234, 183,  21,   6, 205, 181,  18, 126, 187,  41,
  15, 184,   7,   4, 155, 148,  33, 102, 230, 206, 237, 231,  59, 254, 127, 197,
 164,  55, 177,  76, 145, 110, 141, 118,   3,  45, 222, 150,  38, 125, 198,  92,
 211, 242,  79,  25,  63, 220, 121,  29,  82, 235, 243, 109,  94, 251, 105, 178,
 240,  49,  12, 212, 207, 140, 226, 117, 169,  74,  87, 132,  17,  69,  27, 245,
 228,  14, 115, 170, 241, 221,  89,  20, 108, 146,  84, 208, 120, 112, 227,  73,
 128,  80, 167, 246, 119, 147, 134, 131,  42, 199,  91, 233, 238, 143,   1,  61

s𝟑

  56,  65,  22, 118, 217, 147,  96, 242, 114, 194, 171, 154, 117,   6,  87, 160,
 145, 247, 181, 201, 162, 140, 210, 144, 246,   7, 167,  39, 142, 178,  73, 222,
  67,  92, 215, 199,  62, 245, 143, 103,  31,  24, 110, 175,  47, 226, 133,  13,
  83, 240, 156, 101, 234, 163, 174, 158, 236, 128,  45, 107, 168,  43,  54, 166,
 197, 134,  77,  51, 253, 102,  88, 150,  58,   9, 149,  16, 120, 216,  66, 204,
 239,  38, 229,  97,  26,  63,  59, 130, 182, 219, 212, 152, 232, 139,   2, 235,
  10,  44,  29, 176, 111, 141, 136,  14,  25, 135,  78,  11, 169,  12, 121,  17,
 127,  34, 231,  89, 225, 218,  61, 200,  18,   4, 116,  84,  48, 126, 180,  40,
  85, 104,  80, 190, 208, 196,  49, 203,  42, 173,  15, 202, 112, 255,  50, 105,
   8,  98,   0,  36, 209, 251, 186, 237,  69, 129, 115, 109, 132, 159, 238,  74,
 195,  46, 193,   1, 230,  37,  72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
  41, 205, 108,  19, 100, 155,  99, 157, 192,  75, 183, 165, 137,  95, 177,  23,
 244, 188, 211,  70, 207,  55,  94,  71, 148, 250, 252,  91, 151, 254,  90, 172,
  60,  76,   3,  53, 243,  35, 184,  93, 106, 146, 213,  33,  68,  81, 198, 125,
  57, 131, 220, 170, 124, 119,  86,   5,  27, 164,  21,  52,  30,  28, 248,  82,
  32,  20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227,  64,  79

s𝟒

 112,  44, 179, 192, 228,  87, 234, 174,  35, 107,  69, 165, 237,  79,  29, 146,
 134, 175, 124,  31,  62, 220,  94,  11, 166,  57, 213,  93, 217,  90,  81, 108,
 139, 154, 251, 176, 116,  43, 240, 132, 223, 203,  52, 118, 109, 169, 209,   4,
  20,  58, 222,  17,  50, 156,  83, 242, 254, 207, 195, 122,  36, 232,  96, 105,
 170, 160, 161,  98,  84,  30, 224, 100,  16,   0, 163, 117, 138, 230,   9, 221,
 135, 131, 205, 144, 115, 246, 157, 191,  82, 216, 200, 198, 129, 111,  19,  99,
 233, 167, 159, 188,  41, 249,  47, 180, 120,   6, 231, 113, 212, 171, 136, 141,
 114, 185, 248, 172,  54,  42,  60, 241,  64, 211, 187,  67,  21, 173, 119, 128,
 130, 236,  39, 229, 133,  53,  12,  65, 239, 147,  25,  33,  14,  78, 101, 189,
 184, 143, 235, 206,  48,  95, 197,  26, 225, 202,  71,  61,   1, 214,  86,  77,
  13, 102, 204,  45,  18,  32, 177, 153,  76, 194, 126,   5, 183,  49,  23, 215,
  88,  97,  27,  28,  15,  22,  24,  34,  68, 178, 181, 145,   8, 168, 252,  80,
 208, 125, 137, 151,  91, 149, 255, 210, 196,  72, 247, 219,   3, 218,  63, 148,
  92,   2,  74,  51, 103, 243, 127, 226, 155,  38,  55,  59, 150,  75, 190,  46,
 121, 140, 110, 142, 245, 182, 253,  89, 152, 106,  70, 186,  37,  66, 162, 250,
   7,  85, 238,  10,  73, 104,  56, 164,  40, 123, 201, 193, 227, 244, 199, 158

הפונקציה P

הפונקציה P מקבלת מערך של שמונה בתים z1,...,z8 ומחזירה את התמורה שלהם לפי:

z1=z1z3z4z6z7z8
z2=z1z2z4z5z7z8
z3=z1z2z3z5z6z8
z4=z2z3z4z5z6z7
z5=z1z2z6z7z8
z6=z2z3z5z7z8
z7=z3z4z5z6z8
z8=z1z4z5z6z7


דרך אחרת להציג זאת היא על ידי כפל מטריצות:

(z8z7z1)(z8z7z1)=P(z8z7z1)

כאשר

P=(0111100110111100110101101110001101111110101101111101101111101101)

קוד לדוגמה

להלן קוד שלם בשפת ++C של הצפנת קמליה לפי RFC 3713:

const unsigned char SIGMA[48] = {
   0xa0,0x9e,0x66,0x7f,0x3b,0xcc,0x90,0x8b, 0xb6,0x7a,0xe8,0x58,0x4c,0xaa,0x73,0xb2,
   0xc6,0xef,0x37,0x2f,0xe9,0x4f,0x82,0xbe, 0x54,0xff,0x53,0xa5,0xf1,0xd3,0x6f,0x1c,
   0x10,0xe5,0x27,0xfa,0xde,0x68,0x2d,0x1d, 0xb0,0x56,0x88,0xc2,0xb3,0xe6,0xc1,0xfd
};
const int KSFT1[26] = {
    0,64,0,64,15,79,15,79,30,94,45,109,45,124,60,124,77,13,94,30,94,30,111,47,111,47
};
const int KIDX1[26] = {
    0,0,4,4,0,0,4,4,4,4,0,0,4,0,4,4,0,0,0,0,4,4,0,0,4,4
};
const int KSFT2[34] = {
    0,64,0,64,15,79,15,79,30,94,30,94,45,109,45,109,60,124,60,124,60,124,77,13,77,13,
    94,30,94,30,111,47,111,47
};
const int KIDX2[34] = {
    0,0,12,12,8,8,4,4,8,8,12,12,0,0,4,4,0,0,8,8,12,12,0,0,4,4,8,8,4,4,0,0,12,12
};

const unsigned char SBOX[256] = {
    112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, 35,239,107,147,
     69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,134,184,175,143,124,235, 31,206,
     62, 48,220, 95, 94,197, 11, 26,166,225, 57,202,213, 71, 93, 61,217,  1, 90,214,
     81, 86,108, 77,139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
    223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215, 20, 88, 58, 97,
    222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,254, 68,207,178,195,181,122,145,
     36,  8,232,168, 96,252,105, 80,170,208,160,125,161,137, 98,151, 84, 91, 30,149,
    224,255,100,210, 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
    135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226, 82,155,216, 38,
    200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,233,121,167,140,159,110,188,142,
     41,245,249,182, 47,253,180, 89,120,152,  6,106,231, 70,113,186,212, 37,171, 66,
    136,162,141,250,114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
     64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
};

#define SBOX1(n) SBOX[(n)]
#define SBOX2(n) (unsigned char )((SBOX[(n)] >> 7 ^ SBOX[(n)] << 1) & 0xff)
#define SBOX3(n) (unsigned char )((SBOX[(n)] >> 1 ^ SBOX[(n)] << 7) & 0xff)
#define SBOX4(n) SBOX[((n) << 1 ^ (n) >> 7) & 0xff]

void Camellia_Ekeygen( const int n, const unsigned char  *k, unsigned char *e )
{
	unsigned char  t[64] = {0};
	Word u[20];
	if( n == 128 ){
		for(int i=0 ; i<16; i++ ) t[i] = k[i];
	}
	else if( n == 192 ){
		for(int i=0 ; i<24; i++ ) t[i] = k[i];
		for(int i=24; i<32; i++ ) t[i] = k[i-8] ^ 0xff;
	}
	else if( n == 256 ){
		for(int i=0 ; i<32; i++ ) t[i] = k[i];
	}

	XorBlock( t+0, t+16, t+32 );

	Camellia_Feistel( t+32, SIGMA+0, t+40 );
	Camellia_Feistel( t+40, SIGMA+8, t+32 );

	XorBlock( t+32, t+0, t+32 );

	Camellia_Feistel( t+32, SIGMA+16, t+40 );
	Camellia_Feistel( t+40, SIGMA+24, t+32 );

	ByteWord( t+0,  u+0 );
	ByteWord( t+32, u+4 );

	if( n == 128 ){
		for(int i=0; i<26; i+=2 ){
			RotBlock( u+KIDX1[i+0], KSFT1[i+0], u+16 );
			RotBlock( u+KIDX1[i+1], KSFT1[i+1], u+18 );
			WordByte( u+16, e+i*8 );
		}
	}else{
		XorBlock( t+32, t+16, t+48 );
		Camellia_Feistel( t+48, SIGMA+32, t+56 );
		Camellia_Feistel( t+56, SIGMA+40, t+48 );

		ByteWord( t+16, u+8  );
		ByteWord( t+48, u+12 );

		for(int i=0; i<34; i+=2 ){
			RotBlock( u+KIDX2[i+0], KSFT2[i+0], u+16 );
			RotBlock( u+KIDX2[i+1], KSFT2[i+1], u+18 );
			WordByte( u+16, e+(i<<3) );
		}
	}
}

void Camellia_Encrypt( const int n, const unsigned char  *p, const unsigned char  *e, unsigned char  *c )
{
	XorBlock(p, e+0, c);
	for(int i=0; i<3; i++){
		Camellia_Feistel(c+0, e+16+(i<<4), c+8);
		Camellia_Feistel(c+8, e+24+(i<<4), c+0);
	}
	Camellia_FLlayer(c, e+64, e+72);

	for(int i=0; i<3; i++){
		Camellia_Feistel(c+0, e+80+(i<<4), c+8);
		Camellia_Feistel(c+8, e+88+(i<<4), c);
	}
	Camellia_FLlayer(c, e+128, e+136);

	for(int i=0; i<3; i++){
		Camellia_Feistel(c+0, e+144+(i<<4), c+8);
		Camellia_Feistel(c+8, e+152+(i<<4), c);
	}

	if(n == 128){
		SwapHalf(c);
		XorBlock(c, e+192, c);
	}else{
		Camellia_FLlayer(c, e+192, e+200);
		for(int i=0; i<3; i++ ){
			Camellia_Feistel(c+0, e+208+(i<<4), c+8);
			Camellia_Feistel(c+8, e+216+(i<<4), c);
		}
		SwapHalf(c);
		XorBlock(c, e+256, c);
	}
}

void Camellia_Decrypt( const int n, const unsigned char *c, const unsigned char *e, unsigned char *p )
{
	if(n == 128){
		XorBlock(c, e+192, p);
	}else{
		XorBlock(c, e+256, p);

		for(int i=2; i>=0; i-- ){
			Camellia_Feistel(p+0, e+216+(i<<4), p+8);
			Camellia_Feistel(p+8, e+208+(i<<4), p);
		}
		Camellia_FLlayer(p, e+200, e+192);
	}

	for(int i=2; i>=0; i--){
		Camellia_Feistel(p+0, e+152+(i<<4), p+8);
		Camellia_Feistel(p+8, e+144+(i<<4), p);
	}

	Camellia_FLlayer(p, e+136, e+128);

	for(int i=2; i>=0; i-- ){
		Camellia_Feistel(p+0, e+88+(i<<4), p+8);
		Camellia_Feistel(p+8, e+80+(i<<4), p);
	}
	Camellia_FLlayer(p, e+72, e+64);

	for(int i=2; i>=0; i-- ){
		Camellia_Feistel(p+0, e+24+(i<<4), p+8);
		Camellia_Feistel(p+8, e+16+(i<<4), p);
	}
	SwapHalf(p);
	XorBlock(p, e+0, p);
}

void Camellia_Feistel(const unsigned char *x, const unsigned char *k, unsigned char *y)
{
	unsigned char t[8] = {
		SBOX1(x[0]^k[0]), SBOX2(x[1]^k[1]), SBOX3(x[2]^k[2]), SBOX4(x[3]^k[3]),
		SBOX2(x[4]^k[4]), SBOX3(x[5]^k[5]), SBOX4(x[6]^k[6]), SBOX1(x[7]^k[7])
	};

	y[0] ^= t[0]^t[2]^t[3]^t[5]^t[6]^t[7];
	y[1] ^= t[0]^t[1]^t[3]^t[4]^t[6]^t[7];
	y[2] ^= t[0]^t[1]^t[2]^t[4]^t[5]^t[7];
	y[3] ^= t[1]^t[2]^t[3]^t[4]^t[5]^t[6];
	y[4] ^= t[0]^t[1]^t[5]^t[6]^t[7];
	y[5] ^= t[1]^t[2]^t[4]^t[6]^t[7];
	y[6] ^= t[2]^t[3]^t[4]^t[5]^t[7];
	y[7] ^= t[0]^t[3]^t[4]^t[5]^t[6];
}

void Camellia_FLlayer(unsigned char *x, const unsigned char *kl, const unsigned char *kr)
{
	unsigned int t[4],u[4],v[4];
	ByteWord(x, t);
	ByteWord(kl, u);
	ByteWord(kr, v);
	t[1] ^= (t[0] & u[0]) << 1 ^ (t[0] & u[0]) >> 31;
	t[0] ^= t[1] | u[1];
	t[2] ^= t[3] | v[1];
	t[3] ^= (t[2] & v[0]) << 1 ^ (t[2] & v[0]) >> 31;
	WordByte(t, x);
}

void ByteWord(const unsigned char *x, unsigned int *y)
{
	for(int i=0; i<4; i++){
		y[i] = ((unsigned int)x[(i << 2)] << 24) + 
                       ((unsigned int)x[(i << 2) + 1] << 16) +
                       ((unsigned int)x[(i << 2) + 2] << 8 ) +
                       ((unsigned int)x[(i << 2) + 3]);
	}
}

void WordByte(const unsigned int *x, unsigned char *y)
{
	for(int i=0; i<4; i++){
		y[(i << 2)] = (unsigned char)(x[i] >> 24 & 0xff);
		y[(i << 2) + 1] = (unsigned char)(x[i] >> 16 & 0xff);
		y[(i << 2) + 2] = (unsigned char)(x[i] >>  8 & 0xff);
		y[(i << 2) + 3] = (unsigned char)(x[i] & 0xff);
	}
}

void RotBlock(const unsigned int *x, const int n, unsigned int *y)
{
	int r;
	if(r = (n & 31)){
		y[0] = x[((n >> 5) + 0) & 3] << r ^ x[((n >> 5) + 1) & 3] >> (32-r);
		y[1] = x[((n >> 5) + 1) & 3] << r ^ x[((n >> 5) + 2) & 3] >> (32-r);
	}
	else{
		y[0] = x[((n >> 5)) & 3];
		y[1] = x[((n >> 5) + 1) & 3];
	}
}

void SwapHalf(unsigned char *x)
{
	unsigned char t;
	for(int i = 0; i < 8; i++){
		t = x[i];
		x[i] = x[8+i];
		x[8+i] = t;
	}
}

void XorBlock(const unsigned char *x, const unsigned char *y, unsigned char *z)
{
	for(int i = 0; i < 16; i++ ) z[i] = x[i] ^ y[i];
}

ראו גם

הערות שוליים

  1. Specification of Cammelia - a 128-bit Block Cipher
  2. Yeom, Y., S. Park, and I. Kim (2002). "On the security of Camellia against the square attack." Fast Software Encryption, FSE 2002, Lecture Notes in Computer Science, vol. 2365, eds. J. Daemen and V. Rijmen. Springer-Verlag, Berlin, 89–99.
  3. Shirai, T. (2002). "Differential, linear, boomerang and rectangle cryptanalysis of reduced-round Camellia." Proceedings of the Third NESSIE Workshop, NESSIE, November 2002.
  4. Hatano, Y., H. Sekine, and T. Kaneko (2002). "Higher order differential attack of Camellia (II)." Selected Areas in Cryptography, SAC 2002. Lecture Notes in Computer Science, eds. H. Heys and K. Nyberg. Springer-Verlag, Berlin, 39–56.




שגיאות פרמטריות בתבנית:מיון ויקיפדיה

שימוש בפרמטרים מיושנים [ דרגה ]
קמליה (צופן)23157590