ARIA (צופן)

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

בקריפטוגרפיה, ARIA[1] הוא צופן בלוקים סימטרי שפותח ב-2004 על ידי קבוצת חוקרים ב-NSRI עבור המשרד לתקנים וטכנולוגיה של דרום קוריאה (KATS), החבר בגופי התקינה הבינלאומיים ISO ו-IEC.

האלגוריתם בנוי מרשת החלפה-תמורה אינוולוציונית ולמעשה המפרט והממשק שלו דומים במידה רבה ל-AES. הוא מקבל בלוק טקסט קריא באורך 128 סיביות ומפתח הצפנה בשלושה אורכים אפשריים: 128, 192 או 256 סיביות ומפיק מהטקסט הקריא בלוק מוצפן באורך 128 סיביות. הוא עושה שימוש בתיבות החלפה (Sbox) בגודל 8×8 סיביות המבוססות על תיבות ההחלפה של ריינדל והוא פועל ב-12, 14, או 16 סבבים בהתאם לאורך המפתח. תהליך הכנת מפתח ההצפנה מרחיב את המפתח המסופק על ידי המשתמש באמצעות רשת פייסטל משולשת בתוספת קבועים שהם הייצוג הבינארי של π1 (זאת במטרה להוכיח שאינו מכיל דלתות סתר).

האלגוריתם הפך לתקן רשמי של KATS וכן IETF, הוצע בטיוטה RFC 5794 וכן הוצע כתוסף לפרוטוקול SSL/TLS בטיוטה RFC 6209. ביטחונו נחקר היטב על ידי מומחי הצפנה, ביניהם ניתן למנות כמה מחקרים[2][3][4][5][6] שמראים שהצופן בטוח לשימוש בגרסה העדכנית שלו ולא נמצאו בו פגמים רציניים.

גרסאות והיבטי יישום

תרשים כללי של צופן ARIA

ARIA 0.8 הוצע לראשונה ב-2003 בוועידה השנתית לאבטחת מידע של דרום קוריאה. בתחילה הצופן הכיל רק 10, 12, או 14 סבבים בהתאם לאורך המפתח 128/192/256 והכיל רק שתי תיבות החלפה בהן נעשה שימוש לסירוגין. בגרסה 0.9 שהוצעה ב-ICIS 2003 נוספו שתי תיבות החלפה. גרסה 1.0 הנוכחית הוכרזה והופצה על ידי NSRI ב-2004. מספר הסבבים עלה ל-12/14/16 בהתאמה וכן בוצעו שינויים בתהליך הרחבת המפתח. בדצמבר 2004 הכניס מכון התקנים של דרום קוריאה את הצופן לתקן KS X 1213.

ARIA מתאים ליישום בחומרת 8 ביט וכן ב-32 ביט הן בתוכנה והן בחומרה. רוב הפעולות בצופן הן פעולות החלפה פשוטות אותן אפשר לבצע ביעילות עם טבלאות חיפוש (lookup table). אם הזיכרון זמין ניתן להמיר את שכבת הפיזור להכפלה בארבע מטריצות וכן אפשר לשלב את שכבת ההחלפה יחד עם שכבת הפיזור באופן יעיל ולהשיג בכך שיפור משמעותי בתפוקת הצופן. באופן כללי תפוקת ARIA דומה לזו של AES וטובה מקמליה.

תיאור כללי

הצופן בנוי מרשת החלפה תמורה המבצעת סדרה של פעולות הפיכות על בלוק קלט באורך 128 סיביות הנקרא "מצב" (state) באופן אחיד. הפעולות הן ברמה של בתים והמצב הפנימי מיוצג כמערך המכיל 16 בתים. הצופן מבצע את פעולות המצב באופן חוזר ונשנה 12, 14 או 16 פעמים בהתאם לאורך המפתח. עבור מפתח 128 סיביות מבוצעים בסך הכול 12 סבבים, עבור מפתח באורך 192 סיביות מבוצעים בסך הכול 14 סבבים ואילו עבור מפתח באורך 256 סיביות מבוצעים 16 סבבים. המצב הפנימי מאותחל בתחילה עם סיביות הקלט, בכל סבב הצופן מעדכן את המצב והפלט הסופי הוא המצב האחרון לאחר כל הסבבים. פעולות הצופן מחולקות לשלושה מרכיבים:

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

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

