Salsa20 (znany również jako Snuffle 2005) – szyfr strumieniowy opracowany w 2005 roku przez amerykańskiego kryptografa Daniela J. Bernsteina. Należy do rodziny szyfrów wykorzystujących operacje dodawania, rotacji bitów i alternatywy wykluczającej (XOR), określanej skrótem ARX (add–rotate–XOR). Podstawowy wariant Salsa20 wykorzystuje 256-bitowy klucz i 20 rund przekształceń; istnieje również wersja z kluczem 128-bitowym.

Algorytm został zgłoszony do europejskiego projektu eSTREAM, którego celem była ocena i wyłonienie wydajnych szyfrów strumieniowych. Wariant Salsa20/12, wykonujący 12 rund zamiast 20, został włączony do końcowego zestawu szyfrów przeznaczonych do implementacji programowych (profil 1).
Salsa20 jest szyfrem strumieniowym, który generuje pseudolosowy strumień bajtów na podstawie tajnego klucza, jednorazowej wartości nonce oraz licznika bloków. Szyfrowanie polega na wykonaniu operacji XOR między tekstem jawnym a wygenerowanym strumieniem klucza. Odszyfrowanie wykorzystuje tę samą operację i identyczny strumień klucza.
Algorytm operuje na stanie o długości 512 bitów, przedstawianym jako macierz 4 × 4 zawierająca szesnaście 32-bitowych słów. W wariancie z kluczem 256-bitowym stan początkowy składa się z:
Stałe odpowiadają zapisowi ASCII ciągu expand 32-byte k. W wariancie ze 128-bitowym kluczem materiał klucza jest powielany, a stałe odpowiadają ciągowi expand 16-byte k.
Zastosowanie 64-bitowego licznika umożliwia niezależne wyznaczanie kolejnych 64-bajtowych bloków strumienia klucza. Dzięki temu algorytm pozwala na bezpośredni dostęp do dowolnego bloku bez konieczności wcześniejszego obliczania wszystkich poprzednich bloków. Ułatwia to również równoległe przetwarzanie danych.
Salsa20 wykorzystuje trzy podstawowe operacje na 32-bitowych słowach:
Podstawowym przekształceniem jest funkcja quarterround (ćwierćrunda), działająca na czterech 32-bitowych słowach. W jej kolejnych operacjach stosowane są rotacje o 7, 9, 13 i 18 bitów. Przekształcenia są wykonywane sekwencyjnie, a wyniki wcześniejszych operacji stanowią dane wejściowe następnych.
Cztery ćwierćrundy tworzą jedną rundę algorytmu. W rundach nieparzystych przekształcenia obejmują kolumny macierzy stanu, a w rundach parzystych – odpowiednio dobrane grupy słów odpowiadające wierszom. Dwie następujące po sobie rundy tworzą podwójną rundę (doubleround).
Podstawowy Salsa20 wykonuje 20 rund, czyli dziesięć podwójnych rund. Po zakończeniu przekształceń każde słowo wynikowego stanu jest dodawane modulo 232 do odpowiadającego mu słowa stanu początkowego. Otrzymane 512 bitów stanowi 64-bajtowy blok strumienia klucza.
Konstrukcja nie wymaga tablic podstawień (S-box) ani zależnych od klucza odwołań do takich tablic. Umożliwia to wydajne implementacje programowe bez zależnych od danych odczytów tablic, które w innych konstrukcjach mogą stanowić źródło ataków czasowych.
Oprócz podstawowego Salsa20/20 opracowano warianty o mniejszej liczbie rund, umożliwiające uzyskanie większej szybkości kosztem zmniejszenia marginesu bezpieczeństwa kryptograficznego.
| Wariant | Liczba rund | Charakterystyka |
|---|---|---|
| Salsa20/20 | 20 | Podstawowa wersja algorytmu, zapewniająca największy margines bezpieczeństwa spośród trzech wariantów. |
| Salsa20/12 | 12 | Wariant o zwiększonej wydajności, wybrany do końcowego zestawu szyfrów projektu eSTREAM. |
| Salsa20/8 | 8 | Wariant o jeszcze mniejszej liczbie rund i dalszym ograniczeniu marginesu bezpieczeństwa. |
Autor algorytmu zalecał pełny Salsa20/20 do typowych zastosowań kryptograficznych. Warianty Salsa20/12 i Salsa20/8 zaproponowano do zastosowań, w których szczególnie istotna jest wydajność. Komitet eSTREAM uznał Salsa20/12 za rozwiązanie zapewniające korzystny kompromis między szybkością a marginesem bezpieczeństwa.
XSalsa20 to rozszerzenie algorytmu opracowane przez Bernsteina w 2008 roku. Wprowadza 192-bitową wartość nonce zamiast 64-bitowej, zachowując zasadniczy mechanizm generowania strumienia klucza.
XSalsa20 wykorzystuje pierwsze 128 bitów wartości nonce wraz z tajnym kluczem do wyprowadzenia nowego 256-bitowego klucza za pomocą funkcji HSalsa20. Następnie używa otrzymanego klucza i pozostałych 64 bitów wartości nonce w standardowym mechanizmie Salsa20.
Dłuższa wartość nonce zmniejsza ryzyko jej przypadkowego powtórzenia podczas losowego generowania dla kolejnych wiadomości. Bernstein wykazał również, że skuteczny atak na XSalsa20 można byłoby wykorzystać do zaatakowania Salsa20, co pozwala powiązać bezpieczeństwo obu algorytmów.
Bezpieczeństwo Salsa20 było przedmiotem licznych badań kryptograficznych, koncentrujących się przede wszystkim na wariantach o zmniejszonej liczbie rund. W 2005 roku Paul Crowley przedstawił atak na pięciorundowy Salsa20/5, którego szacowana złożoność wynosiła 2165 operacji. W kolejnych latach opublikowano ataki na warianty Salsa20 z 6, 7 i 8 rundami, wykorzystujące między innymi techniki kryptoanalizy różnicowej.
W 2008 roku Jean-Philippe Aumasson i współautorzy opisali atak na Salsa20/8 z kluczem 256-bitowym o szacowanej złożoności 2251 operacji.
W 2025 roku Sabyasachi Dey, Subhamoy Maitra, Santanu Sarkar i Nitin Kumar Sharma przedstawili dalsze usprawnienia kryptoanalizy. Opisali atak na Salsa20/8 z kluczem 256-bitowym o szacowanej złożoności czasowej 2186,01 operacji oraz atak na konstrukcję obejmującą 8,5 rundy o złożoności 2245,84 operacji. Ten drugi wynik dotyczył części dziewiątej rundy, a nie pełnego dziewięciorundowego wariantu.
Wyniki te dotyczą wersji o zmniejszonej liczbie rund i nie oznaczają złamania pełnego Salsa20/20 ani Salsa20/12. Nie opublikowano praktycznego ataku pozwalającego odzyskać klucz tych dwóch wariantów szybciej niż metodą wyczerpującego przeszukiwania przestrzeni kluczy.
Istotnym wymogiem bezpieczeństwa jest niepowtarzanie tej samej wartości nonce przy szyfrowaniu różnych wiadomości tym samym kluczem. Ponowne użycie tej samej pary klucza i wartości nonce powoduje wygenerowanie identycznego strumienia klucza, co może ujawnić informacje o tekstach jawnych. Dokumentacja biblioteki libsodium zaleca stosowanie kolejnych wartości nonce lub użycie rozszerzenia XSalsa20.
Sam Salsa20 zapewnia poufność danych, ale nie gwarantuje ich integralności ani autentyczności. W zastosowaniach wymagających uwierzytelniania łączy się go z odpowiednim mechanizmem uwierzytelniania wiadomości.
Salsa20 i jego warianty zaimplementowano między innymi w bibliotekach kryptograficznych libsodium i NaCl. W bibliotekach tych rozszerzenie XSalsa20 jest wykorzystywane w konstrukcji XSalsa20-Poly1305, łączącej szyfrowanie strumieniowe z uwierzytelnianiem wiadomości za pomocą Poly1305. Mechanizm ten stanowi podstawę interfejsu crypto_secretbox.
W 2008 roku Bernstein opublikował pokrewną rodzinę szyfrów ChaCha, opartą na podobnych operacjach ARX, lecz wykorzystującą zmodyfikowaną funkcję ćwierćrundy i inny sposób przekształcania elementów stanu. Zmiany miały na celu szybsze rozprzestrzenianie się zmian w danych między kolejnymi słowami stanu przy zachowaniu wysokiej wydajności.