בשכבת ההחלפה (substitution layer) משתמש ARIA בשתי תיבות החלפה formula_3 ו-formula_4 וכן התיבות ההופכיות שלהן formula_5 ו-formula_6. תיבות ההחלפה נתונות בארבע הטבלאות להלן. הטבלאות בנויות מ-16 שורות ו-16 עמודות, בסך הכול 256 כניסות, כל כניסה מכילה מספר באורך 8 סיביות בטווח בין 0 ל-256 (או שתי ספרות הקסדצימליות בין formula_7 ל-formula_8). הקלט לפונקציית ההחלפה הוא בית אחד המשמש כאינדקס לשורה והעמודה בטבלה, הניבל הראשון (ספרה הקסדצימלית ראשונה בטווח בין 0 ל-15) מציין עמודה ואילו הניבל השני מציין שורה. למשל אם הקלט הוא formula_7 הטבלה formula_3 תחזיר formula_11 (בבסיס הקסדצימלי) ואילו הטבלה formula_4 תחזיר formula_13 וכן formula_14 או formula_15:
הצופן עושה שימוש בתיבות ההחלפה בשני אופנים (כמתואר בתרשים לעיל). באופן הראשון הנקרא type 1 הבית הראשון מוחלף לפי התיבה הראשונה formula_3 הבית השני לפי התיבה formula_4, השלישי והרביעי לפי ההופכיות שלהן formula_5 ו-formula_6 בהתאמה, החמישי והשישי שוב בתיבה הראשונה והשנייה וחוזר חלילה עד שמחליפים את כל בתי המצב. באופן השני הנקרא type 2 מבצעים את ההחלפה בסדר הפוך תחילה בתיבות ההופכיות formula_5 ו-formula_6 ולאחר מכן formula_3 ו-formula_4 לסירוגין, כמתואר בתרשים להלן. הפסאודו קוד הבא מתאר את פונקציות ההחלפה formula_24 ו-formula_25 לפי type 1 ו-type 2 בהתאמה, הקלט הוא המצב הנוכחי formula_26 והפלט הוא המצב החדש formula_27:
שכבת פיזור.
שכבת הפיזור היא פונקציה המסומנת באות A הממפה קלט באורך 16 בתים formula_28 לפלט באורך דומה formula_29 והיא מוגדרת כדלהלן:
שכבת הפיזור של ARIA תוכננה כך שהיא תהיה אינוולוציה כלומר עבור כל וקטור formula_30 מתקיים formula_31. דרך אחרת להציג את המיפוי של formula_32 היא על ידי כפל מטריצות הבא:
פונקציות סבב.
בכל סבב של צופן ARIA מופעלת אחת משתי הפונקציות formula_33 ו-formula_34 שהן פונקציות סבב זוגית ואי זוגית בהתאמה המבצעות את שלוש הפעולות המתוארות לפי הסדר: הוספת מפתח, החלפה ופיזור, או בניסוח רשמי:
כאשר formula_37 הוא הבלוק הקלט של סבב formula_38 ו-formula_32 היא פונקציית הפיזור, formula_40 מתייחס לשכבת ההחלפה והערכים formula_41 הם מפתחות הסבב אותם מכינים לפי תיאור תהליך הכנת המפתחות להלן. ההבדל בין שתי הפונקציות הוא סדר ההחלפה, ב-formula_34 ההחלפה מבוצעת לפי type 1 ואילו formula_33 היא לפי type 2.
הכנת מפתח.
תהליך ההכנה של מפתחות ההצפנה עבור כל הסבבים כולל שני שלבים: בשלב הראשון מכינים ארבעה ערכים באורך 128 סיביות כל אחד המסומנים formula_44 בהם מציבים את המפתח הסודי formula_45 (מפתח מאסטר) שהוא המפתח הסודי שסופק על ידי המשתמש, תוך שימוש ברשת פייסטל בשלושה סבבים לפי השיטה הבאה. תחילה מחלקים את המפתח הסודי לשני חצאים ימין ושמאל, כלומר מציבים את 128 הסיביות הראשונות של formula_45 במשתנה זמני formula_47 ומה שנותר מהמפתח מציבים במשתנה זמני נוסף formula_48. יתר סיביות המשתנה הזמני formula_48 מאופסות. כך שמתקבל:
הסימן formula_51 מייצג שרשור. בשלב השני מיישמים את רשת פייסטל בשלושה סבבים כך:
הפונקציות formula_33 ו-formula_34 הן פונקציות הסבב המתוארות לעיל כאשר הקבועים formula_54 משמשים כמפתחות הצפנה. כדי להכין את הקבועים formula_54 תחילה מחשבים את formula_56 הסיביות הראשונות של חלק השבר של formula_2 כשהן מחולקות לשלושה המשתנים. הערכים הם:
ואז הקבועים formula_54 מוגדרים בהתאם לאורך המפתח, לדוגמה עבור מפתח 128 סיביות משתמשים בקבועים לפי הסדר הזה ואילו עבור מפתחות אחרים משנים את סדר הקבועים לפי הטבלה הבאה:
את מפתחות כל הסבבים מכינים על ידי שילוב של ערכי formula_62 ומהם מייצרים את 17 מפתחות ההצפנה והפענוח עבור כל הסבבים:
הביטוי formula_63 פירושו הזזה מעגלית ברמה של סיביות formula_64 צעדים לשמאל בגבולות משתנה באורך 32 סיביות.
יש לשים לב שקיים מפתח סבב נוסף מעבר למספר הסבבים. מפתח זה נועד לשימוש בסבב האחרון שבו הטרנספורמציה A מוחלפת בשכבת הוספת מפתח נוספת. בסיכומו של דבר מספר המפתחות הדרוש הוא 13, 15 או 17 בהתאם לאורך המפתח. מפתחות הפענוח נגזרים ממפתחות ההצפנה כדלהלן:
הצפנה ופענוח.
להצפנת בלוק טקסט קריא formula_66 באורך 16 בתים עם מפתח באורך 128 סיביות, משתמשים ב-13 מפתחות הסבבים formula_67 מתהליך הכנת המפתחות לעיל ומבצעים:
formula_68 הוא הטקסט המוצפן. הפונקציות formula_33 ו-formula_34 הן פונקציות הסבב המתוארות לעיל. בסבב האחרון הושמטה פונקציית הפיזור A ובמקומה מבוצע חיבור עם המפתח ה-13. במקרה של מפתחות אחרים המבנה נותר זהה ורק מספר הסבבים משתנה. פונקציית הפענוח של ARIA זהה לחלוטין לפונקציית ההצפנה למעט מפתחות הסבבים המוחלפים ב-formula_71 אותם מכינים ממפתחות ההצפנה כמתואר לעיל.
וקטור בדיקה.
להלן וקטור בדיקה של הצפנה עם מפתח באורך 256 סיביות:
קוד לדוגמה.
typedef unsigned int uint;
typedef unsigned char byte;
(((x) &amp; 0x000000FFUL) « 24) | (((x) &amp; 0x0000FF00UL) « 8) | \
(((x) &amp; 0x00FF0000UL) » 8) | (((x) &amp; 0xFF000000UL) » 24))
typedef struct
uint nr;
uint k[16];
uint ek[68];
uint dk[68];
bool mode = false;
} AriaContext;
//Move operation
(b)[0] = (a)[0]; (b)[1] = (a)[1]; \
(b)[2] = (a)[2]; (b)[3] = (a)[3]; \
//XOR operation
(b)[0] ^= (a)[0]; (b)[1] ^= (a)[1]; \
(b)[2] ^= (a)[2]; (b)[3] ^= (a)[3]; \
//Rotate left operation
(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
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
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
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,