Da ideia à implementação: modificamos o esquema existente de assinatura digital em curvas elípticas para torná-lo determinístico e fornecemos, com base nisso, funções para obter números pseudoaleatórios verificáveis dentro da blockchain.

Ideia
No outono de 2018, a blockchain Waves teve , imediatamente surgiram questões sobre a possibilidade de obter , em que se pode confiar.
Refletindo sobre esta questão, cheguei à conclusão de que qualquer blockchain é uma cela; obter uma fonte confiável de entropia em um sistema fechado é impossível.
Mas uma ideia ainda me agradou: se um fizer a assinatura dos dados do usuário com um algoritmo determinístico, o usuário sempre poderá verificar essa assinatura com a chave pública e estará certo de que o valor obtido é único. O oráculo, por mais que deseje, não pode alterar nada; o algoritmo fornece um resultado único. Na verdade, o usuário fixa o resultado, mas não sabe qual é até que o oráculo o publique. Isso significa que se pode, de fato, não confiar no oráculo, mas verificar o resultado de seu trabalho. Então, em caso de verificação bem-sucedida, tal assinatura pode ser considerada uma fonte de entropia para um número pseudoaleatório.
Na plataforma blockchain Waves, utiliza-se o esquema de assinatura uma variante . Neste esquema, a assinatura consiste nos valores R e S, onde R depende de um valor aleatório, e S é calculado com base na mensagem que está sendo assinada, na chave privada e no mesmo número aleatório que R. Isso resulta em uma dependência não única, ou seja, para a mesma mensagem do usuário, existem várias assinaturas válidas.
É evidente que, em sua forma pura, tal assinatura não pode ser usada como fonte de números pseudoaleatórios, pois é não determinística e, portanto, pode ser facilmente manipulada pelo oráculo.
Mas, como se revelou, é realmente possível torná-la determinística.
Tinha grandes esperanças na , mas após estudar a parte teórica, tivemos que desistir dessa opção. Embora o VRF ofereça uma assinatura determinística e sua prova, há um ponto estranho no algoritmo que abre uma brecha para manipulações do oráculo. Especificamente, ao calcular o valor de k () utiliza-se uma chave privada, que permanece desconhecida para o usuário, logo o usuário não pode verificar a correção do cálculo de k, o que significa que o oráculo pode usar qualquer valor de k desejado e, ao mesmo tempo, manter um banco de dados de correspondências entre k e os dados assinados, de modo a sempre conseguir recalcular o resultado que agrada ao VRF. Se você vir um sorteio baseado em VRF sem a divulgação da chave privada, pode fazer uma observação: aponto a necessidade de divulgar a chave ou excluí-la do cálculo de k, então a chave privada se revelará automaticamente ao surgir a primeira assinatura. Em suma, como já foi mencionado, um esquema estranho para um oráculo aleatório.
Após refletir um pouco e obter o apoio de analistas locais, nasceu o esquema de funcionamento do VECRO.
VECRO é a sigla para Verifiable Elliptic Curve Random Oracle, que em português significa oráculo aleatório verificável sobre curvas elípticas.
Tudo se mostrou bastante simples; para alcançar a determinística é necessário fixar o valor de R antes do surgimento da mensagem a ser assinada. Se R estiver fixado e faz parte da mensagem a ser assinada, o que garante adicionalmente a fixação de R na própria mensagem, o valor de S é univocamente determinado pela mensagem do usuário e, portanto, pode ser usado como fonte para números pseudoaleatórios.
Neste esquema, não importa como R é fixado, isso fica a critério do oráculo. O importante é que S é definido de forma inequívoca pelo usuário, mas seu valor permanece desconhecido até que o oráculo o publique. Tudo como queríamos!
Falando sobre R fixo, observe que A assinatura de diferentes mensagens revela definitivamente a chave privada no esquema EdDSA. Para o proprietário do oráculo, é extremamente importante excluir a possibilidade de reutilização de R para a assinatura de mensagens diferentes do usuário. Ou seja, em qualquer manipulação ou conluio, o oráculo sempre correrá o risco de perder sua chave privada.
Em suma, o oráculo deve fornecer aos usuários duas funções: inicialização, que fixa o valor de R, e assinatura, que retorna o valor de S. Nesse processo, a par R, S constitui uma assinatura verificável comum da mensagem do usuário que contém o valor fixo de R e dados arbitrários do usuário.
Pode-se argumentar que este schema para blockchain não é nada além de um simples . De fato, sim, é isso mesmo. Mas há algumas nuances. Primeiro, o oráculo sempre trabalha com a mesma chave em todas as operações, por exemplo, isso é conveniente para o uso em contratos. Em segundo lugar, existe o risco de o oráculo perder a chave privada devido a comportamentos inadequados, como quando o oráculo permite fazer amostras do resultado; neste caso, basta fazer apenas duas amostras para descobrir a chave privada e obter acesso total à carteira. Em terceiro lugar, a assinatura nativamente verificável no blockchain, que é a fonte de aleatoriedade — isso é bonito.
A ideia de implementação maturou na minha mente por seis meses, até que finalmente surgiu a motivação na forma de . Com um grande subsídio vem uma grande responsabilidade, então o projeto deve acontecer!
Implementação
Assim, neste projeto, no blockchain da Waves em modo de solicitação-resposta através de transações de transferência entre o usuário e o oráculo. Neste processo, o script do oráculo controla o trabalho de acordo com a lógica descrita acima. As transações do oráculo são verificadas com a recuperação de toda a cadeia de interação com o usuário. Todas as quatro transações participam da verificação do valor final, e o contrato inteligente as encadeia em uma rigorosa linha de verificação, passo a passo checando todos os valores e não deixando espaço para manipulações.
Mais uma vez, para que fique claro. O oráculo não apenas opera segundo o esquema proposto. Seu funcionamento é totalmente controlado ao nível do blockchain. . Um passo para o lado, e a transação simplesmente não irá passar. Portanto, se a transação entrou na blockchain, o usuário não precisa verificar nada, pois tudo já foi checado por centenas de nós na rede.
Atualmente, na rede principal do Waves, um VECRO está em funcionamento (você pode iniciar o seu, não é difícil, basta ). O código atual funciona em PHP (em , sobre o qual ).
Para aproveitar o serviço do oráculo, é necessário:
- Registrar R;
- Enviar no mínimo 0.005 Waves para o alias do oráculo init@vecr;
- Receber o R-code no campo de anexos na transferência de 1 token R-vecr do oráculo para o usuário;
- Receber a assinatura;
- Enviar no mínimo 0.005 Waves para o alias do oráculo random@vecr, e também OBRIGATORIAMENTE indicar no campo de anexos o R-code recebido anteriormente e os dados adicionais do usuário;
- Receber o S-code no campo de anexos na transferência de 1 token S-vecr do oráculo para o usuário;
- Utilizar o S-code como fonte de número pseudoaleatório.
Nuances da implementação atual:
- Os Waves enviados ao oráculo são utilizados como taxa para a transação de retorno ao usuário, até um máximo de 1 Waves;
- R-code é a concatenação do byte do símbolo ‘R’ e do valor R de 32 bytes em codificação base58;
- O R-code no anexo deve ser o primeiro, os dados do usuário vêm após o R-code;
- S-code é a concatenação do byte do símbolo ‘S’ e do valor S de 32 bytes em codificação base58;
- S é o resultado da divisão módulo, portanto não se pode usar S como um número pseudoaleatório de 256 bits (esse número pode ser considerado no máximo um número pseudoaleatório de 252 bits);
- A opção mais simples é usar como número pseudoaleatório o hash do S-code.
Exemplo de obtenção do S-code:
- Inicialização:
- Obtenção do R-code:
- Solicitação do resultado da assinatura do R-code e dos dados do usuário 'random':
- Obtenção do S-code:
Do ponto de vista técnico, o oráculo está completamente pronto para uso, você pode utilizá-lo sem problemas. Do ponto de vista do usuário comum, falta uma interface gráfica conveniente, mas isso terá que esperar.
Ficarei feliz em responder às perguntas e receber feedback, obrigado.
Fonte: habr.com