פירוט פעולות הצופן

הפעולות הבאות מבוצעות על כל בתי המצב באופן אחיד.

שכבת החלפה

בשכבת ההחלפה (substitution layer) משתמש ARIA בשתי תיבות החלפה S1 ו-S2 וכן התיבות ההופכיות שלהן S11 ו-S21. תיבות ההחלפה נתונות בארבע הטבלאות להלן. הטבלאות בנויות מ-16 שורות ו-16 עמודות, בסך הכול 256 כניסות, כל כניסה מכילה מספר באורך 8 סיביות בטווח בין 0 ל-256 (או שתי ספרות הקסדצימליות בין 0x00 ל-0xff). הקלט לפונקציית ההחלפה הוא בית אחד המשמש כאינדקס לשורה והעמודה בטבלה, הניבל הראשון (ספרה הקסדצימלית ראשונה בטווח בין 0 ל-15) מציין עמודה ואילו הניבל השני מציין שורה. למשל אם הקלט הוא 0x00 הטבלה S1 תחזיר 0x63 (בבסיס הקסדצימלי) ואילו הטבלה S2 תחזיר 0xe2 וכן S11(0x95)=0xad או S21(0x48)=0x67:

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

הצופן עושה שימוש בתיבות ההחלפה בשני אופנים (כמתואר בתרשים לעיל). באופן הראשון הנקרא type 1 הבית הראשון מוחלף לפי התיבה הראשונה S1 הבית השני לפי התיבה S2, השלישי והרביעי לפי ההופכיות שלהן S11 ו-S21 בהתאמה, החמישי והשישי שוב בתיבה הראשונה והשנייה וחוזר חלילה עד שמחליפים את כל בתי המצב. באופן השני הנקרא type 2 מבצעים את ההחלפה בסדר הפוך תחילה בתיבות ההופכיות S11 ו-S21 ולאחר מכן S1 ו-S2 לסירוגין, כמתואר בתרשים להלן. הפסאודו קוד הבא מתאר את פונקציות ההחלפה SL1 ו-SL2 לפי type 1 ו-type 2 בהתאמה, הקלט הוא המצב הנוכחי X=x0,...,x15 והפלט הוא המצב החדש Y=y0,...,y15:

Y=SL1(X)
y0=S1(x0), y1=S2(x1), y2=S11(x2), y3=S21(x3),
y4=S1(x4), y5=S2(x5), y6=S11(x6), y7=S21(x7),
y8=S1(x8), y9=S2(x9), y10=S11(x10), y11=S21(x11),
y12=S1(x12), y13=S2(x13), y14=S11(x14), y15=S21(x15)
Y=SL2(X)
y0=S11(x0), y1=S21(x1), y2=S1(x2), y3=S2(x3),
y4=S11(x4), y5=S21(x5), y6=S1(x6), y7=S2(x7),
y8=S11(x8), y9=S21(x9), y10=S1(x10), y11=S2(x11),
y12=S11(x12), y13=S21(x13), y14=S1(x14), y15=S2(x15)
סדר השימוש בתיבות ההחלפה

שכבת פיזור

שכבת הפיזור היא פונקציה המסומנת באות A הממפה קלט באורך 16 בתים (x0,x1,...,x15) לפלט באורך דומה (y0,y1,...,y15) והיא מוגדרת כדלהלן:

y0=x3x4x6x8x9x13x14,
y1=x2x5x7x8x9x12x15,
y2=x1x4x6x10x11x12x15,
y3=x0x5x7x10x11x13x14,
y4=x0x2x5x8x11x14x15,
y5=x1x3x4x9x10x14x15,
y6=x0x2x7x9x10x12x13,
y7=x1x3x6x8x11x12x13,
y8=x0x1x4x7x10x13x15,
y9=x0x1x5x6x11x12x14,
y10=x2x3x5x6x8x13x15,
y11=x2x3x4x7x9x12x14,
y12=x1x2x6x7x9x11x12,
y13=x0x3x6x7x8x10x13,
y14=x0x3x4x5x9x11x14,
y15=x1x2x4x5x8x10x15.

שכבת הפיזור של ARIA תוכננה כך שהיא תהיה אינוולוציה כלומר עבור כל וקטור x מתקיים A(A(x))=x. דרך אחרת להציג את המיפוי של A היא על ידי כפל מטריצות הבא:

