לדלג לתוכן

CLEFIA

מתוך ויקיפדיה, האנציקלופדיה החופשית
CLEFIA
מידע כללי
תכנון סוני
פרסום 2007
מבנה הצופן
אורך מפתח 128/192/256 סיביות
אורך בלוק 128 סיביות
מבנה רשת פייסטל כללית
מספר סבבים 18/22/26 בהתאמה

CLEFIAהואצופן בלוקיםקנייניבמבנה פייסטלשפותח על ידיסוניכחלק ממערכתניהול זכויות דיגיטלי[1].שמו נגזר מהמילההצרפתיתClefשפירושה "מפתח". הצופן מקבל בלוקקלטבאורך 128 סיביות ומפתח הצפנה בשלושה אורכים אפשריים: 128, 192 או 256 סיביות ומחזיר בלוק מוצפן באורך 128 סיביות. CLEFIA הוצג לראשונה ב- FSE 2007 (סדנת הצפנה מהירה בתוכנה)[2],הוצע כמועמד לתקןהצפנהעבורממשלת יפןב-CRYPTREC-2013, נחשב בטוח לשימוש ומציג ביצועים 'סטייט אוף דה ארט' בקטגוריה של צפנים קלי משקל. CLEFIA מוגן בזכויות יוצרים והשימוש בו כרוך ברישיון. הוא נמנה עם הצפנים שתוקננו על ידיתקן איזו29192-2 בקטגוריה צופן בלוקים קל משקל[3].

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

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

CLEFIA הוא צופן מאוזן היטב הן מהיבט של יעילות והן מהיבט של ביטחון. הוא משיג ביצועים גבוהים בחומרה, תפוקה של 1.60 Gbps (גיגה-בתים לשנייה) בקירוב עם פחות מ-6000 שערים, עם ספרייתCMOSASIC.בתוכנה הוא מגיע ל-13 מחזורי שעון לבית (cpb) או 1.48 Gbps על מעבדAMDאתלון64 ביט. הביצועים הגבוהים בחומרה מציבים אותו כמתחרה ראוי עבורחומרהמוגבלת משאבים כמוRFIDאוסנסורים אלחוטייםזעירים.

פירוט מהלכי הצופן

[עריכת קוד מקור|עריכה]

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

  1. הלבנה:
  2. הצפנה:
  3. הלבנה:
:,
,
.
  1. הלבנה:
  2. פענוח:
  3. הלבנה:
:,
,
.

פונקציות עזר

[עריכת קוד מקור|עריכה]

פונקציית ההצפנה הפנימית הנקראתהיא בסגנוןרשת פייסטל כללית מסוג 2,כאשרנקרא ענף המייצג את מספר המילים שהפונקציה מקבלת ו-מייצג את מספר החזרות שהיא אמורה לבצע. פונקציית ההצפנה מנצלת שתי פונקציות פנימיות F0 ו-F1 המפורטות להלן שמקבלות קלט באורך 32 סיביות ומחזירותפלטבאורך 32 סיביות. ביתר פירוט, הפונקציהמקבלת ארבע מילים באורך 32 סיביות כל אחת המסומניםוכןמפתחות סבביםבאורך 32 סיביות כל אחד ומחזירה ארבע מילים.הסימן ""משמש להפרדה בין המילים. לדוגמה אם נבחר מפתח באורך 128 סיביות, מספר הסבבים הוא 18 ולכן מספר תת-המפתחות הוא.

תיאור הפונקציה הפנימית בשתי גרסאותשמבוצעת בתהליך ההצפנה ו-לצורך הכנת תת-המפתחות במקרה שנבחר מפתח 192 או 256:

,
,
,
,
,

לפונקציהקיימתפונקציה הופכיתלצורך פענוח המסומנת.את פונקציית הפענוח הפנימית מכינים מפונקציית ההצפנה על ידי שינוי סדר מפתחות הסבביםמהסוף להתחלה וכן שינוי סדר ההחלפה בשלב 2.2 ל-וסדר ההחלפה בשלב 3 משתנה ל-.

הפונקציותו-הן:

F0 F1
,
,
,
,

