Schnorr identification is a simple protocol that lets a verifier verify the identity of a prover and is secure against eavesdropping attacks under the discrete logarithm assumption.

What is an identity?#

Given a cyclic group GG of prime order qq with generator gGg \in G, an identity is given by the public key of a key pair owned by the prover, which is generated as follows:

  • secret key is a random element αZq\alpha \in \mathbb{Z}_{q}
  • public key is the group element u=gαGu = g^{\alpha} \in G

How does it work?#

Schnorr identification is an interactive protocol divided in four phases, where a Prover PP and a verifier VV exchange information with each other. In the first phase, prover PP computes a new key pair that will be used in conjunction with its identity. To do so, it computes a random αtZq\alpha_{t} \leftarrow \mathbb{Z_{q}}, then it derives ut=gαtu_{t} = g^{\alpha_{t}} and lastly it sends utu_{t} to VV. In the second phase, the verifier VV generates and sends to the prover PP a random challenge, which is an element cCc \in C, where CC is a subset of Zq\mathbb{Z_{q}}. In the third step, the prover PP computes and sends αzαt+αcZq\alpha_{z} \leftarrow \alpha_{t} + \alpha c \in \mathbb{Z_{q}} to the verifier VV. In the last step, the verifier VV outputs acceptaccept if gαz=utucg^{\alpha_{z}} = u_{t} u^{c}, rejectreject otherwise.
The algorithm is correct because, since ut=gαtu_{t} = g^{\alpha_{t}} and αz=αt+αc\alpha_{z} = \alpha_{t} + \alpha c, we have: gαz=gαt+αc=gαz(gα)c=utuc g^{\alpha_{z}} = g^{\alpha_{t} + \alpha c} = g^{\alpha_{z}} \cdot (g^{\alpha})^{c} = u_{t} \cdot u^{c}

Therefore the protocol outputs acceptaccept if both the prover and the verifier are correct.

Implementation#

The algorithm described above is taken from the book Applied Cryptography and I decided to implement it in Rust, using Curve25519 as a group and thus Z/lZ\mathbb{Z}/l\mathbb{Z} instead of Zq\mathbb{Z}_{q}. Because of this, I had to use EC multiplication with a scalar instead of exponentiation, and EC addition instead of multiplication. The source code can be found on my Github and is not meant to be production ready (also because of the limited use cases), rather more a personal experiment.