שכבת הפיזור של ARIA המבוצעת ככפל מטריצות

פונקציות סבב

בכל סבב של צופן ARIA מופעלת אחת משתי הפונקציות Fe ו-Fo שהן פונקציות סבב זוגית ואי זוגית בהתאמה המבצעות את שלוש הפעולות המתוארות לפי הסדר: הוספת מפתח, החלפה ופיזור, או בניסוח רשמי:

Fo(Pi,eki)=A(SL1(Pieki))
Fe(Pi,eki)=A(SL2(Pieki))

כאשר Pi הוא הבלוק הקלט של סבב i ו-A היא פונקציית הפיזור, SLi מתייחס לשכבת ההחלפה והערכים eki הם מפתחות הסבב אותם מכינים לפי תיאור תהליך הכנת המפתחות להלן. ההבדל בין שתי הפונקציות הוא סדר ההחלפה, ב-Fo ההחלפה מבוצעת לפי type 1 ואילו Fe היא לפי type 2.

הכנת מפתח

תיאור תהליך הרחבת המפתח של ARIA

תהליך ההכנה של מפתחות ההצפנה עבור כל הסבבים כולל שני שלבים: בשלב הראשון מכינים ארבעה ערכים באורך 128 סיביות כל אחד המסומנים W0,W1,W2,W3 בהם מציבים את המפתח הסודי MK (מפתח מאסטר) שהוא המפתח הסודי שסופק על ידי המשתמש, תוך שימוש ברשת פייסטל בשלושה סבבים לפי השיטה הבאה. תחילה מחלקים את המפתח הסודי לשני חצאים ימין ושמאל, כלומר מציבים את 128 הסיביות הראשונות של MK במשתנה זמני KL ומה שנותר מהמפתח מציבים במשתנה זמני נוסף KR. יתר סיביות המשתנה הזמני KR מאופסות. כך שמתקבל:

KL  KR=MK  0...0

הסימן מייצג שרשור. בשלב השני מיישמים את רשת פייסטל בשלושה סבבים כך:

W0=KL
W1=Fo(W0,CK1)KR
W2=Fe(W1,CK2)W0
W3=Fo(W2,CK3)W1

הפונקציות Fe ו-Fo הן פונקציות הסבב המתוארות לעיל כאשר הקבועים CKi משמשים כמפתחות הצפנה. כדי להכין את הקבועים CKi תחילה מחשבים את 128×3 הסיביות הראשונות של חלק השבר של π1 כשהן מחולקות לשלושה המשתנים. הערכים הם:

C1=0x517cc1b727220a94fe12abe8fa9a6ee0
C2=0x6db14acc9e21c820ff28b1d5ef5de2b0
C3=0xdb92371d2126e9700324977504e8c90e

ואז הקבועים CKi מוגדרים בהתאם לאורך המפתח, לדוגמה עבור מפתח 128 סיביות משתמשים בקבועים לפי הסדר הזה ואילו עבור מפתחות אחרים משנים את סדר הקבועים לפי הטבלה הבאה:

גודל מפתח CK1 CK2 CK3
128 C1 C2 C3
192 C2 C3 C1
256 C3 C1 C2

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

ek1=(W0)(W119),ek2=(W1)(W219),
ek3=(W2)(W319),ek4=(W019)(W3),
ek5=(W0)(W131),ek6=(W1)(W231),
ek7=(W2)(W331),ek8=(W031)(W3),
ek9=(W0)(W161),ek10=(W1)(W261),
ek11=(W2)(W361),ek12=(W061)(W3),
ek13=(W0)(W131),ek14=(W1)(W231),
ek15=(W2)(W331),ek16=(W031)(W3),
ek17=(W0)(W119)

הביטוי n פירושו הזזה מעגלית ברמה של סיביות n צעדים לשמאל בגבולות משתנה באורך 32 סיביות.

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

dk1=ekn1,dk2=A(ekn),dk3=A(ekn1),...,dkn=A(ek2),dkn+1=ek1.

הצפנה ופענוח

להצפנת בלוק טקסט קריא P באורך 16 בתים עם מפתח באורך 128 סיביות, משתמשים ב-13 מפתחות הסבבים ek1,ek2,...,ek13 מתהליך הכנת המפתחות לעיל ומבצעים:

