Skip to content

Instantly share code, notes, and snippets.

@0xtav
Created April 28, 2025 05:24
Show Gist options
  • Save 0xtav/8c0d604b77d101535f48183c6f279e68 to your computer and use it in GitHub Desktop.
Save 0xtav/8c0d604b77d101535f48183c6f279e68 to your computer and use it in GitHub Desktop.

Schnorr

Schnorr é um esquema de assinatura digital baseado no problema matemático de logaritmo discreto. Foi proposta por Claus Schnorr em 1989, sendo uma alternativa segura e eficiente ao sistema de assinado digital DSA (Digital Signature Algorithm).

O esquema de assinatura Schnorr tem algumas vantagens notáveis sobre outras técnicas de assinatura, como a menor complexidade computacional e a possibilidade de agregar assinaturas (ou seja, combinar várias assinaturas em uma só), o que é muito útil em sistemas como o Bitcoin.


Fundamentos Matemáticos da Criptografia Schnorr

A criptografia Schnorr utiliza conceitos de grupos cíclicos e a dificuldade do problema do logaritmo discreto. Vamos entender os passos principais desse algoritmo.

Grupo Cíclico e Parâmetros

O primeiro passo em um esquema de assinatura Schnorr é definir um grupo cíclico ( G ) de ordem ( q ), onde ( q ) é um número primo grande. Dentro desse grupo, há um gerador ( g ), tal que qualquer elemento ( g^k ) (onde ( k ) é um número inteiro) é um elemento do grupo.

  • ( q ): ordem do grupo (número primo)
  • ( g ): gerador do grupo

Para simplificação, supomos que temos um campo ( \mathbb{Z}_q ) (os inteiros módulo ( q )).

Chaves

  1. Chave privada (( x )): Um número secreto escolhido aleatoriamente pelo usuário.
  2. Chave pública (( y )): Calculada como ( y = g^x \mod q ).

Assim, a chave pública é uma representação do valor da chave privada no grupo cíclico ( G ).


Geração de Assinatura Schnorr

A geração de uma assinatura Schnorr envolve três etapas principais:

  1. Escolha de um número aleatório: O signatário escolhe um número aleatório ( k ) tal que ( 0 \leq k < q ).

  2. Cálculo do compromisso: O signatário calcula um compromisso ( r ) como: [ r = g^k \mod q ] Aqui, ( r ) é um valor que "compromete" o signatário a um valor sem revelar o valor de ( k ).

  3. Cálculo do desafio: O signatário então calcula o desafio ( e ), que é um hash do compromisso ( r ) concatenado com a mensagem ( m ) a ser assinada. Este passo assegura a integridade da assinatura: [ e = H(r || m) ] onde ( H ) é uma função hash criptográfica segura (como SHA-256).

  4. Cálculo da resposta: Finalmente, o signatário calcula a resposta ( s ) como: [ s = k - e \cdot x \mod q ] onde ( x ) é a chave privada e ( e ) é o desafio calculado anteriormente.

A assinatura final é o par de valores ( (r, s) ).


Verificação da Assinatura Schnorr

A verificação de uma assinatura Schnorr envolve o seguinte processo:

  1. Cálculo do compromisso: O verificador recebe a assinatura ( (r, s) ) e a mensagem ( m ). Em seguida, calcula: [ r' = g^s \cdot y^e \mod q ] onde ( y ) é a chave pública do signatário e ( e ) é o desafio calculado como: [ e = H(r' || m) ]

  2. Comparação do compromisso: Se ( r' ) for igual ao ( r ) enviado na assinatura, então a assinatura é válida, caso contrário, é inválida.

Ou seja, a verificação verifica se o compromisso ( r ) e a resposta ( s ) são consistentes com a chave pública ( y ) e a mensagem ( m ).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment