mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Move docs to spec
This commit is contained in:
35
spec/cryptography/Distributed Key Generation.md
Normal file
35
spec/cryptography/Distributed Key Generation.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Distributed Key Generation
|
||||
|
||||
Serai uses a modification of Pedersen's Distributed Key Generation, which is
|
||||
actually Feldman's Verifiable Secret Sharing Scheme run by every participant, as
|
||||
described in the FROST paper. The modification included in FROST was to include
|
||||
a Schnorr Proof of Knowledge for coefficient zero, preventing rogue key attacks.
|
||||
This results in a two-round protocol.
|
||||
|
||||
### Encryption
|
||||
|
||||
In order to protect the secret shares during communication, the `dkg` library
|
||||
establishes a public key for encryption at the start of a given protocol.
|
||||
Every encrypted message (such as the secret shares) then includes a per-message
|
||||
encryption key. These two keys are used in an Elliptic-curve Diffie-Hellman
|
||||
handshake to derive a shared key. This shared key is then hashed to obtain a key
|
||||
and IV for use in a ChaCha20 stream cipher instance, which is xor'd against a
|
||||
message to encrypt it.
|
||||
|
||||
### Blame
|
||||
|
||||
Since each message has a distinct key attached, and accordingly a distinct
|
||||
shared key, it's possible to reveal the shared key for a specific message
|
||||
without revealing any other message's decryption keys. This is utilized when a
|
||||
participant misbehaves. A participant who receives an invalid encrypted message
|
||||
publishes its key, able to without concern for side effects, With the key
|
||||
published, all participants can decrypt the message in order to decide blame.
|
||||
|
||||
While key reuse by a participant is considered as them revealing the messages
|
||||
themselves, and therefore out of scope, there is an attack where a malicious
|
||||
adversary claims another participant's encryption key. They'll fail to encrypt
|
||||
their message, and the recipient will issue a blame statement. This blame
|
||||
statement, intended to reveal the malicious adversary, also reveals the message
|
||||
by the participant whose keys were co-opted. To resolve this, a
|
||||
proof-of-possession is also included with encrypted messages, ensuring only
|
||||
those actually with per-message keys can claim to use them.
|
||||
62
spec/cryptography/FROST.md
Normal file
62
spec/cryptography/FROST.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# 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, every nonce would require two DLEq proofs. To
|
||||
make this more efficient, we hash their commitments to obtain a binding factor,
|
||||
before doing a single DLEq proof for `d + be`, similar to how FROST calculates
|
||||
its nonces (as well as MuSig's key aggregation).
|
||||
|
||||
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.
|
||||
|
||||
When multiple nonces are used, with multiple generators, we use a single DLEq
|
||||
proof for all nonces, merging their challenges. This provides a proof of `1 + n`
|
||||
elements instead of `2n`.
|
||||
|
||||
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 added to the
|
||||
participant with the lowest ID.
|
||||
|
||||
# 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.
|
||||
Reference in New Issue
Block a user