תיבות ההחלפה S0 ו-S1

[עריכת קוד מקור|עריכה]

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

S0 S1
0 1 2 3 4 5 6 7 8 9 a b c d e f
0. 57 49 d1 c6 2f 33 74 fb 95 6d 82 ea 0e b0 a8 1c
1. 28 d0 4b 92 5c ee 85 b1 c4 0a 76 3d 63 f9 17 af
2. bf a1 19 65 f7 7a 32 20 06 ce e4 83 9d 5b 4c d8
3. 42 5d 2e e8 d4 9b 0f 13 3c 89 67 c0 71 aa b6 f5
4. a4 be fd 8c 12 00 97 da 78 e1 cf 6b 39 43 55 26
5. 30 98 cc dd eb 54 b3 8f 4e 16 fa 22 a5 77 09 61
6. d6 2a 53 37 45 c1 6c ae ef 70 08 99 8b 1d f2 b4
7. e9 c7 9f 4a 31 25 fe 7c d3 a2 bd 56 14 88 60 0b
8. cd e2 34 50 9e dc 11 05 2b b7 a9 48 ff 66 8a 73
9. 03 75 86 f1 6a a7 40 c2 b9 2c db 1f 58 94 3e ed
a. fc 1b a0 04 b8 8d e6 59 62 93 35 7e ca 21 df 47
b. 15 f3 ba 7f a6 69 c8 4d 87 3b 9c 01 e0 de 24 52
c. 7b 0c 68 1e 80 b2 5a e7 ad d5 23 f4 46 3f 91 c9
d. 6e 84 72 bb 0d 18 d9 96 f0 5f 41 ac 27 c5 e3 3a
e. 81 6f 07 a3 79 f6 2d 38 1a 44 5e b5 d2 ec cb 90
f. 9a 36 e5 29 c3 4f ab 64 51 f8 10 d7 bc 02 7d 8e
0 1 2 3 4 5 6 7 8 9 a b c d e f
0. 6c da c3 e9 4e 9d 0a 3d b8 36 b4 38 13 34 0c d9
1. bf 74 94 8f b7 9c e5 dc 9e 07 49 4f 98 2c b0 93
2. 12 eb cd b3 92 e7 41 60 e3 21 27 3b e6 19 d2 0e
3. 91 11 c7 3f 2a 8e a1 bc 2b c8 c5 0f 5b f3 87 8b
4. fb f5 de 20 c6 a7 84 ce d8 65 51 c9 a4 ef 43 53
5. 25 5d 9b 31 e8 3e 0d d7 80 ff 69 8a ba 0b 73 5c
6. 6e 54 15 62 f6 35 30 52 a3 16 d3 28 32 fa aa 5e
7. cf ea ed 78 33 58 09 7b 63 c0 c1 46 1e df a9 99
8. 55 04 c4 86 39 77 82 ec 40 18 90 97 59 dd 83 1f
9. 9a 37 06 24 64 7c a5 56 48 08 85 d0 61 26 ca 6f
a. 7e 6a b6 71 a0 70 05 d1 45 8c 23 1c f0 ee 89 ad
b. 7a 4b c2 2f db 5a 4d 76 67 17 2d f4 cb b1 4a a8
c. b5 22 47 3a d5 10 4c 72 cc 00 f9 e0 fd e2 fe ae
d. f8 5f ab f1 1b 42 81 d6 be 44 29 a6 57 b9 af f2
e. d4 75 66 bb 68 9f 50 02 01 3c 7f 8d 1a 88 bd ac
f. f7 e4 79 96 a2 fc 6d b2 6b 03 e1 2e 7d 14 95 1d

את ההחלפה אפשר לבצע לפי הטבלאות האמורות או לחשבן תוך כדי ריצה במידה שהזיכרון מוגבל. שטח הזיכרון ששתי טבלאות מאכלסות הוא 512 בתים (4096 סיביות). את הכנת הטבלה S0 אפשר לבצע כך. מתחילים מטבלה המכילה 4 על 16 ערכים בגודל 4 סיביות (בסך הכול 256 סיביות):

