Mistura associativa de hash

14

Considere a lista com poucas ligações simples em um ambiente puramente funcional. Seus louvores foram cantados do topo das montanhas e continuarão sendo cantados. Aqui irei abordar um dos muitos pontos fortes e a questão de como ele pode ser estendido à classe mais ampla de sequências puramente funcionais baseadas em árvores.

O problema é o seguinte: Você deseja testar quase certa igualdade estrutural no tempo O (1) por meio de hash forte. Se a função hash for estruturalmente recursiva, ou seja, hash (x: xs) = mix x (hash xs), você poderá armazenar em cache de forma transparente valores de hash em listas e atualizá-los em O (1) quando um elemento for incluído em uma lista existente . A maioria dos algoritmos para listas de hash é estruturalmente recursiva; portanto, essa abordagem é eminentemente utilizável na prática.

Mas suponha que, em vez de listas vinculadas individualmente, você tenha sequências baseadas em árvore que suportam a concatenação de duas sequências de comprimento O (n) no tempo O (log n). Para que o cache de hash funcione aqui, a função de mistura de hash deve ser associativa para respeitar os graus de liberdade que uma árvore possui para representar a mesma sequência linear. O misturador deve pegar os valores de hash das subárvores e calcular o valor de hash de toda a árvore.

Era aqui que eu estava há seis meses, quando passei o dia pensando e pesquisando sobre esse problema. Parece não ter recebido atenção na literatura sobre estruturas de dados. Eu me deparei com o algoritmo de hash Tillich-Zemor da criptografia. Ele se baseia na multiplicação de matrizes 2x2 (que é associativa), onde os bits 0 e 1 correspondem aos dois geradores de uma subalgebra com entradas em um campo de Galois.

Minha pergunta é: o que eu perdi? Deve haver artigos relevantes na literatura sobre criptografia e estruturas de dados que não encontrei na minha pesquisa. Quaisquer comentários sobre esse problema e possíveis locais a serem explorados serão muito apreciados.

Edit: Estou interessado nesta questão, tanto nas extremidades suaves quanto nas criptograficamente fortes do espectro. No lado mais suave, pode ser usado para tabelas de hash onde as colisões devem ser evitadas, mas não são catastróficas. No lado mais forte, pode ser usado para testes de igualdade.

Per Vognsen
fonte

Respostas:

2

Adicionado : Depois de ler os comentários de Per, acho que essa resposta é apenas uma variação (fraca) do algoritmo de hash de Tillich-Zemor, que já é mencionado na pergunta. Retiro essa resposta, mas deixo esperando que (e os comentários) sejam informativos para alguns leitores.


Edit : Uma revisão anterior desta resposta sugeriu o uso de uma operação monóide em [ m ], mas como Per apontou em um comentário, é desejável usar uma operação de grupo.

Esta resposta é sobre a construção de uma função de hash para tabelas de hash que é fácil de implementar. Uma garantia comprovada da qualidade não é esperada.

Supondo que você já tenha uma função de hash para cada elemento de uma sequência com um conjunto finito [ m ] = {1,…, m }, que tal interpretar cada elemento de [ m ] como um elemento em um grupo finito G e usar o método operação de grupo em G ? Você pode usar qualquer mapeamento de [ m ] a G , mas é desejável que o mapeamento seja injetivo, para que não percam as informações no valor de hash de cada elemento. Também é desejável que o grupo não seja comutativo para que a função hash possa capturar a diferença na ordem dos elementos em uma sequência.

Não sei muito sobre grupos finitos que permitem operações rápidas, mas acho que esses grupos são conhecidos na teoria da codificação. Usar o grupo simétrico de ordem pelo menos m pode não ser tão ruim.

Tsuyoshi Ito
fonte
1
Sim, o hash de Tillich-Zemor também usa multiplicação de matrizes. O que você sugere não pode funcionar sem outras modificações na Tillich-Zemor. Por exemplo, você deve evitar matrizes singulares ou obter acumulação em 0, arruinando as estatísticas de hash. Tillich-Zemor trabalha sobre um campo de Galois; uma versão anterior de seu algoritmo apresentava problemas porque usavam um polinômio gerador que apresentava estatísticas abaixo do ideal; portanto, o campo de Galois em particular pode ser muito importante.
Por Vognsen 26/09/10
@ Per: Entendo. Obrigado pela explicação. Então, que tal usar grupos finitos? Eu modifiquei a resposta para isso.
Tsuyoshi Ito
Concordo. A melhor maneira de gerar famílias infinitas de grupos é com grupos de matrizes sobre campos finitos (cf. o teorema de classificação para grupos simples finitos), portanto parece que algoritmos dessa forma serão do tipo Tillich-Zemor.
Por Vognsen 26/09/10
@ Per: Eu não estou familiarizado com a teoria dos grupos, e não consigo ver por que grupos matriciais sobre campos finitos são melhores que grupos simétricos nesse contexto. Você pode elaborar sobre isso?
Tsuyoshi Ito
1
Há algumas razões. Por um lado, você não pode calcular eficientemente em grandes grupos simétricos e precisa que os grupos estejam na ordem de 2 ^ 128 para resistência à colisão. Por outro lado, você pode calcular com matrizes sobre os campos finitos da característica 2 com muita eficiência, especialmente se você escolher um polinômio de gerador esparso; são apenas algumas manipulações.
Por Vognsen 26/09/10
1

A família quase universal de funções hash

{huma(x)=umaEuxEumodp:umaZp}

huma(x)+uma|x|huma(y)=huma(xy)uma|x|O(1)Zp

xyO(min(|x|,|y|)/p)

jbapple
fonte
1

nn,ny,yy = H ( y , y ) H O ( 1 )ny=H(y,y)HO(1)O(lgn)

H(x1,...,xm)x1,...,xmm

DW
fonte