FEAL

בקריפטוגרפיה, FEAL (ראשי תיבות של Fast data Encipherment ALgorithm, בעברית: אלגוריתם הצפנת נתונים מהיר) כולל משפחה של צפני בלוקים במבנה פייסטל שהראשון שבהם הוצע כאלטרנטיבה לצופן DES והוא מהיר ממנו בתוכנה. הגרסה הראשונה פותחה ב-1987 על ידי אקירו שימיזו ושוי מיאגוטשי מתאגיד הטלגרף והטלפון של יפן (NTT). ב-1994 התקבל הצופן לתקן בינלאומי ISO/IEC9979 וב-1999 נבחר לתקן ATM וכן נכלל בתקן יפני לכרטיסים חכמים ב-1998. בשל קריפטואנליזה שמעידה על חולשות הצופן אינו בשימוש כיום. NTT ממליצים להשתמש בצופן מדור חדש כמו קמליה.
קיימות מספר גרסאות של FEAL כולן במבנה פייסטל עם אותה פונקציית סבב פנימית אך עם מספר סבבים שונה או עם מפתח גדול יותר. הצופן מקבל בלוק קלט באורך 64 סיביות ומחזיר בלוק מוצפן באורך 64 סיביות. הגרסה הראשונה שכיום נקראת FEAL-4 משתמשת במפתח הצפנה באורך 64 סיביות וכוללת ארבעה סבבים של הפונקציה הפנימית. FEAL-8 מכיל שמונה סבבים עם אותו מפתח ואילו FEAL-NX מכילה מספר דינאמי של סבבים בהתאם לצורך כך ש-. (המספר המומלץ הוא ) ואילו "X" מתייחס לאופציה של מפתח באורך 128 סיביות שנוספה בגרסה המאוחרת יותר.

ביטחון

מאז שפורסם הפך FEAL ליעד מועדף מצד קריפטונאליסטים מרחבי העולם ופורסמו מחקרים רבים אודות החולשות שלו. כיום ידוע שהצופן אינו בטוח לשימוש כי הוא פגיע במיוחד למספר התקפות קריפטוגרפיות מעשיות ביניהן קריפטואנליזה דיפרנציאלית וקריפטואנליזה ליניארית. למעשה הצופן שימש כ"קטליזטור" במהלך פיתוח התקפות קריפטוגרפיות אילו. הקריפטואנליזה הדיפרנציאלית הומצאה בשביל לפצח את FEAL ובתוך כך התגלתה ככלי יעיל לניתוח צפנים אחרים. כל גרסאות צופן FEAL אינן מומלצות כיום לשימוש כלל והעניין בהן הוא אקדמי בלבד.
בתחילה התגלו בעיות בגרסה הראשונה של הצופן על ידי דן בואר ושון מרפי שגילו התקפות קריפוטאנליטיות הדורשות כמות מועטה של טקסטים גלויים נבחרים כדי לפצח את הצופן בקלות. ההתקפות שלהם מכילות אלמנטים דומים להתקפה הדיפרנציאלית שהתגלתה מאוחר יותר. ב-1998 ניסו מפתחי הצופן לפתור את הבעיה על ידי העלאת מספר הסבבים וכך נוצר FEAL-8 הכולל שמונה סבבים במקום ארבעה.
ב-1991 פרסמו אלי ביהם ועדי שמיר את ההתקפה הדיפרנציאלית שלהם על FEAL-8. אחריהם פורסמו עוד כמה התקפות מסוג זה שמצליחות לפצח את הצופן עם כמות יחסית קטנה של טקסטים גלויים נבחרים. בתגובה פותח FEAL-NX אך הסתבר שההתקפה הדיפרנציאלית של שמיר וביהם הייתה ישימה גם נגד הגרסה הזו שהיא החזקה ביותר שפותחה, ההתקפה שלהם יעילה מכוח גס כל עוד .
ב-1991 גילו טארדי וגילברט התקפה חדשה נגד גרסאות צופן FEAL שמסוגלת לפצח אותו בסיבוכיות טובה מכוח גס. למשל FEAL-8 ניתן בשיטה זו לשבירה עם  טקסטים גלויים נבחרים. מאוחר יותר פרסם מיצורו מצואי את ההתקפה הליניארית שמבוססת על רעיון זה המסוגלת לשבור את צופן FEAL-4 בתוך כחמש דקות עם ששה טקסטים גלויים ידועים. ב-1994 פורסמה התקפה ליניארית נגד FEAL-8 עם  טקסטים גלויים נבחרים. למעשה בעקבות התקפות אילו נסתם הגולל על FEAL והוא אינו בשימוש כיום כלל. NTT ממליצים להשתמש בקמליה במקומו.
חשיבות הצופן וההתקפות המתוארות היא בעיקר בלקח שאפשר להפיק מהם. זהו הצופן הראשון שפותח על ידי NTT ושימש יסוד ובסיס להתפתחות צפני בלוקים מודרניים חזקים יותר ועמידים יותר נגד קריפטואנליזה דיפרנציאלית וליניארית כמו E2 שהיה מהמועמדים לתקן AES ולא הגיע לגמר וקמליה שנחשב לצופן מודרני חזק.