x 0 1 2 3 4 5 6 7 8 9 a b c d e f
SS0(x) e 6 c a 8 7 2 f b 1 4 0 5 9 d 3
SS1(x) 6 4 0 d 2 b a 3 9 c e f 8 7 5 1
SS2(x) b 8 5 e a 6 4 c f 7 2 3 1 0 d 9
SS3(x) a 2 6 d 3 4 5 e 0 7 8 9 b f c 1

מחלקים את הקלטלשני חצאיםבאורך 4 סיביות כל אחד ומחשבים:

התוצאה היא.

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

f g

מטריצות הפיזור M0 ו-M1

[עריכת קוד מקור|עריכה]

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

הכנת מפתחות הסבבים

[עריכת קוד מקור|עריכה]

תהליך הכנת המפתחות תומך בשלושה מפתחות שונים: 128 סיביות, 192 סיביות או 256 סיביות. התהליך כולל הכנתמפתחות סבביםוארבעה מפתחותהלבנה.והוא כולל פונקציית החלפה הנקראת DoubleSwap המקבלת קלט באורך 128 סיביות ומבצעת החלפה של סיביות לפי הכלל הבא:

,

כאשרפירושו תת-מחרוזת שלהמתחילה בפוזיציהומסתיימת בפוזיציה.

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

אם המפתחשנבחר על ידי המשתמש באורך 128 סיביות מבצעים כדלהלן:

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

הכנת המשתניםמתוךעבור מפתח באורךסיביות כאשראו:

הרחבת המשתניםעבור מפתח באורךסיביות כאשראו:

הקבועים להכנת המפתחות

[עריכת קוד מקור|עריכה]

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

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

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

וקטורי האתחול עבור כל המפתחות, מספר הקבועים ומספר הסבביםמוצגים בטבלה הבאה:

מפתח מספר הקבועים מספר הסבבים וקטור אתחול
128 60 30 0x428a
192 84 42 0x7137
256 92 46 0xb5c0

וקטורי האתחול הם 16 הספרות הבינאריות הראשונות של חלק השבר של שורש ממעלה שלישית של 2, 3 ו-5 בהתאמה.

CLEFIA הוא צופן חדש יחסית עם מעט קריפטואנליזה ידועה, בעיקר וריאציות שלקריפטואנליזה דיפרנציאלית.ההתקפה הטובה ביותר נגד הצופן היא התקפת "דיפרנציאלים בלתי סבירים"[4]שמצריכהטקסטים נבחריםנגד 13 סבבים בסיבוכיות שלהצפנות עם מפתח 128 סיביות. התקפה דומה ישימה נגד הצופן עם 14 ו-15 סבבים עם מפתחות 192 ו-256 בהתאמה. התקפה נוספת היא התקפת "דיפרנציאלים בלתי אפשריים"[5]היעילה נגד CLEFIA-192/256 עם 11 סבבים בסיבוכיות שלטקסטים נבחרים ו-הצפנות. נגד 12 סבבים של CLEFIA-128 ההתקפה מגיעה לסיבוכיות זמן ומקום של.ונגד CLEFIA-192/256 בסיבוכיות שלעם 13 סבבים. עם 14 סבבים הסיבוכיות מגיעה ל-הצפנות. אילו בעיקרון התקפות תאורטיות שאינן מסכנות את השימוש באלגוריתם באופן מעשי.

קוד לדוגמה של CLEFIA 256

