سالسا۲۰
ساختار

از نظر ساختار داخلی، این رمز از جمع بیت به بیت یا همان ⊕ (یای انحصاری)، جمع ۳۲ بیتی به پیمانه ⊞و عملیات چرخش با فاصله ثابت(>>>) بر روی حالت داخلی شانزده کلمه ۳۲ بیتی استفاده می‌کند. تنها استفاده از عملیات add-rotate-xor از امکان حمله زمانی در پیاده‌سازی‌های نرم‌افزاری جلوگیری می‌کند. حالت داخلی از شانزده کلمه ۳۲ بیتی ساخته شده که به عنوان یک ماتریس ۴ × ۴ چیده می‌شود.
| 0 | 1 | 2 | 3 |
| --- | --- | --- | --- |
| ۳ | ۲ | ۱ | ۰ |
| ۷ | ۶ | ۵ | ۴ |
| ۱۱ | ۱۰ | ۹ | ۸ |
| ۱۵ | ۱۴ | ۱۳ | ۱۲ |
حالت اولیه از    ۸ کلمه از کلید،     ۲ کلمه از موقعیت جریان،     ۲ کلمه از نانس (در حقیقت بیتهای موقعیت جریان اضافی)،     و ۴ کلمه ثابت تشکیل شده‌است:
| 0 | 1 | 2 | 3 |
| --- | --- | --- | --- |
| کلید | کلید | کلید | "expa" |
| نانس | نانس | "nd 3" | کلید |
| کلید | "2-by" | موقعیت | موقعیت |
"te k": کلید
کلمه‌های ثابت در اسکی تشکیل عبارت ("expand 32-byte k") را می‌دهد. (برای مثال این چهار کلمه “expa”, “nd 3”,”2-by” , “te k” هستند). این نمونهای از یک عدد "بدون نیرنگ" است. عملیات اصلی در Salsa20، ربع دور، (QR(a, b, c, d است که یک ورودی چهار کلمه ای می‌گیرد و خروجی ای چهار کلمه ای تولید می‌کند.
b ^= (a + d) <<< 7;
c ^= (b + a) <<< 9;
d ^= (c + b) <<< 13;
a ^= (d + c) <<< 18;
دورهای فرد (QR(a, b, c, d  را روی هریک از ۴ ستون ماتریس ۴ × ۴ و دورهای زوج (QR(a,b, c, d  را روی هریک از ۴ سطر ماتریس ۴ × ۴ پیاده می‌کنند. دو دور متوالی (دور ستون و دور سطر) را باهم دور دوتایی (double-round) می‌نامند.
// دور فرد
QR( 0,  4,  8, 12) // ستون 1
QR( 5,  9, 13,  1) // ستون 2
QR(10, 14,  2,  6) // ستون 3
QR(15,  3,  7, 11) // ستون 4
// دور زوج
QR( 0,  1,  2,  3) // سطر 1
QR( 5,  6,  7,  4) // سطر 2
QR(10, 11,  8,  9) // سطر 3
QR(15, 12, 13, 14) // سطر 4
یک پیاده‌سازی از این رمز در زبان C/C++ در کد ذیل موجود است
#include <stdint.h>
#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
#define QR(a, b, c, d)(  \
b ^= ROTL(a + d, 7), \
c ^= ROTL(b + a, 9), \
d ^= ROTL(c + b,13), \
a ^= ROTL(d + c,18))
#define ROUNDS 20

void salsa20_block(uint32_t out[16], uint32_t const in[16])
{
int i;
uint32_t x[16];

for (i = 0; i < 16; ++i)
x[i] = in[i];
// 10 loops × 2 rounds/loop = 20 rounds
for (i = 0; i < ROUNDS; i += 2) {
// Odd round
QR(x[0], x[4], x[8], x[12]); // column 1
QR(x[5], x[9], x[13], x[1]); // column 2
QR(x[10], x[14], x[2], x[6]); // column 3
QR(x[15], x[3], x[7], x[11]); // column 4
// Even round
QR(x[0], x[1], x[2], x[3]); // row 1
QR(x[5], x[6], x[7], x[4]); // row 2
QR(x[10], x[11], x[8], x[9]); // row 3
QR(x[15], x[12], x[13], x[14]); // row 4
}
for (i = 0; i < 16; ++i)
out[i] = x[i] + in[i];
}
در خط آخر آرایهٔ میکس شده کلمه به کلمه با آرایهٔ اصلی جمع می-شود تا بلوک جریان کلید ۶۴ بایتی خود را بدست آورد. این کار (جمع کردن) مهم است زیرا دورهای میکس کردن (mixing rounds) به تنهایی معکوس پذیر و قابل بازگشت هستند. به عبارت دیگر، اعمال عملیات معکوس ماتریس ۴ × ۴ اصلی را تولید خواهد کرد، که شامل کلید می‌شود. جمع کردن آرایهٔ میکس شده با اصلی بازیابی ورودی را غیرممکن می‌کند (این تکنیک به‌طور گسترده در توابع هش (hash functions)از MD4 تا SHA-2 استفاده می‌شود)
Salsa20، بیست دور از میکس کردن را بر روی ورودی خود اجرا می‌کند. با این حال، انواع دیگر آن با دورهای کاسته شده به نام‌های Salsa20/8 و Salsa20/12 که به ترتیب از ۸ و ۱۲ دور استفاده می‌کنند هم معرفی شده‌اند. این گونه‌ها برای تکمیل Salsa20 اصلی معرفی شدند و نه برای جایگیزینی آن و برای آن که عملکرد حتی بهتری در معیارهای eSTREAM نسبت به Salsa20 داشته باشند، اگر چه حاشیه امنیتی متناظر پایین‌تر.