Skip to content

Instantly share code, notes, and snippets.

@adiabat
Last active April 12, 2018 22:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save adiabat/b9a35187460582d4c0081997da278fa2 to your computer and use it in GitHub Desktop.
Save adiabat/b9a35187460582d4c0081997da278fa2 to your computer and use it in GitHub Desktop.
DLC oracle publicly computable R-points
[DON'T USE]
pretty sure none of this works.
The sigantures in DLC need a pre-committed R point as well as pubkey point.
Oracle pubkey = A, R
value message = v
signature = s
(generator point G)
Contract participants compute oracle point P
P = sG = R - h(v, R)A
and add P to their own keys for price-specific transactions within the contract.
The oracle's (A, R) pair can only sign a single price without revealing the private key for A (& R). This means that for every different product and time, different R points will need to be published.
The A point can be shared among all the signatures and should be to indicate that it's the same oracle doing the signing.
The R points aren't exactly huge, but it's a bit annoying to have to request them all. Also, you really should request them all, because otherwise you reveal which products / times you are interested in trading.
A nicer way to do it is to have the oracle's different R points be computable from publicly available data. This is possible using the same construction as the DLC signatures themselves, except in this case the oracle must never reveal the actual signature.
## method
The oracle publishes three points, A, B and Q. The oracle knows the discrete logs (private keys) of all 3 of these points. They should be independent, so if Q = 2A or something bad things will happen.
They also sign off on an agreed / standardized method to encode messages regarding the product (what thing they're reporting the value of), time (when they'll report it) and final value. Split this into two messages: t is the type and timing data, and v is the value data that the oracle reports.
Clients can enumerate the t message they're interested in, and compute the R point from t.
R = Q - h(t, Q)B
once they have R, they can compute the oracle signature points P
P = R - h(v, R)A
for the oracle to sign, they first compute k
k = q - h(t, Q)b
then use it to sign v
s = k - h(v, R)a
the oracle will reveal s, but never reveals k. This allows then to re-use B and Q for all the different type messages t. With this system, the DLC clients can store a 97 byte oracle (A, B, Q) set and derive any point from that.
In practice they need some indication that the oracle is actually *aware* of the t the clients want them to report on, and intends to actually sign the value v then. So there's some other data needed than just the A, B, Q points. But over the long term, if the clients know that the oracle always is signing e.g. the price of the dollar every day at 5pm, they can maintain just those points and make many contracts with that data, and not request more data from the oracles to construct the contracts. (signature s scalars still need to be broadcast by the oracle to report the value)
two points instead of 3:
you could just set B = A, and it seems to work fine. You can factor out the a after the signature happens, so
s = q - h(t, qG)a - h(v, R)a = q - (h1+h2)a
which doesn't actually seem dangerous since you still don't know q or a. But just the fact that you can do *something* feels like to stay safe, maybe the k calculation not use a at all. Then it's
s = q - h(t, qG)b - h(v, qG - h(t, qG)bG)a
= q - h1b + h2a
which doesn't let you factor out the a and add the two hashes.
## even simpler [DOESN'T WORK] [IGNORE]
In fact... the simplest possible way to do it is to have the oracle give points A, Q.
The client computes R = h(t)*Q. Then computes sG = R - h(t, R)A.
The oracle signs with s = h(t)q - h(v)a. That's as simple as you can get.
worst case, say you're signing the SAME v (in practice it could make sense to have v contain information from t)
s1 = h(t1)q - h(v, R1)a
s2 = h(t2)q - h(v, R2)a
s1 - s2 = h(t1)q - h(v, R1)a - h(t2)q - h(v, R2)a
= q(h(t1) - h(t2)) + a(h(v, R2) - h(v, R1))
nothing cancels out...
but that doesn't work because you've got 2 equations 2 unknowns. You can figure out everything. First solve for q in terms of a, then solve for a with the other, and substitute.
@gertjaap
Copy link

gertjaap commented Apr 12, 2018

I think the A in the signature should be a ?

then use it to sign v
s = k - h(v, R)A

@adiabat
Copy link
Author

adiabat commented Apr 12, 2018

@gertjaap - yup, you're right! thanks!

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