[עריכת קוד מקור|עריכה]
constunsignedcharclefia_s0[256]={/* S0 (8-bit S-box based on four 4-bit S-boxes) */
0x57U,0x49U,0xd1U,0xc6U,0x2fU,0x33U,0x74U,0xfbU,0x95U,0x6dU,0x82U,0xeaU,0x0eU,0xb0U,0xa8U,0x1cU,
0x28U,0xd0U,0x4bU,0x92U,0x5cU,0xeeU,0x85U,0xb1U,0xc4U,0x0aU,0x76U,0x3dU,0x63U,0xf9U,0x17U,0xafU,
0xbfU,0xa1U,0x19U,0x65U,0xf7U,0x7aU,0x32U,0x20U,0x06U,0xceU,0xe4U,0x83U,0x9dU,0x5bU,0x4cU,0xd8U,
0x42U,0x5dU,0x2eU,0xe8U,0xd4U,0x9bU,0x0fU,0x13U,0x3cU,0x89U,0x67U,0xc0U,0x71U,0xaaU,0xb6U,0xf5U,
0xa4U,0xbeU,0xfdU,0x8cU,0x12U,0x00U,0x97U,0xdaU,0x78U,0xe1U,0xcfU,0x6bU,0x39U,0x43U,0x55U,0x26U,
0x30U,0x98U,0xccU,0xddU,0xebU,0x54U,0xb3U,0x8fU,0x4eU,0x16U,0xfaU,0x22U,0xa5U,0x77U,0x09U,0x61U,
0xd6U,0x2aU,0x53U,0x37U,0x45U,0xc1U,0x6cU,0xaeU,0xefU,0x70U,0x08U,0x99U,0x8bU,0x1dU,0xf2U,0xb4U,
0xe9U,0xc7U,0x9fU,0x4aU,0x31U,0x25U,0xfeU,0x7cU,0xd3U,0xa2U,0xbdU,0x56U,0x14U,0x88U,0x60U,0x0bU,
0xcdU,0xe2U,0x34U,0x50U,0x9eU,0xdcU,0x11U,0x05U,0x2bU,0xb7U,0xa9U,0x48U,0xffU,0x66U,0x8aU,0x73U,
0x03U,0x75U,0x86U,0xf1U,0x6aU,0xa7U,0x40U,0xc2U,0xb9U,0x2cU,0xdbU,0x1fU,0x58U,0x94U,0x3eU,0xedU,
0xfcU,0x1bU,0xa0U,0x04U,0xb8U,0x8dU,0xe6U,0x59U,0x62U,0x93U,0x35U,0x7eU,0xcaU,0x21U,0xdfU,0x47U,
0x15U,0xf3U,0xbaU,0x7fU,0xa6U,0x69U,0xc8U,0x4dU,0x87U,0x3bU,0x9cU,0x01U,0xe0U,0xdeU,0x24U,0x52U,
0x7bU,0x0cU,0x68U,0x1eU,0x80U,0xb2U,0x5aU,0xe7U,0xadU,0xd5U,0x23U,0xf4U,0x46U,0x3fU,0x91U,0xc9U,
0x6eU,0x84U,0x72U,0xbbU,0x0dU,0x18U,0xd9U,0x96U,0xf0U,0x5fU,0x41U,0xacU,0x27U,0xc5U,0xe3U,0x3aU,
0x81U,0x6fU,0x07U,0xa3U,0x79U,0xf6U,0x2dU,0x38U,0x1aU,0x44U,0x5eU,0xb5U,0xd2U,0xecU,0xcbU,0x90U,
0x9aU,0x36U,0xe5U,0x29U,0xc3U,0x4fU,0xabU,0x64U,0x51U,0xf8U,0x10U,0xd7U,0xbcU,0x02U,0x7dU,0x8eU
};

