F 2 corpo finito com dois elementos
3.7 Funções Hash
1. Divide é um algoritmo probabilístico que mapeia um bit σ em uma sequência ((e1, (p1, w1)),··· ,(em, (pm, wm))) em que (p1,··· , pm) = D(σ ) e Cwi(pi) = eipara todo
i∈ {1,··· ,m}.
2. Verifica é um algoritmo determinístico que recebe(e, (p, w)) e retorna 1 se e = Cw(p). Ou
seja: Verifica(e, (p, w))def= 1 se Cw(p) = e, 0 caso contrário.
3. Reconstr´oi é um algoritmo determinístico que recebe uma sequência de t pedaços e retorna o segredo (bit) que foi dividido. Em símbolos, Reconstr´oi( ¯p) = σ , com ¯p∈ ({0,1}∗)t e
σ ∈ {0,1}.
4. (Condição de reconstrução:) Para todo bit σ ∈ {0,1}, toda sequência
((e1, (p1, w1)),··· ,(em, (pm, wm))) do contradomínio de Divide e todo subconjunto
Idef= {i1,··· ,it} ⊆ [m], com [m] def = {1,··· ,m}, temos que: Reconstr´oi((ei1, (pi1, wi1)),··· ,(eit, (pit, wit))) def = σ se Cwi(pi) = eipara todo i∈ I ⊥ caso contrário.
5. (Condição de sigilo:) Nenhum subconjunto com menos de t pedaços deve revelar infor- mações sobre σ . Formalmente, seja gI(σ )
def
= (pi1··· , pit−1) com I
def
= {i1,··· ,it−1} ⊂ [m]
e (p1,··· , pm) = D(σ ). Então, para todo subconjunto I dessa forma (i.e., com t− 1
elementos), gI(0) tem distribuição idêntica à de gI(1).
3.7 FunçõesHash
De forma geral, uma função hash é uma função que comprime uma cadeia de tamanho arbitrário em uma de tamanho menor. Uma das motivações para o uso de uma função hash é sua aplicação na área de estruturas de dados, permitindo o acesso eficiente a valores previamente armazenados. Para isso, cada elemento é armazenado em uma tabela e indexado a partir de seu valor hash. Dessa maneira, elementos com mesmo valor hash acabam sendo armazenados em uma mesma célula da tabela.
Dois elementos que possuem o mesmo valor hash representam uma colisão. Como o domínio de uma função hash é, em geral, bem maior que seu contradomínio, podendo inclusive ser infinito, a existência de colisões é inevitável. Uma “boa” função hash, no entanto, é aquela em que essas colisões são “difíceis” de serem encontradas. Em outras palavras, uma boa função de hash é resistente a colisões.
Enquanto a resistência à colisão é um requisito desejável para que uma função hash seja utilizada em estruturas de dados, ela se torna essencial para o uso dessas funções em aplicações de criptografia. Nessa área, um exemplo importante de aplicação de funções hash resistentes a
colisões é a geração de códigos de autenticação. Esses códigos conferem integridade a cadeias arbitrárias e podem ser utilizados, por exemplo, para a criação de esquemas de criptografia com níveis mais altos de segurança.
Nosso interesse em funções hash, naturalmente, implica que tais funções sejam resistentes a colisões. Finalizamos essa breve discussão informal com as definições de função hash e resistência a colisões.
Definição 3.20 (Função hash - Definição 5.1 de KATZ e LINDELL (2014)). Uma função hash é um par(Gen, H) de algoritmos probabilísticos de tempo polinomial tais que:
(i) Gen é um algoritmo probabilístico que recebe um parâmetro de segurança 1ncomo entrada e tem como resultado uma fonte de aleatoriedade (ou chave) s∈ {0,1}poly(n).
(ii) H é um algoritmo determinístico de tempo polinomial que recebe s e x∈ {0,1}∗ como entradas e tem como resultado Hs(x)∈ {0,1}poly(n).
Utilizamos H(x) significando Hs(x) para alguma chave s.
A Definição 3.20 formaliza a discussão introdutória que fizemos. Vale ser ressaltado, no entanto, a existência do algoritmo Gen e o determinismo de H. Em geral, é importante que a função H tenha um comportamento probabilístico para que a saída de H não seja totalmente definida por sua entrada x. Isso é alcançado tornando explícita a fonte de aleatoriedade usada por H. As funções hash usadas na prática, entretanto, consistem apenas do algoritmo determinístico H. Dessa forma, cabe à aplicação de mais alto nível prover aleatoriedade para H.
Uma colisão para uma função hash(Gen, H) é um par (x, x0) de cadeias tais que x6= x0e Hs(x) = Hs(x0) para algum s. Uma função hash é resistente a colisões se é “difícil” encontrar
um desses pares. A noção de dificuldade é, naturalmente, capturada pela (não) existência de um algoritmo polinomial para encontrar uma colisão. Formalizamos a noção de resistência a colisões com base no experimento definido a seguir.
Definição 3.21 (Experimento de busca por colisões - KATZ e LINDELL (2014)). Seja Γ= (Gen, H) uma função hash, A um adversário e n∈ N um parâmetro de segurança. Definimos o experimento de busca por colisões, denotado por ColA,Γ(n), como a seguir:
1. Uma chave s= Gen(1n) é gerada.
2. O adversário A recebe s como entrada. Ele deve gerar um par de cadeias(x, x0).
3. O resultado do experimento é 1 se e somente se x6= x e Hs(x) = Hs(x0). Dizemos, neste
caso, que A encontrou uma colisão.
Com a Definição 3.21 podemos formalizar a noção de dificuldade em se encontrar uma colisão para uma determinada função hash.
3.7. FUNÇÕES HASH 54
Definição 3.22 (Resistência a colisões - Definição 5.2 de KATZ e LINDELL (2014)). Uma função hash(Gen, H) é resistente a colisões se, para todo n∈ N e todo algoritmo probabilístico Ade tempo polinomial existe uma função µ desprezível (em n) tal que:
Pr[ColA,Γ(n)= 1]≤ µ(n)
A Definição 3.22 estabelece que uma função hash resistente a colisões não admite um algoritmo eficiente A para encontrar colisões, i.e., pares (x, x0), com probabilidade não desprezível.
Um famoso ataque para se achar colisões em uma função hash é o ataque do aniversário (birthday attack). Ele se baseia no chamado problema do aniversário7(birthday problem): qual a probabilidade de quaisquer 2 pessoas, entre um total de q, fazerem aniversário no mesmo dia do ano? Assumindo que os aniversários são uniformemente distribuídos ao longo dos 365 dias de um ano (não bissexto), quando q= 23 essa probabilidade é superior a 50%. Note que o problema do aniversário lida, basicamente, com as chances de ocorrência de uma colisão de datas de aniversário.
O ataque do aniversário consiste em procurar por uma colisão entre um conjunto com O√2l(n)valores do contradomínio de H de uma função hash(Gen, H)8. Considerando que
Hé uma função aleatória9, quando O√2l(n)
valores são analisados, a chance de se encontrar uma colisão entre quaisquer dois deles é maior que 50%. Uma análise mais aprofundada é feita por KATZ e LINDELL (2014).
Do ponto de vista da complexidade assintótica, não existe diferença entre se conduzir um ataque de força bruta, analisando-se 2l(n) valores, e o ataque do aniversário, onde são considerados “apenas” O√2l(n)
= O2l(n)/2
valores. Do ponto de vista prático, no entanto, existe uma grande diferença. Considere, por exemplo, o caso em que l(n) = 128. Um ataque de força bruta é infactível, pois 2128é uma quantidade demasiadamente grande de elementos para analisar. No entanto, o ataque do aniversário precisa analisar em torno de 264 possibilidades, o que já não pode ser considerado infactível.
As funções hash utilizadas na prática, em geral, têm a chamada segurança heurística. Em particular, algumas não utilizam uma fonte de aleatoriedade (ou chave) como na Definição 3.20 (e.g., a função SHA256). Como consequência, uma colisão(x, x0) pode inutilizar completamente a função. Em uma função hash com uso de chave, uma colisão(x, x0) serve, a princípio, apenas para uma determinada chave.
Além disso, as funções hash usadas na prática normalmente têm um contradomínio de tamanho fixo. Isso significa que não existe a noção de parâmetro de segurança e, portanto, elas
7Também conhecido como paradoxo do aniversário. É chamado de “paradoxo” apenas porque a análise
matemática resulta em uma resposta “não intuitiva” para o problema.
8A quantidade total de elementos no contradomínio de H é 2l(n).
9Como destaca KATZ e LINDELL (2014), o caso da função ser aleatória é o pior caso para o atacante. Quanto
não podem seguir rigorosamente a Definição 3.22. 3.8 Esquemas de Criptografia Assimétricos
Um esquema de criptografia, de maneira geral, permite que uma mensagem m seja “emba- ralhada” por um emissor de modo que apenas o receptor dessa mensagem consiga “desembaralhá- la” corretamente. O processo de embaralhamento da mensagem é chamado encriptação e o de desembaralhamento, decriptação. Chamamos a mensagem original, antes de ser encriptada, de purotexto (plaintext). Já a versão encriptada de uma mensagem é chamada de cifrotexto (ciphertext).
Um cifrotexto não deve revelar nada sobre o purotexto original, de modo que emissor e receptor possam se comunicar sigilosamente mesmo sobre um canal inseguro. Na criptografia moderna, os algoritmos utilizados para encriptação e decriptação são publicamente conhecidos, de modo que a segurança dos cifrotextos gerados se baseia no sigilo de uma chave. A chave é utilizada para encriptar e decriptar as mensagens trocadas entre emissor e receptor.
Em um esquema criptográfico simétrico existe apenas uma chave10. Ela é utilizada tanto para encriptar quanto para decriptar e deve ser conhecida pelo emissor e pelo receptor. Aliás, dada a simetria desse esquema, os papéis de emissor e receptor não são bem definidos, uma vez que cada participante pode enviar e receber mensagens com a mesma chave.
Um dos problemas que precisam ser resolvidos para a utilização deste tipo de esquema é a maneira pela qual a chave é gerada e distribuída entre os participantes da comunicação. Isso porque o adversário que obtiver tal chave terá total acesso à comunicação.
Já em um esquema assimétrico, também chamado de esquema de chave pública, existem duas chaves relacionadas entre si, uma pública e outra secreta. A chave pública é usada para encriptar uma mensagem. Somente sua contraparte secreta pode decriptar o cifrotexto resultante. Dessa forma, o par de chaves deve ser gerado pelo receptor da mensagem. Ele também deve providenciar para que o emissor receba a chave pública. De maneira geral, a chave pública pode ser conhecida mesmo por quem não vai participar da comunicação. A chave secreta, no entanto, deve ser conhecida apenas pelo receptor.
Note que, em um esquema assimétrico, os papéis de receptor e emissor são bem definidos e não permutáveis entre si.
Neste trabalho estaremos interessados apenas em esquemas criptográficos assimétricos. Apresentamos essa definição a seguir.
Definição 3.23 (Esquema de criptografia assimétrico - Definição 11.1 de KATZ e LINDELL (2014)). Um esquema de criptografia assimétrico, ou esquema criptográfico assimétrico, é um trio de algoritmos(Gen, Enc, Dec) probabilísticos de tempo polinomial tais que:
1. O algoritmo Gen recebe um parâmetro de segurança 1ncomo entrada e dá como saída um par de chaves(pk, sk). A chave pk é chamada de chave pública e sk, de chave secreta.