ב-2005 דווח על סוג של ההתקפה דיפרנציאלית נגד גרסה מצומצמת של סלסה בחמשה סבבים, מסומן בקיצור Salsa20/5 בסיבוכיות זמן של formula_60 בקירוב. מפתח ההתקפה זכה באלף דולר מאת דניאל ברנשטיין שהבטיח את הפרס לכל מי שיצליח להציג "קריפטואנליזה הכי מעניינת של סלסה". ב-2006 הצליחו מספר חוקרים לפתח התקפה כנגד Salsa20/6 בסיבוכיות זמן של formula_61 וכן התקפת Related key על Salsa20/7 בזמן של formula_62. ב-2007 פותחה התקפה על Salsa20/8 בזמן של formula_63 עם formula_64 מפתחות. ב-2008 פותחה התקפה נגד Salsa20/7 בזמן של formula_65 וכן התקפה על Salsa20/8 בזמן של formula_66. ב-2012 התקפה של אמסון ושי כנגד Salsa20/8 הצליחה לשבור את הצופן בזמן של formula_67 או בזמן של formula_68 במקרה של מפתח 256 סיביות עם 8 סבבים. ב-2013 פורסמה הוכחה שצופן סלסה מעל 15 סבבים בטוח כנגד התקפה דיפרנציאלית, כלומר לא נמצאו מאפיינים דיפרנציאליים בהסתברות גבוהה מ-formula_69 כך שהיא אינה יעילה מכוח גס.
Salsa20 מהיר יותר מ-AES ובמבחני ביצועים של eSTREAM נמצא שבעשרים סבבים הצופן מסוגל להצפין בקצב של 3.93 מחזורי שעון לבית על Xeon בעל ליבה כפולה 3 גיגה-הרץ. כמו כן קיימות שתי גרסאות של הצופן פחותות סבבים הנקראות Salsa20/8 ו-Salsa20/12 עם שמונה סבבים או 12 סבבים בהתאמה, המיועדים למשתמשים הרואים צורך בצופן יעיל ומוכנים להקריב מעט בביטחונו.
ChaCha.
ב-2008 הציע דניאל ברנשטיין את משפחת ChaCha שהיא גרסה משופרת של צפני זרם החולקת אותם עקרונות תכנון עם Salsa20 אך בשינויים קלים שנועדו בעיקר להגברת רמת הפיזור (diffusion) של הצופן. הפיזור הנוסף אינו בא על חשבון ביצועים, כמו ב-Salsa20 בכל סבב מתבצעים 16 פעולות חיבור, XOR והזזה מעגלית בהיסטים קבועים וכן נשמרת אותה רמת מקביליות ואף יותר. ההערכה היא שגרסאות ChaCha מספקות עמידות גבוהה יותר נגד קריפטואנליזה ומשפרות במעט את הביצועים אם כי רק על פלטפורמות מסוימות. בגלל אחידות כמות העבודה בכל סבב, למספר הסבבים השפעה ישירה על ביצועי הצופן. מסיבה זו הוצעו גרסאות מופחתות סבבים לשיפור ביצועים על חשבון ביטחון. ChaCha8 מבוסס על Salsa20 עם שמונה סבבים, ChaCha12 על Salsa20 עם 12 סבבים בהתאמה. ההבדלים בין צופן Salsa וצופן ChaCha הם כדלהלן:
פונקציית QuarterRound.
פונקציית הסבב הפנימית של ChaCha גם היא מבצעת 4 פעולות חיבור, 4 פעולות XOR ו-4 פעולות הזזה מעגלית על ארבעה משתני המצב הפנימי אך בסדר שונה. ב-Salsa20 כל משתנה מעודכן בפעולה אחת למשל formula_70. לעומתו ב-ChaCha כל מילה מעודכנת פעמיים בנפרד, כך שכל מילת קלט משפיעה על מילות קלט אחרות בשני הכיוונים. אפשר לראות על ידי מעקב אחרי כל סיבית כי ב-ChaCha לפחות 12.5 סיביות בממוצע משתנות בכל סבב לעומת רק 8 ב-Salsa20.
בנוסף קיים הבדל פחות משמעותי בערכי ההיסטים הקבועים של ההזזה המעגלית 16,12,8,7 לעומת 7,9,13,18 ב-Salsa20. ההשפעה של הבדל זה על ביטחון הצופן זניחה. לעומת זאת קיים שיפור במהירות על פלטפורמות מסוימות.
מטריצת הקלט.
בצופן Salsa20 הקלט המורכב מוקטור אתחול ומונה בלוקים וכן שמונה מילות מפתח וארבע מילים קבועות, נטענים לתוך טבלה או מטריצה ראשונית formula_71 במבנה זה:
בכל הרצה של הצופן הפונקציה הפנימית מעבדת במקביל את עמודות המטריצה האמורה formula_72 פעמים ואז מחברת את התוצאה הסופית עם המטריצה הראשונית לקבלת 16 מילים של הפלט. במימושי תוכנה ממוטבים של Salsa20 נהוג היה לבצע תחילה תמורה פנימית של המטריצה הראשונית כך שהעמודה השנייה מוסטת שורה אחת כלפי מעלה, העמודה השלישית שתי שורות כלפי מעלה והרביעית שלוש ומתקבל:
השפעת השינוי על ביטחון הצופן זניחה, לעומת זאת חל שיפור בביצועים כיוון שכעת ניתן לממש ארבעה רבעים של הפונקציה הפנימית בהוראת SIMD אחת על וקטורים (ראה עיבוד מקבילי). הרעיון הוא שהיות שהפונקציה הפנימית מופעלת על כניסות המטריצה באלכסונים, ההיסט גורם לכך שהאלכסון יהפוך לעמודה ואז ניתן להבצע את החישוב בפקודה אחת. שינוי דומה נעשה בסבב השני וכן הסבב השלישי כמו הראשון והרביעי כמו השני. רעיון דומה נעשה ב-ChaCha מאותה סיבה אך בשלושה שינויים. תחילה נעשה השינוי בסדר המילים בבלוק הפלט כדי להתאימו לשינוי המתואר לעיל. זאת על מנת לשפר ביצועים על פלטפורמות התומכות ב-SIMD. בנוסף המטריצה הראשונית מסודרת אחרת:
הנתונים פשוט נטענים לפי סדר קליטתם כאשר הקלט שהוא בשליטת המשתמש (וכן התוקף במקרה של קריפטואנליזה) מוצב בשורה האחרונה. הסבב הראשון תחילה מחבר את הקבועים למפתחות ואז מבצע XOR של התוצאות עם הקלטים, מבצע הזזה מעגלית ושוב מחבר עם המפתחות וכן הלאה. השינוי השלישי הוא, עיבוד השורות מתבצע באותו סדר בכל הסבבים לפי המוצג בתרשים הבא:
ארבעת הרבעים של כל סבב תמיד מסודרים מלמעלה למטה מה שמוסיף מהיבט של מהירות. פונקציית הגיבוב BLAKE הנמנית עם רשימת הפינלסטים של תחרות הגיבוב של NIST וגרסת ההמשך שלה BLAKE2 מבוססים על ChaCha.
שימושים.
ב-2014 אימצה גוגל את ChaCha יחד עם קוד אימות מסרים Poly1305 כתחליף ל-RC4 ב-OpenSSL. כמו כן המימוש של גוגל עבור TLS משמש להגנה על תעבורת הרשת (HTTPS) בין דפדפן כרום לאנדרואיד לבין אתרי גוגל. באופן דומה האלגוריתם שולב בפרוטוקול OpenSSH. הצופן ChaCha נכלל גם במערכות ההפעלה OpenBSD ו-NetBSD. וכן הוצע לפרוטוקול IPSec בטיוטה וטיוטה . פונקציית הגיבוב BLAKE מבוססת על ליבת צופן ChaCha בשינויים מינוריים.
קוד לדוגמה.
להלן קוד C++ שלם של צופן ChaCha20 המלא (20 סבבים). למען הבהירות הקוד אינו ממוטב והוא תואם את ההמלצה המופיעה באתר המפתח. ההנחה שהמהדר תומך בסדר בתים קטן. הפונקציה _lrotl היא פונקציית הזזה מעגלית לשמאל הכלולה בספרייה הסטנדרטית של VS. אפשר לשנות את מספר הסבבים בפונקציה ChaCha_encrypt בקריאה לפונקציה Salsa20_Rounds בהתאם לצורך, למשל לגרסת שמונה סבבים יש לציין 8 בפרמטר האחרון, ערכים מומלצים הם 8,12 או 20.
typedef unsigned char byte;
typedef unsigned int uint;
typedef struct
uint input[16];
} ChaCha_Context;
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
static const char sigma[] = "expand 32-byte k";
static const char tau[] = "expand 16-byte k";
static void Salsa20_Rounds(byte output[64], const uint input[16], uint nrounds)
uint x[16];
for (uint i = 0; i &lt; 16; ++i)
x[i] = input[i];
for (uint i = nrounds; i &gt; 0; i -= 2) {
QUARTERROUND( 0, 4, 8, 12)
QUARTERROUND( 1, 5, 9, 13)
QUARTERROUND( 2, 6, 10, 14)
QUARTERROUND( 3, 7, 11, 15)
QUARTERROUND( 0, 5, 10, 15)
QUARTERROUND( 1, 6, 11, 12)
QUARTERROUND( 2, 7, 8, 13)
QUARTERROUND( 3, 4, 9, 14)
for (uint i = 0; i &lt; 16; ++i)
x[i] = PLUS(x[i], input[i]);
for (uint i = 0; i &lt; 16; ++i)
INT_TO_BYTES(output + 4 * i, x[i]);
void ChaCha_keysetup(ChaCha_Context *ctx, const byte *k, uint kbits, uint ivbits)
const char *constants;
ctx-&gt;input[4] = BYTES_TO_INT(k + 0);
ctx-&gt;input[5] = BYTES_TO_INT(k + 4);
ctx-&gt;input[6] = BYTES_TO_INT(k + 8);
ctx-&gt;input[7] = BYTES_TO_INT(k + 12);
if (kbits == 256) { // recommended
k += 16;
constants = sigma;
else { // kbits == 128
constants = tau;
ctx-&gt;input[8] = BYTES_TO_INT(k + 0);
ctx-&gt;input[9] = BYTES_TO_INT(k + 4);
ctx-&gt;input[10] = BYTES_TO_INT(k + 8);
ctx-&gt;input[11] = BYTES_TO_INT(k + 12);
ctx-&gt;input[0] = BYTES_TO_INT(constants + 0);
ctx-&gt;input[1] = BYTES_TO_INT(constants + 4);
ctx-&gt;input[2] = BYTES_TO_INT(constants + 8);
ctx-&gt;input[3] = BYTES_TO_INT(constants + 12);
void ChaCha_ivsetup(ChaCha_Context *ctx, const byte *iv)
ctx-&gt;input[12] = 0;
ctx-&gt;input[13] = 0;
ctx-&gt;input[14] = BYTES_TO_INT(iv + 0);
ctx-&gt;input[15] = BYTES_TO_INT(iv + 4);
void ChaCha_encrypt(ChaCha_Context *ctx, const byte *m, byte *c, uint bytes)
byte output[64];
if (!bytes) return;
for (;;) {
Salsa20_Rounds(output, ctx-&gt;input, 20);
ctx-&gt;input[12] = PLUSONE(ctx-&gt;input[12]);
if (!ctx-&gt;input[12]) {
ctx-&gt;input[13] = PLUSONE(ctx-&gt;input[13]);
// stopping at 2^70 bytes per nonce is user's responsibility
if (bytes &lt;= 64) {
for (uint i = 0; i &lt; bytes; ++i) c[i] = m[i] ^ output[i];
return;
for (uint i = 0; i &lt; 64; ++i) c[i] = m[i] ^ output[i];
bytes -= 64;
c += 64;
m += 64;
וקטור בדיקה.
מפתח (32 בתים):
וקטור אתחול (8 בתים):
מספר סבבים: 20
64 בתים פסאודו אקראיים הראשונים של פלט הצופן בבסיס הקסדצימלי:
האירוויזיוניסטים
האירוויזיוניסטים הוא סרט תעודה ישראלי בבימויו של אסף לביא הראל, היה פרויקט הגמר שלו במכללת בית ברל ויצא לאקרנים בשנת 2013. הסרט עוקב אחר אסף, במאי הסרט, מעריץ אירוויזיון אשר מנסה להתקבל לקהילת מעריצי האירוויזיון דרך ריטה מרקוביץ', לאון קיכלר ודניאל דונקלמאן, שלושה מעריצי אירוויזיון מושבעים. הסרט מתאר את האופן שבו האירוויזיון משפיע עליהם.