Bem vindo! Novo em Zcash?
The Zcash network is young, but evolving quickly! Sign up and we'll be in touch with monthly highlights on ecosystem growth, network development and how to get started with Zcash!

Idioma

Emparelhamento Criptográfico em Rust

Sean Bowe | Jul 06, 2016

O emparelhamento criptográfico é uma área interessante de pesquisa, e um componente essencial da zkSNARKs da Zcash - provas de que as transações são válidas, sem exigir que os usuários revelam informações privada. No início deste ano nós também utilizado zkSNARKs para fazer o primeiro pagamento contigente de conhecimento-nulo do Bitcoin!

Um dos nossos objetivos daqui para frente é explicar melhor como essas ferramentas funcionam, e torná-las mais acessível ao público. Com esse primeiro passo, estamos começando o desenvolvimento de um biblioteca de emparelhamento criptográfico para Rust chamado de "bn". Emparelhamento Criptográfico é importante para zkSNARKs, mas o que exatamente é isso?

Curvas Elípticas

Construções regulares de curvas elípticas como secp256k1 - utilizados no Bitcoin - são projetados para coisas como assinaturas digitais. Os pontos da curva para formar um grupo cíclico: podem ser somadas e multiplicadas por escalares. Acredita-se que seja impraticável encontrar o multiplicando dado um ponto e o ponto de produto, o chamado "problema do logaritmo discreto da curva elíptica".

Esta assimetria (a facilidade de se multiplicar, mas a dificuldade do inverso) é usado para fazer uma série de ferramentas úteis e protocolos. Cahve Diffie-Hellman é um exemplo simples: Alice multiplica a chave pública de Bob por sua chave privada (escalar) , e vice-versa, para encontrar um segredo compartilhado na presença de um intruso.

Este protocolo de troca de chaves pode ser estendido para três partidos, mas requer duas rodadas: para festas de A, B, e C, A obtém o segredo compartilhado por ter B enviando sua chave pública para C, que multiplica por sua chave privada e envia o resultado para A, que pode, então, derivar o segredo compartilhado pela multiplicação por sua chave privada.

Emparelhamento Criptográfico

Emparelhamento criptográfico é uma extensão destes conceitos. Agora imagine que temos dois grupos cíclicos: \(G_{1}\) and \(G_{2}\), escrito de forma aditiva, e de um mapeamento a um terceiro grupo cíclico do formulário e: \(G_{1} \times G_{2} \rightarrow G_{T}\), onde \(G_{T}\) é escrito multiplicativamente. Se esse mapeamento é bilinear, então:

\(e(a g_{1}, b g_{2}) = e(g_{1}, g_{2})^{ab}\) onde \(a\) e \(b\) são escalares e \(g_{1}\) e \(g_{2}\) são geradores para seus respectivos grupos.

Essencialmente, uma multiplicação escalar de um dos dois primeiros elementos do grupo é equivalente a uma exponenciação do elemento de grupo final.

Joux's chave protocolo de acordo

Vamos aplicar o emparelhamento criptográfico para o cenário de troca de chaves de três partidos acima. Usando emparelhamentos, podemos realizar a troca em uma rodada. Cada uma das partes \(P\) publica a sua chave pública \(P^{pk} = (P^{sk} g_{1}, P^{sk} g_{2})\) e mantém a sua chave privada \(P^{sk}\) secreta. Todas as partes \(A, B, C\) pode computar o mesmo segredo compartilhado usando a função bilinear de emparelhamento:

Alice Computador Bob Computador Carol Computador
\(e(B_{1}^{pk}, C_{2}^{pk})^{A^{sk}}\) \(e(C_{1}^{pk}, A_{2}^{pk})^{B^{sk}}\) \(e(A_{1}^{pk}, B_{2}^{pk})^{C^{sk}}\)
Todos equivalente a \(e(g_{1}, g_{2})^{A^{sk} B^{sk} C^{sk}}\)

Ou, se preferir código, veja um exemplo da nossa nova biblioteca:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Gerar chaves privadas
let alice_sk = Scalar::random(rng);
let bob_sk = Scalar::random(rng);
let carol_sk = Scalar::random(rng);

// Gerar chaves públicas no G1 e G2
let (alice_pk1, alice_pk2) = (G1::one() * &alice_sk, G2::one() * &alice_sk);
let (bob_pk1, bob_pk2) = (G1::one() * &bob_sk, G2::one() * &bob_sk);
let (carol_pk1, carol_pk2) = (G1::one() * &carol_sk, G2::one() * &carol_sk);

// Cada uma das partes calcula o segredo compartilhado
let alice_ss = pairing(&bob_pk1, &carol_pk2) ^ &alice_sk;
let bob_ss = pairing(&carol_pk1, &alice_pk2) ^ &bob_sk;
let carol_ss = pairing(&alice_pk1, &bob_pk2) ^ &carol_sk;

assert!(alice_ss == bob_ss && bob_ss == carol_ss);

bn

A caixa "bn" é um biblioteca da linguagem Rust para realizar estas operações de emparelhamento usando uma construção criptográfica projetado por nossos cientistas na [BCGTV14]. Ele usa uma curva elíptica Barreto-Naehrig sintonizado para uso com zkSNARKs. A biblioteca é nova e incompleta e não deve ser utilizado em software de produção, mas é um bom passo a frente na nossa meta de tornar este novo tipo de criptografia mais amplamente entendida e mais fácil de usar.

Confira a esse assunto sobre bn no github ou na crates.io! E sinta-se livre para se juntar nossa comunidade Slack ou inscreva-se para notificações e-mail de nossa equipe!