[dlc-dev] DLC without pre-committed R values
bjelanovic.goran at gmail.com
Tue Nov 22 11:55:20 CET 2022
I've been playing with DLC lately. Mainly with oracle implementation in
regard to perpetual contracts. And my biggest concern is the number of R
values needed to be pre-committed and to be saved by the oracle. If oracle
pre-commits to R-value where the contract is going to be resolved after a
longer time period (weeks, months) it is not a big issue. But in the case
of perpetual contracts, which are resolved every hour(or less), the number
of R values for an oracle and contract participants to store starts to grow
rapidly. Especially if besides price we are interested in open price,
closed price, RSI, EMA, etc. We could also be interested in 4h, 1D, or
weekly charts. Oracle has to precompute and publish R for each trading pair
(BTC/USD, EUR/LTC, etc...), for each price indicator (open, close, EMA,
RSI, etc...), for each time interval (1h, 4h, 1D, etc...), for each moment
in the time interval from the moment oracle is created to infinity. To
reduce storage impact oracle can publish R on demand, but in the case of
perpetual contracts, all R values have to be pre-committed and published at
least a couple of hours or a day ahead, so that contract participants can
create their CTEs on time. Also what do with old(already signed or not yet
signed events)? Delete or hold them for some time?
The issue made me think. From the oracle and contract participants'
perspective, it would be nice if contract participants could calculate R
without contacting the oracle, but only the oracle can calculate k. (R =
k*G). My first idea was to use something like HD wallets from bitcoin, but
then I thought there might be something simpler.
Rather than commit R for every possible (trading pair, price indicator,
time, digit, mantissa, exponent, ...) combination, oracle just commits to
two public keys (P1, P2) for all oracle events:
P1 = p1 * G
P2 = p2 * G
Only oracle knows p1 and p2.
p2 has the same role as the private key in the regular Schnorr signature.
p1 is used to generate k(and thus R). P2 is used to generate R by contract
If we recall Schnorr singature is:
s = k + hash(m || R) * p2
and a signature public key is:
S = R + hash(m || R) * P2
Now, we change R to depend on the message:
k = hash(m || P2) * p1
R = hash(m || P2) * P1
Only oracle can calculate k, but every contract participant can calculate R
for any message(and thus signature public key S for their CTEs) in advance.
Contract participants need to contact the oracle only for the contract
resolution. Oracle doesn't have to store any additional data except two
Every oracle has to publish which format of the messages they support, for
instance: "It was [cloudy|rainy|sunny] at yyyy-mm-dd hh:mm", "Closing price
of bitcoin at yyyy-mm-dd was greater than %d", etc...
When a contract resolution event is reached, participants will contact the
oracle with a message, matching oracle format, to sign. For instance: "It
was cloudy at 2022-11-11 12:00". Oracle will parse the message and if the
statement matches the oracle's knowledge of the event, the oracle will sign
the message. If the message is not in the correct format or the statement
is false, the oracle will not sign the message, and it will return an error
Because R is now calculated from the message, two different messages for
the same event will produce two different R values. This means that an
oracle can sign two different outcomes for the same event without revealing
its private key. Oracle revealing a private key, if it signs two different
outcomes is a nice feature, but in the case of DLC, it doesn't bring much.
At least I couldn't come up with a valid reason, what would be the benefit
to the oracle in signing two different outcomes. I could see a benefit in
signing the wrong outcome if one counterparty bribes the oracle, but not
With pre-committed R, an oracle can deposit some funds into an address with
a public key corresponding to the public key of the oracle. If oracle signs
two messages with the same R this private key is leaked, and anyone will be
able to collect those funds. Again, I don't think something like this is a
likely scenario. Because, if oracle is ready to sign two different
outcomes(for whatever reason), the first thing it will do is to move those
funds, and then sign two different R outcomes. Sure, contract participants
will be aware in advance that oracle is going rogue when those funds are
moved, but they can't do anything about it. All they can do against the
oracle is to publish the proof of double sign. Which is the same as what
contract participants without pre-committed R-value will do. In both DLC
implementations, with or without pre-committed R, contract participants
will publish two conflicting signed messages from the oracle as proof of
cheating. Also, it might be possible to write a CET, in such a matter if
multiple outcomes are signed contract is nullified, and thus minimize the
consequences of this scenario.
I'm no expert in this field at all, and I might be missing something big
here. I'd love to hear what you think.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the dlc-dev