• Nenhum resultado encontrado

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.