Hi! I thought I'd write this up while it was fresh in my mind. It
could be used as an alternative method to the current proposed client
authentication mechanism. We could implement both, or just this, or
just the other.
My description here will be a bit terser than we'd want in a proper
proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication
design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden
service operator about the public key. This keypair takes the place
of the long-term shared secret. For some client C, denote the secret
key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y,
Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y)
and uses this as the input for two KDF functions. Call these outputs
K1_C and K2_C. The hidden service generates an auth-client line for
each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is
derived from a truncated version of K1_C, and the encrypted-cookie
portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer,
then sees the value of Y that the hidden server advertised. It
computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C
to find the appropriate entry on the list, and then uses K2_C to
decrypt it and find the descriptor cookie.
=============
Advantages:
* managing public keys can be easier than managing shared secrets.
* The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
* probably others?
Disadvantages:
* Curve25519 costs more computationally than non-public-key operations
* probably others?
--
Nick