serai/docs/cryptography/FROST.md
Luke Parker af86b7a499
Support caching preprocesses in FROST (#190)
* Remove the explicit included participants from FROST

Now, whoever submits preprocesses becomes the signing set. Better separates
preprocess from sign, at the cost of slightly more annoying integrations
(Monero needs to now independently lagrange/offset its key images).

* Support caching preprocesses

Closes https://github.com/serai-dex/serai/issues/40.

I *could* have added a serialization trait to Algorithm and written a ton of
data to disk, while requiring Algorithm implementors also accept such work.
Instead, I moved preprocess to a seeded RNG (Chacha20) which should be as
secure as the regular RNG. Rebuilding from cache simply loads the previously
used Chacha seed, making the Algorithm oblivious to the fact it's being
rebuilt from a cache. This removes any requirements for it to be modified
while guaranteeing equivalency.

This builds on the last commit which delayed determining the signing set till
post-preprocess acquisition. Unfortunately, that commit did force preprocess
from ThresholdView to ThresholdKeys which had visible effects on Monero.

Serai will actually need delayed set determination for #163, and overall,
it remains better, hence it's inclusion.

* Document FROST preprocess caching

* Update ethereum to new FROST

* Fix bug in Monero offset calculation and update processor
2022-12-08 19:04:35 -05:00

56 lines
2.9 KiB
Markdown

# FROST
Serai implements [FROST](https://eprint.iacr.org/2020/852), as specified in
[draft-irtf-cfrg-frost-11](https://datatracker.ietf.org/doc/draft-irtf-cfrg-frost/).
### Modularity
In order to support other algorithms which decompose to Schnorr, our FROST
implementation is generic, able to run any algorithm satisfying its `Algorithm`
trait. With these algorithms, there's frequently a requirement for further
transcripting than what FROST expects. Accordingly, the transcript format is
also modular so formats which aren't naive like the IETF's can be used.
### Extensions
In order to support algorithms which require their nonces be represented across
multiple generators, FROST supports providing a nonce's commitments across
multiple generators. In order to ensure their correctness, an extended
[CP93's Discrete Log Equality Proof](https://chaum.com/wp-content/uploads/2021/12/Wallet_Databases.pdf)
is used. The extension is simply to transcript `n` generators, instead of just
two, enabling proving for all of them at once. Since FROST nonces are binomial,
two DLEq proofs are provided, one for each nonce component. In the future, a
modified proof proving for both components simultaneously may be used.
As some algorithms require multiple nonces, effectively including multiple
Schnorr signatures within one signature, the library also supports providing
multiple nonces. The second component of a FROST nonce is intended to be
multiplied by a per-participant binding factor to ensure the security of FROST.
When additional nonces are used, this is actually a per-nonce per-participant
binding factor.
Finally, to support additive offset signing schemes (accounts, stealth
addresses, randomization), it's possible to specify a scalar offset for keys.
The public key signed for is also offset by this value. During the signing
process, the offset is explicitly transcripted. Then, the offset is divided by
`p`, the amount of participating signers, and each signer adds it to their
post-interpolation key share.
# Caching
modular-frost supports caching a preprocess. This is done by having all
preprocesses use a seeded RNG. Accordingly, the entire preprocess can be derived
from the RNG seed, making the cache just the seed.
Reusing preprocesses would enable a third-party to recover your private key
share. Accordingly, you MUST not reuse preprocesses. Third-party knowledge of
your preprocess would also enable their recovery of your private key share.
Accordingly, you MUST treat cached preprocesses with the same security as your
private key share.
Since a reused seed will lead to a reused preprocess, seeded RNGs are generally
frowned upon when doing multisignature operations. This isn't an issue as each
new preprocess obtains a fresh seed from the specified RNG. Assuming the
provided RNG isn't generating the same seed multiple times, the only way for
this seeded RNG to fail is if a preprocess is loaded multiple times, which was
already a failure point.