P1=Fo(P,ek1)
P2=Fe(P1,ek2)
P3=Fo(P2,ek3)
P4=Fe(P3,ek4)
P5=Fo(P4,ek5)
P6=Fe(P5,ek6)
P7=Fo(P6,ek7)
P8=Fe(P7,ek8)
P9=Fo(P8,ek9)
P10=Fe(P9,ek10)
P11=Fo(P10,ek11)
C=SL2(P11ek12)ek13

C הוא הטקסט המוצפן. הפונקציות Fe ו-Fo הן פונקציות הסבב המתוארות לעיל. בסבב האחרון הושמטה פונקציית הפיזור A ובמקומה מבוצע חיבור עם המפתח ה-13. במקרה של מפתחות אחרים המבנה נותר זהה ורק מספר הסבבים משתנה. פונקציית הפענוח של ARIA זהה לחלוטין לפונקציית ההצפנה למעט מפתחות הסבבים המוחלפים ב-dk1,dk2,...,dk13 אותם מכינים ממפתחות ההצפנה כמתואר לעיל.

וקטור בדיקה

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

טקסט קריא להצפנה 00112233445566778899aabbccddeeff
מפתח 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
טקסט מוצפן f92bd7c79fb72e2f2b8f80c1972d24fc

קוד לדוגמה

typedef unsigned int uint;
typedef unsigned char byte;
#define ARIA_BLOCK_SIZE 16
#define MODE_ENC 0
#define MODE_DEC 1
#define SWAPINT32(x) ( \
      (((x) & 0x000000FFUL) << 24) | (((x) & 0x0000FF00UL) << 8) | \
      (((x) & 0x00FF0000UL) >> 8) |  (((x) & 0xFF000000UL) >> 24))

typedef struct
{
	uint nr;
	uint k[16];
	uint ek[68];
	uint dk[68];
	bool mode = false;
} AriaContext;

//Move operation
#define MOV128(b, a) \
    { \
       (b)[0] = (a)[0]; (b)[1] = (a)[1]; \
       (b)[2] = (a)[2]; (b)[3] = (a)[3]; \
    }

//XOR operation
#define XOR128(b, a) \
    { \
       (b)[0] ^= (a)[0]; (b)[1] ^= (a)[1]; \
       (b)[2] ^= (a)[2]; (b)[3] ^= (a)[3]; \
    }

//Rotate left operation
#define ROL128(b, a, n) \
    { \
       (b)[0] = ((a)[((n) / 32 + 0) % 4] << ((n) % 32)) | ((a)[((n) / 32 + 1) % 4] >> (32 - ((n) % 32))); \
       (b)[1] = ((a)[((n) / 32 + 1) % 4] << ((n) % 32)) | ((a)[((n) / 32 + 2) % 4] >> (32 - ((n) % 32))); \
       (b)[2] = ((a)[((n) / 32 + 2) % 4] << ((n) % 32)) | ((a)[((n) / 32 + 3) % 4] >> (32 - ((n) % 32))); \
       (b)[3] = ((a)[((n) / 32 + 3) % 4] << ((n) % 32)) | ((a)[((n) / 32 + 0) % 4] >> (32 - ((n) % 32))); \
    }

//Substitution layer SL1
#define SL1(b, a) \
    { \
       byte *x = (byte *) (a); \
       byte *y = (byte *) (b); \
       y[0] = sb1[x[0]];     y[1] = sb2[x[1]]; \
       y[2] = sb3[x[2]];     y[3] = sb4[x[3]]; \
       y[4] = sb1[x[4]];     y[5] = sb2[x[5]]; \
       y[6] = sb3[x[6]];     y[7] = sb4[x[7]]; \
       y[8] = sb1[x[8]];     y[9] = sb2[x[9]]; \
       y[10] = sb3[x[10]];   y[11] = sb4[x[11]]; \
       y[12] = sb1[x[12]];   y[13] = sb2[x[13]]; \
       y[14] = sb3[x[14]];   y[15] = sb4[x[15]]; \
    }

