Per le moderne funzioni hash crittografiche, no, non esiste un predicato di prossimità calcolabile in modo efficiente, supponendo che la distribuzione su Xha entropia sufficiente. L'intuizione è che queste funzioni hash sono progettate per "non avere struttura", quindi non ammettono nulla del genere.
In termini tecnici, le moderne funzioni hash crittografiche si comportano "come un oracolo casuale". Per un oracolo casuale, non esiste un simile predicato di vicinanza: il meglio che puoi fare sembra essere invertire la funzione hash, quindi enumerare tutte le stringhe vicine e cancellarle. Di conseguenza, non c'è modo di farlo per le moderne funzioni hash crittografiche.
Dal punto di vista euristico, è possibile progettare una funzione hash personalizzata che ammetta un predicato di vicinanza efficiente e che sia (approssimativamente) "il più sicuro possibile" dato questo fatto. Supponiamo che le stringhe che stiamo per eseguire l'hash siano di lunghezza fissa. Supponiamo di avere un buon codice di correzione degli errori, e lasciaD essere l'algoritmo di decodifica (quindi, se possibile, associa una stringa di bit a una parola in codice vicina).
Per ottenere uno schema semplice ma imperfetto, immagina di definirlo h ( x ) = SHA256 ( D ( x ) ). Sex , y sono due stringhe casuali sufficientemente vicine, quindi esiste una buona possibilità h ( x ) = h ( y). Sex , y non sono vicini, quindi h ( x ) non assomiglierà per niente h ( y)e non otterremo informazioni oltre al fatto che x , ynon sono vicini. Questo è semplice Tuttavia, è anche imperfetto. Ci sono molte coppiex , y che sono vicini ma da cui non possiamo rilevare questo fatto h ( x ) , h ( y) (ad es. perché la funzione di decodifica D non riesce).
Euristicamente, sembra possibile migliorare questa costruzione. In fase di progettazione, scegliere stringhe di bit casualir1, ... ,rK. Ora, definisci la seguente funzione hash:
h ( x ) = ( SHA256 ( D ( x ⊕r1) , … , SHA256 ( D ( x ⊕rK) ) .
Ora se x , y sono sufficientemente vicini, è probabile che esista io tale che D ( x ⊕rio) = D ( y⊕rio), e quindi h ( x)io= h ( y)io. Ciò suggerisce immediatamente un predicato di vicinanza: seh ( x ) fiammiferi h ( y) in uno dei suoi K componenti, quindi x , ysono vicini; altrimenti, dedurre che non sono vicini.
Se si desidera inoltre una resistenza alle collisioni, una semplice costruzione è la seguente: let h1( ⋅ )essere una funzione hash con un predicato di vicinanza; poih ( x ) = (h1( x ) , SHA256 ( x ) ) è resistente alle collisioni (qualsiasi collisione per questo è anche una collisione per SHA256) e ha un predicato di vicinanza (basta usare il predicato di vicinanza per h1). Puoi lasciareh1( ⋅ ) essere la funzione hash definita sopra.
Questo è tutto per la distanza di Hamming. La modifica della distanza è probabilmente molto più difficile.
Nel venire con la costruzione di cui sopra, sono stato ispirato dal seguente documento:
Ari Juels, Martin Wattenberg. Uno schema di impegno fuzzy .
Ari Juels, Madhi Sudhan. Uno schema di Fuzzy Vault . Disegni, codici e crittografia 38 (2): 237-257, 2006.
Per inciso: nella crittografia, le funzioni hash non sono sotto chiave. Se volevi una cosa con chiave, potresti dare un'occhiata alle funzioni pseudocasuali.