constunsignedcharclefia_s1[256]={/* S1 (8-bit S-box based on inverse function) */
0x6cU,0xdaU,0xc3U,0xe9U,0x4eU,0x9dU,0x0aU,0x3dU,0xb8U,0x36U,0xb4U,0x38U,0x13U,0x34U,0x0cU,0xd9U,
0xbfU,0x74U,0x94U,0x8fU,0xb7U,0x9cU,0xe5U,0xdcU,0x9eU,0x07U,0x49U,0x4fU,0x98U,0x2cU,0xb0U,0x93U,
0x12U,0xebU,0xcdU,0xb3U,0x92U,0xe7U,0x41U,0x60U,0xe3U,0x21U,0x27U,0x3bU,0xe6U,0x19U,0xd2U,0x0eU,
0x91U,0x11U,0xc7U,0x3fU,0x2aU,0x8eU,0xa1U,0xbcU,0x2bU,0xc8U,0xc5U,0x0fU,0x5bU,0xf3U,0x87U,0x8bU,
0xfbU,0xf5U,0xdeU,0x20U,0xc6U,0xa7U,0x84U,0xceU,0xd8U,0x65U,0x51U,0xc9U,0xa4U,0xefU,0x43U,0x53U,
0x25U,0x5dU,0x9bU,0x31U,0xe8U,0x3eU,0x0dU,0xd7U,0x80U,0xffU,0x69U,0x8aU,0xbaU,0x0bU,0x73U,0x5cU,
0x6eU,0x54U,0x15U,0x62U,0xf6U,0x35U,0x30U,0x52U,0xa3U,0x16U,0xd3U,0x28U,0x32U,0xfaU,0xaaU,0x5eU,
0xcfU,0xeaU,0xedU,0x78U,0x33U,0x58U,0x09U,0x7bU,0x63U,0xc0U,0xc1U,0x46U,0x1eU,0xdfU,0xa9U,0x99U,
0x55U,0x04U,0xc4U,0x86U,0x39U,0x77U,0x82U,0xecU,0x40U,0x18U,0x90U,0x97U,0x59U,0xddU,0x83U,0x1fU,
0x9aU,0x37U,0x06U,0x24U,0x64U,0x7cU,0xa5U,0x56U,0x48U,0x08U,0x85U,0xd0U,0x61U,0x26U,0xcaU,0x6fU,
0x7eU,0x6aU,0xb6U,0x71U,0xa0U,0x70U,0x05U,0xd1U,0x45U,0x8cU,0x23U,0x1cU,0xf0U,0xeeU,0x89U,0xadU,
0x7aU,0x4bU,0xc2U,0x2fU,0xdbU,0x5aU,0x4dU,0x76U,0x67U,0x17U,0x2dU,0xf4U,0xcbU,0xb1U,0x4aU,0xa8U,
0xb5U,0x22U,0x47U,0x3aU,0xd5U,0x10U,0x4cU,0x72U,0xccU,0x00U,0xf9U,0xe0U,0xfdU,0xe2U,0xfeU,0xaeU,
0xf8U,0x5fU,0xabU,0xf1U,0x1bU,0x42U,0x81U,0xd6U,0xbeU,0x44U,0x29U,0xa6U,0x57U,0xb9U,0xafU,0xf2U,
0xd4U,0x75U,0x66U,0xbbU,0x68U,0x9fU,0x50U,0x02U,0x01U,0x3cU,0x7fU,0x8dU,0x1aU,0x88U,0xbdU,0xacU,
0xf7U,0xe4U,0x79U,0x96U,0xa2U,0xfcU,0x6dU,0xb2U,0x6bU,0x03U,0xe1U,0x2eU,0x7dU,0x14U,0x95U,0x1dU
};

voidByteXor(unsignedchar*dst,constunsignedchar*a,constunsignedchar*b,intbytelen)
{
while(bytelen-->0){
*dst++=*a++^*b++;
}
}

unsignedcharClefiaMul2(unsignedcharx)
{
if(x&0x80U)x^=0x0eU;// multiplication over GF(2^8) (p(x) = '11d')
return((x<<1)|(x>>7));
}

#define ClefiaMul4(_x) (ClefiaMul2(ClefiaMul2((_x))))
#define ClefiaMul6(_x) (ClefiaMul2((_x)) ^ ClefiaMul4((_x)))
#define ClefiaMul8(_x) (ClefiaMul2(ClefiaMul4((_x))))
#define ClefiaMulA(_x) (ClefiaMul2((_x)) ^ ClefiaMul8((_x)))

voidClefiaF0Xor(unsignedchar*dst,constunsignedchar*src,constunsignedchar*rk)
{
unsignedcharx[4],y[4],z[4];
/* Key addition */
ByteXor(x,src,rk,4);
/* Substitution layer */
z[0]=clefia_s0[x[0]];
z[1]=clefia_s1[x[1]];
z[2]=clefia_s0[x[2]];
z[3]=clefia_s1[x[3]];
/* Diffusion layer (M0) */
y[0]=z[0]^ClefiaMul2(z[1])^ClefiaMul4(z[2])^ClefiaMul6(z[3]);
y[1]=ClefiaMul2(z[0])^z[1]^ClefiaMul6(z[2])^ClefiaMul4(z[3]);
y[2]=ClefiaMul4(z[0])^ClefiaMul6(z[1])^z[2]^ClefiaMul2(z[3]);
y[3]=ClefiaMul6(z[0])^ClefiaMul4(z[1])^ClefiaMul2(z[2])^z[3];
/* Xoring after F0 */
memcpy(dst+0,src+0,4);
ByteXor(dst+4,src+4,y,4);
}