//Substitution layer SL2
#define SL2(b, a) \
    { \
      byte *x = (byte *) (a); \
      byte *y = (byte *) (b); \
      y[0] = sb3[x[0]];       y[1] = sb4[x[1]]; \
      y[2] = sb1[x[2]];       y[3] = sb2[x[3]]; \
      y[4] = sb3[x[4]];       y[5] = sb4[x[5]]; \
      y[6] = sb1[x[6]];       y[7] = sb2[x[7]]; \
      y[8] = sb3[x[8]];       y[9] = sb4[x[9]]; \
      y[10] = sb1[x[10]];     y[11] = sb2[x[11]]; \
      y[12] = sb3[x[12]];     y[13] = sb4[x[13]]; \
      y[14] = sb1[x[14]];     y[15] = sb2[x[15]]; \
   }

//Diffusion layer
#define A(b, a) \
   { \
      byte *x = (byte *) (a); \
      byte *y = (byte *) (b); \
      y[0] = x[3] ^ x[4] ^ x[6] ^ x[8] ^ x[9] ^ x[13] ^ x[14]; \
      y[1] = x[2] ^ x[5] ^ x[7] ^ x[8] ^ x[9] ^ x[12] ^ x[15]; \
      y[2] = x[1] ^ x[4] ^ x[6] ^ x[10] ^ x[11] ^ x[12] ^ x[15]; \
      y[3] = x[0] ^ x[5] ^ x[7] ^ x[10] ^ x[11] ^ x[13] ^ x[14]; \
      y[4] = x[0] ^ x[2] ^ x[5] ^ x[8] ^ x[11] ^ x[14] ^ x[15]; \
      y[5] = x[1] ^ x[3] ^ x[4] ^ x[9] ^ x[10] ^ x[14] ^ x[15]; \
      y[6] = x[0] ^ x[2] ^ x[7] ^ x[9] ^ x[10] ^ x[12] ^ x[13]; \
      y[7] = x[1] ^ x[3] ^ x[6] ^ x[8] ^ x[11] ^ x[12] ^ x[13]; \
      y[8] = x[0] ^ x[1] ^ x[4] ^ x[7] ^ x[10] ^ x[13] ^ x[15]; \
      y[9] = x[0] ^ x[1] ^ x[5] ^ x[6] ^ x[11] ^ x[12] ^ x[14]; \
      y[10] = x[2] ^ x[3] ^ x[5] ^ x[6] ^ x[8] ^ x[13] ^ x[15]; \
      y[11] = x[2] ^ x[3] ^ x[4] ^ x[7] ^ x[9] ^ x[12] ^ x[14]; \
      y[12] = x[1] ^ x[2] ^ x[6] ^ x[7] ^ x[9] ^ x[11] ^ x[12]; \
      y[13] = x[0] ^ x[3] ^ x[6] ^ x[7] ^ x[8] ^ x[10] ^ x[13]; \
      y[14] = x[0] ^ x[3] ^ x[4] ^ x[5] ^ x[9] ^ x[11] ^ x[14]; \
      y[15] = x[1] ^ x[2] ^ x[4] ^ x[5] ^ x[8] ^ x[10] ^ x[15]; \
   }

//S-box 1
static const byte sb1[256] =
{
	0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
	0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
	0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
	0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
	0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
	0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
	0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
	0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
	0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
	0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
	0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
	0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
	0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
	0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
	0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
	0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};

//S-box 2
static const byte sb2[256] =
{
	0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46, 0x3C, 0x4D, 0x8B, 0xD1,
	0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1,
	0x1D, 0x06, 0x41, 0x6B, 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
	0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA, 0x0F, 0xEE, 0x10, 0xEB,
	0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD,
	0x08, 0x7A, 0x88, 0x38, 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
	0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, 0x32, 0xCA, 0xE9, 0xB1,
	0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40,
	0xEC, 0x20, 0x8C, 0xBD, 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
	0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E, 0xE8, 0x25, 0x92, 0xE5,
	0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A, 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43,
	0xA7, 0xE1, 0xD0, 0xF5, 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
	0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, 0x16, 0x82, 0x5F, 0xDA,
	0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C,
	0x90, 0x0B, 0x5B, 0x33, 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
	0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, 0xAF, 0xBA, 0xB5, 0x81
};

