Continuamos nossa série sobre o blockchain Monero, e o artigo de hoje se concentrará no protocolo RingCT (Ring Confidential Transactions), que introduz transações confidenciais e novas assinaturas de anel. Infelizmente, há pouca informação na Internet sobre como funciona e tentamos preencher esta lacuna.
Falaremos sobre como a rede oculta valores de transferência usando este protocolo, por que eles abandonaram as clássicas assinaturas em anel de criptomoedas e como essa tecnologia se desenvolverá ainda mais.
Como este protocolo é uma das tecnologias mais complexas do Monero, o leitor precisará de um conhecimento básico do design deste blockchain e de um conhecimento prévio de criptografia de curva elíptica (para aprimorar esse conhecimento, você pode ler os primeiros capítulos do nosso artigo anterior sobre
Protocolo RingCT
Um dos possíveis ataques às moedas criptográficas é a análise de blockchain baseada no conhecimento do valor e do horário da transação enviada. Isso permite
Vale ressaltar que a ideia de ocultar valores não é nova. O desenvolvedor do Bitcoin Core, Greg Maxwell, foi um dos primeiros a descrevê-lo em seu
Entre outras coisas, o protocolo ajuda a eliminar problemas com a mistura de saídas de poeira - saídas de pequena quantidade (geralmente recebidas na forma de troco de transações), que criaram mais problemas do que valeram.
Em janeiro de 2017, ocorreu um hard fork da rede Monero, permitindo o uso opcional de transações confidenciais. E já em setembro do mesmo ano, com o hard fork da versão 6, tais transações passaram a ser as únicas permitidas na rede.
RingCT usa vários mecanismos ao mesmo tempo: assinaturas de grupo anônimas espontâneas vinculadas em múltiplas camadas (assinatura de grupo anônima espontânea linkável em várias camadas, doravante denominada MLSAG), um esquema de compromisso (compromissos de Pedersen) e provas de intervalo (este termo não tem uma tradução estabelecida para o russo) .
O protocolo RingCT introduz dois tipos de transações anônimas: simples e completas. A carteira gera o primeiro quando uma transação utiliza mais de um input, o segundo - na situação oposta. Eles diferem na validação dos valores das transações e nos dados assinados com assinatura MLSAG (falaremos mais sobre isso a seguir). Além disso, transações do tipo full podem ser geradas com qualquer número de entradas, não havendo diferença fundamental. No livro
Assinatura MLSAG
Vamos lembrar o que são entradas de transações assinadas. Cada transação gasta e gera alguns fundos. A geração de fundos ocorre através da criação de saídas de transação (uma analogia direta são as notas), e a saída que a transação gasta (afinal, na vida real gastamos notas) passa a ser a entrada (cuidado, é muito fácil se confundir aqui).
Uma entrada faz referência a múltiplas saídas, mas gasta apenas uma, criando assim uma “cortina de fumaça” que dificulta a análise do histórico da tradução. Se uma transação tiver mais de uma entrada, então tal estrutura pode ser representada como uma matriz, onde as linhas são as entradas e as colunas são as saídas mistas. Para provar à rede que a transação gasta exatamente suas saídas (conhece suas chaves secretas), as entradas são assinadas com uma assinatura em anel. Tal assinatura garante que o signatário conhecia as chaves secretas de todos os elementos de qualquer uma das colunas.
As transações confidenciais não usam mais as clássicas
Eles são chamados de multicamadas porque assinam várias entradas ao mesmo tempo, cada uma delas misturada com várias outras, ou seja, uma matriz é assinada, e não uma linha. Como veremos mais tarde, isso ajuda a economizar no tamanho da assinatura.
Vejamos como uma assinatura de anel é formada, usando o exemplo de uma transação que gasta 2 saídas reais e usa m - 1 saídas aleatórias do blockchain para mixagem. Vamos denotar as chaves públicas dos resultados que gastamos como
e imagens principais para eles de acordo: Assim, obtemos uma matriz de tamanho 2xm. Primeiro, precisamos calcular os chamados desafios para cada par de resultados:
Iniciamos os cálculos com os resultados, que gastamos usando suas chaves públicas:e números aleatóriosComo resultado, obtemos os seguintes valores:
, que usamos para calcular o desafio
o próximo par de saídas (para facilitar a compreensão do que estamos substituindo e onde, destacamos esses valores em cores diferentes). Todos os valores a seguir são calculados em círculo usando as fórmulas fornecidas na primeira ilustração. A última coisa a calcular é o desafio para um par de resultados reais.
Como podemos ver, todas as colunas, exceto aquela que contém resultados reais, usam números gerados aleatoriamente. Para π- coluna também precisaremos deles. Vamos transformarem S:
A assinatura em si é uma tupla de todos estes valores:
Esses dados são então gravados em uma transação.
Como podemos ver, o MLSAG contém apenas um desafio c0, que permite economizar no tamanho da assinatura (que já ocupa muito espaço). A seguir, qualquer inspetor, usando os dados, restaura os valores c1,…, cm e verifica se. Assim, nosso anel está fechado e a assinatura foi verificada.
Para transações RingCT do tipo completo, mais uma linha é adicionada à matriz com saídas mistas, mas falaremos sobre isso a seguir.
Compromissos Pedersen
Os compromissos Monero são usados para ocultar os valores das transferências e usam a opção mais comum - os compromissos Pedersen. A propósito, um fato interessante - a princípio os desenvolvedores propuseram ocultar os valores por mistura comum, ou seja, adicionar resultados em valores arbitrários para introduzir incerteza, mas depois mudaram para compromissos (não é fato que economizaram em o tamanho da transação, como veremos abaixo).
Em geral, o compromisso é assim:
Onde C — o significado do próprio compromisso, a - quantia oculta, H é um ponto fixo na curva elíptica (gerador adicional), e x — algum tipo de máscara arbitrária, um fator de ocultação gerado aleatoriamente. A máscara é necessária aqui para que terceiros não possam simplesmente adivinhar o valor do compromisso.
Quando uma nova saída é gerada, a carteira calcula o compromisso para ela e, quando gasta, pega o valor calculado durante a geração ou o recalcula, dependendo do tipo de transação.
RingCT simples
No caso de transações simples do RingCT, para garantir que a transação criou produtos iguais à quantidade de insumos (não produziu dinheiro do nada), é necessário que a soma dos compromissos do primeiro e do segundo seja o isso mesmo, ou seja:
As comissões de compromisso consideram isso de uma forma um pouco diferente - sem máscara:
Onde a — o valor da comissão, está disponível ao público.
Essa abordagem nos permite provar à parte confiável que estamos usando os mesmos valores sem divulgá-los.
Para deixar as coisas mais claras, vejamos um exemplo. Digamos que uma transação gaste duas saídas (ou seja, elas se tornam entradas) de 10 e 5 XMR e gere três saídas no valor de 12 XMR: 3, 4 e 5 XMR. Ao mesmo tempo, ele paga uma comissão de 3 XMR. Assim, o valor gasto mais o valor gerado e a comissão é igual a 15 XMR. Vamos tentar calcular os compromissos e observar a diferença em seus valores (lembre-se da matemática):
Aqui vemos que para a equação convergir, precisamos que as somas das máscaras de entrada e saída sejam iguais. Para fazer isso, a carteira gera aleatoriamente x1, y1, y2 e y3, e o restante x2 calcula assim:
Usando estas máscaras, podemos provar a qualquer verificador que não geramos mais fundos do que gastamos, sem divulgar o montante. Originais, certo?
AnelCT completo
Nas transações completas do RingCT, verificar os valores da transferência é um pouco mais complicado. Nessas transações, a carteira não recalcula os compromissos de insumos, mas utiliza aqueles calculados no momento da geração. Neste caso, devemos assumir que não obteremos mais a diferença nas somas iguais a zero, mas sim:
é z — diferença entre máscaras de entrada e saída. Se considerarmos zG como uma chave pública (o que de fato é), então z é a chave privada. Assim, conhecemos as chaves públicas e privadas correspondentes. Com esses dados em mãos, podemos utilizá-los na assinatura do anel MLSAG junto com as chaves públicas das saídas que estão sendo mixadas:
Assim, uma assinatura de anel válida garantirá que conhecemos todas as chaves privadas de uma das colunas, e só poderemos conhecer a chave privada da última linha se a transação não gerar mais fundos do que gasta. A propósito, aqui está a resposta à pergunta “por que a diferença nos valores dos compromissos não leva a zero” - se zG = 0, então expandiremos a coluna com resultados reais.
Como o destinatário dos fundos sabe quanto dinheiro foi enviado para ele? Tudo é simples aqui - o remetente da transação e o destinatário trocam chaves usando o protocolo Diffie-Hellman, usando a chave da transação e a chave de visualização do destinatário e calculam o segredo compartilhado. O remetente grava dados sobre os valores de saída, criptografados com esta chave compartilhada, em campos especiais da transação.
Provas de alcance
O que acontece se você usar um número negativo como valor dos compromissos? Isto pode levar à geração de moedas adicionais! Este resultado é inaceitável, por isso precisamos de garantir que os valores que utilizamos não são negativos (sem divulgar esses valores, claro, caso contrário há tanto trabalho e tudo em vão). Em outras palavras, devemos provar que a soma está no intervalo [0, 2n - 1].
Para fazer isso, a soma de cada saída é dividida em dígitos binários e o compromisso é calculado para cada dígito separadamente. É melhor ver como isso acontece com um exemplo.
Vamos supor que nossas quantidades sejam pequenas e cabem em 4 bits (na prática são 64 bits) e criamos uma saída no valor de 5 XMR. Calculamos os compromissos para cada categoria e o compromisso total para o valor total:
Em seguida, cada compromisso é misturado com um substituto (Ci-2iH) e é assinado em pares com a assinatura do anel Borromeo (outra assinatura do anel), proposta por Greg Maxwell em 2015 (você pode ler mais sobre isso
Em conjunto, isso é chamado de prova de intervalo e permite garantir que os compromissos usem valores no intervalo [0, 2n - 1].
Qual é o próximo?
Na implementação atual, as provas de intervalo ocupam muito espaço – 6176 bytes por saída. Isso leva a transações maiores e, portanto, a taxas mais altas. Para reduzir o tamanho de uma transação Monero, os desenvolvedores estão introduzindo bulletproofs em vez de assinaturas Borromeo – um mecanismo de prova de intervalo sem compromissos bit a bit.
Tire suas dúvidas, sugira temas para novos artigos sobre tecnologias na área de criptomoedas e também inscreva-se em nosso grupo em
Fonte: habr.com