voidClefiaF1Xor(unsignedchar*dst,constunsignedchar*src,constunsignedchar*rk)
{
unsignedcharx[4],y[4],z[4];
/* Key addition */
ByteXor(x,src,rk,4);
/* Substitution layer */
z[0]=clefia_s1[x[0]];
z[1]=clefia_s0[x[1]];
z[2]=clefia_s1[x[2]];
z[3]=clefia_s0[x[3]];
/* Diffusion layer (M1) */
y[0]=z[0]^ClefiaMul8(z[1])^ClefiaMul2(z[2])^ClefiaMulA(z[3]);
y[1]=ClefiaMul8(z[0])^z[1]^ClefiaMulA(z[2])^ClefiaMul2(z[3]);
y[2]=ClefiaMul2(z[0])^ClefiaMulA(z[1])^z[2]^ClefiaMul8(z[3]);
y[3]=ClefiaMulA(z[0])^ClefiaMul2(z[1])^ClefiaMul8(z[2])^z[3];
/* Xoring after F1 */
memcpy(dst+0,src+0,4);
ByteXor(dst+4,src+4,y,4);
}

voidClefiaGfn4(unsignedchar*y,constunsignedchar*x,constunsignedchar*rk,intr)
{
unsignedcharfin[16],fout[16];

memcpy(fin,x,16);
while(r-->0){
ClefiaF0Xor(fout+0,fin+0,rk+0);
ClefiaF1Xor(fout+8,fin+8,rk+4);
rk+=8;
if(r){/* swapping for encryption */
memcpy(fin+0,fout+4,12);
memcpy(fin+12,fout+0,4);
}
}
memcpy(y,fout,16);
}

voidClefiaGfn8(unsignedchar*y,constunsignedchar*x,constunsignedchar*rk,intr)
{
unsignedcharfin[32],fout[32];

memcpy(fin,x,32);
while(r-->0){
ClefiaF0Xor(fout+0,fin+0,rk+0);
ClefiaF1Xor(fout+8,fin+8,rk+4);
ClefiaF0Xor(fout+16,fin+16,rk+8);
ClefiaF1Xor(fout+24,fin+24,rk+12);
rk+=16;
if(r){/* swapping for encryption */
memcpy(fin+0,fout+4,28);
memcpy(fin+28,fout+0,4);
}
}
memcpy(y,fout,32);
}

voidClefiaGfn4Inv(unsignedchar*y,constunsignedchar*x,constunsignedchar*rk,intr)
{
unsignedcharfin[16],fout[16];

rk+=(r-1)*8;
memcpy(fin,x,16);
while(r-->0){
ClefiaF0Xor(fout+0,fin+0,rk+0);
ClefiaF1Xor(fout+8,fin+8,rk+4);
rk-=8;
if(r){/* swapping for decryption */
memcpy(fin+0,fout+12,4);
memcpy(fin+4,fout+0,12);
}
}
memcpy(y,fout,16);
}

voidClefiaDoubleSwap(unsignedchar*lk)
{
unsignedchart[16];
t[0]=(lk[0]<<7)|(lk[1]>>1),t[1]=(lk[1]<<7)|(lk[2]>>1);
t[2]=(lk[2]<<7)|(lk[3]>>1),t[3]=(lk[3]<<7)|(lk[4]>>1);
t[4]=(lk[4]<<7)|(lk[5]>>1),t[5]=(lk[5]<<7)|(lk[6]>>1);
t[6]=(lk[6]<<7)|(lk[7]>>1),t[7]=(lk[7]<<7)|(lk[15]&0x7fU);

t[8]=(lk[8]>>7)|(lk[0]&0xfeU),t[9]=(lk[9]>>7)|(lk[8]<<1);
t[10]=(lk[10]>>7)|(lk[9]<<1),t[11]=(lk[11]>>7)|(lk[10]<<1);
t[12]=(lk[12]>>7)|(lk[11]<<1),t[13]=(lk[13]>>7)|(lk[12]<<1);
t[14]=(lk[14]>>7)|(lk[13]<<1),t[15]=(lk[15]>>7)|(lk[14]<<1);
memcpy(lk,t,16);
}

