The goal of this protocol is for Bob to get Alice to perform a Diffie-Hellman key exchange blindly, such that when the unblinded value is returned, Alice recognizes it as her own, but can’t distinguish it from others (i.e. similar to a blind signature).
Alice:
A = a*G
return A
Bob:
Y = hash_to_curve(secret_message)
r = random blinding factor
B'= Y + r*G
return B'
Alice:
C' = a*B'
(= a*Y + a*r*G)
return C'
Bob:
C = C' - r*A
(= C' - a*r*G)
(= a*Y)
return C, secret_message
Alice:
Y = hash_to_curve(secret_message)
C == a*Y
If true, C must have originated from Alice
I unearthed this protocol from a seemingly long forgotten cypherpunk mailing list post by David Wagner from 1996 (edit: perhaps not as forgotten as I thought, as Lucre is an implementation of it). It was devised as an alternative to RSA blinding in order to get around the now-expired patent by David Chaum. As in all ecash protocols, the secret_message
is remembered by Alice
in order to prevent double spends.
One benefit of this scheme is that it's relatively straightforward to perform in a threshold setting (only requires curve multiplication). One downside is that validation is more involved than simply checking a signature, as this step requries repeating the Diffie-Hellman Key Exchange.
The protocol also has one additional weakness that can be addressed. Bob can't be certain that C'
was correctly generated and thus corresponds to a*B'
. Alice can resolve this by also supplying a discrete log equality proof (DLEQ), showing that a
in A = a*G
is equal to a
in C' = a*B'
. This equality can be proven with a relatively simple Schnorr signature, as described below.
(These steps occur once Alice returns C')
Alice:
r = random nonce
R1 = r*G
R2 = r*B'
e = hash(R1,R2,A,C')
s = r + e*a
return e, s
Bob:
R1 = s*G - e*A
R2 = s*B'- e*C'
e == hash(R1,R2,A,C')
If true, a in A = a*G must be equal to a in C' = a*B'
Thanks to Eric Sirion, Andrew Poelstra, and Adam Gibson for their helpful comments.
My impression from reading privacypass is: differences aren't too great, except that using a MAC with the key derived from the token, on some binding data, makes more sense than just transmitting the token directly. Reasoning as per @nothingmuch's statement above.
The difference between additive ($T = Y + rG$ ) and multiplicative ( $T = rY$ ) tweaking - that is less clear to me whether one is better than the other (performance: trivially the former looks like an extra step, but I don't know about that), and the fact that the latter requires a mod inverse in unblinding.
The security proof in the privacypass paper linked above, for reduction to one-more-ElGamal decryption, make sense (although it's a little terse, e.g. about the DLEQ part), I think that basically exactly the same proof would carry over for this scheme; because in both cases the purported$(l+1)$ one-more-token-forgery adversary:
The only extra bit in the proof for the privacypass case is, because of the use of the MAC, you have to make an RO lookup table for that. Other than that I think it's the same - please correct me if I'm wrong!
To switch to (much!) more practical considerations - I think a switch from this scheme to a privacypass or variant would not be that big of a deal for developers - using a HMAC is hardly difficult, and multiplicative instead of additive tweaking is similarly available from libsecp256k1 libs. I would be inclined to do that, even if I believed my own reasoning above (which is trying to claim that we have the same one-more-forgery reduction proof, more or less), since the former is more studied and analyzed (and has at least one extra feature).