Uma confidential transaction consiste em cifrar os valores transacionados através de homo-
morphic encryption, desta forma é possível manter algumas propriedades algébricas, como a
soma, e realizar cálculos sobre os valores cifrados. A ferramenta básica para isso é um Pe-
dersen commitment. Um commitment permite manter os dados secretos, mas obriga a ficar
comprometido com eles para que não seja possível alterá-los mais tarde. Um simples exemplo é escrever um número no papel e guardá-lo numa caixa. Desta maneira ninguém consegue adi- vinhar o número que está dentro dela, mas se quiser-se mostrar esse número a alguém, esta apenas se pode abrir para o número que foi escrito.
Commitment = SHA_256(blinding_f actor||dados) (3.1)
O blinding factor é um número aleatório usado apenas para impedir que alguém tente adivinhar os dados. Por exemplo, se os dados fossem números de um intervalo curto, era fácil adivinhar e comparar o palpite com o commitment. Desta forma, se alguém revelar um commitment, ninguém consegue determinar os dados para os quais essa pessoa se comprometeu, mas mais tarde, se decidir revelar os dados e o blinding factor, qualquer um pode verificar que de facto se comprometeu com esses dados. Pedersen commitments sobre curvas elípticas têm a seguinte forma:
commit(v, r) = vG + rH (3.2)
Onde G e H são pontos da curva, r é o blinding factor e v é o valor com o qual alguém se está a comprometer. De notar que v e r são valores secretos, e apenas conhecendo o commitment,
Ge H, é difícil descobrir v. O ponto H deve ser escolhido de maneira a que ninguém conheça o logaritmo discreto de H com respeito a G, ou seja, ninguém deve conhecer o x, para o qual
xG = H. Assim, H deve ser escolhido com a ajuda de uma função hash criptográfica:
H = to_point(SHA_256(EN CODE(G))) (3.3)
Os Pedersen commitments mantêm as propriedades algébricas da soma. Assim a soma de um conjunto de commitments é igual a um commitment com a soma dos valores e a soma dos
blinding factors: C(v1, r1) + C(v2, r2) = v1G + r1H + v2G + r2 = (v1+ v2)G + (r1+ r2H) = C(v1+ v2, r1+ r2) (3.4) C(v1, r1)− C(v1, r1) = 0 (3.5) Se vn ={5, 3, 2} e rn={20, 15, 5} então: C(v1, r1)− C(v2, r2)− C(v3, r3) = 0 (3.6)
A segurança do esquema depende do problema do logaritmo discreto e da escolha do blinding
factor, que deve ser aleatória.
Através dos Pedersen commitments é possível substituir os valores transacionados por um com-
mitment. A comunidade, mesmo não sabendo a quantidade dos valores transacionados, pode
verificar a transação ao conferir se a soma dos commitments como output é igual à soma dos
dos valores como inputs. De notar que a soma dos bliding factors como outputs deve também ser igual à soma dos bliding factors como inputs. Por exemplo, uma transacção com um 1 input e 2 outputs, pode ser verificada da seguinte maneira:
C(in1, r1)− (C(out1, r2) + C(out2, r3) + f ee∗ H) = 0 (3.7)
Onde in1= out1+ out2+ f eee r1= r2+ r3. A taxa de transação, fee, é o único valor explicito
na transação.
Apesar de já ser possível verificar o balanço entre os inputs e os outputs, o esquema é inseguro. Os Pedersen commitments assentam sobre grupos cíclicos. Isto significa que o grupo tem uma ordem e que a soma de dois valores é mod P . Uma adição de grandes números pode causar um overflow e comportar-se como valores negativos. Isto significa que as operações de adição podem conter valores negativos para dar zero. Por exemplo, poderíamos criar uma transação válida com os valores{2, 3, 5} como inputs, e {−10, 5, 15} como outputs:
(2 + 3 + 5)− (−10 + 5 + 15) = 0 (3.8)
A equação é verdadeira mas um dos valores de output é negativo e, a soma dos outros é maior que a soma dos valores de input. Desta forma criou-se dinheiro do nada e ninguém se irá aper- ceber, pois é desprezado o valor negativo e os valores deixam de estar visíveis. A transação pode ser interpretada como alguém que gastou 10 moedas e o seu receptor recebeu uma moeda de -10, que descarta, mais uma de 5 e outra de 15. Ou seja, se a transação for feita entre endereços da mesma carteira, alguém com 10 moedas conseguiu falsificar 10 moedas, ficando agora com 20 moedas para gastar. Este problema gera inflação que ninguém poderá prever, podendo causar a perca de valor de mercado da moeda.
Para resolver o problema, podia-se enviar os valores e os blinding factors. Assim, a comunidade já os podia verificar mas, desta forma, voltava a perder-se a privacidade nas transações. Em vez disso, é necessário provar que o valor com o qual alguém se comprometeu (commited value) está dentro de um intervalo, e.g. [0, 264), mas sem revelar mais nada acerca do valor. Para isso
é necessário uma NIZK, mais conhecida como range proof, ou em português prova de intervalo. Através de um commitment de um valor, é possível provar que este está dentro de um intervalo sem revelar nada acerca do valor. Então, para verificar uma transação, é necessário verificar se a soma dos commitments como inputs é igual à soma dos commitments como outputs e, caso, contenha mais do que um output, é preciso fazer uma range proof para cada um deles.
3.4
Conclusão
Todas as pessoas têm direito à sua privacidade, seja nas suas conversas na internet, como nas redes sociais e até mesmo nas suas transações numa blockchain. Mas tudo o que é positivo tem os seus aspectos negativos: a privacidade vai incentivar ainda mais os criminosos a usarem as criptomoedas. A Bitcoin é um dos meios de pagamento mais utilizados na dark web e a sua priva- cidade ainda é fraca. Esta pode ser usada para lavagens de dinheiro, como forma de pagamento de actos ilícitos, e o pior de tudo, pode ser usada para financiar organizações terroristas. As
técnicas para obtenção de privacidade devem ser implementadas mas devem continuar a haver formas de controlar o uso das criptomoedas como forma de financiamento para fins ilícitos. Qualquer blockchain que implemente estas técnicas para obtenção de privacidade, perde a capacidade de deteção de possíveis bugs, os quais podem permitir o roubo de carteiras ou fal- sificação de criptomoedas. Como os dados mais sensíveis de uma transação deixam de estar expostos, torna impossível a detetação destes bugs através das transações, a menos que alguém o descubra e proponha uma alteração no código. O risco de ter inflações indetetáveis é um risco para qualquer ciptomoeda, pois pode levar a perdas significativas no seu valor de mercado. O capítulo abordou as principais técnicas para a obtenção de privacidade, mas existem muitas mais e irão continuar a surgir novas, já que existe um grande interesse de investigação nesta área. O objectivo da investigação é melhorar as técnicas já existentes e com isso aumentar a escalabilidade das blockchains, ao fornecer formas mais rápidas de verificar transações e diminuir o seu tamanho, mantendo a privacidade e segurança dos seus utilizadores. A Visa consegue processar milhares de transações por segundo, em comparação com as blockchains mais conhecidas onde os valores, em média, ficam abaixo das centenas, o que ainda é uma diferença considerável.
Capítulo 4
Implementação de Range Proofs com Bulletproofs
4.1
Introdução
Como foi referido anteriormente, uma range proof permite verificar se um commitment re- presenta um valor dentro de um intervalo específico, sem revelar nada acerca do valor. Por exemplo, uma range proof pode ser usada para validar se a idade de alguém está entre os 28 e 52 anos, sem revelar a idade exata da pessoa. As confidential transactions, onde os valores transacionados são escondidos, possibilitam uma forma de verificar se os valores não são nega- tivos e não excedem um determinado valor, e.g. [0, 264). O capítulo abordará como se podem
construir range proofs através das Bulletproofs, quais as etapas e equações envolvidas no pro- cesso, e como se pode verificar uma prova. Este capítulo foi elaborada através da consulta do
paper das Bulletproofs [BBB+18] e da documentação de uma implementação escrita em Rust
[Cha18].
Foi escolhida a linguagem de programação funcional Ocaml, pois esta implementação tem em vista a sua integração numa plataforma blockchain escrita também em Ocaml, mais conhecida como Tezos.