voidClefiaConSet(unsignedchar*con,constunsignedchar*iv,intlk)
{
unsignedchart[2];
unsignedchartmp;
memcpy(t,iv,2);
while(lk-->0){
con[0]=t[0]^0xb7U;/* P_16 = 0xb7e1 (natural logarithm) */
con[1]=t[1]^0xe1U;
con[2]=~((t[0]<<1)|(t[1]>>7));
con[3]=~((t[1]<<1)|(t[0]>>7));
con[4]=~t[0]^0x24U;/* Q_16 = 0x243f (circle ratio) */
con[5]=~t[1]^0x3fU;
con[6]=t[1];
con[7]=t[0];
con+=8;

/* updating T */
if(t[1]&0x01U){
t[0]^=0xa8U;
t[1]^=0x30U;
}
tmp=t[0]<<7;
t[0]=(t[0]>>1)|(t[1]<<7);
t[1]=(t[1]>>1)|tmp;
}
}

voidClefiaKeySet256(unsignedchar*rk,constunsignedchar*skey)
{
constunsignedchariv[2]={0xb5,0xc0U};/* cubic root of 5 */
unsignedcharlk[32];
unsignedcharcon256[4*92];
inti;
/* generating CONi^(256) (0 <= i < 92, lk = 46) */
ClefiaConSet(con256,iv,46);
/* GFN_{8,10} (generating L from K) */
ClefiaGfn8(lk,skey,con256,10);

ByteXor(rk,skey,skey+16,8);/* initial whitening key (WK0, WK1) */
rk+=8;
for(i=0;i<13;i++){/* round key (RKi (0 <= i < 52)) */
if((i/2)%2){
ByteXor(rk,lk+16,con256+i*16+(4*40),16);/* LR */
if(i%2){
ByteXor(rk,rk,skey+0,16);/* Xoring KL */
}
ClefiaDoubleSwap(lk+16);/* updating LR */
}
else{
ByteXor(rk,lk+0,con256+i*16+(4*40),16);/* LL */
if(i%2){
ByteXor(rk,rk,skey+16,16);/* Xoring KR */
}
ClefiaDoubleSwap(lk+0);/* updating LL */
}
rk+=16;
}
ByteXor(rk,skey+8,skey+24,8);/* final whitening key (WK2, WK3) */
}

voidClefiaEncrypt(unsignedchar*ct,constunsignedchar*pt,constunsignedchar*rk,constintr)
{
unsignedcharrin[16],rout[16];
memcpy(rin,pt,16);

ByteXor(rin+4,rin+4,rk+0,4);/* initial key whitening */
ByteXor(rin+12,rin+12,rk+4,4);
rk+=8;

ClefiaGfn4(rout,rin,rk,r);/* GFN_{4,r} */

memcpy(ct,rout,16);
ByteXor(ct+4,ct+4,rk+r*8+0,4);/* final key whitening */
ByteXor(ct+12,ct+12,rk+r*8+4,4);
}

voidClefiaDecrypt(unsignedchar*pt,constunsignedchar*ct,constunsignedchar*rk,constintr)
{
unsignedcharrin[16],rout[16];
memcpy(rin,ct,16);

ByteXor(rin+4,rin+4,rk+r*8+8,4);/* initial key whitening */
ByteXor(rin+12,rin+12,rk+r*8+12,4);
rk+=8;

ClefiaGfn4Inv(rout,rin,rk,r);/* GFN^{-1}_{4,r} */

memcpy(pt,rout,16);
ByteXor(pt+4,pt+4,rk-8,4);/* final key whitening */
ByteXor(pt+12,pt+12,rk-4,4);
}

הערות שוליים

[עריכת קוד מקור|עריכה]