//S-box 3
static const byte sb3[256] =
{
	0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
	0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
	0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
	0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
	0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
	0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
	0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
	0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
	0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
	0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
	0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
	0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
	0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
	0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
	0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
	0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

//S-box 4
static const byte sb4[256] =
{
	0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1, 0x72, 0x09, 0x62, 0x3C,
	0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3, 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D,
	0x81, 0x65, 0xF5, 0x89, 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
	0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98, 0x0C, 0xF4, 0x9B, 0xED,
	0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B,
	0x8C, 0xC2, 0xE6, 0x5F, 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
	0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, 0xDF, 0xEF, 0xCA, 0xD9,
	0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41,
	0xDA, 0xFF, 0xCD, 0x55, 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
	0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE, 0x29, 0xAE, 0x92, 0xD7,
	0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0, 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC,
	0xEB, 0x6F, 0xD5, 0xF6, 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
	0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, 0x07, 0x4F, 0x4E, 0x45,
	0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D,
	0xF2, 0xB1, 0x00, 0x94, 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
	0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, 0x03, 0xA2, 0xAC, 0x60
};

//Key scheduling constants
static const uint c[12] =
{
	SWAPINT32(0x517CC1B7), SWAPINT32(0x27220A94), SWAPINT32(0xFE13ABE8), SWAPINT32(0xFA9A6EE0),
	SWAPINT32(0x6DB14ACC), SWAPINT32(0x9E21C820), SWAPINT32(0xFF28B1D5), SWAPINT32(0xEF5DE2B0),
	SWAPINT32(0xDB92371D), SWAPINT32(0x2126E970), SWAPINT32(0x03249775), SWAPINT32(0x04E8C90E)
};

static void OF(uint *d, const uint *rk)
{
	uint t[4];
	XOR128(d, rk);  //XOR D with RK
	SL1(t, d);      //Substitution layer SL1
	A(d, t);        //Diffusion layer
}

static void EF(uint *d, const uint *rk)
{
	uint t[4];
	XOR128(d, rk);   //XOR D with RK
	SL2(t, d);       //Substitution layer SL2
	A(d, t);         //Diffusion layer
}

int ariaInit(AriaContext *context, const byte *key, size_t keyLength)
{
	uint i;
	uint *ek, *dk;
	const uint *ck1, *ck2, *ck3;
	uint w[16];

	//128-bit master key?
	if (keyLength == 16)
	{
		ck1 = c + 0;  //Select the relevant constants
		ck2 = c + 4;
		ck3 = c + 8;
		//The number of rounds depends on the size of the master key
		context->nr = 12;
	} else if (keyLength == 24) { //192-bit master key?
	    ck1 = c + 4;  //Select the relevant constants
		ck2 = c + 8;
		ck3 = c + 0;
		//The number of rounds depends on the size of the master key
		context->nr = 14;
	} else if (keyLength == 32)	{  //256-bit master key?
		ck1 = c + 8;   //Select the relevant constants
		ck2 = c + 0;
		ck3 = c + 4;
		//The number of rounds depends on the size of the master key
		context->nr = 16;
	}
	else return -1;

	//Compute 128-bit values KL and KR
	memset(w, 0, sizeof(w));
	memcpy(w, key, keyLength);

	//Save KR...
	MOV128(w + 8, w + 4);

	//Compute intermediate values W0, W1, W2, and W3
	MOV128(w + 4, w + 0);
	OF(w + 4, ck1);
	XOR128(w + 4, w + 8);

	MOV128(w + 8, w + 4);
	EF(w + 8, ck2);
	XOR128(w + 8, w + 0);

	MOV128(w + 12, w + 8);
	OF(w + 12, ck3);
	XOR128(w + 12, w + 4);

	//Convert from big-endian byte order to host byte order
	for (i = 0; i < 16; i++)
		w[i] = SWAPINT32(w[i]);

	//Point to the encryption round keys
	ek = context->ek;

	//Compute ek1, ..., ek17 as follow
	ROL128(ek + 0, w + 4, 109);    	XOR128(ek + 0, w + 0);
	ROL128(ek + 4, w + 8, 109);  	XOR128(ek + 4, w + 4);
	ROL128(ek + 8, w + 12, 109);	XOR128(ek + 8, w + 8);
	ROL128(ek + 12, w + 0, 109);	XOR128(ek + 12, w + 12);
	ROL128(ek + 16, w + 4, 97);   	XOR128(ek + 16, w + 0);
	ROL128(ek + 20, w + 8, 97); 	XOR128(ek + 20, w + 4);
	ROL128(ek + 24, w + 12, 97);	XOR128(ek + 24, w + 8);
	ROL128(ek + 28, w + 0, 97);  	XOR128(ek + 28, w + 12);
	ROL128(ek + 32, w + 4, 61); 	XOR128(ek + 32, w + 0);
	ROL128(ek + 36, w + 8, 61); 	XOR128(ek + 36, w + 4);
	ROL128(ek + 40, w + 12, 61); 	XOR128(ek + 40, w + 8);
	ROL128(ek + 44, w + 0, 61); 	XOR128(ek + 44, w + 12);
	ROL128(ek + 48, w + 4, 31); 	XOR128(ek + 48, w + 0);
	ROL128(ek + 52, w + 8, 31); 	XOR128(ek + 52, w + 4);
	ROL128(ek + 56, w + 12, 31); 	XOR128(ek + 56, w + 8);
	ROL128(ek + 60, w + 0, 31); 	XOR128(ek + 60, w + 12);
	ROL128(ek + 64, w + 4, 19); 	XOR128(ek + 64, w + 0);

	//Convert from host byte order to big-endian byte order
	for (i = 0; i < 68; i++)
		ek[i] = SWAPINT32(ek[i]);

	//Decryption round keys are derived from the encryption round keys
	dk = context->dk;
	//Compute dk1
	MOV128(dk + 0, ek + context->nr * 4);

	//Compute dk2, ..., dk(n)
	for (i = 1; i < context->nr; i++)
		A(dk + i * 4, ek + (context->nr - i) * 4);

	//Compute dk(n + 1)
	MOV128(dk + i * 4, ek + 0);

	//No error to report
	return 0;
}


void ariaEncryptBlock(AriaContext *context, const byte *input, byte *output, bool mode)
{
	uint *ek;
	uint p[4], q[4];

	//Copy the plaintext to the buffer
	memcpy(p, input, ARIA_BLOCK_SIZE);

	//Point to the encryption/decryption round keys
	if(mode == MODE_DEC) ek = context->dk;
	else ek = context->ek;
	
	//Apply 11 rounds
	OF(p, ek + 0);     	EF(p, ek + 4);
	OF(p, ek + 8);   	EF(p, ek + 12);
	OF(p, ek + 16);  	EF(p, ek + 20);
	OF(p, ek + 24); 	EF(p, ek + 28);
	OF(p, ek + 32); 	EF(p, ek + 36);
	OF(p, ek + 40);

	//128-bit master keys require a total of 12 rounds
	if (context->nr == 12)
	{
		XOR128(p, ek + 44);
		SL2(q, p);
		XOR128(q, ek + 48);
	} else if (context->nr == 14) {  //192-bit master keys require a total of 14 rounds
		EF(p, ek + 44);
		OF(p, ek + 48);
		XOR128(p, ek + 52);
		SL2(q, p);
		XOR128(q, ek + 56);
	} else { //256-bit master keys require a total of 16 rounds
		EF(p, ek + 44);
		OF(p, ek + 48);
		EF(p, ek + 52);
		OF(p, ek + 56);
		XOR128(p, ek + 60);
		SL2(q, p);
		XOR128(q, ek + 64);
	}
	//Copy the resulting ciphertext from the buffer
	memcpy(output, q, ARIA_BLOCK_SIZE);
}

ראו גם

הערות שוליים

  1. New Block Cipher: ARIA
  2. A. Biryukov; C. De Canni're; J. Lano; B. Preneel; S. B. Ors (January 7, 2004). "Security and Performance Analysis of ARIA"(PostScript). Version 1.2-Final Report. Katholieke Universiteit Leuven. Retrieved March 2, 2007.
  3. Wenling Wu; Wentao Zhang; Dengguo Feng (2006). Impossible Differential Cryptanalysis of ARIA and Camellia (PDF). Retrieved January 19, 2007.
  4. Xuehai Tang; Bing Sun; Ruilin Li; Chao Li (March 30, 2010). "A Meet-in-the-Middle Attack on ARIA" (PDF). Retrieved April 24, 2010.
  5. Linear Cryptanalysis of ARIA Block Cipher
  6. Security Analysis of the Keyschedule of ARIA-128
הערך באדיבות ויקיפדיה העברית, קרדיט,
רשימת התורמים
רישיון cc-by-sa 3.0

ARIA (צופן)35156415Q840633