La maggior parte delle funzioni hash crittografiche operano su uno stato interno di dimensioni fisse ed elaborano il messaggio da sottoporre a blocco blocco per blocco, dove un blocco è un numero di bit. MD5, SHA-1 e SHA-2 seguono la costruzione Merkle-Damgård che opera come segue:
- Sia S una matrice di bit N , inizializzata su un valore predefinito. N è la dimensione dello stato interno e potrebbe essere diversa dalla dimensione finale dell'hash.
- Aggiorna lo stato in base a ciascun blocco di messaggi in successione. Più precisamente, per ogni blocco di messaggi M i , imposta S: = C (M i , S). La funzione C è nota come funzione di compressione; prende un K -bit block e un N valore di stato -bit e produce un nuovo valore N -bit.
- Per gli ultimi bit di input, che potrebbero non formare un blocco completo (se la lunghezza del messaggio non è un multiplo della lunghezza del blocco), applicare una funzione di riempimento a S che tenga conto della lunghezza del messaggio (la costruzione Merkle-Damgård richiede un metodo di imbottitura specifico che non sto descrivendo qui).
- Restituisce F (S) dove F è chiamata funzione di finalizzazione. F accetta uno stato N come input e restituisce un hash n -bit
La funzione di compressione è così chiamata perché prende K + N bit di input e restituisce solo N bit di output. Questo ovviamente significa che ci sono molte collisioni: coppie distinte (M i , S) che producono lo stesso stato risultante. Tuttavia, se fatto bene, vale a dire se è computazionalmente incommensurabile trovare le collisioni per la funzione di compressione, allora anche l'hash è collisione-resistenti.
Esistono funzioni di hash crittografiche non Merkle-Damgård, ad esempio SHA-3, che utilizza una costruzione di spugne . Il metodo operativo è leggermente diverso, ma il principio di base è lo stesso:
- Funziona con uno stato di dimensioni fisse.
- Trasforma lo stato in base a un blocco di messaggi alla volta.
- Applica padding all'ultimo blocco.
- Applica una funzione di finalizzazione allo stato interno per restituire il valore hash.
Gli hash non crittografici spesso fanno affidamento sull'aritmetica (ma questo approccio non tende a produrre funzioni hash rapide e crittografiche). Utilizzano la aritmetica modulare come funzione di compressione per mantenere lo stato corrente su una dimensione fissa.