The server has a private key \(x\) and public key \(X =
x*G\).
(\(G\) is the generator point of an elliptic curve -
basically all you need to know is that it is
impossible to find \(x\) from knowing \(X\)).
Server generates a random secret \(k\) and public nonce \(R=k*G\), and saves them.
Request the server to produce a signature for the
challenge using the nonce secret \(k\) and private key
\(x\)
\(s = k + c'*x\).
Signature \(s\):
Choose a message \(m\) and generate three random scalar
values \(\alpha, \beta, t\).
These scalars will used to blind (disguise) what we
request the server to sign.
Blinding values:
Blind the nonce \(R' = R + \alpha*G + \beta*X\).
Blind the public key \(X' = X + t*G\).
For a message \(m\) create a challenge \(c = H(X', R', m)\) using a hash function \(H\), then blind it \(c' = c + \beta\).
Blinded nonce \(R'\):
Blinded pubkey \(X'\):
Challenge \(c'\):
Use the blinding values to get the tweaked signature \(s' = s + \alpha + c*t\).
Signature \(s'\):
Once the user shares this signature-nonce pair, anyone
can now verify that the signature-nonce pair \((s', R)\)
solves the schnorr verification equation \(s' * G = R' +
c*X'\) for some message \(m\) (see proof below).
Most importantly,
the server has no way of correlating this
signature-nonce pair with the challenge and nonce they
signed with earlier.
Valid?:
Prove \((s', R')\) solves the schnorr verification equation \((s' * G = R' + c*X')\) for challenge \(c\) under public key \(X'\).
Hint: Expand \(s'\) from definitions (plug and chug algebra)