קוד לדוגמה

void FEAL_keygen(byte *k, byte *e, uint r){
byte a[4], b[4], d[4], kr1[4], kr2[4], t, s[4];

for (uint i = 0; i < 4; i++) {
a[i] = k[i], b[i] = k[i + 4];
kr1[i] = k[i + 8], kr2[i] = k[i + 12];
d[i] = 0;
}

for (uint i = 0; i < r + 8; i += 2) {
for (uint j = 0; j < 4; j++) {
s[j] = b[j];
if ((i / 2) % 3 == 0) {
s[j] ^= (kr1[j] ^ kr2[j]);
}
else if ((i / 2) % 3 == 1) {
s[j] ^= kr1[j];
}
else {
s[j] ^= kr2[j];
}
s[j] ^= d[j];
d[j] = a[j];  /*  for next steps  */
}
FEAL_Fk(a, s);

for (uint j = 0; j < 4; j++) {
e[2 * i + j] = a[j];
}

for (uint j = 0; j < 4; j++) {
t = a[j];
a[j] = b[j], b[j] = t;
}
}}void FEAL_encrypt(byte *p, uint r, byte *e, byte *c){
byte a[4], b[4], t, s[4];

for (uint j = 0; j < 4; j++) {
a[j] = p[j] ^ e[2 * r + j];
b[j] = p[j + 4] ^ e[2 * r + j + 4] ^ a[j];
}

for (uint i = 0; i < r; i++) {
FEAL_F(s, b, e + 2 * i);

for (uint j = 0; j < 4; j++) {
a[j] ^= s[j];
}

for (uint j = 0; j < 4; j++) {
t = a[j];
a[j] = b[j], b[j] = t;
}
}

for (uint j = 0; j < 4; j++) {
a[j] ^= b[j];
}

for (uint j = 0; j < 4; j++) {
c[j] = (b[j] ^ e[2 * r + j + 8]);
c[j + 4] = (a[j] ^ e[2 * r + j + 12]);
}}void FEAL_decrypt(byte *c, uint r, byte *e, byte *p){
byte a[4], b[4], t, s[4];

for (uint j = 0; j < 4; j++) {
a[j] = c[j] ^ e[2 * r + j + 8];
b[j] = c[j + 4] ^ e[2 * r + j + 12] ^ a[j];
}

for (uint i = 0; i < r; i++) {
FEAL_F(s, b, e + 2 * (r - 1 - i));

for (uint j = 0; j < 4; j++) {
a[j] ^= s[j];
}

for (uint j = 0; j < 4; j++) {
t = a[j];
a[j] = b[j], b[j] = t;
}
}

for (uint j = 0; j < 4; j++) {
a[j] ^= b[j];
}

for (uint j = 0; j < 4; j++) {
p[j] = (b[j] ^ e[2 * r + j]);
p[j + 4] = (a[j] ^ e[2 * r + j + 4]);
}}